diff --git a/internal/controller/irsasetup_controller.go b/internal/controller/irsasetup_controller.go index 2be0614..3b978aa 100644 --- a/internal/controller/irsasetup_controller.go +++ b/internal/controller/irsasetup_controller.go @@ -18,6 +18,7 @@ package controller import ( "context" + "fmt" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" @@ -97,7 +98,11 @@ func (r *IRSASetupReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( }() if !obj.DeletionTimestamp.IsZero() { - err = r.reconcileDelete(ctx, obj, kubeClient) + if obj.Spec.Mode == irsav1alpha1.ModeEks { + err = r.reconcileDeleteEks() + } else { + err = r.reconcileDeleteSelfhosted(ctx, obj, kubeClient) + } if err != nil { return ctrl.Result{}, err } @@ -118,11 +123,18 @@ func (r *IRSASetupReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } func (r *IRSASetupReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.IRSASetup, kubeClient *kubernetes.KubernetesClient) error { + if obj.Spec.Mode == irsav1alpha1.ModeEks { + return reconcileEks(obj) + } err := reconcileSelfhosted(ctx, obj, r.AwsClient, kubeClient) return err } -func (r *IRSASetupReconciler) reconcileDelete(ctx context.Context, obj *irsav1alpha1.IRSASetup, kubeClient *kubernetes.KubernetesClient) error { +func (r *IRSASetupReconciler) reconcileDeleteEks() error { + return nil +} + +func (r *IRSASetupReconciler) reconcileDeleteSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, kubeClient *kubernetes.KubernetesClient) error { if !obj.Spec.Cleanup { return nil } @@ -147,7 +159,7 @@ func (r *IRSASetupReconciler) reconcileDelete(ctx context.Context, obj *irsav1al if err != nil { return err } - issuerMeta, err := issuer.NewS3IssuerMeta(&obj.Spec.Discovery.S3) + issuerMeta, err := issuer.NewOIDCIssuerMeta(obj) if err != nil { return err } @@ -210,7 +222,7 @@ func reconcileSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, awsCl string(irsav1alpha1.SelfHostedReasonFailedKeys), string(irsav1alpha1.SelfHostedReasonFailedOidc), ) - issuerMeta, err := issuer.NewS3IssuerMeta(&obj.Spec.Discovery.S3) + issuerMeta, err := issuer.NewOIDCIssuerMeta(obj) if err != nil { return err } @@ -251,6 +263,14 @@ func reconcileSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, awsCl return nil } +// reconcileEks ensures the required IAM OIDC Provider is set for EKS mode. +func reconcileEks(obj *irsav1alpha1.IRSASetup) error { + if obj.Spec.IamOIDCProvider == "" { + return fmt.Errorf("IamOIDCProvider parameter must be set when Mode is 'eks'") + } + return nil +} + func newOIDCIdpFactory(ctx context.Context, obj *irsav1alpha1.IRSASetup, jwk *selfhosted.JWK, awsClient awsclient.AwsClient) (selfhosted.OIDCIdPFactory, error) { region := obj.Spec.Discovery.S3.Region bucketName := obj.Spec.Discovery.S3.BucketName diff --git a/internal/controller/irsasetup_controller_test.go b/internal/controller/irsasetup_controller_test.go index ae4b011..93e4575 100644 --- a/internal/controller/irsasetup_controller_test.go +++ b/internal/controller/irsasetup_controller_test.go @@ -288,6 +288,42 @@ var _ = Describe("IRSASetup Controller", func() { } }, }, + { + name: "EKS mode", + obj: &irsav1alpha1.IRSASetup{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-resource-eks1", + Namespace: "default", + }, + Spec: irsav1alpha1.IRSASetupSpec{ + Cleanup: false, + Mode: irsav1alpha1.ModeEks, + IamOIDCProvider: "oidc.example", + }, + }, + f: func(r *IRSASetupReconciler, obj *irsav1alpha1.IRSASetup) { + typeNamespacedName := types.NamespacedName{ + Name: obj.Name, + Namespace: obj.Namespace, + } + _, err := r.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).NotTo(HaveOccurred()) + _, err = r.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).To(Not(HaveOccurred())) + By("removing the custom resource (not cleanup)") + Eventually(func() error { + return k8sClient.Delete(ctx, obj) + }, timeout).Should(Succeed()) + _, err = r.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).To(Not(HaveOccurred())) + }, + }, } for _, tt := range tests { It(tt.name, func() { diff --git a/internal/issuer/issuer.go b/internal/issuer/issuer.go index 8b3711f..2417183 100644 --- a/internal/issuer/issuer.go +++ b/internal/issuer/issuer.go @@ -11,7 +11,7 @@ type OIDCIssuerMeta interface { IssuerUrl() string } -type S3IssuerMeta struct { +type s3IssuerMeta struct { region string bucketName string } @@ -20,25 +20,25 @@ func NewOIDCIssuerMeta(i *irsav1alpha1.IRSASetup) (OIDCIssuerMeta, error) { if i.Spec.Mode == irsav1alpha1.ModeEks { return newIamOIDCProviderIssuerMeta(i.Spec.IamOIDCProvider) } - return NewS3IssuerMeta(&i.Spec.Discovery.S3) + return newS3IssuerMeta(&i.Spec.Discovery.S3) } -func NewS3IssuerMeta(s3 *irsav1alpha1.S3Discovery) (*S3IssuerMeta, error) { +func newS3IssuerMeta(s3 *irsav1alpha1.S3Discovery) (*s3IssuerMeta, error) { region := s3.Region bucketName := s3.BucketName if region == "" || bucketName == "" { return nil, fmt.Errorf("s3 region and bucket name must not be empty. region: %s, bucketName: %s", region, bucketName) } - return &S3IssuerMeta{region, bucketName}, nil + return &s3IssuerMeta{region, bucketName}, nil } -func (i *S3IssuerMeta) IssuerHostPath() string { +func (i *s3IssuerMeta) IssuerHostPath() string { return fmt.Sprintf("s3-%s.amazonaws.com/%s", i.region, i.bucketName) } // IssuerUrl constructs the URL path for the OIDC issuer based on the provided AWS region and bucket name. // This utility function generates the expected host path for accessing the OIDC configuration stored in an S3 bucket. -func (i *S3IssuerMeta) IssuerUrl() string { +func (i *s3IssuerMeta) IssuerUrl() string { return fmt.Sprintf("https://%s", i.IssuerHostPath()) }