From 9d7542b7ad5799cfb7c4546a50aece2673b5208f Mon Sep 17 00:00:00 2001 From: kkb0318 Date: Fri, 26 Jul 2024 20:29:02 +0900 Subject: [PATCH] change issuer settings of irsa_controller for eks mode --- internal/controller/irsa_controller.go | 9 +-- internal/controller/irsa_controller_test.go | 86 ++++++++++++++++++++- internal/controller/irsasetup_controller.go | 7 -- internal/issuer/issuer.go | 29 ++++++- 4 files changed, 112 insertions(+), 19 deletions(-) diff --git a/internal/controller/irsa_controller.go b/internal/controller/irsa_controller.go index df8f97c..997a489 100644 --- a/internal/controller/irsa_controller.go +++ b/internal/controller/irsa_controller.go @@ -51,13 +51,6 @@ type IRSAReconciler struct { // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the IRSA object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.3/pkg/reconcile func (r *IRSAReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := ctrllog.FromContext(ctx) obj := &irsav1alpha1.IRSA{} @@ -152,7 +145,7 @@ func (r *IRSAReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.IRSA, return fmt.Errorf("error converting to IRSASetup for %s: %v", list.Items[0].GetName(), err) } serviceAccount := obj.Spec.ServiceAccount - issuerMeta, err := issuer.NewS3IssuerMeta(&irsaSetup.Spec.Discovery.S3) + issuerMeta, err := issuer.NewOIDCIssuerMeta(irsaSetup) if err != nil { return err } diff --git a/internal/controller/irsa_controller_test.go b/internal/controller/irsa_controller_test.go index 3e70e13..a245698 100644 --- a/internal/controller/irsa_controller_test.go +++ b/internal/controller/irsa_controller_test.go @@ -211,7 +211,7 @@ var _ = Describe("IRSA Controller", func() { f: newServiceAccount, }, ) - f := createCallBack(ctx, r, typeNamespacedName, obj) + f := createCallBackForFixingNamespace(ctx, r, typeNamespacedName, obj) By("Add Namespace 'default'") f(obj.Spec.ServiceAccount.Name, []string{"default", "kube-system"}) @@ -222,6 +222,75 @@ var _ = Describe("IRSA Controller", func() { f: newServiceAccount, }) + By("removing the custom resource for the Kind") + 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 _, expect := range expected { + checkNoExist(expect) + } + }, + }, + { + name: "should update serviceaccount successfully with EKS mode", + obj: &irsav1alpha1.IRSA{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-resource-eks-1", + Namespace: "default", + }, + Spec: irsav1alpha1.IRSASpec{ + Cleanup: true, + ServiceAccount: irsav1alpha1.IRSAServiceAccount{ + Name: "sa-eks-1", + Namespaces: []string{ + "kube-system", + }, + }, + }, + }, + irsaSetupObj: newMockIRSASetupForEKS(), + f: func(r *IRSAReconciler, obj *irsav1alpha1.IRSA) { + expected := []expectedResource{ + { + NamespacedName: types.NamespacedName{Name: "sa-eks-1", Namespace: "kube-system"}, + f: newServiceAccount, + }, + { + NamespacedName: types.NamespacedName{Name: "sa-eks-1", Namespace: "default"}, + f: newServiceAccount, + }, + } + + By("Reconciling the created resource") + typeNamespacedName := types.NamespacedName{ + Name: obj.Name, + Namespace: obj.Namespace, + } + _, err := r.Reconcile(ctx, reconcile.Request{ + NamespacedName: typeNamespacedName, + }) + Expect(err).NotTo(HaveOccurred()) + checkExist( + expectedResource{ + NamespacedName: types.NamespacedName{Name: "sa-eks-1", Namespace: "kube-system"}, + f: newServiceAccount, + }, + ) + f := createCallBackForFixingNamespace(ctx, r, typeNamespacedName, obj) + + By("Add Namespace 'default'") + f(obj.Spec.ServiceAccount.Name, []string{"default", "kube-system"}) + By("Remove Namespace 'kube-system'") + f(obj.Spec.ServiceAccount.Name, []string{"default"}) + checkNoExist(expectedResource{ + NamespacedName: types.NamespacedName{Name: "sa-eks-1", Namespace: "kube-system"}, + f: newServiceAccount, + }) + By("removing the custom resource for the Kind") Eventually(func() error { return k8sClient.Delete(ctx, obj) @@ -298,7 +367,20 @@ func newMockIRSASetup() *irsav1alpha1.IRSASetup { } } -func createCallBack(ctx context.Context, r *IRSAReconciler, typeNamespacedName types.NamespacedName, obj *irsav1alpha1.IRSA) func(name string, namespaces []string) { +func newMockIRSASetupForEKS() *irsav1alpha1.IRSASetup { + return &irsav1alpha1.IRSASetup{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + Spec: irsav1alpha1.IRSASetupSpec{ + Mode: irsav1alpha1.ModeEks, + IamOIDCProvider: "oidc.example", + }, + } +} + +func createCallBackForFixingNamespace(ctx context.Context, r *IRSAReconciler, typeNamespacedName types.NamespacedName, obj *irsav1alpha1.IRSA) func(name string, namespaces []string) { return func(name string, namespaces []string) { fixNamespacesAndReconcile(ctx, r, typeNamespacedName, obj, name, namespaces) } diff --git a/internal/controller/irsasetup_controller.go b/internal/controller/irsasetup_controller.go index 184c48c..2be0614 100644 --- a/internal/controller/irsasetup_controller.go +++ b/internal/controller/irsasetup_controller.go @@ -59,13 +59,6 @@ type IRSASetupReconciler struct { // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the IRSASetup object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. -// -// For more details, check Reconcile and its Result here: -// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.16.3/pkg/reconcile func (r *IRSASetupReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := ctrllog.FromContext(ctx) obj := &irsav1alpha1.IRSASetup{} diff --git a/internal/issuer/issuer.go b/internal/issuer/issuer.go index 7329702..8b3711f 100644 --- a/internal/issuer/issuer.go +++ b/internal/issuer/issuer.go @@ -16,6 +16,13 @@ type S3IssuerMeta struct { bucketName string } +func NewOIDCIssuerMeta(i *irsav1alpha1.IRSASetup) (OIDCIssuerMeta, error) { + if i.Spec.Mode == irsav1alpha1.ModeEks { + return newIamOIDCProviderIssuerMeta(i.Spec.IamOIDCProvider) + } + return NewS3IssuerMeta(&i.Spec.Discovery.S3) +} + func NewS3IssuerMeta(s3 *irsav1alpha1.S3Discovery) (*S3IssuerMeta, error) { region := s3.Region bucketName := s3.BucketName @@ -32,6 +39,24 @@ func (i *S3IssuerMeta) IssuerHostPath() string { // 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 { - return fmt.Sprintf("https://%s", i. - IssuerHostPath()) + return fmt.Sprintf("https://%s", i.IssuerHostPath()) +} + +func newIamOIDCProviderIssuerMeta(providerName string) (*iamOIDCProviderIssuerMeta, error) { + if providerName == "" { + return nil, fmt.Errorf("IAM OIDC Provider Name must not be empty") + } + return &iamOIDCProviderIssuerMeta{providerName}, nil +} + +type iamOIDCProviderIssuerMeta struct { + providerName string +} + +func (i *iamOIDCProviderIssuerMeta) IssuerHostPath() string { + return i.providerName +} + +func (i *iamOIDCProviderIssuerMeta) IssuerUrl() string { + return fmt.Sprintf("https://%s", i.IssuerHostPath()) }