mirror of
https://github.com/storytold/irsa-manager.git
synced 2026-10-09 00:09:43 +00:00
fix api (for mode: eks), status
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,2 +1,8 @@
|
||||
resources:
|
||||
- manager.yaml
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
images:
|
||||
- name: controller
|
||||
newName: ghcr.io/kkb0318/irsa-manager
|
||||
newTag: latest
|
||||
|
||||
+3
-1
@@ -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<br />of resources that are no longer needed or managed. | | |
|
||||
| `mode` _[SetupMode](#setupmode)_ | Mode specifies the operation mode of the controller.<br />Possible values:<br /> - "selfhosted": For self-managed Kubernetes clusters.<br /> - "eks": For Amazon EKS environments.<br />Default: "selfhosted" | | Enum: [selfhosted eks] <br /> |
|
||||
| `discovery` _[Discovery](#discovery)_ | Discovery configures the IdP Discovery process, essential for setting up IRSA by locating<br />the OIDC provider information.<br />Only applicable when Mode is "selfhosted". | | |
|
||||
| `provider` _string_ | IamOIDCProvider configures IAM OIDC IamOIDCProvider Name<br />Only applicable when Mode is "eks". | | |
|
||||
| `iamOIDCProvider` _string_ | IamOIDCProvider configures IAM OIDC IamOIDCProvider Name<br />Only applicable when Mode is "eks". | | |
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.<region>.amazonaws.com/id/<id>"
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user