2022-01-14 18:49:22 +00:00
// Copyright 2020-2022 the Pinniped contributors. All Rights Reserved.
2020-10-09 00:40:58 +00:00
// SPDX-License-Identifier: Apache-2.0
package supervisorconfig
import (
"context"
2020-10-09 14:39:17 +00:00
"errors"
2021-02-05 17:56:05 +00:00
"fmt"
2020-10-23 23:25:44 +00:00
"net/url"
2020-10-09 14:39:17 +00:00
"reflect"
"sync"
2020-10-09 00:40:58 +00:00
"testing"
"time"
"github.com/sclevine/spec"
"github.com/sclevine/spec/report"
"github.com/stretchr/testify/require"
2020-10-09 14:39:17 +00:00
k8serrors "k8s.io/apimachinery/pkg/api/errors"
2020-10-09 00:40:58 +00:00
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2020-10-09 14:39:17 +00:00
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
coretesting "k8s.io/client-go/testing"
2021-12-10 22:22:36 +00:00
clocktesting "k8s.io/utils/clock/testing"
2020-10-09 00:40:58 +00:00
2021-02-16 19:00:08 +00:00
"go.pinniped.dev/generated/latest/apis/supervisor/config/v1alpha1"
pinnipedfake "go.pinniped.dev/generated/latest/client/supervisor/clientset/versioned/fake"
pinnipedinformers "go.pinniped.dev/generated/latest/client/supervisor/informers/externalversions"
2020-10-09 00:40:58 +00:00
"go.pinniped.dev/internal/controllerlib"
2020-10-09 14:39:17 +00:00
"go.pinniped.dev/internal/here"
2020-10-09 00:40:58 +00:00
"go.pinniped.dev/internal/oidc/provider"
"go.pinniped.dev/internal/testutil"
)
func TestInformerFilters ( t * testing . T ) {
spec . Run ( t , "informer filters" , func ( t * testing . T , when spec . G , it spec . S ) {
var r * require . Assertions
var observableWithInformerOption * testutil . ObservableWithInformerOption
var configMapInformerFilter controllerlib . Filter
it . Before ( func ( ) {
r = require . New ( t )
observableWithInformerOption = testutil . NewObservableWithInformerOption ( )
2020-12-17 19:34:49 +00:00
federationDomainInformer := pinnipedinformers . NewSharedInformerFactoryWithOptions ( nil , 0 ) . Config ( ) . V1alpha1 ( ) . FederationDomains ( )
2020-12-16 22:27:09 +00:00
_ = NewFederationDomainWatcherController (
2020-10-09 00:40:58 +00:00
nil ,
nil ,
nil ,
2020-12-17 19:34:49 +00:00
federationDomainInformer ,
2020-10-09 00:40:58 +00:00
observableWithInformerOption . WithInformer , // make it possible to observe the behavior of the Filters
)
2020-12-17 19:34:49 +00:00
configMapInformerFilter = observableWithInformerOption . GetFilterForInformer ( federationDomainInformer )
2020-10-09 00:40:58 +00:00
} )
2020-12-16 22:27:09 +00:00
when ( "watching FederationDomain objects" , func ( ) {
2020-10-09 00:40:58 +00:00
var subject controllerlib . Filter
2020-12-16 22:27:09 +00:00
var target , otherNamespace , otherName * v1alpha1 . FederationDomain
2020-10-09 00:40:58 +00:00
it . Before ( func ( ) {
subject = configMapInformerFilter
2020-12-16 22:27:09 +00:00
target = & v1alpha1 . FederationDomain { ObjectMeta : metav1 . ObjectMeta { Name : "some-name" , Namespace : "some-namespace" } }
otherNamespace = & v1alpha1 . FederationDomain { ObjectMeta : metav1 . ObjectMeta { Name : "some-name" , Namespace : "other-namespace" } }
otherName = & v1alpha1 . FederationDomain { ObjectMeta : metav1 . ObjectMeta { Name : "other-name" , Namespace : "some-namespace" } }
2020-10-09 00:40:58 +00:00
} )
2020-12-16 22:27:09 +00:00
when ( "any FederationDomain changes" , func ( ) {
2020-10-09 00:40:58 +00:00
it ( "returns true to trigger the sync method" , func ( ) {
r . True ( subject . Add ( target ) )
r . True ( subject . Add ( otherName ) )
r . True ( subject . Add ( otherNamespace ) )
r . True ( subject . Update ( target , otherName ) )
r . True ( subject . Update ( otherName , otherName ) )
r . True ( subject . Update ( otherNamespace , otherName ) )
r . True ( subject . Update ( otherName , target ) )
r . True ( subject . Update ( otherName , otherName ) )
r . True ( subject . Update ( otherName , otherNamespace ) )
r . True ( subject . Delete ( target ) )
r . True ( subject . Delete ( otherName ) )
r . True ( subject . Delete ( otherNamespace ) )
} )
} )
} )
} , spec . Parallel ( ) , spec . Report ( report . Terminal { } ) )
}
type fakeProvidersSetter struct {
2020-12-16 22:27:09 +00:00
SetProvidersWasCalled bool
2020-12-17 19:34:49 +00:00
FederationDomainsReceived [ ] * provider . FederationDomainIssuer
2020-10-09 00:40:58 +00:00
}
2020-12-17 19:34:49 +00:00
func ( f * fakeProvidersSetter ) SetProviders ( federationDomains ... * provider . FederationDomainIssuer ) {
2020-10-09 00:40:58 +00:00
f . SetProvidersWasCalled = true
2020-12-16 22:27:09 +00:00
f . FederationDomainsReceived = federationDomains
2020-10-09 00:40:58 +00:00
}
func TestSync ( t * testing . T ) {
spec . Run ( t , "Sync" , func ( t * testing . T , when spec . G , it spec . S ) {
2020-10-09 14:39:17 +00:00
const namespace = "some-namespace"
2020-10-09 00:40:58 +00:00
var r * require . Assertions
var subject controllerlib . Controller
2020-12-17 19:34:49 +00:00
var federationDomainInformerClient * pinnipedfake . Clientset
var federationDomainInformers pinnipedinformers . SharedInformerFactory
2020-10-09 00:40:58 +00:00
var pinnipedAPIClient * pinnipedfake . Clientset
2021-03-05 01:25:43 +00:00
var cancelContext context . Context
var cancelContextCancelFunc context . CancelFunc
2020-10-09 00:40:58 +00:00
var syncContext * controllerlib . Context
var frozenNow time . Time
var providersSetter * fakeProvidersSetter
2020-12-16 22:27:09 +00:00
var federationDomainGVR schema . GroupVersionResource
2020-10-09 00:40:58 +00:00
// Defer starting the informers until the last possible moment so that the
// nested Before's can keep adding things to the informer caches.
var startInformersAndController = func ( ) {
// Set this at the last second to allow for injection of server override.
2020-12-16 22:27:09 +00:00
subject = NewFederationDomainWatcherController (
2020-10-09 00:40:58 +00:00
providersSetter ,
2021-12-10 22:22:36 +00:00
clocktesting . NewFakeClock ( frozenNow ) ,
2020-10-09 00:40:58 +00:00
pinnipedAPIClient ,
2020-12-17 19:34:49 +00:00
federationDomainInformers . Config ( ) . V1alpha1 ( ) . FederationDomains ( ) ,
2020-10-09 00:40:58 +00:00
controllerlib . WithInformer ,
)
// Set this at the last second to support calling subject.Name().
syncContext = & controllerlib . Context {
2021-03-05 01:25:43 +00:00
Context : cancelContext ,
2020-10-09 00:40:58 +00:00
Name : subject . Name ( ) ,
Key : controllerlib . Key {
2020-10-09 14:39:17 +00:00
Namespace : namespace ,
2020-10-09 00:40:58 +00:00
Name : "config-name" ,
} ,
}
// Must start informers before calling TestRunSynchronously()
2021-03-05 01:25:43 +00:00
federationDomainInformers . Start ( cancelContext . Done ( ) )
2020-10-09 00:40:58 +00:00
controllerlib . TestRunSynchronously ( t , subject )
}
it . Before ( func ( ) {
r = require . New ( t )
providersSetter = & fakeProvidersSetter { }
frozenNow = time . Date ( 2020 , time . September , 23 , 7 , 42 , 0 , 0 , time . Local )
2021-03-05 01:25:43 +00:00
cancelContext , cancelContextCancelFunc = context . WithCancel ( context . Background ( ) )
2020-10-09 00:40:58 +00:00
2020-12-17 19:34:49 +00:00
federationDomainInformerClient = pinnipedfake . NewSimpleClientset ( )
federationDomainInformers = pinnipedinformers . NewSharedInformerFactory ( federationDomainInformerClient , 0 )
2020-10-09 00:40:58 +00:00
pinnipedAPIClient = pinnipedfake . NewSimpleClientset ( )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomainGVR = schema . GroupVersionResource {
2020-10-09 14:39:17 +00:00
Group : v1alpha1 . SchemeGroupVersion . Group ,
Version : v1alpha1 . SchemeGroupVersion . Version ,
2020-12-16 22:27:09 +00:00
Resource : "federationdomains" ,
2020-10-09 14:39:17 +00:00
}
2020-10-09 00:40:58 +00:00
} )
it . After ( func ( ) {
2021-03-05 01:25:43 +00:00
cancelContextCancelFunc ( )
2020-10-09 00:40:58 +00:00
} )
2020-12-16 22:27:09 +00:00
when ( "there are some valid FederationDomains in the informer" , func ( ) {
2020-10-09 14:39:17 +00:00
var (
2020-12-16 22:27:09 +00:00
federationDomain1 * v1alpha1 . FederationDomain
federationDomain2 * v1alpha1 . FederationDomain
2020-10-09 14:39:17 +00:00
)
2020-10-09 00:40:58 +00:00
it . Before ( func ( ) {
2020-12-16 22:27:09 +00:00
federationDomain1 = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "config1" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://issuer1.com" } ,
2020-10-09 00:40:58 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomain1 ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomain1 ) )
2020-10-09 00:40:58 +00:00
2020-12-16 22:27:09 +00:00
federationDomain2 = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "config2" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://issuer2.com" } ,
2020-10-09 00:40:58 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomain2 ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomain2 ) )
2020-10-09 00:40:58 +00:00
} )
2020-10-09 14:39:17 +00:00
it ( "calls the ProvidersSetter" , func ( ) {
2020-10-09 00:40:58 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-17 19:34:49 +00:00
provider1 , err := provider . NewFederationDomainIssuer ( federationDomain1 . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
2020-12-17 19:34:49 +00:00
provider2 , err := provider . NewFederationDomainIssuer ( federationDomain2 . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
2020-10-09 00:40:58 +00:00
r . True ( providersSetter . SetProvidersWasCalled )
2020-10-09 14:39:17 +00:00
r . ElementsMatch (
2020-12-17 19:34:49 +00:00
[ ] * provider . FederationDomainIssuer {
2020-10-09 14:39:17 +00:00
provider1 ,
provider2 ,
} ,
2020-12-16 22:27:09 +00:00
providersSetter . FederationDomainsReceived ,
2020-10-09 14:39:17 +00:00
)
} )
2020-12-16 22:27:09 +00:00
it ( "updates the status to success in the FederationDomains" , func ( ) {
2020-10-09 14:39:17 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-16 22:27:09 +00:00
federationDomain1 . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain1 . Status . Message = "Provider successfully created"
federationDomain1 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomain2 . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain2 . Status . Message = "Provider successfully created"
federationDomain2 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain1 . Namespace ,
federationDomain1 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain1 . Namespace ,
federationDomain1 ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain2 . Namespace ,
federationDomain2 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain2 . Namespace ,
federationDomain2 ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
2020-12-16 22:27:09 +00:00
when ( "one FederationDomain is already up to date" , func ( ) {
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
2020-12-16 22:27:09 +00:00
federationDomain1 . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain1 . Status . Message = "Provider successfully created"
federationDomain1 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Update ( federationDomainGVR , federationDomain1 , federationDomain1 . Namespace ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Update ( federationDomainGVR , federationDomain1 , federationDomain1 . Namespace ) )
2020-10-09 14:39:17 +00:00
} )
2020-12-16 22:27:09 +00:00
it ( "only updates the out-of-date FederationDomain" , func ( ) {
2020-10-09 14:39:17 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-16 22:27:09 +00:00
federationDomain2 . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain2 . Status . Message = "Provider successfully created"
federationDomain2 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain1 . Namespace ,
federationDomain1 . Name ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain2 . Namespace ,
federationDomain2 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain2 . Namespace ,
federationDomain2 ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
2020-12-16 22:27:09 +00:00
it ( "calls the ProvidersSetter with both FederationDomain's" , func ( ) {
2020-10-09 14:39:17 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-10-09 00:40:58 +00:00
2020-12-17 19:34:49 +00:00
provider1 , err := provider . NewFederationDomainIssuer ( federationDomain1 . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
2020-12-17 19:34:49 +00:00
provider2 , err := provider . NewFederationDomainIssuer ( federationDomain2 . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
r . True ( providersSetter . SetProvidersWasCalled )
r . ElementsMatch (
2020-12-17 19:34:49 +00:00
[ ] * provider . FederationDomainIssuer {
2020-10-09 14:39:17 +00:00
provider1 ,
provider2 ,
} ,
2020-12-16 22:27:09 +00:00
providersSetter . FederationDomainsReceived ,
2020-10-09 14:39:17 +00:00
)
} )
} )
2020-12-16 22:27:09 +00:00
when ( "updating only one FederationDomain fails for a reason other than conflict" , func ( ) {
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
once := sync . Once { }
pinnipedAPIClient . PrependReactor (
"update" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-09 14:39:17 +00:00
func ( _ coretesting . Action ) ( bool , runtime . Object , error ) {
var err error
once . Do ( func ( ) {
err = errors . New ( "some update error" )
} )
return true , nil , err
} ,
)
} )
it ( "sets the provider that it could actually update in the API" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
2021-02-05 17:56:05 +00:00
r . EqualError ( err , "could not update status: some update error" )
2020-10-09 14:39:17 +00:00
2020-12-17 19:34:49 +00:00
provider1 , err := provider . NewFederationDomainIssuer ( federationDomain1 . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
2020-12-17 19:34:49 +00:00
provider2 , err := provider . NewFederationDomainIssuer ( federationDomain2 . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
r . True ( providersSetter . SetProvidersWasCalled )
2020-12-16 22:27:09 +00:00
r . Len ( providersSetter . FederationDomainsReceived , 1 )
2020-10-09 14:39:17 +00:00
r . True (
2020-12-16 22:27:09 +00:00
reflect . DeepEqual ( providersSetter . FederationDomainsReceived [ 0 ] , provider1 ) ||
reflect . DeepEqual ( providersSetter . FederationDomainsReceived [ 0 ] , provider2 ) ,
2020-10-09 14:39:17 +00:00
)
} )
it ( "returns an error" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
2021-02-05 17:56:05 +00:00
r . EqualError ( err , "could not update status: some update error" )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomain1 . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain1 . Status . Message = "Provider successfully created"
federationDomain1 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomain2 . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain2 . Status . Message = "Provider successfully created"
federationDomain2 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain1 . Namespace ,
federationDomain1 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain1 . Namespace ,
federationDomain1 ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain2 . Namespace ,
federationDomain2 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain2 . Namespace ,
federationDomain2 ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
} )
} )
2020-12-16 22:27:09 +00:00
when ( "there are errors updating the FederationDomains" , func ( ) {
2020-10-09 14:39:17 +00:00
var (
2020-12-16 22:27:09 +00:00
federationDomain * v1alpha1 . FederationDomain
2020-10-09 14:39:17 +00:00
)
it . Before ( func ( ) {
2020-12-16 22:27:09 +00:00
federationDomain = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "config" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://issuer.com" } ,
2020-10-09 14:39:17 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomain ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomain ) )
2020-10-09 00:40:58 +00:00
} )
2020-12-16 22:27:09 +00:00
when ( "there is a conflict while updating an FederationDomain" , func ( ) {
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
once := sync . Once { }
pinnipedAPIClient . PrependReactor (
"update" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-09 14:39:17 +00:00
func ( _ coretesting . Action ) ( bool , runtime . Object , error ) {
var err error
once . Do ( func ( ) {
err = k8serrors . NewConflict ( schema . GroupResource { } , "" , nil )
} )
return true , nil , err
} ,
)
} )
2020-12-16 22:27:09 +00:00
it ( "retries updating the FederationDomain" , func ( ) {
2020-10-09 14:39:17 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-16 22:27:09 +00:00
federationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain . Status . Message = "Provider successfully created"
federationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain . Namespace ,
federationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain . Namespace ,
federationDomain ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain . Namespace ,
federationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain . Namespace ,
federationDomain ,
2020-10-09 14:39:17 +00:00
) ,
}
r . Equal ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
} )
2020-12-16 22:27:09 +00:00
when ( "updating the FederationDomain fails for a reason other than conflict" , func ( ) {
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
pinnipedAPIClient . PrependReactor (
"update" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-09 14:39:17 +00:00
func ( _ coretesting . Action ) ( bool , runtime . Object , error ) {
return true , nil , errors . New ( "some update error" )
} ,
)
} )
it ( "returns an error" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
2021-02-05 17:56:05 +00:00
r . EqualError ( err , "could not update status: some update error" )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain . Status . Message = "Provider successfully created"
federationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain . Namespace ,
federationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain . Namespace ,
federationDomain ,
2020-10-09 14:39:17 +00:00
) ,
}
r . Equal ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
} )
2020-12-16 22:27:09 +00:00
when ( "there is an error when getting the FederationDomain" , func ( ) {
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
pinnipedAPIClient . PrependReactor (
"get" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-09 14:39:17 +00:00
func ( _ coretesting . Action ) ( bool , runtime . Object , error ) {
return true , nil , errors . New ( "some get error" )
} ,
)
} )
it ( "returns the get error" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
2021-02-05 17:56:05 +00:00
r . EqualError ( err , "could not update status: get failed: some get error" )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain . Status . Message = "Provider successfully created"
federationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain . Namespace ,
federationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
}
r . Equal ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
2020-10-09 00:40:58 +00:00
} )
} )
2020-12-16 22:27:09 +00:00
when ( "there are both valid and invalid FederationDomains in the informer" , func ( ) {
2020-10-09 14:39:17 +00:00
var (
2020-12-16 22:27:09 +00:00
validFederationDomain * v1alpha1 . FederationDomain
invalidFederationDomain * v1alpha1 . FederationDomain
2020-10-09 14:39:17 +00:00
)
it . Before ( func ( ) {
2020-12-16 22:27:09 +00:00
validFederationDomain = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "valid-config" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://valid-issuer.com" } ,
2020-10-09 14:39:17 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( validFederationDomain ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( validFederationDomain ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
invalidFederationDomain = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "invalid-config" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://invalid-issuer.com?some=query" } ,
2020-10-09 14:39:17 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( invalidFederationDomain ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( invalidFederationDomain ) )
2020-10-09 14:39:17 +00:00
} )
it ( "calls the ProvidersSetter with the valid provider" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-17 19:34:49 +00:00
validProvider , err := provider . NewFederationDomainIssuer ( validFederationDomain . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
r . True ( providersSetter . SetProvidersWasCalled )
r . Equal (
2020-12-17 19:34:49 +00:00
[ ] * provider . FederationDomainIssuer {
2020-10-09 14:39:17 +00:00
validProvider ,
} ,
2020-12-16 22:27:09 +00:00
providersSetter . FederationDomainsReceived ,
2020-10-09 14:39:17 +00:00
)
} )
2020-12-16 22:27:09 +00:00
it ( "updates the status to success/invalid in the FederationDomains" , func ( ) {
2020-10-09 14:39:17 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-16 22:27:09 +00:00
validFederationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
validFederationDomain . Status . Message = "Provider successfully created"
validFederationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
invalidFederationDomain . Status . Status = v1alpha1 . InvalidFederationDomainStatusCondition
invalidFederationDomain . Status . Message = "Invalid: issuer must not have query"
invalidFederationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
invalidFederationDomain . Namespace ,
invalidFederationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
invalidFederationDomain . Namespace ,
invalidFederationDomain ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
validFederationDomain . Namespace ,
validFederationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
validFederationDomain . Namespace ,
validFederationDomain ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
2020-12-16 22:27:09 +00:00
when ( "updating only the invalid FederationDomain fails for a reason other than conflict" , func ( ) {
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
pinnipedAPIClient . PrependReactor (
"update" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-09 14:39:17 +00:00
func ( action coretesting . Action ) ( bool , runtime . Object , error ) {
updateAction := action . ( coretesting . UpdateActionImpl )
2020-12-17 19:34:49 +00:00
federationDomain := updateAction . Object . ( * v1alpha1 . FederationDomain )
if federationDomain . Name == validFederationDomain . Name {
2020-10-09 14:39:17 +00:00
return true , nil , nil
}
return true , nil , errors . New ( "some update error" )
} ,
)
} )
it ( "sets the provider that it could actually update in the API" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
2021-02-05 17:56:05 +00:00
r . EqualError ( err , "could not update status: some update error" )
2020-10-09 14:39:17 +00:00
2020-12-17 19:34:49 +00:00
validProvider , err := provider . NewFederationDomainIssuer ( validFederationDomain . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
r . True ( providersSetter . SetProvidersWasCalled )
r . Equal (
2020-12-17 19:34:49 +00:00
[ ] * provider . FederationDomainIssuer {
2020-10-09 14:39:17 +00:00
validProvider ,
} ,
2020-12-16 22:27:09 +00:00
providersSetter . FederationDomainsReceived ,
2020-10-09 14:39:17 +00:00
)
} )
it ( "returns an error" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
2021-02-05 17:56:05 +00:00
r . EqualError ( err , "could not update status: some update error" )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
validFederationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
validFederationDomain . Status . Message = "Provider successfully created"
validFederationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
invalidFederationDomain . Status . Status = v1alpha1 . InvalidFederationDomainStatusCondition
invalidFederationDomain . Status . Message = "Invalid: issuer must not have query"
invalidFederationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
invalidFederationDomain . Namespace ,
invalidFederationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
invalidFederationDomain . Namespace ,
invalidFederationDomain ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
validFederationDomain . Namespace ,
validFederationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
validFederationDomain . Namespace ,
validFederationDomain ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
} )
2020-10-09 00:40:58 +00:00
} )
2020-12-16 22:27:09 +00:00
when ( "there are FederationDomains with duplicate issuer names in the informer" , func ( ) {
2020-10-09 14:39:17 +00:00
var (
2020-12-16 22:27:09 +00:00
federationDomainDuplicate1 * v1alpha1 . FederationDomain
federationDomainDuplicate2 * v1alpha1 . FederationDomain
federationDomain * v1alpha1 . FederationDomain
2020-10-09 14:39:17 +00:00
)
it . Before ( func ( ) {
2020-10-23 23:25:44 +00:00
// Hostnames are case-insensitive, so consider them to be duplicates if they only differ by case.
// Paths are case-sensitive, so having a path that differs only by case makes a new issuer.
2020-12-16 22:27:09 +00:00
federationDomainDuplicate1 = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "duplicate1" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://iSSueR-duPlicAte.cOm/a" } ,
2020-10-09 14:39:17 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomainDuplicate1 ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomainDuplicate1 ) )
2020-12-16 22:27:09 +00:00
federationDomainDuplicate2 = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "duplicate2" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://issuer-duplicate.com/a" } ,
2020-10-09 14:39:17 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomainDuplicate2 ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomainDuplicate2 ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomain = & v1alpha1 . FederationDomain {
2020-10-09 14:39:17 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "not-duplicate" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec { Issuer : "https://issuer-duplicate.com/A" } , // different path
2020-10-09 14:39:17 +00:00
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomain ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomain ) )
2020-10-09 14:39:17 +00:00
} )
it ( "calls the ProvidersSetter with the non-duplicate" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-17 19:34:49 +00:00
nonDuplicateProvider , err := provider . NewFederationDomainIssuer ( federationDomain . Spec . Issuer )
2020-10-09 14:39:17 +00:00
r . NoError ( err )
r . True ( providersSetter . SetProvidersWasCalled )
r . Equal (
2020-12-17 19:34:49 +00:00
[ ] * provider . FederationDomainIssuer {
2020-10-09 14:39:17 +00:00
nonDuplicateProvider ,
} ,
2020-12-16 22:27:09 +00:00
providersSetter . FederationDomainsReceived ,
2020-10-09 14:39:17 +00:00
)
} )
it ( "updates the statuses" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-16 22:27:09 +00:00
federationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain . Status . Message = "Provider successfully created"
federationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomainDuplicate1 . Status . Status = v1alpha1 . DuplicateFederationDomainStatusCondition
federationDomainDuplicate1 . Status . Message = "Duplicate issuer: https://iSSueR-duPlicAte.cOm/a"
federationDomainDuplicate1 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
2020-12-16 22:27:09 +00:00
federationDomainDuplicate2 . Status . Status = v1alpha1 . DuplicateFederationDomainStatusCondition
federationDomainDuplicate2 . Status . Message = "Duplicate issuer: https://issuer-duplicate.com/a"
federationDomainDuplicate2 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainDuplicate1 . Namespace ,
federationDomainDuplicate1 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomainDuplicate1 . Namespace ,
federationDomainDuplicate1 ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainDuplicate2 . Namespace ,
federationDomainDuplicate2 . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomainDuplicate2 . Namespace ,
federationDomainDuplicate2 ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain . Namespace ,
federationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomain . Namespace ,
federationDomain ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
when ( "we cannot talk to the API" , func ( ) {
2021-02-05 17:56:05 +00:00
var count int
2020-10-09 14:39:17 +00:00
it . Before ( func ( ) {
pinnipedAPIClient . PrependReactor (
"get" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-09 14:39:17 +00:00
func ( _ coretesting . Action ) ( bool , runtime . Object , error ) {
2021-02-05 17:56:05 +00:00
count ++
return true , nil , fmt . Errorf ( "some get error %d" , count )
2020-10-09 14:39:17 +00:00
} ,
)
} )
it ( "returns the get errors" , func ( ) {
2021-02-05 17:56:05 +00:00
expectedError := here . Doc ( ` [could not update status: get failed: some get error 1, could not update status: get failed: some get error 2, could not update status: get failed: some get error 3] ` )
2020-10-09 14:39:17 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . EqualError ( err , expectedError )
2020-12-16 22:27:09 +00:00
federationDomain . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomain . Status . Message = "Provider successfully created"
federationDomain . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-09 14:39:17 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainDuplicate1 . Namespace ,
federationDomainDuplicate1 . Name ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainDuplicate2 . Namespace ,
federationDomainDuplicate2 . Name ,
2020-10-09 14:39:17 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomain . Namespace ,
federationDomain . Name ,
2020-10-09 14:39:17 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
} )
2020-10-09 00:40:58 +00:00
} )
2020-12-16 22:27:09 +00:00
when ( "there are FederationDomains with the same issuer DNS hostname using different secretNames" , func ( ) {
2020-10-23 23:25:44 +00:00
var (
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress1 * v1alpha1 . FederationDomain
federationDomainSameIssuerAddress2 * v1alpha1 . FederationDomain
federationDomainDifferentIssuerAddress * v1alpha1 . FederationDomain
federationDomainWithInvalidIssuerURL * v1alpha1 . FederationDomain
2020-10-23 23:25:44 +00:00
)
it . Before ( func ( ) {
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress1 = & v1alpha1 . FederationDomain {
2020-10-23 23:25:44 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "provider1" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec {
2020-11-02 22:55:29 +00:00
Issuer : "https://iSSueR-duPlicAte-adDress.cOm/path1" ,
2020-12-16 22:27:09 +00:00
TLS : & v1alpha1 . FederationDomainTLSSpec { SecretName : "secret1" } ,
2020-10-23 23:25:44 +00:00
} ,
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomainSameIssuerAddress1 ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomainSameIssuerAddress1 ) )
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress2 = & v1alpha1 . FederationDomain {
2020-10-23 23:25:44 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "provider2" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec {
2020-10-27 00:03:26 +00:00
// Validation treats these as the same DNS hostname even though they have different port numbers,
// because SNI information on the incoming requests is not going to include port numbers.
2020-11-02 22:55:29 +00:00
Issuer : "https://issuer-duplicate-address.com:1234/path2" ,
2020-12-16 22:27:09 +00:00
TLS : & v1alpha1 . FederationDomainTLSSpec { SecretName : "secret2" } ,
2020-10-23 23:25:44 +00:00
} ,
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomainSameIssuerAddress2 ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomainSameIssuerAddress2 ) )
2020-10-23 23:25:44 +00:00
2020-12-16 22:27:09 +00:00
federationDomainDifferentIssuerAddress = & v1alpha1 . FederationDomain {
2020-10-23 23:25:44 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "differentIssuerAddressProvider" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec {
2020-11-02 22:55:29 +00:00
Issuer : "https://issuer-not-duplicate.com" ,
2020-12-16 22:27:09 +00:00
TLS : & v1alpha1 . FederationDomainTLSSpec { SecretName : "secret1" } ,
2020-10-23 23:25:44 +00:00
} ,
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomainDifferentIssuerAddress ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomainDifferentIssuerAddress ) )
2020-10-23 23:25:44 +00:00
// Also add one with a URL that cannot be parsed to make sure that the error handling
// for the duplicate issuers and secret names are not confused by invalid URLs.
invalidIssuerURL := ":/host//path"
_ , err := url . Parse ( invalidIssuerURL ) //nolint:staticcheck // Yes, this URL is intentionally invalid.
r . Error ( err )
2020-12-16 22:27:09 +00:00
federationDomainWithInvalidIssuerURL = & v1alpha1 . FederationDomain {
2020-10-23 23:25:44 +00:00
ObjectMeta : metav1 . ObjectMeta { Name : "invalidIssuerURLProvider" , Namespace : namespace } ,
2020-12-16 22:27:09 +00:00
Spec : v1alpha1 . FederationDomainSpec {
2020-11-02 22:55:29 +00:00
Issuer : invalidIssuerURL ,
2020-12-16 22:27:09 +00:00
TLS : & v1alpha1 . FederationDomainTLSSpec { SecretName : "secret1" } ,
2020-10-23 23:25:44 +00:00
} ,
}
2020-12-16 22:27:09 +00:00
r . NoError ( pinnipedAPIClient . Tracker ( ) . Add ( federationDomainWithInvalidIssuerURL ) )
2020-12-17 19:34:49 +00:00
r . NoError ( federationDomainInformerClient . Tracker ( ) . Add ( federationDomainWithInvalidIssuerURL ) )
2020-10-23 23:25:44 +00:00
} )
it ( "calls the ProvidersSetter with the non-duplicate" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-17 19:34:49 +00:00
nonDuplicateProvider , err := provider . NewFederationDomainIssuer ( federationDomainDifferentIssuerAddress . Spec . Issuer )
2020-10-23 23:25:44 +00:00
r . NoError ( err )
r . True ( providersSetter . SetProvidersWasCalled )
r . Equal (
2020-12-17 19:34:49 +00:00
[ ] * provider . FederationDomainIssuer {
2020-10-23 23:25:44 +00:00
nonDuplicateProvider ,
} ,
2020-12-16 22:27:09 +00:00
providersSetter . FederationDomainsReceived ,
2020-10-23 23:25:44 +00:00
)
} )
it ( "updates the statuses" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
2020-12-16 22:27:09 +00:00
federationDomainDifferentIssuerAddress . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomainDifferentIssuerAddress . Status . Message = "Provider successfully created"
federationDomainDifferentIssuerAddress . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-23 23:25:44 +00:00
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress1 . Status . Status = v1alpha1 . SameIssuerHostMustUseSameSecretFederationDomainStatusCondition
federationDomainSameIssuerAddress1 . Status . Message = "Issuers with the same DNS hostname (address not including port) must use the same secretName: issuer-duplicate-address.com"
federationDomainSameIssuerAddress1 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-23 23:25:44 +00:00
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress2 . Status . Status = v1alpha1 . SameIssuerHostMustUseSameSecretFederationDomainStatusCondition
federationDomainSameIssuerAddress2 . Status . Message = "Issuers with the same DNS hostname (address not including port) must use the same secretName: issuer-duplicate-address.com"
federationDomainSameIssuerAddress2 . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-23 23:25:44 +00:00
2020-12-16 22:27:09 +00:00
federationDomainWithInvalidIssuerURL . Status . Status = v1alpha1 . InvalidFederationDomainStatusCondition
federationDomainWithInvalidIssuerURL . Status . Message = ` Invalid: could not parse issuer as URL: parse ":/host//path": missing protocol scheme `
federationDomainWithInvalidIssuerURL . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-23 23:25:44 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainSameIssuerAddress1 . Namespace ,
federationDomainSameIssuerAddress1 . Name ,
2020-10-23 23:25:44 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress1 . Namespace ,
federationDomainSameIssuerAddress1 ,
2020-10-23 23:25:44 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainSameIssuerAddress2 . Namespace ,
federationDomainSameIssuerAddress2 . Name ,
2020-10-23 23:25:44 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomainSameIssuerAddress2 . Namespace ,
federationDomainSameIssuerAddress2 ,
2020-10-23 23:25:44 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainDifferentIssuerAddress . Namespace ,
federationDomainDifferentIssuerAddress . Name ,
2020-10-23 23:25:44 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomainDifferentIssuerAddress . Namespace ,
federationDomainDifferentIssuerAddress ,
2020-10-23 23:25:44 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainWithInvalidIssuerURL . Namespace ,
federationDomainWithInvalidIssuerURL . Name ,
2020-10-23 23:25:44 +00:00
) ,
2021-02-11 02:46:03 +00:00
coretesting . NewUpdateSubresourceAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
2021-02-11 02:46:03 +00:00
"status" ,
2020-12-16 22:27:09 +00:00
federationDomainWithInvalidIssuerURL . Namespace ,
federationDomainWithInvalidIssuerURL ,
2020-10-23 23:25:44 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
when ( "we cannot talk to the API" , func ( ) {
2021-02-05 17:56:05 +00:00
var count int
2020-10-23 23:25:44 +00:00
it . Before ( func ( ) {
pinnipedAPIClient . PrependReactor (
"get" ,
2020-12-16 22:27:09 +00:00
"federationdomains" ,
2020-10-23 23:25:44 +00:00
func ( _ coretesting . Action ) ( bool , runtime . Object , error ) {
2021-02-05 17:56:05 +00:00
count ++
return true , nil , fmt . Errorf ( "some get error %d" , count )
2020-10-23 23:25:44 +00:00
} ,
)
} )
it ( "returns the get errors" , func ( ) {
2021-02-05 17:56:05 +00:00
expectedError := here . Doc ( ` [could not update status: get failed: some get error 1, could not update status: get failed: some get error 2, could not update status: get failed: some get error 3, could not update status: get failed: some get error 4] ` )
2020-10-23 23:25:44 +00:00
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . EqualError ( err , expectedError )
2020-12-16 22:27:09 +00:00
federationDomainDifferentIssuerAddress . Status . Status = v1alpha1 . SuccessFederationDomainStatusCondition
federationDomainDifferentIssuerAddress . Status . Message = "Provider successfully created"
federationDomainDifferentIssuerAddress . Status . LastUpdateTime = timePtr ( metav1 . NewTime ( frozenNow ) )
2020-10-23 23:25:44 +00:00
expectedActions := [ ] coretesting . Action {
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainSameIssuerAddress1 . Namespace ,
federationDomainSameIssuerAddress1 . Name ,
2020-10-23 23:25:44 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainSameIssuerAddress2 . Namespace ,
federationDomainSameIssuerAddress2 . Name ,
2020-10-23 23:25:44 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainDifferentIssuerAddress . Namespace ,
federationDomainDifferentIssuerAddress . Name ,
2020-10-23 23:25:44 +00:00
) ,
coretesting . NewGetAction (
2020-12-16 22:27:09 +00:00
federationDomainGVR ,
federationDomainWithInvalidIssuerURL . Namespace ,
federationDomainWithInvalidIssuerURL . Name ,
2020-10-23 23:25:44 +00:00
) ,
}
r . ElementsMatch ( expectedActions , pinnipedAPIClient . Actions ( ) )
} )
} )
} )
2020-12-16 22:27:09 +00:00
when ( "there are no FederationDomains in the informer" , func ( ) {
2020-10-09 00:40:58 +00:00
it ( "keeps waiting for one" , func ( ) {
startInformersAndController ( )
err := controllerlib . TestSync ( t , subject , * syncContext )
r . NoError ( err )
r . Empty ( pinnipedAPIClient . Actions ( ) )
r . True ( providersSetter . SetProvidersWasCalled )
2020-12-16 22:27:09 +00:00
r . Empty ( providersSetter . FederationDomainsReceived )
2020-10-09 00:40:58 +00:00
} )
} )
} , spec . Parallel ( ) , spec . Report ( report . Terminal { } ) )
}