From 9ab7c39d56e41987a3325aafd98592c96cfa3fad Mon Sep 17 00:00:00 2001 From: Ashish Amarnath Date: Tue, 2 Jul 2024 00:11:30 -0700 Subject: [PATCH] jwt cache filler Signed-off-by: Ashish Amarnath --- .../jwtcachefiller/jwtcachefiller.go | 42 ++++++++----------- .../jwtcachefiller/jwtcachefiller_test.go | 13 ++++-- .../controllermanager/prepare_controllers.go | 2 + 3 files changed, 29 insertions(+), 28 deletions(-) diff --git a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go index ed1acf2bb..fb68efc38 100644 --- a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go +++ b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller.go @@ -25,6 +25,7 @@ import ( "k8s.io/apiserver/pkg/apis/apiserver" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/plugin/pkg/authenticator/token/oidc" + corev1informers "k8s.io/client-go/informers/core/v1" "k8s.io/klog/v2" "k8s.io/utils/clock" "k8s.io/utils/ptr" @@ -37,6 +38,7 @@ import ( pinnipedauthenticator "go.pinniped.dev/internal/controller/authenticator" "go.pinniped.dev/internal/controller/authenticator/authncache" "go.pinniped.dev/internal/controller/conditionsutil" + "go.pinniped.dev/internal/controller/tlsconfigutil" "go.pinniped.dev/internal/controllerlib" "go.pinniped.dev/internal/net/phttp" "go.pinniped.dev/internal/plog" @@ -132,6 +134,8 @@ func New( cache *authncache.Cache, client conciergeclientset.Interface, jwtAuthenticators authinformers.JWTAuthenticatorInformer, + secretInformer corev1informers.SecretInformer, + configMapInformer corev1informers.ConfigMapInformer, clock clock.Clock, log plog.Logger, ) controllerlib.Controller { @@ -142,6 +146,8 @@ func New( cache: cache, client: client, jwtAuthenticators: jwtAuthenticators, + secretInformer: secretInformer, + configMapInformer: configMapInformer, clock: clock, log: log.WithName(controllerName), }, @@ -157,6 +163,8 @@ func New( type jwtCacheFillerController struct { cache *authncache.Cache jwtAuthenticators authinformers.JWTAuthenticatorInformer + secretInformer corev1informers.SecretInformer + configMapInformer corev1informers.ConfigMapInformer client conciergeclientset.Interface clock clock.Clock log plog.Logger @@ -202,7 +210,7 @@ func (c *jwtCacheFillerController) Sync(ctx controllerlib.Context) error { conditions := make([]*metav1.Condition, 0) var errs []error - rootCAs, conditions, tlsOk := c.validateTLSBundle(obj.Spec.TLS, conditions) + rootCAs, conditions, tlsOk := c.validateTLSBundle(obj.Spec.TLS, obj.Namespace, conditions) _, conditions, issuerOk := c.validateIssuer(obj.Spec.Issuer, conditions) okSoFar := tlsOk && issuerOk @@ -270,30 +278,16 @@ func (c *jwtCacheFillerController) cacheValueAsJWTAuthenticator(value authncache return jwtAuthenticator } -func (c *jwtCacheFillerController) validateTLSBundle(tlsSpec *authenticationv1alpha1.TLSSpec, conditions []*metav1.Condition) (*x509.CertPool, []*metav1.Condition, bool) { - rootCAs, _, err := pinnipedcontroller.BuildCertPoolAuth(tlsSpec) - if err != nil { - msg := fmt.Sprintf("%s: %s", "invalid TLS configuration", err.Error()) - conditions = append(conditions, &metav1.Condition{ - Type: typeTLSConfigurationValid, - Status: metav1.ConditionFalse, - Reason: reasonInvalidTLSConfiguration, - Message: msg, - }) - return rootCAs, conditions, false - } +func (c *jwtCacheFillerController) validateTLSBundle(tlsSpec *authenticationv1alpha1.TLSSpec, namespace string, conditions []*metav1.Condition) (*x509.CertPool, []*metav1.Condition, bool) { + condition, _, rootCAs, _ := tlsconfigutil.ValidateTLSConfig( + tlsconfigutil.TlsSpecForConcierge(tlsSpec), + "spec.tls", + namespace, + c.secretInformer, + c.configMapInformer) - msg := "successfully parsed specified CA bundle" - if rootCAs == nil { - msg = "no CA bundle specified" - } - conditions = append(conditions, &metav1.Condition{ - Type: typeTLSConfigurationValid, - Status: metav1.ConditionTrue, - Reason: reasonSuccess, - Message: msg, - }) - return rootCAs, conditions, true + conditions = append(conditions, condition) + return rootCAs, conditions, condition.Status == metav1.ConditionTrue } func (c *jwtCacheFillerController) validateIssuer(issuer string, conditions []*metav1.Condition) (*url.URL, []*metav1.Condition, bool) { diff --git a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go index cdc207b1b..3e5b9729e 100644 --- a/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go +++ b/internal/controller/authenticator/jwtcachefiller/jwtcachefiller_test.go @@ -32,6 +32,8 @@ import ( "k8s.io/apimachinery/pkg/util/wait" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/user" + kubeinformers "k8s.io/client-go/informers" + kubernetesfake "k8s.io/client-go/kubernetes/fake" coretesting "k8s.io/client-go/testing" clocktesting "k8s.io/utils/clock/testing" @@ -379,7 +381,7 @@ func TestController(t *testing.T) { ObservedGeneration: observedGeneration, LastTransitionTime: time, Reason: "Success", - Message: "successfully parsed specified CA bundle", + Message: "spec.tls is valid: loaded TLS configuration", } } happyTLSConfigurationValidNoCA := func(time metav1.Time, observedGeneration int64) metav1.Condition { @@ -389,7 +391,7 @@ func TestController(t *testing.T) { ObservedGeneration: observedGeneration, LastTransitionTime: time, Reason: "Success", - Message: "no CA bundle specified", + Message: "spec.tls is valid: no TLS configuration provided", } } sadTLSConfigurationValid := func(time metav1.Time, observedGeneration int64) metav1.Condition { @@ -398,8 +400,8 @@ func TestController(t *testing.T) { Status: "False", ObservedGeneration: observedGeneration, LastTransitionTime: time, - Reason: "InvalidTLSConfiguration", - Message: "invalid TLS configuration: illegal base64 data at input byte 7", + Reason: "InvalidTLSConfig", + Message: "spec.tls.certificateAuthorityData is invalid: illegal base64 data at input byte 7", } } @@ -1842,6 +1844,7 @@ func TestController(t *testing.T) { tt.configClient(pinnipedAPIClient) } pinnipedInformers := conciergeinformers.NewSharedInformerFactory(pinnipedAPIClient, 0) + kubeInformers := kubeinformers.NewSharedInformerFactory(kubernetesfake.NewSimpleClientset(), 0) cache := authncache.New() var log bytes.Buffer @@ -1855,6 +1858,8 @@ func TestController(t *testing.T) { cache, pinnipedAPIClient, pinnipedInformers.Authentication().V1alpha1().JWTAuthenticators(), + kubeInformers.Core().V1().Secrets(), + kubeInformers.Core().V1().ConfigMaps(), frozenClock, logger) diff --git a/internal/controllermanager/prepare_controllers.go b/internal/controllermanager/prepare_controllers.go index 274aebcec..31c8b81bb 100644 --- a/internal/controllermanager/prepare_controllers.go +++ b/internal/controllermanager/prepare_controllers.go @@ -250,6 +250,8 @@ func PrepareControllers(c *Config) (controllerinit.RunnerBuilder, error) { //nol c.AuthenticatorCache, client.PinnipedConcierge, informers.pinniped.Authentication().V1alpha1().JWTAuthenticators(), + informers.installationNamespaceK8s.Core().V1().Secrets(), + informers.installationNamespaceK8s.Core().V1().ConfigMaps(), clock.RealClock{}, plog.New(), ),