@@ -48,6 +48,7 @@ import (
4848 "sigs.k8s.io/controller-runtime/pkg/predicate"
4949 "sigs.k8s.io/controller-runtime/pkg/reconcile"
5050
51+ "github.com/fluxcd/cli-utils/pkg/kstatus/polling"
5152 "github.com/fluxcd/cli-utils/pkg/kstatus/polling/engine"
5253 "github.com/fluxcd/cli-utils/pkg/object"
5354 apiacl "github.com/fluxcd/pkg/apis/acl"
@@ -63,6 +64,7 @@ import (
6364 "github.com/fluxcd/pkg/runtime/jitter"
6465 "github.com/fluxcd/pkg/runtime/patch"
6566 "github.com/fluxcd/pkg/runtime/predicates"
67+ "github.com/fluxcd/pkg/runtime/statusreaders"
6668 "github.com/fluxcd/pkg/ssa"
6769 "github.com/fluxcd/pkg/tar"
6870 sourcev1 "github.com/fluxcd/source-controller/api/v1"
@@ -384,11 +386,14 @@ func (r *KustomizationReconciler) reconcile(
384386
385387 // Configure the Kubernetes client for impersonation.
386388 var impersonatorOpts []runtimeClient.ImpersonatorOption
389+ var mustImpersonate bool
387390 if r .DefaultServiceAccount != "" || obj .Spec .ServiceAccountName != "" {
391+ mustImpersonate = true
388392 impersonatorOpts = append (impersonatorOpts ,
389393 runtimeClient .WithServiceAccount (r .DefaultServiceAccount , obj .Spec .ServiceAccountName , obj .GetNamespace ()))
390394 }
391395 if obj .Spec .KubeConfig != nil {
396+ mustImpersonate = true
392397 impersonatorOpts = append (impersonatorOpts ,
393398 runtimeClient .WithKubeConfig (obj .Spec .KubeConfig , r .KubeConfigOpts , obj .GetNamespace ()))
394399 }
@@ -399,7 +404,13 @@ func (r *KustomizationReconciler) reconcile(
399404 impersonation := runtimeClient .NewImpersonator (r .Client , impersonatorOpts ... )
400405
401406 // Create the Kubernetes client that runs under impersonation.
402- kubeClient , statusPoller , err := impersonation .GetClient (ctx )
407+ var kubeClient client.Client
408+ var statusPoller * polling.StatusPoller
409+ if mustImpersonate {
410+ kubeClient , statusPoller , err = impersonation .GetClient (ctx )
411+ } else {
412+ kubeClient , statusPoller = r .getClientAndPoller (statusReaders )
413+ }
403414 if err != nil {
404415 conditions .MarkFalse (obj , meta .ReadyCondition , meta .ReconciliationFailedReason , "%s" , err )
405416 return fmt .Errorf ("failed to build kube client: %w" , err )
@@ -1018,11 +1029,14 @@ func (r *KustomizationReconciler) finalize(ctx context.Context,
10181029 objects , _ := inventory .List (obj .Status .Inventory )
10191030
10201031 var impersonatorOpts []runtimeClient.ImpersonatorOption
1032+ var mustImpersonate bool
10211033 if r .DefaultServiceAccount != "" || obj .Spec .ServiceAccountName != "" {
1034+ mustImpersonate = true
10221035 impersonatorOpts = append (impersonatorOpts ,
10231036 runtimeClient .WithServiceAccount (r .DefaultServiceAccount , obj .Spec .ServiceAccountName , obj .GetNamespace ()))
10241037 }
10251038 if obj .Spec .KubeConfig != nil {
1039+ mustImpersonate = true
10261040 impersonatorOpts = append (impersonatorOpts ,
10271041 runtimeClient .WithKubeConfig (obj .Spec .KubeConfig , r .KubeConfigOpts , obj .GetNamespace ()))
10281042 }
@@ -1031,7 +1045,13 @@ func (r *KustomizationReconciler) finalize(ctx context.Context,
10311045 }
10321046 impersonation := runtimeClient .NewImpersonator (r .Client , impersonatorOpts ... )
10331047 if impersonation .CanImpersonate (ctx ) {
1034- kubeClient , _ , err := impersonation .GetClient (ctx )
1048+ var kubeClient client.Client
1049+ var err error
1050+ if mustImpersonate {
1051+ kubeClient , _ , err = impersonation .GetClient (ctx )
1052+ } else {
1053+ kubeClient = r .Client
1054+ }
10351055 if err != nil {
10361056 return ctrl.Result {}, err
10371057 }
@@ -1160,6 +1180,29 @@ func (r *KustomizationReconciler) patch(ctx context.Context,
11601180 return nil
11611181}
11621182
1183+ // getClientAndPoller creates a status poller with the custom status readers
1184+ // from CEL expressions and the custom job status reader, and returns the
1185+ // Kubernetes client of the controller and the status poller.
1186+ // Should be used for reconciliations that are not configured to use
1187+ // ServiceAccount impersonation or kubeconfig.
1188+ func (r * KustomizationReconciler ) getClientAndPoller (
1189+ readerCtors []func (apimeta.RESTMapper ) engine.StatusReader ,
1190+ ) (client.Client , * polling.StatusPoller ) {
1191+
1192+ readers := make ([]engine.StatusReader , 0 , 1 + len (readerCtors ))
1193+ readers = append (readers , statusreaders .NewCustomJobStatusReader (r .Mapper ))
1194+ for _ , ctor := range readerCtors {
1195+ readers = append (readers , ctor (r .Mapper ))
1196+ }
1197+
1198+ poller := polling .NewStatusPoller (r .Client , r .Mapper , polling.Options {
1199+ CustomStatusReaders : readers ,
1200+ ClusterReaderFactory : r .ClusterReader ,
1201+ })
1202+
1203+ return r .Client , poller
1204+ }
1205+
11631206// getOriginRevision returns the origin revision of the source artifact,
11641207// or the empty string if it's not present, or if the artifact itself
11651208// is not present.
0 commit comments