diff --git a/cmd/agent/console.go b/cmd/agent/console.go index 483fc6b5..8de0db4a 100644 --- a/cmd/agent/console.go +++ b/cmd/agent/console.go @@ -10,6 +10,7 @@ import ( consolectrl "github.com/pluralsh/deployment-operator/pkg/controller" "github.com/pluralsh/deployment-operator/pkg/controller/stacks" v1 "github.com/pluralsh/deployment-operator/pkg/controller/v1" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/rest" ctrclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -49,6 +50,7 @@ func registerConsoleReconcilersOrDie( mgr *controller.Manager, config *rest.Config, k8sClient ctrclient.Client, + scheme *runtime.Scheme, consoleClient client.Client, ) { mgr.AddReconcilerOrDie(service.Identifier, func() (v1.Reconciler, error) { @@ -78,7 +80,7 @@ func registerConsoleReconcilersOrDie( os.Exit(1) } - r := stacks.NewStackReconciler(consoleClient, k8sClient, args.ControllerCacheTTL(), stacksPollInterval, namespace, args.ConsoleUrl(), args.DeployToken()) + r := stacks.NewStackReconciler(consoleClient, k8sClient, scheme, args.ControllerCacheTTL(), stacksPollInterval, namespace, args.ConsoleUrl(), args.DeployToken()) return r, nil }) } diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 3813a338..a2e02eb9 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -57,7 +57,7 @@ func main() { // Initialize Pipeline Gate Cache cache.InitGateCache(args.ControllerCacheTTL(), extConsoleClient) - registerConsoleReconcilersOrDie(consoleManager, config, kubeManager.GetClient(), extConsoleClient) + registerConsoleReconcilersOrDie(consoleManager, config, kubeManager.GetClient(), kubeManager.GetScheme(), extConsoleClient) registerKubeReconcilersOrDie(ctx, kubeManager, consoleManager, config, extConsoleClient, discoveryClient) //+kubebuilder:scaffold:builder diff --git a/internal/utils/kubernetes.go b/internal/utils/kubernetes.go index 88eab6ce..a1e6f174 100644 --- a/internal/utils/kubernetes.go +++ b/internal/utils/kubernetes.go @@ -52,6 +52,33 @@ func TryAddControllerRef(ctx context.Context, client ctrlruntimeclient.Client, o }) } +func TryAddOwnerRef(ctx context.Context, client ctrlruntimeclient.Client, owner ctrlruntimeclient.Object, object ctrlruntimeclient.Object, scheme *runtime.Scheme) error { + key := ctrlruntimeclient.ObjectKeyFromObject(object) + + return retry.RetryOnConflict(retry.DefaultRetry, func() error { + if err := client.Get(ctx, key, object); err != nil { + return err + } + + if owner.GetDeletionTimestamp() != nil || object.GetDeletionTimestamp() != nil { + return nil + } + + original := object.DeepCopyObject().(ctrlruntimeclient.Object) + + err := controllerutil.SetOwnerReference(owner, object, scheme) + if err != nil { + return err + } + + if reflect.DeepEqual(original.GetOwnerReferences(), object.GetOwnerReferences()) { + return nil + } + + return client.Patch(ctx, object, ctrlruntimeclient.MergeFromWithOptions(original, ctrlruntimeclient.MergeFromWithOptimisticLock{})) + }) +} + func AsName(val string) string { return strings.ReplaceAll(val, " ", "-") } diff --git a/pkg/controller/stacks/job.go b/pkg/controller/stacks/job.go index a6cbeab3..cd4437e1 100644 --- a/pkg/controller/stacks/job.go +++ b/pkg/controller/stacks/job.go @@ -8,6 +8,7 @@ import ( console "github.com/pluralsh/console/go/client" "github.com/pluralsh/deployment-operator/internal/metrics" + "github.com/pluralsh/deployment-operator/internal/utils" consoleclient "github.com/pluralsh/deployment-operator/pkg/client" "github.com/pluralsh/polly/algorithms" "github.com/samber/lo" @@ -88,7 +89,8 @@ func (r *StackReconciler) reconcileRunJob(ctx context.Context, run *console.Stac return nil, err } - if _, err = r.upsertRunSecret(ctx, name, namespace, run.ID); err != nil { + secret, err := r.upsertRunSecret(ctx, name, namespace, run.ID) + if err != nil { return nil, err } @@ -99,6 +101,11 @@ func (r *StackReconciler) reconcileRunJob(ctx context.Context, run *console.Stac return nil, err } + if err := utils.TryAddOwnerRef(ctx, r.k8sClient, job, secret, r.scheme); err != nil { + logger.Error(err, "error setting owner reference for job secret") + return nil, err + } + metrics.Record().StackRunJobCreation() if err := r.consoleClient.UpdateStackRun(run.ID, console.StackRunAttributes{ Status: run.Status, @@ -112,8 +119,8 @@ func (r *StackReconciler) reconcileRunJob(ctx context.Context, run *console.Stac return job, nil } - return foundJob, nil + return foundJob, nil } // GetRunResourceName returns a resource name used for a job and a secret connected to a given run. diff --git a/pkg/controller/stacks/reconciler.go b/pkg/controller/stacks/reconciler.go index 8c59df0d..b318e870 100644 --- a/pkg/controller/stacks/reconciler.go +++ b/pkg/controller/stacks/reconciler.go @@ -7,6 +7,7 @@ import ( console "github.com/pluralsh/console/go/client" "github.com/pluralsh/polly/algorithms" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/util/workqueue" ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" @@ -25,6 +26,7 @@ const ( type StackReconciler struct { consoleClient client.Client k8sClient ctrlclient.Client + scheme *runtime.Scheme stackQueue workqueue.TypedRateLimitingInterface[string] stackCache *client.Cache[console.StackRunFragment] namespace string @@ -33,10 +35,11 @@ type StackReconciler struct { pollInterval time.Duration } -func NewStackReconciler(consoleClient client.Client, k8sClient ctrlclient.Client, refresh, pollInterval time.Duration, namespace, consoleURL, deployToken string) *StackReconciler { +func NewStackReconciler(consoleClient client.Client, k8sClient ctrlclient.Client, scheme *runtime.Scheme, refresh, pollInterval time.Duration, namespace, consoleURL, deployToken string) *StackReconciler { return &StackReconciler{ consoleClient: consoleClient, k8sClient: k8sClient, + scheme: scheme, stackQueue: workqueue.NewTypedRateLimitingQueue(workqueue.DefaultTypedControllerRateLimiter[string]()), stackCache: client.NewCache[console.StackRunFragment](refresh, func(id string) (*console.StackRunFragment, error) { return consoleClient.GetStackRun(id)