diff --git a/api/v1alpha1/irsasetup_types.go b/api/v1alpha1/irsasetup_types.go
index bcb87ec..707ae85 100644
--- a/api/v1alpha1/irsasetup_types.go
+++ b/api/v1alpha1/irsasetup_types.go
@@ -43,11 +43,12 @@ type IRSASetupSpec struct {
// Discovery configures the IdP Discovery process, essential for setting up IRSA by locating
// the OIDC provider information.
// Only applicable when Mode is "selfhosted".
- Discovery Discovery `json:"discovery"`
+ // +optional
+ Discovery Discovery `json:"discovery,omitempty"`
// IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
// Only applicable when Mode is "eks".
- IamOIDCProvider string `json:"provider,omitempty"`
+ IamOIDCProvider string `json:"iamOIDCProvider,omitempty"`
}
// +kubebuilder:default=selfhosted
@@ -78,39 +79,39 @@ type S3Discovery struct {
// IRSASetupStatus defines the observed state of IRSASetup
type IRSASetupStatus struct {
- SelfHostedSetup []metav1.Condition `json:"selfHostedSetup,omitempty"`
+ Conditions []metav1.Condition `json:"conditions,omitempty"`
}
-// GetSelfhostedStatusConditions returns a pointer to the Status.Conditions slice
-func (in *IRSASetup) GetSelfhostedStatusConditions() *[]metav1.Condition {
- return &in.Status.SelfHostedSetup
+// GetStatusConditions returns a pointer to the Status.Conditions slice
+func (in *IRSASetup) GetStatusConditions() *[]metav1.Condition {
+ return &in.Status.Conditions
}
-func SetupSelfHostedStatusReady(irsa IRSASetup, reason, message string) IRSASetup {
+func SetupStatusReady(irsa IRSASetup, reason, message string) IRSASetup {
newCondition := metav1.Condition{
Type: ReadyCondition,
Status: metav1.ConditionTrue,
Reason: reason,
Message: message,
}
- apimeta.SetStatusCondition(irsa.GetSelfhostedStatusConditions(), newCondition)
+ apimeta.SetStatusCondition(irsa.GetStatusConditions(), newCondition)
return irsa
}
-func SelfHostedStatusNotReady(irsa IRSASetup, reason, message string) IRSASetup {
+func StatusNotReady(irsa IRSASetup, reason, message string) IRSASetup {
newCondition := metav1.Condition{
Type: ReadyCondition,
Status: metav1.ConditionFalse,
Reason: reason,
Message: message,
}
- apimeta.SetStatusCondition(irsa.GetSelfhostedStatusConditions(), newCondition)
+ apimeta.SetStatusCondition(irsa.GetStatusConditions(), newCondition)
return irsa
}
-// SelfHostedReadyStatus
-func SelfHostedReadyStatus(irsa IRSASetup) *metav1.Condition {
- if c := apimeta.FindStatusCondition(irsa.Status.SelfHostedSetup, ReadyCondition); c != nil {
+// ReadyStatus
+func ReadyStatus(irsa IRSASetup) *metav1.Condition {
+ if c := apimeta.FindStatusCondition(irsa.Status.Conditions, ReadyCondition); c != nil {
return c
}
return nil
@@ -129,22 +130,30 @@ func HasConditionReason(cond *metav1.Condition, reasons ...string) bool {
return false
}
-func IsSelfHostedReadyConditionTrue(irsa IRSASetup) bool {
- return apimeta.IsStatusConditionTrue(irsa.Status.SelfHostedSetup, ReadyCondition)
+func IsReadyConditionTrue(irsa IRSASetup) bool {
+ return apimeta.IsStatusConditionTrue(irsa.Status.Conditions, ReadyCondition)
}
-type SelfHostedReason string
+type SelfhostedConditionReason string
const (
- SelfHostedReasonFailedWebhook SelfHostedReason = "SelfHostedSetupFailedWebhookCreation"
- SelfHostedReasonFailedOidc SelfHostedReason = "SelfHostedSetupFailedOidcCreation"
- SelfHostedReasonFailedKeys SelfHostedReason = "SelfHostedSetupFailedKeysCreation"
- SelfHostedReasonReady SelfHostedReason = "SelfHostedSetupReady"
+ SelfHostedReasonFailedWebhook SelfhostedConditionReason = "SelfHostedSetupFailedWebhookCreation"
+ SelfHostedReasonFailedOidc SelfhostedConditionReason = "SelfHostedSetupFailedOidcCreation"
+ SelfHostedReasonFailedIssuer SelfhostedConditionReason = "SelfHostedSetupFailedIssuer"
+ SelfHostedReasonFailedKeys SelfhostedConditionReason = "SelfHostedSetupFailedKeysCreation"
+ SelfHostedReasonReady SelfhostedConditionReason = "SelfHostedSetupReady"
+)
+
+type EksConditionReason string
+
+const (
+ EksNotReady EksConditionReason = "EksOIDCNotReady"
+ EksReasonReady EksConditionReason = "EksOIDCSetupReady"
)
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
-//+kubebuilder:printcolumn:name="SelfHostedReady",type="string",JSONPath=".status.selfHostedSetup[?(@.type==\"Ready\")].status",description=""
+//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
// IRSASetup represents a configuration for setting up IAM Roles for Service Accounts (IRSA) in a Kubernetes cluster.
type IRSASetup struct {
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 65e1d9d..a7f7d20 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -213,8 +213,8 @@ func (in *IRSASetupSpec) DeepCopy() *IRSASetupSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *IRSASetupStatus) DeepCopyInto(out *IRSASetupStatus) {
*out = *in
- if in.SelfHostedSetup != nil {
- in, out := &in.SelfHostedSetup, &out.SelfHostedSetup
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
*out = make([]v1.Condition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
diff --git a/charts/irsa-manager/crds/irsasetup-crd.yaml b/charts/irsa-manager/crds/irsasetup-crd.yaml
index 6ea464b..9ea7918 100644
--- a/charts/irsa-manager/crds/irsasetup-crd.yaml
+++ b/charts/irsa-manager/crds/irsasetup-crd.yaml
@@ -14,8 +14,8 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- - jsonPath: .status.selfHostedSetup[?(@.type=="Ready")].status
- name: SelfHostedReady
+ - jsonPath: .status.conditions[?(@.type=="Ready")].status
+ name: Ready
type: string
name: v1alpha1
schema:
@@ -71,6 +71,11 @@ spec:
- region
type: object
type: object
+ iamOIDCProvider:
+ description: |-
+ IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
+ Only applicable when Mode is "eks".
+ type: string
mode:
description: |-
Mode specifies the operation mode of the controller.
@@ -85,19 +90,13 @@ spec:
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
- provider:
- description: |-
- IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
- Only applicable when Mode is "eks".
- type: string
required:
- cleanup
- - discovery
type: object
status:
description: IRSASetupStatus defines the observed state of IRSASetup
properties:
- selfHostedSetup:
+ conditions:
items:
description: "Condition contains details for one aspect of the current
state of this API Resource.\n---\nThis struct is intended for
diff --git a/config/crd/bases/irsa-manager.kkb0318.github.io_irsasetups.yaml b/config/crd/bases/irsa-manager.kkb0318.github.io_irsasetups.yaml
index c3ffe7b..fc94415 100644
--- a/config/crd/bases/irsa-manager.kkb0318.github.io_irsasetups.yaml
+++ b/config/crd/bases/irsa-manager.kkb0318.github.io_irsasetups.yaml
@@ -15,8 +15,8 @@ spec:
scope: Namespaced
versions:
- additionalPrinterColumns:
- - jsonPath: .status.selfHostedSetup[?(@.type=="Ready")].status
- name: SelfHostedReady
+ - jsonPath: .status.conditions[?(@.type=="Ready")].status
+ name: Ready
type: string
name: v1alpha1
schema:
@@ -72,6 +72,11 @@ spec:
- region
type: object
type: object
+ iamOIDCProvider:
+ description: |-
+ IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
+ Only applicable when Mode is "eks".
+ type: string
mode:
description: |-
Mode specifies the operation mode of the controller.
@@ -86,19 +91,13 @@ spec:
x-kubernetes-validations:
- message: Value is immutable
rule: self == oldSelf
- provider:
- description: |-
- IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
- Only applicable when Mode is "eks".
- type: string
required:
- cleanup
- - discovery
type: object
status:
description: IRSASetupStatus defines the observed state of IRSASetup
properties:
- selfHostedSetup:
+ conditions:
items:
description: "Condition contains details for one aspect of the current
state of this API Resource.\n---\nThis struct is intended for
diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml
index 7394a6d..4b9bfd7 100644
--- a/config/manager/kustomization.yaml
+++ b/config/manager/kustomization.yaml
@@ -1,2 +1,8 @@
resources:
- - manager.yaml
+- manager.yaml
+apiVersion: kustomize.config.k8s.io/v1beta1
+kind: Kustomization
+images:
+- name: controller
+ newName: ghcr.io/kkb0318/irsa-manager
+ newTag: latest
diff --git a/docs/api.md b/docs/api.md
index 3bb9855..afc8c5b 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -31,6 +31,8 @@ _Appears in:_
| `s3` _[S3Discovery](#s3discovery)_ | S3 specifies the AWS S3 bucket details where the OIDC provider's discovery information is hosted. | | |
+
+
#### IRSA
@@ -104,7 +106,7 @@ _Appears in:_
| `cleanup` _boolean_ | Cleanup, when enabled, allows the IRSASetup to perform garbage collection
of resources that are no longer needed or managed. | | |
| `mode` _[SetupMode](#setupmode)_ | Mode specifies the operation mode of the controller.
Possible values:
- "selfhosted": For self-managed Kubernetes clusters.
- "eks": For Amazon EKS environments.
Default: "selfhosted" | | Enum: [selfhosted eks]
|
| `discovery` _[Discovery](#discovery)_ | Discovery configures the IdP Discovery process, essential for setting up IRSA by locating
the OIDC provider information.
Only applicable when Mode is "selfhosted". | | |
-| `provider` _string_ | IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
Only applicable when Mode is "eks". | | |
+| `iamOIDCProvider` _string_ | IamOIDCProvider configures IAM OIDC IamOIDCProvider Name
Only applicable when Mode is "eks". | | |
diff --git a/examples/eks.yaml b/examples/eks.yaml
new file mode 100644
index 0000000..b6172a2
--- /dev/null
+++ b/examples/eks.yaml
@@ -0,0 +1,9 @@
+apiVersion: irsa-manager.kkb0318.github.io/v1alpha1
+kind: IRSASetup
+metadata:
+ name: irsa-init
+ namespace: irsa-manager-system
+spec:
+ mode: eks
+ cleanup: true
+ iamOIDCProvider: "oidc.eks..amazonaws.com/id/"
diff --git a/examples/irsa.yaml b/examples/irsa.yaml
index 6b4373e..5f774e9 100644
--- a/examples/irsa.yaml
+++ b/examples/irsa.yaml
@@ -6,11 +6,11 @@ metadata:
spec:
cleanup: true
serviceAccount:
- name: irsa1-sa
+ name: irsa111-sa
namespaces:
- kube-system
- default
iamRole:
- name: irsa1-role
+ name: irsa111-role
iamPolicies:
- AmazonS3FullAccess
diff --git a/internal/controller/irsasetup_controller.go b/internal/controller/irsasetup_controller.go
index 3b978aa..ad55884 100644
--- a/internal/controller/irsasetup_controller.go
+++ b/internal/controller/irsasetup_controller.go
@@ -18,7 +18,6 @@ package controller
import (
"context"
- "fmt"
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
@@ -28,6 +27,7 @@ import (
irsav1alpha1 "github.com/kkb0318/irsa-manager/api/v1alpha1"
awsclient "github.com/kkb0318/irsa-manager/internal/aws"
+ "github.com/kkb0318/irsa-manager/internal/eks"
"github.com/kkb0318/irsa-manager/internal/handler"
"github.com/kkb0318/irsa-manager/internal/issuer"
"github.com/kkb0318/irsa-manager/internal/kubernetes"
@@ -124,10 +124,9 @@ 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)
+ return reconcileEks(ctx, obj)
}
- err := reconcileSelfhosted(ctx, obj, r.AwsClient, kubeClient)
- return err
+ return reconcileSelfhosted(ctx, obj, r.AwsClient, kubeClient)
}
func (r *IRSASetupReconciler) reconcileDeleteEks() error {
@@ -177,7 +176,7 @@ func (r *IRSASetupReconciler) reconcileDeleteSelfhosted(ctx context.Context, obj
// - The function enforces a 'force update' strategy in case of failures related to kubernetes Secrets creation or OIDC setup. This means it starts from scratch to ensure all components are correctly configured.
func reconcileSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, awsClient awsclient.AwsClient, kubeClient *kubernetes.KubernetesClient) error {
log := ctrllog.FromContext(ctx)
- if irsav1alpha1.IsSelfHostedReadyConditionTrue(*obj) {
+ if irsav1alpha1.IsReadyConditionTrue(*obj) {
// Selfhosted Setup have already succeeded
log.Info("the self-hosted resources have already set up")
return nil
@@ -210,20 +209,22 @@ func reconcileSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, awsCl
// e is set only when an error occurs in an external dependency process and is reflected in the CRs status
var e error
- var reason irsav1alpha1.SelfHostedReason
+ var reason irsav1alpha1.SelfhostedConditionReason
defer func() {
if e != nil {
- *obj = irsav1alpha1.SelfHostedStatusNotReady(*obj, string(reason), e.Error())
+ *obj = irsav1alpha1.StatusNotReady(*obj, string(reason), e.Error())
}
}()
forceUpdate := irsav1alpha1.HasConditionReason(
- irsav1alpha1.SelfHostedReadyStatus(*obj),
+ irsav1alpha1.ReadyStatus(*obj),
string(irsav1alpha1.SelfHostedReasonFailedKeys),
string(irsav1alpha1.SelfHostedReasonFailedOidc),
)
issuerMeta, err := issuer.NewOIDCIssuerMeta(obj)
if err != nil {
+ e = err
+ reason = irsav1alpha1.SelfHostedReasonFailedIssuer
return err
}
err = selfhosted.Execute(
@@ -258,16 +259,31 @@ func reconcileSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, awsCl
reason = irsav1alpha1.SelfHostedReasonFailedWebhook
return err
}
- *obj = irsav1alpha1.SetupSelfHostedStatusReady(*obj, string(irsav1alpha1.SelfHostedReasonReady), "successfully setup resources for self-hosted")
+ *obj = irsav1alpha1.SetupStatusReady(*obj, string(irsav1alpha1.SelfHostedReasonReady), "successfully setup resources for self-hosted")
log.Info("the self-hosted resources have successfully set up")
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'")
+// reconcileEks iterates tasks for EKS mode.
+func reconcileEks(ctx context.Context, obj *irsav1alpha1.IRSASetup) error {
+ log := ctrllog.FromContext(ctx)
+ var reason irsav1alpha1.EksConditionReason
+
+ // e is set only when an error occurs in an external dependency process and is reflected in the CRs status
+ var e error
+ defer func() {
+ if e != nil {
+ *obj = irsav1alpha1.StatusNotReady(*obj, string(reason), e.Error())
+ }
+ }()
+ err := eks.Validate(obj)
+ if err != nil {
+ e = err
+ reason = irsav1alpha1.EksNotReady
+ return err
}
+ *obj = irsav1alpha1.SetupStatusReady(*obj, string(irsav1alpha1.EksReasonReady), "successfully setup for eks")
+ log.Info("The OIDC for EKS has been successfully set up")
return nil
}
diff --git a/internal/eks/validation.go b/internal/eks/validation.go
new file mode 100644
index 0000000..a592d1e
--- /dev/null
+++ b/internal/eks/validation.go
@@ -0,0 +1,14 @@
+package eks
+
+import (
+ "fmt"
+
+ irsav1alpha1 "github.com/kkb0318/irsa-manager/api/v1alpha1"
+)
+
+func Validate(obj *irsav1alpha1.IRSASetup) error {
+ if obj.Spec.IamOIDCProvider == "" {
+ return fmt.Errorf("IamOIDCProvider parameter must be set when Mode is 'eks'")
+ }
+ return nil
+}