mirror of
https://github.com/storytold/irsa-manager.git
synced 2026-10-09 00:09:43 +00:00
irsa Status Management
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package v1alpha1
|
||||
|
||||
const (
|
||||
// ReadyCondition indicates the resource is ready and fully reconciled.
|
||||
// If the Condition is False, the resource SHOULD be considered to be in the process of reconciling and not a
|
||||
// representation of actual state.
|
||||
ReadyCondition string = "Ready"
|
||||
)
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
@@ -55,12 +56,47 @@ type IamRole struct {
|
||||
|
||||
// IRSAStatus defines the observed state of IRSA
|
||||
type IRSAStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// GetIRSAStatusConditions returns a pointer to the Status.Conditions slice
|
||||
func (in *IRSA) GetIRSAStatusConditions() *[]metav1.Condition {
|
||||
return &in.Status.Conditions
|
||||
}
|
||||
|
||||
func IRSAStatusReady(irsa IRSA, reason, message string) IRSA {
|
||||
newCondition := metav1.Condition{
|
||||
Type: ReadyCondition,
|
||||
Status: metav1.ConditionTrue,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
}
|
||||
apimeta.SetStatusCondition(irsa.GetIRSAStatusConditions(), newCondition)
|
||||
return irsa
|
||||
}
|
||||
|
||||
func IRSAStatusNotReady(irsa IRSA, reason, message string) IRSA {
|
||||
newCondition := metav1.Condition{
|
||||
Type: ReadyCondition,
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
}
|
||||
apimeta.SetStatusCondition(irsa.GetIRSAStatusConditions(), newCondition)
|
||||
return irsa
|
||||
}
|
||||
|
||||
type IRSAReason string
|
||||
|
||||
const (
|
||||
IRSAReasonFailedRoleUpdate IRSAReason = "IRSAFailedRoleUpdate"
|
||||
IRSAReasonFailedK8sApply IRSAReason = "IRSAFailedApplyingResources"
|
||||
IRSAReasonReady IRSAReason = "IRSAReady"
|
||||
)
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
//+kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description=""
|
||||
|
||||
// IRSA is the Schema for the irsas API
|
||||
type IRSA struct {
|
||||
|
||||
@@ -17,7 +17,6 @@ limitations under the License.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
apimeta "k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
@@ -81,14 +80,14 @@ type IRSASetupStatus struct {
|
||||
SelfHostedSetup []metav1.Condition `json:"selfHostedSetup,omitempty"`
|
||||
}
|
||||
|
||||
// GetStatusConditions returns a pointer to the Status.Conditions slice
|
||||
// GetSelfhostedStatusConditions returns a pointer to the Status.Conditions slice
|
||||
func (in *IRSASetup) GetSelfhostedStatusConditions() *[]metav1.Condition {
|
||||
return &in.Status.SelfHostedSetup
|
||||
}
|
||||
|
||||
func SetupSelfHostedStatusReady(irsa IRSASetup, reason, message string) IRSASetup {
|
||||
newCondition := metav1.Condition{
|
||||
Type: meta.ReadyCondition,
|
||||
Type: ReadyCondition,
|
||||
Status: metav1.ConditionTrue,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
@@ -99,7 +98,7 @@ func SetupSelfHostedStatusReady(irsa IRSASetup, reason, message string) IRSASetu
|
||||
|
||||
func SelfHostedStatusNotReady(irsa IRSASetup, reason, message string) IRSASetup {
|
||||
newCondition := metav1.Condition{
|
||||
Type: meta.ReadyCondition,
|
||||
Type: ReadyCondition,
|
||||
Status: metav1.ConditionFalse,
|
||||
Reason: reason,
|
||||
Message: message,
|
||||
@@ -110,7 +109,7 @@ func SelfHostedStatusNotReady(irsa IRSASetup, reason, message string) IRSASetup
|
||||
|
||||
// SelfHostedReadyStatus
|
||||
func SelfHostedReadyStatus(irsa IRSASetup) *metav1.Condition {
|
||||
if c := apimeta.FindStatusCondition(irsa.Status.SelfHostedSetup, meta.ReadyCondition); c != nil {
|
||||
if c := apimeta.FindStatusCondition(irsa.Status.SelfHostedSetup, ReadyCondition); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
@@ -130,7 +129,7 @@ func HasConditionReason(cond *metav1.Condition, reasons ...string) bool {
|
||||
}
|
||||
|
||||
func IsSelfHostedReadyConditionTrue(irsa IRSASetup) bool {
|
||||
return apimeta.IsStatusConditionTrue(irsa.Status.SelfHostedSetup, meta.ReadyCondition)
|
||||
return apimeta.IsStatusConditionTrue(irsa.Status.SelfHostedSetup, ReadyCondition)
|
||||
}
|
||||
|
||||
type SelfHostedReason string
|
||||
|
||||
@@ -63,7 +63,7 @@ func (in *IRSA) DeepCopyInto(out *IRSA) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IRSA.
|
||||
@@ -259,6 +259,13 @@ func (in *IRSASpec) DeepCopy() *IRSASpec {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *IRSAStatus) DeepCopyInto(out *IRSAStatus) {
|
||||
*out = *in
|
||||
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])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IRSAStatus.
|
||||
|
||||
@@ -14,7 +14,11 @@ spec:
|
||||
singular: irsa
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||
name: Ready
|
||||
type: string
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: IRSA is the Schema for the irsas API
|
||||
@@ -78,6 +82,76 @@ spec:
|
||||
type: object
|
||||
status:
|
||||
description: IRSAStatus defines the observed state of IRSA
|
||||
properties:
|
||||
conditions:
|
||||
items:
|
||||
description: "Condition contains details for one aspect of the current
|
||||
state of this API Resource.\n---\nThis struct is intended for
|
||||
direct use as an array at the field path .status.conditions. For
|
||||
example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
|
||||
observations of a foo's current state.\n\t // Known .status.conditions.type
|
||||
are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
|
||||
+patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
|
||||
\ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
|
||||
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
|
||||
\ // other fields\n\t}"
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: |-
|
||||
type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
---
|
||||
Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
|
||||
useful (see .node.status.conditions), the ability to deconflict is important.
|
||||
The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
|
||||
@@ -65,6 +65,8 @@ IRSA is the Schema for the irsas API
|
||||
| `spec` _[IRSASpec](#irsaspec)_ | | | |
|
||||
|
||||
|
||||
|
||||
|
||||
#### IRSAServiceAccount
|
||||
|
||||
|
||||
|
||||
@@ -159,10 +159,23 @@ func (r *IRSAReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.IRSA,
|
||||
if err != nil {
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 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.IRSAReason
|
||||
defer func() {
|
||||
if e != nil {
|
||||
*obj = irsav1alpha1.IRSAStatusNotReady(*obj, string(reason), e.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
accountId, err := r.AwsClient.StsClient().GetAccountId()
|
||||
if err != nil {
|
||||
e = err
|
||||
return err
|
||||
}
|
||||
roleManager := awsclient.RoleManager{
|
||||
@@ -171,18 +184,17 @@ func (r *IRSAReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.IRSA,
|
||||
Policies: obj.Spec.IamPolicies,
|
||||
AccountId: accountId,
|
||||
}
|
||||
issuerMeta, err := issuer.NewS3IssuerMeta(&irsaSetup.Spec.Discovery.S3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = r.AwsClient.IamClient().CreateIRSARole(
|
||||
ctx,
|
||||
issuerMeta,
|
||||
roleManager,
|
||||
)
|
||||
if err != nil {
|
||||
e = err
|
||||
reason = irsav1alpha1.IRSAReasonFailedRoleUpdate
|
||||
return err
|
||||
}
|
||||
|
||||
kubeHandler := handler.NewKubernetesHandler(kubeClient)
|
||||
|
||||
for _, ns := range serviceAccount.Namespaces {
|
||||
@@ -192,7 +204,14 @@ func (r *IRSAReconciler) reconcile(ctx context.Context, obj *irsav1alpha1.IRSA,
|
||||
})
|
||||
kubeHandler.Append(sa)
|
||||
}
|
||||
return kubeHandler.ApplyAll(ctx)
|
||||
err = kubeHandler.ApplyAll(ctx)
|
||||
if err != nil {
|
||||
e = err
|
||||
reason = irsav1alpha1.IRSAReasonFailedK8sApply
|
||||
return err
|
||||
}
|
||||
*obj = irsav1alpha1.IRSAStatusReady(*obj, string(irsav1alpha1.IRSAReasonReady), "successfully setup resources")
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
|
||||
@@ -203,6 +203,7 @@ func reconcileSelfhosted(ctx context.Context, obj *irsav1alpha1.IRSASetup, awsCl
|
||||
return err
|
||||
}
|
||||
|
||||
// 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
|
||||
defer func() {
|
||||
|
||||
Reference in New Issue
Block a user