feat(k8-operator): dynamic secrets status conditions logging

This commit is contained in:
Daniel Hougaard
2024-12-08 23:24:30 +04:00
parent 36af975594
commit 925a594a1b
6 changed files with 275 additions and 10 deletions
@@ -0,0 +1,173 @@
package controllers
import (
"context"
"fmt"
"github.com/Infisical/infisical/k8-operator/api/v1alpha1"
"github.com/go-logr/logr"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func (r *InfisicalDynamicSecretReconciler) SetReconcileAutoRedeploymentStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, numDeployments int, errorToConditionOn error) {
if infisicalDynamicSecret.Status.Conditions == nil {
infisicalDynamicSecret.Status.Conditions = []metav1.Condition{}
}
if errorToConditionOn == nil {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/AutoRedeployReady",
Status: metav1.ConditionTrue,
Reason: "OK",
Message: fmt.Sprintf("Infisical has found %v deployments which are ready to be auto redeployed when dynamic secret lease changes", numDeployments),
})
} else {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/AutoRedeployReady",
Status: metav1.ConditionFalse,
Reason: "Error",
Message: fmt.Sprintf("Failed reconcile deployments because: %v", errorToConditionOn),
})
}
err := r.Client.Status().Update(ctx, infisicalDynamicSecret)
if err != nil {
logger.Error(err, "Could not set condition for AutoRedeployReady")
}
}
func (r *InfisicalDynamicSecretReconciler) SetAuthenticatedStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) {
if infisicalDynamicSecret.Status.Conditions == nil {
infisicalDynamicSecret.Status.Conditions = []metav1.Condition{}
}
if errorToConditionOn == nil {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/Authenticated",
Status: metav1.ConditionTrue,
Reason: "OK",
Message: "Infisical has successfully authenticated with the Infisical API",
})
} else {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/Authenticated",
Status: metav1.ConditionFalse,
Reason: "Error",
Message: fmt.Sprintf("Failed to authenticate with Infisical API because: %v", errorToConditionOn),
})
}
err := r.Client.Status().Update(ctx, infisicalDynamicSecret)
if err != nil {
logger.Error(err, "Could not set condition for Authenticated")
}
}
func (r *InfisicalDynamicSecretReconciler) SetLeaseRenewalStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) {
if infisicalDynamicSecret.Status.Conditions == nil {
infisicalDynamicSecret.Status.Conditions = []metav1.Condition{}
}
if errorToConditionOn == nil {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/LeaseRenewal",
Status: metav1.ConditionTrue,
Reason: "OK",
Message: "Infisical has successfully renewed the lease",
})
} else {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/LeaseRenewal",
Status: metav1.ConditionFalse,
Reason: "Error",
Message: fmt.Sprintf("Failed to renew the lease because: %v", errorToConditionOn),
})
}
err := r.Client.Status().Update(ctx, infisicalDynamicSecret)
if err != nil {
logger.Error(err, "Could not set condition for LeaseRenewal")
}
}
func (r *InfisicalDynamicSecretReconciler) SetCreatedLeaseStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) {
if infisicalDynamicSecret.Status.Conditions == nil {
infisicalDynamicSecret.Status.Conditions = []metav1.Condition{}
}
if errorToConditionOn == nil {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/LeaseCreated",
Status: metav1.ConditionTrue,
Reason: "OK",
Message: "Infisical has successfully created the lease",
})
} else {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/LeaseCreated",
Status: metav1.ConditionFalse,
Reason: "Error",
Message: fmt.Sprintf("Failed to create the lease because: %v", errorToConditionOn),
})
}
err := r.Client.Status().Update(ctx, infisicalDynamicSecret)
if err != nil {
logger.Error(err, "Could not set condition for LeaseCreated")
}
}
func (r *InfisicalDynamicSecretReconciler) SetRevokedLeaseStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) {
if infisicalDynamicSecret.Status.Conditions == nil {
infisicalDynamicSecret.Status.Conditions = []metav1.Condition{}
}
if errorToConditionOn == nil {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/LeaseRevoked",
Status: metav1.ConditionTrue,
Reason: "OK",
Message: "Infisical has successfully revoked the lease",
})
} else {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/LeaseRevoked",
Status: metav1.ConditionFalse,
Reason: "Error",
Message: fmt.Sprintf("Failed to revoke the lease because: %v", errorToConditionOn),
})
}
err := r.Client.Status().Update(ctx, infisicalDynamicSecret)
if err != nil {
logger.Error(err, "Could not set condition for LeaseRevoked")
}
}
func (r *InfisicalDynamicSecretReconciler) SetReconcileStatus(ctx context.Context, logger logr.Logger, infisicalDynamicSecret *v1alpha1.InfisicalDynamicSecret, errorToConditionOn error) {
if infisicalDynamicSecret.Status.Conditions == nil {
infisicalDynamicSecret.Status.Conditions = []metav1.Condition{}
}
if errorToConditionOn == nil {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/Reconcile",
Status: metav1.ConditionTrue,
Reason: "OK",
Message: "Infisical has successfully reconciled the InfisicalDynamicSecret",
})
} else {
meta.SetStatusCondition(&infisicalDynamicSecret.Status.Conditions, metav1.Condition{
Type: "secrets.infisical.com/Reconcile",
Status: metav1.ConditionFalse,
Reason: "Error",
Message: fmt.Sprintf("Failed to reconcile the InfisicalDynamicSecret because: %v", errorToConditionOn),
})
}
err := r.Client.Status().Update(ctx, infisicalDynamicSecret)
if err != nil {
logger.Error(err, "Could not set condition for Reconcile")
}
}
@@ -30,16 +30,20 @@ type InfisicalDynamicSecretReconciler struct {
BaseLogger logr.Logger
}
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets/finalizers,verbs=update
var infisicalDynamicSecretsResourceVariablesMap map[string]util.ResourceVariables = make(map[string]util.ResourceVariables)
func (r *InfisicalDynamicSecretReconciler) GetLogger(req ctrl.Request) logr.Logger {
return r.BaseLogger.WithValues("infisicaldynamicsecret", req.NamespacedName)
}
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=secrets.infisical.com,resources=infisicaldynamicsecrets/finalizers,verbs=update
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;delete
// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;update;delete
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch;get;update
// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch
func (r *InfisicalDynamicSecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := r.GetLogger(req)
@@ -82,6 +86,7 @@ func (r *InfisicalDynamicSecretReconciler) Reconcile(ctx context.Context, req ct
}
err := r.HandleLeaseRevocation(ctx, logger, infisicalDynamicSecretCRD)
r.SetRevokedLeaseStatus(ctx, logger, &infisicalDynamicSecretCRD, err)
if infisicalDynamicSecretsResourceVariablesMap != nil {
if rv, ok := infisicalDynamicSecretsResourceVariablesMap[string(infisicalDynamicSecretCRD.GetUID())]; ok {
@@ -128,7 +133,7 @@ func (r *InfisicalDynamicSecretReconciler) Reconcile(ctx context.Context, req ct
}
nextReconcile, err := r.ReconcileInfisicalDynamicSecret(ctx, logger, infisicalDynamicSecretCRD)
// r.SetSuccessfullyReconciledConditions(ctx, &infisicalDynamicSecretCRD, err)
r.SetReconcileStatus(ctx, logger, &infisicalDynamicSecretCRD, err)
if err == nil && nextReconcile.Seconds() >= 5 {
requeueTime = nextReconcile
@@ -141,7 +146,8 @@ func (r *InfisicalDynamicSecretReconciler) Reconcile(ctx context.Context, req ct
}, nil
}
_, err = controllerhelpers.ReconcileDeploymentsWithManagedSecrets(ctx, r.Client, logger, infisicalDynamicSecretCRD.Spec.ManagedSecretReference)
numDeployments, err := controllerhelpers.ReconcileDeploymentsWithManagedSecrets(ctx, r.Client, logger, infisicalDynamicSecretCRD.Spec.ManagedSecretReference)
r.SetReconcileAutoRedeploymentStatus(ctx, logger, &infisicalDynamicSecretCRD, numDeployments, err)
if err != nil {
logger.Error(err, fmt.Sprintf("unable to reconcile auto redeployment. Will requeue after [requeueTime=%v]", requeueTime))
@@ -270,6 +270,7 @@ func (r *InfisicalDynamicSecretReconciler) HandleLeaseRevocation(ctx context.Con
logger.Info("Authenticating for lease revocation")
authDetails, err := r.handleAuthentication(ctx, infisicalDynamicSecret, infisicalClient)
r.SetAuthenticatedStatus(ctx, logger, &infisicalDynamicSecret, err)
if err != nil {
return fmt.Errorf("unable to authenticate for lease revocation [err=%s]", err)
@@ -334,6 +335,7 @@ func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx c
if authDetails.AuthStrategy == "" {
logger.Info("No authentication strategy found. Attempting to authenticate")
authDetails, err = r.handleAuthentication(ctx, infisicalDynamicSecret, infisicalClient)
r.SetAuthenticatedStatus(ctx, logger, &infisicalDynamicSecret, err)
if err != nil {
return nextReconcile, fmt.Errorf("unable to authenticate [err=%s]", err)
@@ -368,7 +370,10 @@ func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx c
}
if infisicalDynamicSecret.Status.Lease == nil {
r.CreateDynamicSecretLease(ctx, logger, infisicalClient, &infisicalDynamicSecret, destination)
err := r.CreateDynamicSecretLease(ctx, logger, infisicalClient, &infisicalDynamicSecret, destination)
r.SetCreatedLeaseStatus(ctx, logger, &infisicalDynamicSecret, err)
return defaultNextReconcile, err // Short requeue after creation
} else {
now := time.Now()
leaseExpiresAt := infisicalDynamicSecret.Status.Lease.ExpiresAt.Time
@@ -403,6 +408,7 @@ func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx c
maxTTLThreshold))
err := r.CreateDynamicSecretLease(ctx, logger, infisicalClient, &infisicalDynamicSecret, destination)
r.SetCreatedLeaseStatus(ctx, logger, &infisicalDynamicSecret, err)
return defaultNextReconcile, err // Short requeue after creation
}
}
@@ -411,6 +417,7 @@ func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx c
if now.After(leaseExpiresAt) {
logger.Info("Lease has expired, creating new lease...")
err = r.CreateDynamicSecretLease(ctx, logger, infisicalClient, &infisicalDynamicSecret, destination)
r.SetCreatedLeaseStatus(ctx, logger, &infisicalDynamicSecret, err)
return defaultNextReconcile, err // Short requeue after creation
}
@@ -421,10 +428,12 @@ func (r *InfisicalDynamicSecretReconciler) ReconcileInfisicalDynamicSecret(ctx c
renewalThreshold))
err = r.RenewDynamicSecretLease(ctx, logger, infisicalClient, &infisicalDynamicSecret, destination)
r.SetLeaseRenewalStatus(ctx, logger, &infisicalDynamicSecret, err)
if err == constants.ErrInvalidLease {
logger.Info("Failed to renew expired lease, creating new lease...")
err = r.CreateDynamicSecretLease(ctx, logger, infisicalClient, &infisicalDynamicSecret, destination)
r.SetCreatedLeaseStatus(ctx, logger, &infisicalDynamicSecret, err)
}
return defaultNextReconcile, err // Short requeue after renewal/creation