Skip to content

Commit 7246c5a

Browse files
committed
operator: Wait for owned resources managed by ResourceSets
Signed-off-by: Stefan Prodan <[email protected]>
1 parent 1926a69 commit 7246c5a

File tree

3 files changed

+66
-11
lines changed

3 files changed

+66
-11
lines changed

api/v1/common_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const (
1919

2020
ReconciliationDisabledReason = "ReconciliationDisabled"
2121
ReconciliationDisabledMessage = "Reconciliation is disabled"
22+
23+
HealthCheckExpr = "status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True' && e.observedGeneration == metadata.generation)"
2224
)
2325

2426
var (

internal/controller/resourceset_controller.go

Lines changed: 63 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/fluxcd/cli-utils/pkg/kstatus/polling/engine"
1515
"github.com/fluxcd/cli-utils/pkg/kstatus/status"
1616
"github.com/fluxcd/cli-utils/pkg/object"
17+
"github.com/fluxcd/pkg/apis/kustomize"
1718
"github.com/fluxcd/pkg/apis/meta"
1819
"github.com/fluxcd/pkg/runtime/cel"
1920
runtimeClient "github.com/fluxcd/pkg/runtime/client"
@@ -314,7 +315,9 @@ func (r *ResourceSetReconciler) checkDependencies(ctx context.Context,
314315
}
315316

316317
if dep.Ready {
317-
if dep.ReadyExpr != "" {
318+
switch {
319+
// Custom CEL ready expression.
320+
case dep.ReadyExpr != "":
318321
isReady, err := exprs[i].EvaluateBoolean(ctx, depObj.UnstructuredContent())
319322
if err != nil {
320323
return err
@@ -323,7 +326,23 @@ func (r *ResourceSetReconciler) checkDependencies(ctx context.Context,
323326
if !isReady {
324327
return fmt.Errorf("dependency %s/%s not ready: expression '%s'", dep.APIVersion, ssautil.FmtObjMetadata(depMd), dep.ReadyExpr)
325328
}
326-
} else {
329+
// Built-in CEL ready expression for ResourceSet and ResourceSetInputProvider.
330+
case dep.Kind == fluxcdv1.ResourceSetKind || dep.Kind == fluxcdv1.ResourceSetInputProviderKind:
331+
expr, err := cel.NewExpression(fluxcdv1.HealthCheckExpr)
332+
if err != nil {
333+
return err
334+
}
335+
336+
isReady, err := expr.EvaluateBoolean(ctx, depObj.UnstructuredContent())
337+
if err != nil {
338+
return err
339+
}
340+
341+
if !isReady {
342+
return fmt.Errorf("dependency %s/%s not ready", dep.APIVersion, ssautil.FmtObjMetadata(depMd))
343+
}
344+
// Default status check using kstatus.
345+
default:
327346
stat, err := status.Compute(depObj)
328347
if err != nil {
329348
return fmt.Errorf("dependency %s/%s not ready: %w", dep.APIVersion, ssautil.FmtObjMetadata(depMd), err)
@@ -432,15 +451,10 @@ func (r *ResourceSetReconciler) apply(ctx context.Context,
432451
}
433452

434453
// Configure the Kubernetes client for impersonation.
435-
var impersonatorOpts []runtimeClient.ImpersonatorOption
436-
if r.DefaultServiceAccount != "" || obj.Spec.ServiceAccountName != "" {
437-
impersonatorOpts = append(impersonatorOpts,
438-
runtimeClient.WithServiceAccount(r.DefaultServiceAccount, obj.Spec.ServiceAccountName, obj.GetNamespace()))
439-
}
440-
if r.ClusterReader != nil {
441-
impersonatorOpts = append(impersonatorOpts, runtimeClient.WithPolling(r.ClusterReader))
454+
impersonation, err := r.makeImpersonator(ctx, obj)
455+
if err != nil {
456+
return "", err
442457
}
443-
impersonation := runtimeClient.NewImpersonator(r.Client, impersonatorOpts...)
444458

445459
// Create the Kubernetes client that runs under impersonation.
446460
kubeClient, statusPoller, err := impersonation.GetClient(ctx)
@@ -795,6 +809,45 @@ func (r *ResourceSetReconciler) patch(ctx context.Context,
795809
return nil
796810
}
797811

812+
// makeImpersonator creates an impersonator for the ResourceSet.
813+
// It configures service account impersonation and custom health check readers.
814+
func (r *ResourceSetReconciler) makeImpersonator(ctx context.Context, obj *fluxcdv1.ResourceSet) (*runtimeClient.Impersonator, error) {
815+
var impersonatorOpts []runtimeClient.ImpersonatorOption
816+
817+
// Configure service account for impersonation.
818+
if r.DefaultServiceAccount != "" || obj.Spec.ServiceAccountName != "" {
819+
impersonatorOpts = append(impersonatorOpts,
820+
runtimeClient.WithServiceAccount(r.DefaultServiceAccount, obj.Spec.ServiceAccountName, obj.GetNamespace()))
821+
}
822+
823+
// Configure the kstatus poller with custom health checks for
824+
// Flux Operator owned resources.
825+
if r.ClusterReader != nil {
826+
kinds := []string{fluxcdv1.FluxInstanceKind, fluxcdv1.ResourceSetKind, fluxcdv1.ResourceSetInputProviderKind}
827+
healthChecks := make([]kustomize.CustomHealthCheck, 0, len(kinds))
828+
for _, kind := range kinds {
829+
healthChecks = append(healthChecks, kustomize.CustomHealthCheck{
830+
APIVersion: fluxcdv1.GroupVersion.String(),
831+
Kind: kind,
832+
HealthCheckExpressions: kustomize.HealthCheckExpressions{
833+
Current: fluxcdv1.HealthCheckExpr,
834+
},
835+
})
836+
}
837+
838+
statusReaders, err := cel.PollerWithCustomHealthChecks(ctx, healthChecks)
839+
if err != nil {
840+
return nil, fmt.Errorf("failed to create custom health check readers: %w", err)
841+
}
842+
843+
impersonatorOpts = append(impersonatorOpts,
844+
runtimeClient.WithPolling(r.ClusterReader, statusReaders...),
845+
)
846+
}
847+
848+
return runtimeClient.NewImpersonator(r.Client, impersonatorOpts...), nil
849+
}
850+
798851
func (r *ResourceSetReconciler) recordMetrics(obj *fluxcdv1.ResourceSet) error {
799852
if !obj.ObjectMeta.DeletionTimestamp.IsZero() {
800853
reporter.DeleteMetricsFor(fluxcdv1.ResourceSetKind, obj.GetName(), obj.GetNamespace())

internal/install/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func NewStatusPoller(ctx context.Context, reader client.Reader, mapper meta.REST
8989
APIVersion: fluxcdv1.GroupVersion.String(),
9090
Kind: kind,
9191
HealthCheckExpressions: kustomize.HealthCheckExpressions{
92-
Current: "status.conditions.filter(e, e.type == 'Ready').all(e, e.status == 'True' && e.observedGeneration == metadata.generation)",
92+
Current: fluxcdv1.HealthCheckExpr,
9393
},
9494
})
9595
}

0 commit comments

Comments
 (0)