Update impersonatorconfig controller to use CredentialIssuer API instead of ConfigMap.
Signed-off-by: Margo Crawford <margaretc@vmware.com> Signed-off-by: Matt Moyer <moyerm@vmware.com>
This commit is contained in:
parent
1a131e64fe
commit
18ccf11905
@ -8,6 +8,8 @@ import (
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
)
|
||||
|
||||
type Mode string
|
||||
@ -63,3 +65,19 @@ func ConfigFromConfigMap(configMap *v1.ConfigMap) (*Config, error) {
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func ConfigFromCredentialIssuer(credIssuer *v1alpha1.CredentialIssuer) (*Config, error) {
|
||||
config := NewConfig()
|
||||
switch mode := credIssuer.Spec.ImpersonationProxy.Mode; mode {
|
||||
case v1alpha1.ImpersonationProxyModeAuto:
|
||||
config.Mode = ModeAuto
|
||||
case v1alpha1.ImpersonationProxyModeDisabled:
|
||||
config.Mode = ModeDisabled
|
||||
case v1alpha1.ImpersonationProxyModeEnabled:
|
||||
config.Mode = ModeEnabled
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid impersonation proxy mode %q, valid values are auto, disabled, or enabled", mode)
|
||||
}
|
||||
config.Endpoint = credIssuer.Spec.ImpersonationProxy.ExternalEndpoint
|
||||
return config, nil
|
||||
}
|
||||
|
@ -33,9 +33,11 @@ type APIConfigSpec struct {
|
||||
|
||||
// NamesConfigSpec configures the names of some Kubernetes resources for the Concierge.
|
||||
type NamesConfigSpec struct {
|
||||
ServingCertificateSecret string `json:"servingCertificateSecret"`
|
||||
CredentialIssuer string `json:"credentialIssuer"`
|
||||
APIService string `json:"apiService"`
|
||||
ServingCertificateSecret string `json:"servingCertificateSecret"`
|
||||
CredentialIssuer string `json:"credentialIssuer"`
|
||||
APIService string `json:"apiService"`
|
||||
|
||||
// TODO: remove this key entirely
|
||||
ImpersonationConfigMap string `json:"impersonationConfigMap"`
|
||||
ImpersonationLoadBalancerService string `json:"impersonationLoadBalancerService"`
|
||||
ImpersonationTLSCertificateSecret string `json:"impersonationTLSCertificateSecret"`
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
pinnipedclientset "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned"
|
||||
conciergeconfiginformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions/config/v1alpha1"
|
||||
"go.pinniped.dev/internal/certauthority"
|
||||
"go.pinniped.dev/internal/clusterhost"
|
||||
"go.pinniped.dev/internal/concierge/impersonator"
|
||||
@ -51,7 +52,6 @@ const (
|
||||
|
||||
type impersonatorConfigController struct {
|
||||
namespace string
|
||||
configMapResourceName string
|
||||
credentialIssuerResourceName string
|
||||
generatedLoadBalancerServiceName string
|
||||
tlsSecretName string
|
||||
@ -61,7 +61,7 @@ type impersonatorConfigController struct {
|
||||
k8sClient kubernetes.Interface
|
||||
pinnipedAPIClient pinnipedclientset.Interface
|
||||
|
||||
configMapsInformer corev1informers.ConfigMapInformer
|
||||
credIssuerInformer conciergeconfiginformers.CredentialIssuerInformer
|
||||
servicesInformer corev1informers.ServiceInformer
|
||||
secretsInformer corev1informers.SecretInformer
|
||||
|
||||
@ -78,11 +78,10 @@ type impersonatorConfigController struct {
|
||||
|
||||
func NewImpersonatorConfigController(
|
||||
namespace string,
|
||||
configMapResourceName string,
|
||||
credentialIssuerResourceName string,
|
||||
k8sClient kubernetes.Interface,
|
||||
pinnipedAPIClient pinnipedclientset.Interface,
|
||||
configMapsInformer corev1informers.ConfigMapInformer,
|
||||
credentialIssuerInformer conciergeconfiginformers.CredentialIssuerInformer,
|
||||
servicesInformer corev1informers.ServiceInformer,
|
||||
secretsInformer corev1informers.SecretInformer,
|
||||
withInformer pinnipedcontroller.WithInformerOptionFunc,
|
||||
@ -102,7 +101,6 @@ func NewImpersonatorConfigController(
|
||||
Name: "impersonator-config-controller",
|
||||
Syncer: &impersonatorConfigController{
|
||||
namespace: namespace,
|
||||
configMapResourceName: configMapResourceName,
|
||||
credentialIssuerResourceName: credentialIssuerResourceName,
|
||||
generatedLoadBalancerServiceName: generatedLoadBalancerServiceName,
|
||||
tlsSecretName: tlsSecretName,
|
||||
@ -110,7 +108,7 @@ func NewImpersonatorConfigController(
|
||||
impersonationSignerSecretName: impersonationSignerSecretName,
|
||||
k8sClient: k8sClient,
|
||||
pinnipedAPIClient: pinnipedAPIClient,
|
||||
configMapsInformer: configMapsInformer,
|
||||
credIssuerInformer: credentialIssuerInformer,
|
||||
servicesInformer: servicesInformer,
|
||||
secretsInformer: secretsInformer,
|
||||
labels: labels,
|
||||
@ -120,9 +118,10 @@ func NewImpersonatorConfigController(
|
||||
tlsServingCertDynamicCertProvider: dynamiccert.NewServingCert("impersonation-proxy-serving-cert"),
|
||||
},
|
||||
},
|
||||
withInformer(
|
||||
configMapsInformer,
|
||||
pinnipedcontroller.NameAndNamespaceExactMatchFilterFactory(configMapResourceName, namespace),
|
||||
withInformer(credentialIssuerInformer,
|
||||
pinnipedcontroller.SimpleFilterWithSingletonQueue(func(obj metav1.Object) bool {
|
||||
return obj.GetName() == credentialIssuerResourceName
|
||||
}),
|
||||
controllerlib.InformerOption{},
|
||||
),
|
||||
withInformer(
|
||||
@ -137,12 +136,9 @@ func NewImpersonatorConfigController(
|
||||
}, nil),
|
||||
controllerlib.InformerOption{},
|
||||
),
|
||||
// Be sure to run once even if the ConfigMap that the informer is watching doesn't exist so we can implement
|
||||
// Be sure to run once even if the CredentialIssuer that the informer is watching doesn't exist so we can implement
|
||||
// the default configuration behavior.
|
||||
withInitialEvent(controllerlib.Key{
|
||||
Namespace: namespace,
|
||||
Name: configMapResourceName,
|
||||
}),
|
||||
withInitialEvent(controllerlib.Key{Name: credentialIssuerResourceName}),
|
||||
// TODO fix these controller options to make this a singleton queue
|
||||
)
|
||||
}
|
||||
@ -264,30 +260,26 @@ func (c *impersonatorConfigController) doSync(syncCtx controllerlib.Context) (*v
|
||||
}
|
||||
|
||||
func (c *impersonatorConfigController) loadImpersonationProxyConfiguration() (*impersonator.Config, error) {
|
||||
configMap, err := c.configMapsInformer.Lister().ConfigMaps(c.namespace).Get(c.configMapResourceName)
|
||||
notFound := k8serrors.IsNotFound(err)
|
||||
if err != nil && !notFound {
|
||||
return nil, fmt.Errorf("failed to get %s/%s configmap: %w", c.namespace, c.configMapResourceName, err)
|
||||
}
|
||||
credIssuer, err := c.credIssuerInformer.Lister().Get(c.credentialIssuerResourceName)
|
||||
|
||||
var config *impersonator.Config
|
||||
if notFound {
|
||||
if k8serrors.IsNotFound(err) {
|
||||
plog.Info("Did not find impersonation proxy config: using default config values",
|
||||
"configmap", c.configMapResourceName,
|
||||
"namespace", c.namespace,
|
||||
)
|
||||
config = impersonator.NewConfig() // use default configuration options
|
||||
} else {
|
||||
config, err = impersonator.ConfigFromConfigMap(configMap)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid impersonator configuration: %v", err)
|
||||
}
|
||||
plog.Info("Read impersonation proxy config",
|
||||
"configmap", c.configMapResourceName,
|
||||
"namespace", c.namespace,
|
||||
"credentialIssuer", c.credentialIssuerResourceName,
|
||||
)
|
||||
return impersonator.NewConfig(), nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get %s CredentialIssuer: %w", c.credentialIssuerResourceName, err)
|
||||
}
|
||||
|
||||
config, err := impersonator.ConfigFromCredentialIssuer(credIssuer)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid impersonator configuration: %v", err)
|
||||
}
|
||||
plog.Info("Read impersonation proxy config",
|
||||
"credentialIssuer", c.credentialIssuerResourceName,
|
||||
)
|
||||
return config, nil
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
|
||||
"go.pinniped.dev/generated/latest/apis/concierge/config/v1alpha1"
|
||||
pinnipedfake "go.pinniped.dev/generated/latest/client/concierge/clientset/versioned/fake"
|
||||
pinnipedinformers "go.pinniped.dev/generated/latest/client/concierge/informers/externalversions"
|
||||
"go.pinniped.dev/internal/certauthority"
|
||||
"go.pinniped.dev/internal/controller/apicerts"
|
||||
"go.pinniped.dev/internal/controllerlib"
|
||||
@ -46,7 +47,7 @@ import (
|
||||
func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
||||
spec.Run(t, "options", func(t *testing.T, when spec.G, it spec.S) {
|
||||
const installedInNamespace = "some-namespace"
|
||||
const configMapResourceName = "some-configmap-resource-name"
|
||||
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
|
||||
const generatedLoadBalancerServiceName = "some-service-resource-name"
|
||||
const tlsSecretName = "some-tls-secret-name" //nolint:gosec // this is not a credential
|
||||
const caSecretName = "some-ca-secret-name"
|
||||
@ -55,7 +56,7 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
||||
var r *require.Assertions
|
||||
var observableWithInformerOption *testutil.ObservableWithInformerOption
|
||||
var observableWithInitialEventOption *testutil.ObservableWithInitialEventOption
|
||||
var configMapsInformerFilter controllerlib.Filter
|
||||
var credIssuerInformerFilter controllerlib.Filter
|
||||
var servicesInformerFilter controllerlib.Filter
|
||||
var secretsInformerFilter controllerlib.Filter
|
||||
|
||||
@ -63,18 +64,18 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
||||
r = require.New(t)
|
||||
observableWithInformerOption = testutil.NewObservableWithInformerOption()
|
||||
observableWithInitialEventOption = testutil.NewObservableWithInitialEventOption()
|
||||
pinnipedInformerFactory := pinnipedinformers.NewSharedInformerFactory(nil, 0)
|
||||
sharedInformerFactory := kubeinformers.NewSharedInformerFactory(nil, 0)
|
||||
configMapsInformer := sharedInformerFactory.Core().V1().ConfigMaps()
|
||||
credIssuerInformer := pinnipedInformerFactory.Config().V1alpha1().CredentialIssuers()
|
||||
servicesInformer := sharedInformerFactory.Core().V1().Services()
|
||||
secretsInformer := sharedInformerFactory.Core().V1().Secrets()
|
||||
|
||||
_ = NewImpersonatorConfigController(
|
||||
installedInNamespace,
|
||||
configMapResourceName,
|
||||
"",
|
||||
credentialIssuerResourceName,
|
||||
nil,
|
||||
nil,
|
||||
configMapsInformer,
|
||||
credIssuerInformer,
|
||||
servicesInformer,
|
||||
secretsInformer,
|
||||
observableWithInformerOption.WithInformer,
|
||||
@ -88,57 +89,39 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
||||
caSignerName,
|
||||
nil,
|
||||
)
|
||||
configMapsInformerFilter = observableWithInformerOption.GetFilterForInformer(configMapsInformer)
|
||||
credIssuerInformerFilter = observableWithInformerOption.GetFilterForInformer(credIssuerInformer)
|
||||
servicesInformerFilter = observableWithInformerOption.GetFilterForInformer(servicesInformer)
|
||||
secretsInformerFilter = observableWithInformerOption.GetFilterForInformer(secretsInformer)
|
||||
})
|
||||
|
||||
when("watching ConfigMap objects", func() {
|
||||
when("watching CredentialIssuer objects", func() {
|
||||
var subject controllerlib.Filter
|
||||
var target, wrongNamespace, wrongName, unrelated *corev1.ConfigMap
|
||||
var target, wrongName, otherWrongName *v1alpha1.CredentialIssuer
|
||||
|
||||
it.Before(func() {
|
||||
subject = configMapsInformerFilter
|
||||
target = &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: configMapResourceName, Namespace: installedInNamespace}}
|
||||
wrongNamespace = &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: configMapResourceName, Namespace: "wrong-namespace"}}
|
||||
wrongName = &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "wrong-name", Namespace: installedInNamespace}}
|
||||
unrelated = &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "wrong-name", Namespace: "wrong-namespace"}}
|
||||
subject = credIssuerInformerFilter
|
||||
target = &v1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: credentialIssuerResourceName}}
|
||||
wrongName = &v1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "wrong-name"}}
|
||||
otherWrongName = &v1alpha1.CredentialIssuer{ObjectMeta: metav1.ObjectMeta{Name: "other-wrong-name"}}
|
||||
})
|
||||
|
||||
when("the target ConfigMap changes", func() {
|
||||
when("the target CredentialIssuer changes", func() {
|
||||
it("returns true to trigger the sync method", func() {
|
||||
r.True(subject.Add(target))
|
||||
r.True(subject.Update(target, unrelated))
|
||||
r.True(subject.Update(unrelated, target))
|
||||
r.True(subject.Update(target, wrongName))
|
||||
r.True(subject.Update(wrongName, target))
|
||||
r.True(subject.Delete(target))
|
||||
})
|
||||
})
|
||||
|
||||
when("a ConfigMap from another namespace changes", func() {
|
||||
it("returns false to avoid triggering the sync method", func() {
|
||||
r.False(subject.Add(wrongNamespace))
|
||||
r.False(subject.Update(wrongNamespace, unrelated))
|
||||
r.False(subject.Update(unrelated, wrongNamespace))
|
||||
r.False(subject.Delete(wrongNamespace))
|
||||
})
|
||||
})
|
||||
|
||||
when("a ConfigMap with a different name changes", func() {
|
||||
when("a CredentialIssuer with a different name changes", func() {
|
||||
it("returns false to avoid triggering the sync method", func() {
|
||||
r.False(subject.Add(wrongName))
|
||||
r.False(subject.Update(wrongName, unrelated))
|
||||
r.False(subject.Update(unrelated, wrongName))
|
||||
r.False(subject.Update(wrongName, otherWrongName))
|
||||
r.False(subject.Update(otherWrongName, wrongName))
|
||||
r.False(subject.Delete(wrongName))
|
||||
})
|
||||
})
|
||||
|
||||
when("a ConfigMap with a different name and a different namespace changes", func() {
|
||||
it("returns false to avoid triggering the sync method", func() {
|
||||
r.False(subject.Add(unrelated))
|
||||
r.False(subject.Update(unrelated, unrelated))
|
||||
r.False(subject.Delete(unrelated))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
when("watching Service objects", func() {
|
||||
@ -253,10 +236,9 @@ func TestImpersonatorConfigControllerOptions(t *testing.T) {
|
||||
})
|
||||
|
||||
when("starting up", func() {
|
||||
it("asks for an initial event because the ConfigMap may not exist yet and it needs to run anyway", func() {
|
||||
it("asks for an initial event because the CredentialIssuer may not exist yet and it needs to run anyway", func() {
|
||||
r.Equal(&controllerlib.Key{
|
||||
Namespace: installedInNamespace,
|
||||
Name: configMapResourceName,
|
||||
Name: credentialIssuerResourceName,
|
||||
}, observableWithInitialEventOption.GetInitialEventKey())
|
||||
})
|
||||
})
|
||||
@ -267,7 +249,6 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
name := t.Name()
|
||||
spec.Run(t, "Sync", func(t *testing.T, when spec.G, it spec.S) {
|
||||
const installedInNamespace = "some-namespace"
|
||||
const configMapResourceName = "some-configmap-resource-name"
|
||||
const credentialIssuerResourceName = "some-credential-issuer-resource-name"
|
||||
const loadBalancerServiceName = "some-service-resource-name"
|
||||
const tlsSecretName = "some-tls-secret-name" //nolint:gosec // this is not a credential
|
||||
@ -283,6 +264,8 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
var subject controllerlib.Controller
|
||||
var kubeAPIClient *kubernetesfake.Clientset
|
||||
var pinnipedAPIClient *pinnipedfake.Clientset
|
||||
var pinnipedInformerClient *pinnipedfake.Clientset
|
||||
var pinnipedInformers pinnipedinformers.SharedInformerFactory
|
||||
var kubeInformerClient *kubernetesfake.Clientset
|
||||
var kubeInformers kubeinformers.SharedInformerFactory
|
||||
var cancelContext context.Context
|
||||
@ -533,11 +516,10 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
// Set this at the last second to allow for injection of server override.
|
||||
subject = NewImpersonatorConfigController(
|
||||
installedInNamespace,
|
||||
configMapResourceName,
|
||||
credentialIssuerResourceName,
|
||||
kubeAPIClient,
|
||||
pinnipedAPIClient,
|
||||
kubeInformers.Core().V1().ConfigMaps(),
|
||||
pinnipedInformers.Config().V1alpha1().CredentialIssuers(),
|
||||
kubeInformers.Core().V1().Services(),
|
||||
kubeInformers.Core().V1().Secrets(),
|
||||
controllerlib.WithInformer,
|
||||
@ -557,28 +539,25 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
Context: cancelContext,
|
||||
Name: subject.Name(),
|
||||
Key: controllerlib.Key{
|
||||
Namespace: installedInNamespace,
|
||||
Name: configMapResourceName,
|
||||
Name: credentialIssuerResourceName,
|
||||
},
|
||||
Queue: queue,
|
||||
}
|
||||
|
||||
// Must start informers before calling TestRunSynchronously()
|
||||
kubeInformers.Start(cancelContext.Done())
|
||||
pinnipedInformers.Start(cancelContext.Done())
|
||||
controllerlib.TestRunSynchronously(t, subject)
|
||||
}
|
||||
|
||||
var addImpersonatorConfigMapToTracker = func(resourceName, configYAML string, client *kubernetesfake.Clientset) {
|
||||
impersonatorConfigMap := &corev1.ConfigMap{
|
||||
var addCredentialIssuerToTracker = func(resourceName string, credIssuerSpec v1alpha1.CredentialIssuerSpec, client *pinnipedfake.Clientset) {
|
||||
t.Logf("adding CredentialIssuer %s to informer clientset", resourceName)
|
||||
r.NoError(client.Tracker().Add(&v1alpha1.CredentialIssuer{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: resourceName,
|
||||
Namespace: installedInNamespace,
|
||||
Name: resourceName,
|
||||
},
|
||||
Data: map[string]string{
|
||||
"config.yaml": configYAML,
|
||||
},
|
||||
}
|
||||
r.NoError(client.Tracker().Add(impersonatorConfigMap))
|
||||
Spec: credIssuerSpec,
|
||||
}))
|
||||
}
|
||||
|
||||
var newSecretWithData = func(resourceName string, data map[string][]byte) *corev1.Secret {
|
||||
@ -670,6 +649,19 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
r.Equal(obj, objFromInformer, "was waiting for expected to be found in informer, but found actual")
|
||||
}
|
||||
|
||||
var waitForClusterScopedObjectToAppearInInformer = func(obj kubeclient.Object, informer controllerlib.InformerGetter) {
|
||||
var objFromInformer interface{}
|
||||
var exists bool
|
||||
var err error
|
||||
assert.Eventually(t, func() bool {
|
||||
objFromInformer, exists, err = informer.Informer().GetIndexer().GetByKey(obj.GetName())
|
||||
return err == nil && exists && reflect.DeepEqual(objFromInformer.(kubeclient.Object), obj)
|
||||
}, 30*time.Second, 10*time.Millisecond)
|
||||
r.NoError(err)
|
||||
r.True(exists, "this object should have existed in informer but didn't: %+v", obj)
|
||||
r.Equal(obj, objFromInformer, "was waiting for expected to be found in informer, but found actual")
|
||||
}
|
||||
|
||||
// See comment for waitForObjectToAppearInInformer above.
|
||||
var waitForObjectToBeDeletedFromInformer = func(resourceName string, informer controllerlib.InformerGetter) {
|
||||
var objFromInformer interface{}
|
||||
@ -683,7 +675,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
r.False(exists, "this object should have been deleted from informer but wasn't: %s", objFromInformer)
|
||||
}
|
||||
|
||||
var addObjectToInformerAndWait = func(obj kubeclient.Object, informer controllerlib.InformerGetter) {
|
||||
var addObjectToKubeInformerAndWait = func(obj kubeclient.Object, informer controllerlib.InformerGetter) {
|
||||
r.NoError(kubeInformerClient.Tracker().Add(obj))
|
||||
waitForObjectToAppearInInformer(obj, informer)
|
||||
}
|
||||
@ -691,27 +683,19 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
var addObjectFromCreateActionToInformerAndWait = func(action coretesting.Action, informer controllerlib.InformerGetter) {
|
||||
createdObject, ok := action.(coretesting.CreateAction).GetObject().(kubeclient.Object)
|
||||
r.True(ok, "should have been able to cast this action's object to kubeclient.Object: %v", action)
|
||||
addObjectToInformerAndWait(createdObject, informer)
|
||||
addObjectToKubeInformerAndWait(createdObject, informer)
|
||||
}
|
||||
|
||||
var updateImpersonatorConfigMapInInformerAndWait = func(resourceName, configYAML string, informer controllerlib.InformerGetter) {
|
||||
configMapObj, err := kubeInformerClient.Tracker().Get(
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "configmaps"},
|
||||
installedInNamespace,
|
||||
resourceName,
|
||||
)
|
||||
r.NoError(err)
|
||||
configMap := configMapObj.(*corev1.ConfigMap)
|
||||
configMap = configMap.DeepCopy() // don't edit the original from the tracker
|
||||
configMap.Data = map[string]string{
|
||||
"config.yaml": configYAML,
|
||||
}
|
||||
r.NoError(kubeInformerClient.Tracker().Update(
|
||||
schema.GroupVersionResource{Version: "v1", Resource: "configmaps"},
|
||||
configMap,
|
||||
installedInNamespace,
|
||||
))
|
||||
waitForObjectToAppearInInformer(configMap, informer)
|
||||
var updateCredentialIssuerInInformerAndWait = func(resourceName string, credIssuerSpec v1alpha1.CredentialIssuerSpec, informer controllerlib.InformerGetter) {
|
||||
credIssuersGVR := v1alpha1.Resource("credentialissuers").WithVersion("v1alpha1")
|
||||
credIssuerObj, err := pinnipedInformerClient.Tracker().Get(credIssuersGVR, "", resourceName)
|
||||
r.NoError(err, "could not find CredentialIssuer to update for test")
|
||||
|
||||
credIssuer := credIssuerObj.(*v1alpha1.CredentialIssuer)
|
||||
credIssuer = credIssuer.DeepCopy() // don't edit the original from the tracker
|
||||
credIssuer.Spec = credIssuerSpec
|
||||
r.NoError(pinnipedInformerClient.Tracker().Update(credIssuersGVR, credIssuer, ""))
|
||||
waitForClusterScopedObjectToAppearInInformer(credIssuer, informer)
|
||||
}
|
||||
|
||||
var updateLoadBalancerServiceInInformerAndWait = func(resourceName string, ingresses []corev1.LoadBalancerIngress, informer controllerlib.InformerGetter) {
|
||||
@ -968,6 +952,10 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
r = require.New(t)
|
||||
queue = &testQueue{}
|
||||
cancelContext, cancelContextCancelFunc = context.WithCancel(context.Background())
|
||||
|
||||
pinnipedInformerClient = pinnipedfake.NewSimpleClientset()
|
||||
pinnipedInformers = pinnipedinformers.NewSharedInformerFactoryWithOptions(pinnipedInformerClient, 0)
|
||||
|
||||
kubeInformerClient = kubernetesfake.NewSimpleClientset()
|
||||
kubeInformers = kubeinformers.NewSharedInformerFactoryWithOptions(kubeInformerClient, 0,
|
||||
kubeinformers.WithNamespace(installedInNamespace),
|
||||
@ -992,10 +980,9 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
closeTestHTTPServer()
|
||||
})
|
||||
|
||||
when("the ConfigMap does not yet exist in the installation namespace or it was deleted (defaults to auto mode)", func() {
|
||||
when("the CredentialIssuer does not yet exist or it was deleted (defaults to auto mode)", func() {
|
||||
it.Before(func() {
|
||||
addSecretToTrackers(signingCASecret, kubeInformerClient)
|
||||
addImpersonatorConfigMapToTracker("some-other-unrelated-configmap", "foo: bar", kubeInformerClient)
|
||||
})
|
||||
|
||||
when("there are visible control plane nodes", func() {
|
||||
@ -1286,15 +1273,19 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
when("the ConfigMap is already in the installation namespace", func() {
|
||||
when("the CredentialIssuer is already present", func() {
|
||||
it.Before(func() {
|
||||
addSecretToTrackers(signingCASecret, kubeInformerClient)
|
||||
})
|
||||
|
||||
when("the configuration is auto mode with an endpoint", func() {
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: auto, endpoint: %s}", localhostIP)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeAuto,
|
||||
ExternalEndpoint: localhostIP,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
})
|
||||
|
||||
when("there are visible control plane nodes", func() {
|
||||
@ -1318,7 +1309,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
it("starts the impersonator according to the settings in the ConfigMap", func() {
|
||||
it("starts the impersonator according to the settings in the CredentialIssuer", func() {
|
||||
startInformersAndController()
|
||||
r.NoError(runControllerSync())
|
||||
r.Len(kubeAPIClient.Actions(), 3)
|
||||
@ -1334,7 +1325,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
|
||||
when("the configuration is disabled mode", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: disabled", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeDisabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1352,7 +1347,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("the configuration is enabled mode", func() {
|
||||
when("no load balancer", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: enabled", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("control-plane", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1379,7 +1378,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
|
||||
when("a loadbalancer already exists", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: enabled", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
addLoadBalancerServiceToTracker(loadBalancerServiceName, kubeInformerClient)
|
||||
addLoadBalancerServiceToTracker(loadBalancerServiceName, kubeAPIClient)
|
||||
@ -1408,7 +1411,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("a load balancer and a secret already exists", func() {
|
||||
var caCrt []byte
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: enabled", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
ca := newCA()
|
||||
caSecret := newActualCASecret(ca, caSecretName)
|
||||
@ -1431,11 +1438,15 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
when("the configmap has a hostname specified for the endpoint", func() {
|
||||
when("the CredentialIssuer has a hostname specified for the endpoint", func() {
|
||||
const fakeHostname = "fake.example.com"
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostname)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostname,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1453,11 +1464,15 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
when("the configmap has a endpoint which is an IP address with a port", func() {
|
||||
when("the CredentialIssuer has a endpoint which is an IP address with a port", func() {
|
||||
const fakeIPWithPort = "127.0.0.1:3000"
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeIPWithPort)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeIPWithPort,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1475,11 +1490,15 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
when("the configmap has a endpoint which is a hostname with a port", func() {
|
||||
when("the CredentialIssuer has a endpoint which is a hostname with a port", func() {
|
||||
const fakeHostnameWithPort = "fake.example.com:3000"
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostnameWithPort)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostnameWithPort,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1497,13 +1516,25 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
when("switching the configmap from ip address endpoint to hostname endpoint and back to ip address", func() {
|
||||
when("switching the CredentialIssuer from ip address endpoint to hostname endpoint and back to ip address", func() {
|
||||
const fakeHostname = "fake.example.com"
|
||||
const fakeIP = "127.0.0.42"
|
||||
var hostnameYAML = fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostname)
|
||||
var ipAddressYAML = fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeIP)
|
||||
|
||||
var hostnameConfig = v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostname,
|
||||
},
|
||||
}
|
||||
var ipAddressConfig = v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeIP,
|
||||
},
|
||||
}
|
||||
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, ipAddressYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, ipAddressConfig, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1524,7 +1555,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
addObjectFromCreateActionToInformerAndWait(kubeAPIClient.Actions()[2], kubeInformers.Core().V1().Secrets())
|
||||
|
||||
// Switch the endpoint config to a hostname.
|
||||
updateImpersonatorConfigMapInInformerAndWait(configMapResourceName, hostnameYAML, kubeInformers.Core().V1().ConfigMaps())
|
||||
updateCredentialIssuerInInformerAndWait(credentialIssuerResourceName, hostnameConfig, pinnipedInformers.Config().V1alpha1().CredentialIssuers())
|
||||
|
||||
r.NoError(runControllerSync())
|
||||
r.Len(kubeAPIClient.Actions(), 5)
|
||||
@ -1541,7 +1572,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
addObjectFromCreateActionToInformerAndWait(kubeAPIClient.Actions()[4], kubeInformers.Core().V1().Secrets())
|
||||
|
||||
// Switch the endpoint config back to an IP.
|
||||
updateImpersonatorConfigMapInInformerAndWait(configMapResourceName, ipAddressYAML, kubeInformers.Core().V1().ConfigMaps())
|
||||
updateCredentialIssuerInInformerAndWait(credentialIssuerResourceName, ipAddressConfig, pinnipedInformers.Config().V1alpha1().CredentialIssuers())
|
||||
|
||||
r.NoError(runControllerSync())
|
||||
r.Len(kubeAPIClient.Actions(), 7)
|
||||
@ -1557,8 +1588,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("the TLS cert goes missing and needs to be recreated, e.g. when a user manually deleted it", func() {
|
||||
const fakeHostname = "fake.example.com"
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostname)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostname,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
startInformersAndController()
|
||||
})
|
||||
@ -1595,8 +1630,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("the CA cert goes missing and needs to be recreated, e.g. when a user manually deleted it", func() {
|
||||
const fakeHostname = "fake.example.com"
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostname)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostname,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
startInformersAndController()
|
||||
})
|
||||
@ -1636,8 +1675,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
const fakeHostname = "fake.example.com"
|
||||
var caCrt []byte
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostname)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostname,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
startInformersAndController()
|
||||
r.NoError(runControllerSync())
|
||||
@ -1662,7 +1705,7 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
newCASecret := newActualCASecret(anotherCA, caSecretName)
|
||||
caCrt = newCASecret.Data["ca.crt"]
|
||||
addSecretToTrackers(newCASecret, kubeAPIClient)
|
||||
addObjectToInformerAndWait(newCASecret, kubeInformers.Core().V1().Secrets())
|
||||
addObjectToKubeInformerAndWait(newCASecret, kubeInformers.Core().V1().Secrets())
|
||||
})
|
||||
|
||||
it("deletes the old TLS cert and makes a new TLS cert using the new CA", func() {
|
||||
@ -1700,7 +1743,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
|
||||
when("the configuration switches from enabled to disabled mode", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: enabled", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1720,8 +1767,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
addObjectFromCreateActionToInformerAndWait(kubeAPIClient.Actions()[1], kubeInformers.Core().V1().Services())
|
||||
addObjectFromCreateActionToInformerAndWait(kubeAPIClient.Actions()[2], kubeInformers.Core().V1().Secrets())
|
||||
|
||||
// Update the configmap.
|
||||
updateImpersonatorConfigMapInInformerAndWait(configMapResourceName, "mode: disabled", kubeInformers.Core().V1().ConfigMaps())
|
||||
// Update the CredentialIssuer.
|
||||
updateCredentialIssuerInInformerAndWait(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeDisabled,
|
||||
},
|
||||
}, pinnipedInformers.Config().V1alpha1().CredentialIssuers())
|
||||
|
||||
r.NoError(runControllerSync())
|
||||
requireTLSServerIsNoLongerRunning()
|
||||
@ -1733,8 +1784,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
deleteServiceFromTracker(loadBalancerServiceName, kubeInformerClient)
|
||||
waitForObjectToBeDeletedFromInformer(loadBalancerServiceName, kubeInformers.Core().V1().Services())
|
||||
|
||||
// Update the configmap again.
|
||||
updateImpersonatorConfigMapInInformerAndWait(configMapResourceName, "mode: enabled", kubeInformers.Core().V1().ConfigMaps())
|
||||
// Update the CredentialIssuer again.
|
||||
updateCredentialIssuerInInformerAndWait(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformers.Config().V1alpha1().CredentialIssuers())
|
||||
|
||||
r.NoError(runControllerSync())
|
||||
requireTLSServerIsRunningWithoutCerts()
|
||||
@ -1747,8 +1802,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
|
||||
when("the endpoint switches from specified, to not specified, to specified again", func() {
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", localhostIP)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: localhostIP,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
@ -1770,7 +1829,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
addObjectFromCreateActionToInformerAndWait(kubeAPIClient.Actions()[2], kubeInformers.Core().V1().Secrets())
|
||||
|
||||
// Switch to "enabled" mode without an "endpoint", so a load balancer is needed now.
|
||||
updateImpersonatorConfigMapInInformerAndWait(configMapResourceName, "mode: enabled", kubeInformers.Core().V1().ConfigMaps())
|
||||
updateCredentialIssuerInInformerAndWait(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformers.Config().V1alpha1().CredentialIssuers())
|
||||
|
||||
r.NoError(runControllerSync())
|
||||
r.Len(kubeAPIClient.Actions(), 5)
|
||||
@ -1807,8 +1870,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
addObjectFromCreateActionToInformerAndWait(kubeAPIClient.Actions()[5], kubeInformers.Core().V1().Secrets())
|
||||
|
||||
// Now switch back to having the "endpoint" specified, so the load balancer is not needed anymore.
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", localhostIP)
|
||||
updateImpersonatorConfigMapInInformerAndWait(configMapResourceName, configMapYAML, kubeInformers.Core().V1().ConfigMaps())
|
||||
updateCredentialIssuerInInformerAndWait(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: localhostIP,
|
||||
},
|
||||
}, pinnipedInformers.Config().V1alpha1().CredentialIssuers())
|
||||
|
||||
r.NoError(runControllerSync())
|
||||
r.Len(kubeAPIClient.Actions(), 9)
|
||||
@ -2077,14 +2144,18 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
when("the configmap is invalid", func() {
|
||||
when("the CredentialIssuer is invalid", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "not yaml", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: "not-valid",
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
})
|
||||
|
||||
it("returns an error", func() {
|
||||
startInformersAndController()
|
||||
errString := "invalid impersonator configuration: decode yaml: error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type impersonator.Config"
|
||||
errString := `invalid impersonator configuration: invalid impersonation proxy mode "not-valid", valid values are auto, disabled, or enabled`
|
||||
r.EqualError(runControllerSync(), errString)
|
||||
requireCredentialIssuer(newErrorStrategy(errString))
|
||||
requireSigningCertProviderIsEmpty()
|
||||
@ -2111,7 +2182,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
|
||||
when("there is an error creating the tls secret", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "{mode: enabled, endpoint: example.com}", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: "example.com",
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("control-plane", kubeAPIClient)
|
||||
kubeAPIClient.PrependReactor("create", "secrets", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
createdSecret := action.(coretesting.CreateAction).GetObject().(*corev1.Secret)
|
||||
@ -2137,7 +2213,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
|
||||
when("there is an error creating the CA secret", func() {
|
||||
it.Before(func() {
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "{mode: enabled, endpoint: example.com}", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: "example.com",
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("control-plane", kubeAPIClient)
|
||||
kubeAPIClient.PrependReactor("create", "secrets", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
createdSecret := action.(coretesting.CreateAction).GetObject().(*corev1.Secret)
|
||||
@ -2163,7 +2244,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("the CA secret exists but is invalid while the TLS secret needs to be created", func() {
|
||||
it.Before(func() {
|
||||
addNodeWithRoleToTracker("control-plane", kubeAPIClient)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "{mode: enabled, endpoint: example.com}", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: "example.com",
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addSecretToTrackers(newEmptySecret(caSecretName), kubeAPIClient, kubeInformerClient)
|
||||
})
|
||||
|
||||
@ -2207,7 +2293,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
it.Before(func() {
|
||||
addNodeWithRoleToTracker("control-plane", kubeAPIClient)
|
||||
addSecretToTrackers(newEmptySecret(tlsSecretName), kubeInformerClient)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "{mode: disabled}", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeDisabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
})
|
||||
|
||||
it("does not pass the not found error through", func() {
|
||||
@ -2225,8 +2315,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("the PEM formatted data in the TLS Secret is not a valid cert", func() {
|
||||
it.Before(func() {
|
||||
addSecretToTrackers(signingCASecret, kubeInformerClient)
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", localhostIP)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: localhostIP,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
tlsSecret := &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@ -2281,7 +2375,11 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
var caCrt []byte
|
||||
it.Before(func() {
|
||||
addSecretToTrackers(signingCASecret, kubeInformerClient)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: enabled", kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
ca := newCA()
|
||||
caSecret := newActualCASecret(ca, caSecretName)
|
||||
@ -2330,7 +2428,6 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
var caCrt []byte
|
||||
it.Before(func() {
|
||||
addSecretToTrackers(signingCASecret, kubeInformerClient)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, "mode: enabled", kubeInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
ca := newCA()
|
||||
caSecret := newActualCASecret(ca, caSecretName)
|
||||
@ -2408,8 +2505,12 @@ func TestImpersonatorConfigControllerSync(t *testing.T) {
|
||||
when("the impersonator is ready but there is a problem with the signing secret, which should be created by another controller", func() {
|
||||
const fakeHostname = "foo.example.com"
|
||||
it.Before(func() {
|
||||
configMapYAML := fmt.Sprintf("{mode: enabled, endpoint: %s}", fakeHostname)
|
||||
addImpersonatorConfigMapToTracker(configMapResourceName, configMapYAML, kubeInformerClient)
|
||||
addCredentialIssuerToTracker(credentialIssuerResourceName, v1alpha1.CredentialIssuerSpec{
|
||||
ImpersonationProxy: v1alpha1.ImpersonationProxySpec{
|
||||
Mode: v1alpha1.ImpersonationProxyModeEnabled,
|
||||
ExternalEndpoint: fakeHostname,
|
||||
},
|
||||
}, pinnipedInformerClient)
|
||||
addNodeWithRoleToTracker("worker", kubeAPIClient)
|
||||
})
|
||||
|
||||
|
@ -251,11 +251,10 @@ func PrepareControllers(c *Config) (func(ctx context.Context), error) {
|
||||
WithController(
|
||||
impersonatorconfig.NewImpersonatorConfigController(
|
||||
c.ServerInstallationInfo.Namespace,
|
||||
c.NamesConfig.ImpersonationConfigMap,
|
||||
c.NamesConfig.CredentialIssuer,
|
||||
client.Kubernetes,
|
||||
client.PinnipedConcierge,
|
||||
informers.installationNamespaceK8s.Core().V1().ConfigMaps(),
|
||||
informers.pinniped.Config().V1alpha1().CredentialIssuers(),
|
||||
informers.installationNamespaceK8s.Core().V1().Services(),
|
||||
informers.installationNamespaceK8s.Core().V1().Secrets(),
|
||||
controllerlib.WithInformer,
|
||||
|
Loading…
Reference in New Issue
Block a user