From efbe96e93ae46c4c6cb10c784633bddbfb10c391 Mon Sep 17 00:00:00 2001 From: Volodymyr Zotov Date: Sun, 8 Jun 2025 10:28:15 -0500 Subject: [PATCH] Use global context --- cmd/main.go | 20 ++++++----- internal/controller/deployment_controller.go | 30 ++++++++-------- .../controller/deployment_controller_test.go | 9 +++-- .../controller/onepassworditem_controller.go | 34 +++++++++---------- .../kubernetes_secrets_builder.go | 8 ++--- .../kubernetes_secrets_builder_test.go | 22 +++++++----- pkg/mocks/mocksecretserver.go | 9 ++--- pkg/onepassword/client/client.go | 13 +++---- pkg/onepassword/client/connect/connect.go | 9 ++--- .../client/connect/connect_test.go | 9 ++--- pkg/onepassword/client/sdk/sdk.go | 20 +++++------ pkg/onepassword/client/sdk/sdk_test.go | 8 ++--- pkg/onepassword/connect_setup.go | 26 +++++++------- pkg/onepassword/connect_setup_test.go | 10 +++--- pkg/onepassword/items.go | 19 ++++++----- pkg/onepassword/secret_update_handler.go | 32 ++++++++--------- pkg/onepassword/secret_update_handler_test.go | 8 ++--- 17 files changed, 150 insertions(+), 136 deletions(-) diff --git a/cmd/main.go b/cmd/main.go index 3ee68f7..bdfd60b 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -25,6 +25,7 @@ SOFTWARE. package main import ( + "context" "errors" "flag" "fmt" @@ -112,6 +113,9 @@ func main() { printVersion() + // Create a root context that will be cancelled on termination signals + ctx := ctrl.SetupSignalHandler() + watchNamespace, err := getWatchNamespace() if err != nil { setupLog.Error(err, "unable to get WatchNamespace, "+ @@ -152,7 +156,7 @@ func main() { } // Setup One Password Client - opClient, err := opclient.NewClient(version.OperatorVersion) + opClient, err := opclient.NewClient(ctx, version.OperatorVersion) if err != nil { setupLog.Error(err, "unable to create 1Password client") os.Exit(1) @@ -182,10 +186,10 @@ func main() { //Setup 1PasswordConnect if shouldManageConnect() { setupLog.Info("Automated Connect Management Enabled") - go func() { + go func(ctx context.Context) { connectStarted := false for connectStarted == false { - err := op.SetupConnect(mgr.GetClient(), deploymentNamespace) + err := op.SetupConnect(ctx, mgr.GetClient(), deploymentNamespace) // Cache Not Started is an acceptable error. Retry until cache is started. if err != nil && !errors.Is(err, &cache.ErrCacheNotStarted{}) { setupLog.Error(err, "") @@ -195,7 +199,7 @@ func main() { connectStarted = true } } - }() + }(ctx) } else { setupLog.Info("Automated Connect Management Disabled") } @@ -204,20 +208,20 @@ func main() { updatedSecretsPoller := op.NewManager(mgr.GetClient(), opClient, shouldAutoRestartDeployments()) done := make(chan bool) ticker := time.NewTicker(getPollingIntervalForUpdatingSecrets()) - go func() { + go func(ctx context.Context) { for { select { case <-done: ticker.Stop() return case <-ticker.C: - err := updatedSecretsPoller.UpdateKubernetesSecretsTask() + err := updatedSecretsPoller.UpdateKubernetesSecretsTask(ctx) if err != nil { setupLog.Error(err, "error running update kubernetes secret task") } } } - }() + }(ctx) if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { setupLog.Error(err, "unable to set up health check") @@ -229,7 +233,7 @@ func main() { } setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + if err := mgr.Start(ctx); err != nil { setupLog.Error(err, "problem running manager") os.Exit(1) } diff --git a/internal/controller/deployment_controller.go b/internal/controller/deployment_controller.go index db3b2f4..56aa443 100644 --- a/internal/controller/deployment_controller.go +++ b/internal/controller/deployment_controller.go @@ -76,7 +76,7 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) reqLogger.V(logs.DebugLevel).Info("Reconciling Deployment") deployment := &appsv1.Deployment{} - err := r.Get(context.Background(), req.NamespacedName, deployment) + err := r.Get(ctx, req.NamespacedName, deployment) if err != nil { if errors.IsNotFound(err) { return reconcile.Result{}, nil @@ -96,12 +96,12 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) // This is so we can handle cleanup of associated secrets properly if !utils.ContainsString(deployment.ObjectMeta.Finalizers, finalizer) { deployment.ObjectMeta.Finalizers = append(deployment.ObjectMeta.Finalizers, finalizer) - if err = r.Update(context.Background(), deployment); err != nil { + if err = r.Update(ctx, deployment); err != nil { return reconcile.Result{}, err } } // Handles creation or updating secrets for deployment if needed - if err = r.handleApplyingDeployment(deployment, deployment.Namespace, annotations, req); err != nil { + if err = r.handleApplyingDeployment(ctx, deployment, deployment.Namespace, annotations, req); err != nil { return ctrl.Result{}, err } return ctrl.Result{}, nil @@ -111,12 +111,12 @@ func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) if utils.ContainsString(deployment.ObjectMeta.Finalizers, finalizer) { secretName := annotations[op.NameAnnotation] - if err = r.cleanupKubernetesSecretForDeployment(secretName, deployment); err != nil { + if err = r.cleanupKubernetesSecretForDeployment(ctx, secretName, deployment); err != nil { return ctrl.Result{}, err } // Remove the finalizer from the deployment so deletion of deployment can be completed - if err = r.removeOnePasswordFinalizerFromDeployment(deployment); err != nil { + if err = r.removeOnePasswordFinalizerFromDeployment(ctx, deployment); err != nil { return reconcile.Result{}, err } } @@ -130,7 +130,7 @@ func (r *DeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func (r *DeploymentReconciler) cleanupKubernetesSecretForDeployment(secretName string, deletedDeployment *appsv1.Deployment) error { +func (r *DeploymentReconciler) cleanupKubernetesSecretForDeployment(ctx context.Context, secretName string, deletedDeployment *appsv1.Deployment) error { kubernetesSecret := &corev1.Secret{} kubernetesSecret.ObjectMeta.Name = secretName kubernetesSecret.ObjectMeta.Namespace = deletedDeployment.Namespace @@ -140,14 +140,14 @@ func (r *DeploymentReconciler) cleanupKubernetesSecretForDeployment(secretName s } updatedSecrets := map[string]*corev1.Secret{secretName: kubernetesSecret} - multipleDeploymentsUsingSecret, err := r.areMultipleDeploymentsUsingSecret(updatedSecrets, *deletedDeployment) + multipleDeploymentsUsingSecret, err := r.areMultipleDeploymentsUsingSecret(ctx, updatedSecrets, *deletedDeployment) if err != nil { return err } // Only delete the associated kubernetes secret if it is not being used by other deployments if !multipleDeploymentsUsingSecret { - if err = r.Delete(context.Background(), kubernetesSecret); err != nil { + if err = r.Delete(ctx, kubernetesSecret); err != nil { if !errors.IsNotFound(err) { return err } @@ -156,13 +156,13 @@ func (r *DeploymentReconciler) cleanupKubernetesSecretForDeployment(secretName s return nil } -func (r *DeploymentReconciler) areMultipleDeploymentsUsingSecret(updatedSecrets map[string]*corev1.Secret, deletedDeployment appsv1.Deployment) (bool, error) { +func (r *DeploymentReconciler) areMultipleDeploymentsUsingSecret(ctx context.Context, updatedSecrets map[string]*corev1.Secret, deletedDeployment appsv1.Deployment) (bool, error) { deployments := &appsv1.DeploymentList{} opts := []client.ListOption{ client.InNamespace(deletedDeployment.Namespace), } - err := r.List(context.Background(), deployments, opts...) + err := r.List(ctx, deployments, opts...) if err != nil { logDeployment.Error(err, "Failed to list kubernetes deployments") return false, err @@ -178,12 +178,12 @@ func (r *DeploymentReconciler) areMultipleDeploymentsUsingSecret(updatedSecrets return false, nil } -func (r *DeploymentReconciler) removeOnePasswordFinalizerFromDeployment(deployment *appsv1.Deployment) error { +func (r *DeploymentReconciler) removeOnePasswordFinalizerFromDeployment(ctx context.Context, deployment *appsv1.Deployment) error { deployment.ObjectMeta.Finalizers = utils.RemoveString(deployment.ObjectMeta.Finalizers, finalizer) - return r.Update(context.Background(), deployment) + return r.Update(ctx, deployment) } -func (r *DeploymentReconciler) handleApplyingDeployment(deployment *appsv1.Deployment, namespace string, annotations map[string]string, request reconcile.Request) error { +func (r *DeploymentReconciler) handleApplyingDeployment(ctx context.Context, deployment *appsv1.Deployment, namespace string, annotations map[string]string, request reconcile.Request) error { reqLog := logDeployment.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) secretName := annotations[op.NameAnnotation] @@ -195,7 +195,7 @@ func (r *DeploymentReconciler) handleApplyingDeployment(deployment *appsv1.Deplo return nil } - item, err := op.GetOnePasswordItemByPath(r.OpClient, annotations[op.ItemPathAnnotation]) + item, err := op.GetOnePasswordItemByPath(ctx, r.OpClient, annotations[op.ItemPathAnnotation]) if err != nil { return fmt.Errorf("Failed to retrieve item: %v", err) } @@ -212,5 +212,5 @@ func (r *DeploymentReconciler) handleApplyingDeployment(deployment *appsv1.Deplo UID: deployment.GetUID(), } - return kubeSecrets.CreateKubernetesSecretFromItem(r.Client, secretName, namespace, item, annotations[op.RestartDeploymentsAnnotation], secretLabels, secretType, ownerRef) + return kubeSecrets.CreateKubernetesSecretFromItem(ctx, r.Client, secretName, namespace, item, annotations[op.RestartDeploymentsAnnotation], secretLabels, secretType, ownerRef) } diff --git a/internal/controller/deployment_controller_test.go b/internal/controller/deployment_controller_test.go index 85364d0..7703fb8 100644 --- a/internal/controller/deployment_controller_test.go +++ b/internal/controller/deployment_controller_test.go @@ -24,14 +24,13 @@ const ( ) var _ = Describe("Deployment controller", func() { - var ctx context.Context + ctx := context.Background() var deploymentKey types.NamespacedName var secretKey types.NamespacedName var deploymentResource *appsv1.Deployment createdSecret := &v1.Secret{} makeDeployment := func() { - ctx = context.Background() deploymentKey = types.NamespacedName{ Name: deploymentName, @@ -93,13 +92,13 @@ var _ = Describe("Deployment controller", func() { cleanK8sResources := func() { // failed test runs that don't clean up leave resources behind. - err := k8sClient.DeleteAllOf(context.Background(), &onepasswordv1.OnePasswordItem{}, client.InNamespace(namespace)) + err := k8sClient.DeleteAllOf(ctx, &onepasswordv1.OnePasswordItem{}, client.InNamespace(namespace)) Expect(err).ToNot(HaveOccurred()) - err = k8sClient.DeleteAllOf(context.Background(), &v1.Secret{}, client.InNamespace(namespace)) + err = k8sClient.DeleteAllOf(ctx, &v1.Secret{}, client.InNamespace(namespace)) Expect(err).ToNot(HaveOccurred()) - err = k8sClient.DeleteAllOf(context.Background(), &appsv1.Deployment{}, client.InNamespace(namespace)) + err = k8sClient.DeleteAllOf(ctx, &appsv1.Deployment{}, client.InNamespace(namespace)) Expect(err).ToNot(HaveOccurred()) } diff --git a/internal/controller/onepassworditem_controller.go b/internal/controller/onepassworditem_controller.go index d38e55b..7e68ebf 100644 --- a/internal/controller/onepassworditem_controller.go +++ b/internal/controller/onepassworditem_controller.go @@ -82,7 +82,7 @@ func (r *OnePasswordItemReconciler) Reconcile(ctx context.Context, req ctrl.Requ reqLogger.V(logs.DebugLevel).Info("Reconciling OnePasswordItem") onepassworditem := &onepasswordv1.OnePasswordItem{} - err := r.Get(context.Background(), req.NamespacedName, onepassworditem) + err := r.Get(ctx, req.NamespacedName, onepassworditem) if err != nil { if errors.IsNotFound(err) { return ctrl.Result{}, nil @@ -96,14 +96,14 @@ func (r *OnePasswordItemReconciler) Reconcile(ctx context.Context, req ctrl.Requ // This is so we can handle cleanup of associated secrets properly if !utils.ContainsString(onepassworditem.ObjectMeta.Finalizers, finalizer) { onepassworditem.ObjectMeta.Finalizers = append(onepassworditem.ObjectMeta.Finalizers, finalizer) - if err = r.Update(context.Background(), onepassworditem); err != nil { + if err = r.Update(ctx, onepassworditem); err != nil { return ctrl.Result{}, err } } // Handles creation or updating secrets for deployment if needed - err = r.handleOnePasswordItem(onepassworditem, req) - if updateStatusErr := r.updateStatus(onepassworditem, err); updateStatusErr != nil { + err = r.handleOnePasswordItem(ctx, onepassworditem, req) + if updateStatusErr := r.updateStatus(ctx, onepassworditem, err); updateStatusErr != nil { return ctrl.Result{}, fmt.Errorf("cannot update status: %s", updateStatusErr) } return ctrl.Result{}, err @@ -112,12 +112,12 @@ func (r *OnePasswordItemReconciler) Reconcile(ctx context.Context, req ctrl.Requ if utils.ContainsString(onepassworditem.ObjectMeta.Finalizers, finalizer) { // Delete associated kubernetes secret - if err = r.cleanupKubernetesSecret(onepassworditem); err != nil { + if err = r.cleanupKubernetesSecret(ctx, onepassworditem); err != nil { return ctrl.Result{}, err } // Remove finalizer now that cleanup is complete - if err = r.removeFinalizer(onepassworditem); err != nil { + if err = r.removeFinalizer(ctx, onepassworditem); err != nil { return ctrl.Result{}, err } } @@ -131,20 +131,20 @@ func (r *OnePasswordItemReconciler) SetupWithManager(mgr ctrl.Manager) error { Complete(r) } -func (r *OnePasswordItemReconciler) removeFinalizer(onePasswordItem *onepasswordv1.OnePasswordItem) error { +func (r *OnePasswordItemReconciler) removeFinalizer(ctx context.Context, onePasswordItem *onepasswordv1.OnePasswordItem) error { onePasswordItem.ObjectMeta.Finalizers = utils.RemoveString(onePasswordItem.ObjectMeta.Finalizers, finalizer) - if err := r.Update(context.Background(), onePasswordItem); err != nil { + if err := r.Update(ctx, onePasswordItem); err != nil { return err } return nil } -func (r *OnePasswordItemReconciler) cleanupKubernetesSecret(onePasswordItem *onepasswordv1.OnePasswordItem) error { +func (r *OnePasswordItemReconciler) cleanupKubernetesSecret(ctx context.Context, onePasswordItem *onepasswordv1.OnePasswordItem) error { kubernetesSecret := &corev1.Secret{} kubernetesSecret.ObjectMeta.Name = onePasswordItem.Name kubernetesSecret.ObjectMeta.Namespace = onePasswordItem.Namespace - if err := r.Delete(context.Background(), kubernetesSecret); err != nil { + if err := r.Delete(ctx, kubernetesSecret); err != nil { if !errors.IsNotFound(err) { return err } @@ -152,18 +152,18 @@ func (r *OnePasswordItemReconciler) cleanupKubernetesSecret(onePasswordItem *one return nil } -func (r *OnePasswordItemReconciler) removeOnePasswordFinalizerFromOnePasswordItem(opSecret *onepasswordv1.OnePasswordItem) error { +func (r *OnePasswordItemReconciler) removeOnePasswordFinalizerFromOnePasswordItem(ctx context.Context, opSecret *onepasswordv1.OnePasswordItem) error { opSecret.ObjectMeta.Finalizers = utils.RemoveString(opSecret.ObjectMeta.Finalizers, finalizer) - return r.Update(context.Background(), opSecret) + return r.Update(ctx, opSecret) } -func (r *OnePasswordItemReconciler) handleOnePasswordItem(resource *onepasswordv1.OnePasswordItem, req ctrl.Request) error { +func (r *OnePasswordItemReconciler) handleOnePasswordItem(ctx context.Context, resource *onepasswordv1.OnePasswordItem, req ctrl.Request) error { secretName := resource.GetName() labels := resource.Labels secretType := resource.Type autoRestart := resource.Annotations[op.RestartDeploymentsAnnotation] - item, err := op.GetOnePasswordItemByPath(r.OpClient, resource.Spec.ItemPath) + item, err := op.GetOnePasswordItemByPath(ctx, r.OpClient, resource.Spec.ItemPath) if err != nil { return fmt.Errorf("Failed to retrieve item: %v", err) } @@ -180,10 +180,10 @@ func (r *OnePasswordItemReconciler) handleOnePasswordItem(resource *onepasswordv UID: resource.GetUID(), } - return kubeSecrets.CreateKubernetesSecretFromItem(r.Client, secretName, resource.Namespace, item, autoRestart, labels, secretType, ownerRef) + return kubeSecrets.CreateKubernetesSecretFromItem(ctx, r.Client, secretName, resource.Namespace, item, autoRestart, labels, secretType, ownerRef) } -func (r *OnePasswordItemReconciler) updateStatus(resource *onepasswordv1.OnePasswordItem, err error) error { +func (r *OnePasswordItemReconciler) updateStatus(ctx context.Context, resource *onepasswordv1.OnePasswordItem, err error) error { existingCondition := findCondition(resource.Status.Conditions, onepasswordv1.OnePasswordItemReady) updatedCondition := existingCondition if err != nil { @@ -199,7 +199,7 @@ func (r *OnePasswordItemReconciler) updateStatus(resource *onepasswordv1.OnePass } resource.Status.Conditions = []onepasswordv1.OnePasswordItemCondition{updatedCondition} - return r.Status().Update(context.Background(), resource) + return r.Status().Update(ctx, resource) } func findCondition(conditions []onepasswordv1.OnePasswordItemCondition, t onepasswordv1.OnePasswordItemConditionType) onepasswordv1.OnePasswordItemCondition { diff --git a/pkg/kubernetessecrets/kubernetes_secrets_builder.go b/pkg/kubernetessecrets/kubernetes_secrets_builder.go index d7982fd..429d93e 100644 --- a/pkg/kubernetessecrets/kubernetes_secrets_builder.go +++ b/pkg/kubernetessecrets/kubernetes_secrets_builder.go @@ -33,7 +33,7 @@ var ErrCannotUpdateSecretType = errs.New("Cannot change secret type. Secret type var log = logf.Log -func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretName, namespace string, item *model.Item, autoRestart string, labels map[string]string, secretType string, ownerRef *metav1.OwnerReference) error { +func CreateKubernetesSecretFromItem(ctx context.Context, kubeClient kubernetesClient.Client, secretName, namespace string, item *model.Item, autoRestart string, labels map[string]string, secretType string, ownerRef *metav1.OwnerReference) error { itemVersion := fmt.Sprint(item.Version) secretAnnotations := map[string]string{ VersionAnnotation: itemVersion, @@ -52,10 +52,10 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa secret := BuildKubernetesSecretFromOnePasswordItem(secretName, namespace, secretAnnotations, labels, secretType, *item, ownerRef) currentSecret := &corev1.Secret{} - err := kubeClient.Get(context.Background(), types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, currentSecret) + err := kubeClient.Get(ctx, types.NamespacedName{Name: secret.Name, Namespace: secret.Namespace}, currentSecret) if err != nil && errors.IsNotFound(err) { log.Info(fmt.Sprintf("Creating Secret %v at namespace '%v'", secret.Name, secret.Namespace)) - return kubeClient.Create(context.Background(), secret) + return kubeClient.Create(ctx, secret) } else if err != nil { return err } @@ -81,7 +81,7 @@ func CreateKubernetesSecretFromItem(kubeClient kubernetesClient.Client, secretNa currentSecret.ObjectMeta.Annotations = secretAnnotations currentSecret.ObjectMeta.Labels = labels currentSecret.Data = secret.Data - if err := kubeClient.Update(context.Background(), currentSecret); err != nil { + if err := kubeClient.Update(ctx, currentSecret); err != nil { return fmt.Errorf("Kubernetes secret update failed: %w", err) } return nil diff --git a/pkg/kubernetessecrets/kubernetes_secrets_builder_test.go b/pkg/kubernetessecrets/kubernetes_secrets_builder_test.go index c7128b1..a3e8039 100644 --- a/pkg/kubernetessecrets/kubernetes_secrets_builder_test.go +++ b/pkg/kubernetessecrets/kubernetes_secrets_builder_test.go @@ -17,6 +17,7 @@ import ( const restartDeploymentAnnotation = "false" func TestCreateKubernetesSecretFromOnePasswordItem(t *testing.T) { + ctx := context.Background() secretName := "test-secret-name" namespace := "test" @@ -30,12 +31,12 @@ func TestCreateKubernetesSecretFromOnePasswordItem(t *testing.T) { secretLabels := map[string]string{} secretType := "" - err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, nil) + err := CreateKubernetesSecretFromItem(ctx, kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, nil) if err != nil { t.Errorf("Unexpected error: %v", err) } createdSecret := &corev1.Secret{} - err = kubeClient.Get(context.Background(), types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret) + err = kubeClient.Get(ctx, types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret) if err != nil { t.Errorf("Secret was not created: %v", err) @@ -45,6 +46,7 @@ func TestCreateKubernetesSecretFromOnePasswordItem(t *testing.T) { } func TestKubernetesSecretFromOnePasswordItemOwnerReferences(t *testing.T) { + ctx := context.Background() secretName := "test-secret-name" namespace := "test" @@ -64,12 +66,12 @@ func TestKubernetesSecretFromOnePasswordItemOwnerReferences(t *testing.T) { Name: "test-deployment", UID: types.UID("test-uid"), } - err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, ownerRef) + err := CreateKubernetesSecretFromItem(ctx, kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, ownerRef) if err != nil { t.Errorf("Unexpected error: %v", err) } createdSecret := &corev1.Secret{} - err = kubeClient.Get(context.Background(), types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret) + err = kubeClient.Get(ctx, types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret) // Check owner references. gotOwnerRefs := createdSecret.ObjectMeta.OwnerReferences @@ -90,6 +92,7 @@ func TestKubernetesSecretFromOnePasswordItemOwnerReferences(t *testing.T) { } func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) { + ctx := context.Background() secretName := "test-secret-update" namespace := "test" @@ -103,7 +106,7 @@ func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) { secretLabels := map[string]string{} secretType := "" - err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, nil) + err := CreateKubernetesSecretFromItem(ctx, kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, nil) if err != nil { t.Errorf("Unexpected error: %v", err) @@ -115,12 +118,12 @@ func TestUpdateKubernetesSecretFromOnePasswordItem(t *testing.T) { newItem.Version = 456 newItem.VaultID = "hfnjvi6aymbsnfc2xeeoheizda" newItem.ID = "h46bb3jddvay7nxopfhvlwg35q" - err = CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &newItem, restartDeploymentAnnotation, secretLabels, secretType, nil) + err = CreateKubernetesSecretFromItem(ctx, kubeClient, secretName, namespace, &newItem, restartDeploymentAnnotation, secretLabels, secretType, nil) if err != nil { t.Errorf("Unexpected error: %v", err) } updatedSecret := &corev1.Secret{} - err = kubeClient.Get(context.Background(), types.NamespacedName{Name: secretName, Namespace: namespace}, updatedSecret) + err = kubeClient.Get(ctx, types.NamespacedName{Name: secretName, Namespace: namespace}, updatedSecret) if err != nil { t.Errorf("Secret was not found: %v", err) @@ -205,6 +208,7 @@ func TestBuildKubernetesSecretFixesInvalidLabels(t *testing.T) { } func TestCreateKubernetesTLSSecretFromOnePasswordItem(t *testing.T) { + ctx := context.Background() secretName := "tls-test-secret-name" namespace := "test" @@ -218,12 +222,12 @@ func TestCreateKubernetesTLSSecretFromOnePasswordItem(t *testing.T) { secretLabels := map[string]string{} secretType := "kubernetes.io/tls" - err := CreateKubernetesSecretFromItem(kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, nil) + err := CreateKubernetesSecretFromItem(ctx, kubeClient, secretName, namespace, &item, restartDeploymentAnnotation, secretLabels, secretType, nil) if err != nil { t.Errorf("Unexpected error: %v", err) } createdSecret := &corev1.Secret{} - err = kubeClient.Get(context.Background(), types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret) + err = kubeClient.Get(ctx, types.NamespacedName{Name: secretName, Namespace: namespace}, createdSecret) if err != nil { t.Errorf("Secret was not created: %v", err) diff --git a/pkg/mocks/mocksecretserver.go b/pkg/mocks/mocksecretserver.go index c6c3463..4fa091f 100644 --- a/pkg/mocks/mocksecretserver.go +++ b/pkg/mocks/mocksecretserver.go @@ -1,6 +1,7 @@ package mocks import ( + "context" "github.com/stretchr/testify/mock" "github.com/1Password/onepassword-operator/pkg/onepassword/model" @@ -10,7 +11,7 @@ type TestClient struct { mock.Mock } -func (tc *TestClient) GetItemByID(vaultID, itemID string) (*model.Item, error) { +func (tc *TestClient) GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) { args := tc.Called(vaultID, itemID) if args.Get(0) == nil { return nil, args.Error(1) @@ -18,12 +19,12 @@ func (tc *TestClient) GetItemByID(vaultID, itemID string) (*model.Item, error) { return args.Get(0).(*model.Item), args.Error(1) } -func (tc *TestClient) GetItemsByTitle(vaultID, itemTitle string) ([]model.Item, error) { +func (tc *TestClient) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string) ([]model.Item, error) { args := tc.Called(vaultID, itemTitle) return args.Get(0).([]model.Item), args.Error(1) } -func (tc *TestClient) GetFileContent(vaultID, itemID, fileID string) ([]byte, error) { +func (tc *TestClient) GetFileContent(ctx context.Context, vaultID, itemID, fileID string) ([]byte, error) { args := tc.Called(vaultID, itemID, fileID) if args.Get(0) == nil { return nil, args.Error(1) @@ -31,7 +32,7 @@ func (tc *TestClient) GetFileContent(vaultID, itemID, fileID string) ([]byte, er return args.Get(0).([]byte), args.Error(1) } -func (tc *TestClient) GetVaultsByTitle(title string) ([]model.Vault, error) { +func (tc *TestClient) GetVaultsByTitle(ctx context.Context, title string) ([]model.Vault, error) { args := tc.Called(title) return args.Get(0).([]model.Vault), args.Error(1) } diff --git a/pkg/onepassword/client/client.go b/pkg/onepassword/client/client.go index 7147381..10ec58b 100644 --- a/pkg/onepassword/client/client.go +++ b/pkg/onepassword/client/client.go @@ -1,6 +1,7 @@ package client import ( + "context" "errors" "fmt" "os" @@ -12,14 +13,14 @@ import ( // Client is an interface for interacting with 1Password items and vaults. type Client interface { - GetItemByID(vaultID, itemID string) (*model.Item, error) - GetItemsByTitle(vaultID, itemTitle string) ([]model.Item, error) - GetFileContent(vaultID, itemID, fileID string) ([]byte, error) - GetVaultsByTitle(title string) ([]model.Vault, error) + GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) + GetItemsByTitle(ctx context.Context, vaultID, itemTitle string) ([]model.Item, error) + GetFileContent(ctx context.Context, vaultID, itemID, fileID string) ([]byte, error) + GetVaultsByTitle(ctx context.Context, title string) ([]model.Vault, error) } // NewClient creates a new 1Password client based on the provided configuration. -func NewClient(integrationVersion string) (Client, error) { +func NewClient(ctx context.Context, integrationVersion string) (Client, error) { connectHost, _ := os.LookupEnv("OP_CONNECT_HOST") connectToken, _ := os.LookupEnv("OP_CONNECT_TOKEN") serviceAccountToken, _ := os.LookupEnv("OP_SERVICE_ACCOUNT_TOKEN") @@ -30,7 +31,7 @@ func NewClient(integrationVersion string) (Client, error) { if serviceAccountToken != "" { fmt.Printf("Using Service Account Token") - return sdk.NewClient(sdk.Config{ + return sdk.NewClient(ctx, sdk.Config{ ServiceAccountToken: serviceAccountToken, IntegrationName: "1password-operator", IntegrationVersion: integrationVersion, diff --git a/pkg/onepassword/client/connect/connect.go b/pkg/onepassword/client/connect/connect.go index e45df48..efa49ed 100644 --- a/pkg/onepassword/client/connect/connect.go +++ b/pkg/onepassword/client/connect/connect.go @@ -1,6 +1,7 @@ package connect import ( + "context" "fmt" "github.com/1Password/connect-sdk-go/connect" @@ -27,7 +28,7 @@ func NewClient(config Config) *Connect { } } -func (c *Connect) GetItemByID(vaultID, itemID string) (*model.Item, error) { +func (c *Connect) GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) { connectItem, err := c.client.GetItemByUUID(itemID, vaultID) if err != nil { return nil, fmt.Errorf("1password Connect error: %w", err) @@ -38,7 +39,7 @@ func (c *Connect) GetItemByID(vaultID, itemID string) (*model.Item, error) { return &item, nil } -func (c *Connect) GetItemsByTitle(vaultID, itemTitle string) ([]model.Item, error) { +func (c *Connect) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string) ([]model.Item, error) { // Get all items in the vault with the specified title connectItems, err := c.client.GetItemsByTitle(itemTitle, vaultID) if err != nil { @@ -55,7 +56,7 @@ func (c *Connect) GetItemsByTitle(vaultID, itemTitle string) ([]model.Item, erro return items, nil } -func (c *Connect) GetFileContent(vaultID, itemID, fileID string) ([]byte, error) { +func (c *Connect) GetFileContent(ctx context.Context, vaultID, itemID, fileID string) ([]byte, error) { bytes, err := c.client.GetFileContent(&onepassword.File{ ContentPath: fmt.Sprintf("/v1/vaults/%s/items/%s/files/%s/content", vaultID, itemID, fileID), }) @@ -66,7 +67,7 @@ func (c *Connect) GetFileContent(vaultID, itemID, fileID string) ([]byte, error) return bytes, nil } -func (c *Connect) GetVaultsByTitle(vaultQuery string) ([]model.Vault, error) { +func (c *Connect) GetVaultsByTitle(ctx context.Context, vaultQuery string) ([]model.Vault, error) { connectVaults, err := c.client.GetVaultsByTitle(vaultQuery) if err != nil { return nil, fmt.Errorf("1password Connect error: %w", err) diff --git a/pkg/onepassword/client/connect/connect_test.go b/pkg/onepassword/client/connect/connect_test.go index ef21b90..eafb481 100644 --- a/pkg/onepassword/client/connect/connect_test.go +++ b/pkg/onepassword/client/connect/connect_test.go @@ -1,6 +1,7 @@ package connect import ( + "context" "errors" "testing" @@ -48,7 +49,7 @@ func TestConnect_GetItemByID(t *testing.T) { for description, tc := range testCases { t.Run(description, func(t *testing.T) { client := &Connect{client: tc.mockClient()} - item, err := client.GetItemByID("vault-id", "item-id") + item, err := client.GetItemByID(context.Background(), "vault-id", "item-id") tc.check(t, item, err) }) } @@ -110,7 +111,7 @@ func TestConnect_GetItemsByTitle(t *testing.T) { for description, tc := range testCases { t.Run(description, func(t *testing.T) { client := &Connect{client: tc.mockClient()} - items, err := client.GetItemsByTitle("vault-id", "item-title") + items, err := client.GetItemsByTitle(context.Background(), "vault-id", "item-title") tc.check(t, items, err) }) } @@ -152,7 +153,7 @@ func TestConnect_GetFileContent(t *testing.T) { for description, tc := range testCases { t.Run(description, func(t *testing.T) { client := &Connect{client: tc.mockClient()} - content, err := client.GetFileContent("vault-id", "item-id", "file-id") + content, err := client.GetFileContent(context.Background(), "vault-id", "item-id", "file-id") tc.check(t, content, err) }) } @@ -224,7 +225,7 @@ func TestConnect_GetVaultsByTitle(t *testing.T) { for description, tc := range testCases { t.Run(description, func(t *testing.T) { client := &Connect{client: tc.mockClient()} - vault, err := client.GetVaultsByTitle(VaultTitleEmployee) + vault, err := client.GetVaultsByTitle(context.Background(), VaultTitleEmployee) tc.check(t, vault, err) }) } diff --git a/pkg/onepassword/client/sdk/sdk.go b/pkg/onepassword/client/sdk/sdk.go index b6a89ee..588d147 100644 --- a/pkg/onepassword/client/sdk/sdk.go +++ b/pkg/onepassword/client/sdk/sdk.go @@ -20,8 +20,8 @@ type SDK struct { client *sdk.Client } -func NewClient(config Config) (*SDK, error) { - client, err := sdk.NewClient(context.Background(), +func NewClient(ctx context.Context, config Config) (*SDK, error) { + client, err := sdk.NewClient(ctx, sdk.WithServiceAccountToken(config.ServiceAccountToken), sdk.WithIntegrationInfo(config.IntegrationName, config.IntegrationVersion), ) @@ -34,8 +34,8 @@ func NewClient(config Config) (*SDK, error) { }, nil } -func (s *SDK) GetItemByID(vaultID, itemID string) (*model.Item, error) { - sdkItem, err := s.client.Items().Get(context.Background(), vaultID, itemID) +func (s *SDK) GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) { + sdkItem, err := s.client.Items().Get(ctx, vaultID, itemID) if err != nil { return nil, fmt.Errorf("1password sdk error: %w", err) } @@ -45,9 +45,9 @@ func (s *SDK) GetItemByID(vaultID, itemID string) (*model.Item, error) { return &item, nil } -func (s *SDK) GetItemsByTitle(vaultID, itemTitle string) ([]model.Item, error) { +func (s *SDK) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string) ([]model.Item, error) { // Get all items in the vault - sdkItems, err := s.client.Items().List(context.Background(), vaultID) + sdkItems, err := s.client.Items().List(ctx, vaultID) if err != nil { return nil, fmt.Errorf("1password sdk error: %w", err) } @@ -65,8 +65,8 @@ func (s *SDK) GetItemsByTitle(vaultID, itemTitle string) ([]model.Item, error) { return items, nil } -func (s *SDK) GetFileContent(vaultID, itemID, fileID string) ([]byte, error) { - bytes, err := s.client.Items().Files().Read(context.Background(), vaultID, itemID, sdk.FileAttributes{ +func (s *SDK) GetFileContent(ctx context.Context, vaultID, itemID, fileID string) ([]byte, error) { + bytes, err := s.client.Items().Files().Read(ctx, vaultID, itemID, sdk.FileAttributes{ ID: fileID, }) if err != nil { @@ -76,9 +76,9 @@ func (s *SDK) GetFileContent(vaultID, itemID, fileID string) ([]byte, error) { return bytes, nil } -func (s *SDK) GetVaultsByTitle(title string) ([]model.Vault, error) { +func (s *SDK) GetVaultsByTitle(ctx context.Context, title string) ([]model.Vault, error) { // List all vaults - sdkVaults, err := s.client.Vaults().List(context.Background()) + sdkVaults, err := s.client.Vaults().List(ctx) if err != nil { return nil, fmt.Errorf("1password sdk error: %w", err) } diff --git a/pkg/onepassword/client/sdk/sdk_test.go b/pkg/onepassword/client/sdk/sdk_test.go index 5455c5b..91c2a21 100644 --- a/pkg/onepassword/client/sdk/sdk_test.go +++ b/pkg/onepassword/client/sdk/sdk_test.go @@ -54,7 +54,7 @@ func TestSDK_GetItemByID(t *testing.T) { ItemsAPI: tc.mockItemAPI(), }, } - item, err := client.GetItemByID("vault-id", "item-id") + item, err := client.GetItemByID(context.Background(), "vault-id", "item-id") tc.check(t, item, err) }) } @@ -123,7 +123,7 @@ func TestSDK_GetItemsByTitle(t *testing.T) { ItemsAPI: tc.mockItemAPI(), }, } - items, err := client.GetItemsByTitle("vault-id", "item-title") + items, err := client.GetItemsByTitle(context.Background(), "vault-id", "item-title") tc.check(t, items, err) }) } @@ -185,7 +185,7 @@ func TestSDK_GetFileContent(t *testing.T) { ItemsAPI: tc.mockItemAPI(), }, } - content, err := client.GetFileContent("vault-id", "item-id", "file-id") + content, err := client.GetFileContent(context.Background(), "vault-id", "item-id", "file-id") tc.check(t, content, err) }) } @@ -262,7 +262,7 @@ func TestSDK_GetVaultsByTitle(t *testing.T) { VaultsAPI: tc.mockVaultAPI(), }, } - vault, err := client.GetVaultsByTitle(VaultTitleEmployee) + vault, err := client.GetVaultsByTitle(context.Background(), VaultTitleEmployee) tc.check(t, vault, err) }) } diff --git a/pkg/onepassword/connect_setup.go b/pkg/onepassword/connect_setup.go index 16d2d0c..57bf057 100644 --- a/pkg/onepassword/connect_setup.go +++ b/pkg/onepassword/connect_setup.go @@ -18,13 +18,13 @@ var logConnectSetup = logf.Log.WithName("ConnectSetup") var deploymentPath = "../config/connect/deployment.yaml" var servicePath = "../config/connect/service.yaml" -func SetupConnect(kubeClient client.Client, deploymentNamespace string) error { - err := setupService(kubeClient, servicePath, deploymentNamespace) +func SetupConnect(ctx context.Context, kubeClient client.Client, deploymentNamespace string) error { + err := setupService(ctx, kubeClient, servicePath, deploymentNamespace) if err != nil { return err } - err = setupDeployment(kubeClient, deploymentPath, deploymentNamespace) + err = setupDeployment(ctx, kubeClient, deploymentPath, deploymentNamespace) if err != nil { return err } @@ -32,27 +32,27 @@ func SetupConnect(kubeClient client.Client, deploymentNamespace string) error { return nil } -func setupDeployment(kubeClient client.Client, deploymentPath string, deploymentNamespace string) error { +func setupDeployment(ctx context.Context, kubeClient client.Client, deploymentPath string, deploymentNamespace string) error { existingDeployment := &appsv1.Deployment{} // check if deployment has already been created - err := kubeClient.Get(context.Background(), types.NamespacedName{Name: "onepassword-connect", Namespace: deploymentNamespace}, existingDeployment) + err := kubeClient.Get(ctx, types.NamespacedName{Name: "onepassword-connect", Namespace: deploymentNamespace}, existingDeployment) if err != nil { if errors.IsNotFound(err) { logConnectSetup.Info("No existing Connect deployment found. Creating Deployment") - return createDeployment(kubeClient, deploymentPath, deploymentNamespace) + return createDeployment(ctx, kubeClient, deploymentPath, deploymentNamespace) } } return err } -func createDeployment(kubeClient client.Client, deploymentPath string, deploymentNamespace string) error { +func createDeployment(ctx context.Context, kubeClient client.Client, deploymentPath string, deploymentNamespace string) error { deployment, err := getDeploymentToCreate(deploymentPath, deploymentNamespace) if err != nil { return err } - err = kubeClient.Create(context.Background(), deployment) + err = kubeClient.Create(ctx, deployment) if err != nil { return err } @@ -78,21 +78,21 @@ func getDeploymentToCreate(deploymentPath string, deploymentNamespace string) (* return deployment, nil } -func setupService(kubeClient client.Client, servicePath string, deploymentNamespace string) error { +func setupService(ctx context.Context, kubeClient client.Client, servicePath string, deploymentNamespace string) error { existingService := &corev1.Service{} //check if service has already been created - err := kubeClient.Get(context.Background(), types.NamespacedName{Name: "onepassword-connect", Namespace: deploymentNamespace}, existingService) + err := kubeClient.Get(ctx, types.NamespacedName{Name: "onepassword-connect", Namespace: deploymentNamespace}, existingService) if err != nil { if errors.IsNotFound(err) { logConnectSetup.Info("No existing Connect service found. Creating Service") - return createService(kubeClient, servicePath, deploymentNamespace) + return createService(ctx, kubeClient, servicePath, deploymentNamespace) } } return err } -func createService(kubeClient client.Client, servicePath string, deploymentNamespace string) error { +func createService(ctx context.Context, kubeClient client.Client, servicePath string, deploymentNamespace string) error { f, err := os.Open(servicePath) if err != nil { return err @@ -108,7 +108,7 @@ func createService(kubeClient client.Client, servicePath string, deploymentNames return err } - err = kubeClient.Create(context.Background(), service) + err = kubeClient.Create(ctx, service) if err != nil { return err } diff --git a/pkg/onepassword/connect_setup_test.go b/pkg/onepassword/connect_setup_test.go index f0e5864..8e47df4 100644 --- a/pkg/onepassword/connect_setup_test.go +++ b/pkg/onepassword/connect_setup_test.go @@ -15,6 +15,7 @@ import ( var defaultNamespacedName = types.NamespacedName{Name: "onepassword-connect", Namespace: "default"} func TestServiceSetup(t *testing.T) { + ctx := context.Background() // Register operator types with the runtime scheme. s := scheme.Scheme @@ -25,7 +26,7 @@ func TestServiceSetup(t *testing.T) { // Create a fake client to mock API calls. client := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - err := setupService(client, "../../config/connect/service.yaml", defaultNamespacedName.Namespace) + err := setupService(ctx, client, "../../config/connect/service.yaml", defaultNamespacedName.Namespace) if err != nil { t.Errorf("Error Setting Up Connect: %v", err) @@ -33,13 +34,14 @@ func TestServiceSetup(t *testing.T) { // check that service was created service := &corev1.Service{} - err = client.Get(context.TODO(), defaultNamespacedName, service) + err = client.Get(ctx, defaultNamespacedName, service) if err != nil { t.Errorf("Error Setting Up Connect service: %v", err) } } func TestDeploymentSetup(t *testing.T) { + ctx := context.Background() // Register operator types with the runtime scheme. s := scheme.Scheme @@ -50,7 +52,7 @@ func TestDeploymentSetup(t *testing.T) { // Create a fake client to mock API calls. client := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...).Build() - err := setupDeployment(client, "../../config/connect/deployment.yaml", defaultNamespacedName.Namespace) + err := setupDeployment(ctx, client, "../../config/connect/deployment.yaml", defaultNamespacedName.Namespace) if err != nil { t.Errorf("Error Setting Up Connect: %v", err) @@ -58,7 +60,7 @@ func TestDeploymentSetup(t *testing.T) { // check that deployment was created deployment := &appsv1.Deployment{} - err = client.Get(context.TODO(), defaultNamespacedName, deployment) + err = client.Get(ctx, defaultNamespacedName, deployment) if err != nil { t.Errorf("Error Setting Up Connect deployment: %v", err) } diff --git a/pkg/onepassword/items.go b/pkg/onepassword/items.go index eb121a3..6b4a983 100644 --- a/pkg/onepassword/items.go +++ b/pkg/onepassword/items.go @@ -1,6 +1,7 @@ package onepassword import ( + "context" "fmt" "strings" @@ -12,28 +13,28 @@ import ( var logger = logf.Log.WithName("retrieve_item") -func GetOnePasswordItemByPath(opClient opclient.Client, path string) (*model.Item, error) { +func GetOnePasswordItemByPath(ctx context.Context, opClient opclient.Client, path string) (*model.Item, error) { vaultIdentifier, itemIdentifier, err := ParseVaultAndItemFromPath(path) if err != nil { return nil, err } - vaultID, err := getVaultID(opClient, vaultIdentifier) + vaultID, err := getVaultID(ctx, opClient, vaultIdentifier) if err != nil { return nil, fmt.Errorf("failed to 'getVaultID' for vaultIdentifier='%s': %w", vaultIdentifier, err) } - itemID, err := getItemID(opClient, vaultID, itemIdentifier) + itemID, err := getItemID(ctx, opClient, vaultID, itemIdentifier) if err != nil { return nil, fmt.Errorf("faild to 'getItemID' for vaultID='%s' and itemIdentifier='%s': %w", vaultID, itemIdentifier, err) } - item, err := opClient.GetItemByID(vaultID, itemID) + item, err := opClient.GetItemByID(ctx, vaultID, itemID) if err != nil { return nil, fmt.Errorf("faield to 'GetItemByID' for vaultID='%s' and itemID='%s': %w", vaultID, itemID, err) } for _, file := range item.Files { - _, err := opClient.GetFileContent(vaultID, itemID, file.ID) + _, err := opClient.GetFileContent(ctx, vaultID, itemID, file.ID) if err != nil { return nil, err } @@ -50,9 +51,9 @@ func ParseVaultAndItemFromPath(path string) (string, string, error) { return "", "", fmt.Errorf("%q is not an acceptable path for One Password item. Must be of the format: `vaults/{vault_id}/items/{item_id}`", path) } -func getVaultID(client opclient.Client, vaultIdentifier string) (string, error) { +func getVaultID(ctx context.Context, client opclient.Client, vaultIdentifier string) (string, error) { if !IsValidClientUUID(vaultIdentifier) { - vaults, err := client.GetVaultsByTitle(vaultIdentifier) + vaults, err := client.GetVaultsByTitle(ctx, vaultIdentifier) if err != nil { return "", err } @@ -75,9 +76,9 @@ func getVaultID(client opclient.Client, vaultIdentifier string) (string, error) return vaultIdentifier, nil } -func getItemID(client opclient.Client, vaultId, itemIdentifier string) (string, error) { +func getItemID(ctx context.Context, client opclient.Client, vaultId, itemIdentifier string) (string, error) { if !IsValidClientUUID(itemIdentifier) { - items, err := client.GetItemsByTitle(vaultId, itemIdentifier) + items, err := client.GetItemsByTitle(ctx, vaultId, itemIdentifier) if err != nil { return "", err } diff --git a/pkg/onepassword/secret_update_handler.go b/pkg/onepassword/secret_update_handler.go index d7f0156..1042740 100644 --- a/pkg/onepassword/secret_update_handler.go +++ b/pkg/onepassword/secret_update_handler.go @@ -37,23 +37,23 @@ type SecretUpdateHandler struct { shouldAutoRestartDeploymentsGlobal bool } -func (h *SecretUpdateHandler) UpdateKubernetesSecretsTask() error { - updatedKubernetesSecrets, err := h.updateKubernetesSecrets() +func (h *SecretUpdateHandler) UpdateKubernetesSecretsTask(ctx context.Context) error { + updatedKubernetesSecrets, err := h.updateKubernetesSecrets(ctx) if err != nil { return err } - return h.restartDeploymentsWithUpdatedSecrets(updatedKubernetesSecrets) + return h.restartDeploymentsWithUpdatedSecrets(ctx, updatedKubernetesSecrets) } -func (h *SecretUpdateHandler) restartDeploymentsWithUpdatedSecrets(updatedSecretsByNamespace map[string]map[string]*corev1.Secret) error { +func (h *SecretUpdateHandler) restartDeploymentsWithUpdatedSecrets(ctx context.Context, updatedSecretsByNamespace map[string]map[string]*corev1.Secret) error { // No secrets to update. Exit if len(updatedSecretsByNamespace) == 0 || updatedSecretsByNamespace == nil { return nil } deployments := &appsv1.DeploymentList{} - err := h.client.List(context.Background(), deployments) + err := h.client.List(ctx, deployments) if err != nil { log.Error(err, "Failed to list kubernetes deployments") return err @@ -63,7 +63,7 @@ func (h *SecretUpdateHandler) restartDeploymentsWithUpdatedSecrets(updatedSecret return nil } - setForAutoRestartByNamespaceMap, err := h.getIsSetForAutoRestartByNamespaceMap() + setForAutoRestartByNamespaceMap, err := h.getIsSetForAutoRestartByNamespaceMap(ctx) if err != nil { return err } @@ -78,7 +78,7 @@ func (h *SecretUpdateHandler) restartDeploymentsWithUpdatedSecrets(updatedSecret } for _, secret := range updatedDeploymentSecrets { if isSecretSetForAutoRestart(secret, deployment, setForAutoRestartByNamespaceMap) { - h.restartDeployment(deployment) + h.restartDeployment(ctx, deployment) continue } } @@ -89,21 +89,21 @@ func (h *SecretUpdateHandler) restartDeploymentsWithUpdatedSecrets(updatedSecret return nil } -func (h *SecretUpdateHandler) restartDeployment(deployment *appsv1.Deployment) { +func (h *SecretUpdateHandler) restartDeployment(ctx context.Context, deployment *appsv1.Deployment) { log.Info(fmt.Sprintf("Deployment %q at namespace %q references an updated secret. Restarting", deployment.GetName(), deployment.Namespace)) if deployment.Spec.Template.Annotations == nil { deployment.Spec.Template.Annotations = map[string]string{} } deployment.Spec.Template.Annotations[RestartAnnotation] = time.Now().String() - err := h.client.Update(context.Background(), deployment) + err := h.client.Update(ctx, deployment) if err != nil { log.Error(err, "Problem restarting deployment") } } -func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]*corev1.Secret, error) { +func (h *SecretUpdateHandler) updateKubernetesSecrets(ctx context.Context) (map[string]map[string]*corev1.Secret, error) { secrets := &corev1.SecretList{} - err := h.client.List(context.Background(), secrets) + err := h.client.List(ctx, secrets) if err != nil { log.Error(err, "Failed to list kubernetes secrets") return nil, err @@ -121,7 +121,7 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]* OnePasswordItemPath := h.getPathFromOnePasswordItem(secret) - item, err := GetOnePasswordItemByPath(h.opClient, OnePasswordItemPath) + item, err := GetOnePasswordItemByPath(ctx, h.opClient, OnePasswordItemPath) if err != nil { log.Error(err, "failed to retrieve 1Password item at path \"%s\" for secret \"%s\"", secret.Annotations[ItemPathAnnotation], secret.Name) continue @@ -135,7 +135,7 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]* log.V(logs.DebugLevel).Info(fmt.Sprintf("Secret '%v' has been updated in 1Password but is set to be ignored. Updates to an ignored secret will not trigger an update to a kubernetes secret or a rolling restart.", secret.GetName())) secret.Annotations[VersionAnnotation] = itemVersion secret.Annotations[ItemPathAnnotation] = itemPathString - if err := h.client.Update(context.Background(), &secret); err != nil { + if err := h.client.Update(ctx, &secret); err != nil { log.Error(err, "failed to update secret %s annotations to version %d: %s", secret.Name, itemVersion, err) continue } @@ -146,7 +146,7 @@ func (h *SecretUpdateHandler) updateKubernetesSecrets() (map[string]map[string]* secret.Annotations[ItemPathAnnotation] = itemPathString secret.Data = kubeSecrets.BuildKubernetesSecretData(item.Fields, item.Files) log.V(logs.DebugLevel).Info(fmt.Sprintf("New secret path: %v and version: %v", secret.Annotations[ItemPathAnnotation], secret.Annotations[VersionAnnotation])) - if err := h.client.Update(context.Background(), &secret); err != nil { + if err := h.client.Update(ctx, &secret); err != nil { log.Error(err, "failed to update secret %s to version %d: %s", secret.Name, itemVersion, err) continue } @@ -177,9 +177,9 @@ func isUpdatedSecret(secretName string, updatedSecrets map[string]*corev1.Secret return false } -func (h *SecretUpdateHandler) getIsSetForAutoRestartByNamespaceMap() (map[string]bool, error) { +func (h *SecretUpdateHandler) getIsSetForAutoRestartByNamespaceMap(ctx context.Context) (map[string]bool, error) { namespaces := &corev1.NamespaceList{} - err := h.client.List(context.Background(), namespaces) + err := h.client.List(ctx, namespaces) if err != nil { log.Error(err, "Failed to list kubernetes namespaces") return nil, err diff --git a/pkg/onepassword/secret_update_handler_test.go b/pkg/onepassword/secret_update_handler_test.go index f6dad7f..9568b39 100644 --- a/pkg/onepassword/secret_update_handler_test.go +++ b/pkg/onepassword/secret_update_handler_test.go @@ -787,7 +787,7 @@ var tests = []testUpdateSecretTask{ func TestUpdateSecretHandler(t *testing.T) { for _, testData := range tests { t.Run(testData.testName, func(t *testing.T) { - + ctx := context.Background() // Register operator types with the runtime scheme. s := scheme.Scheme s.AddKnownTypes(appsv1.SchemeGroupVersion, testData.existingDeployment) @@ -822,7 +822,7 @@ func TestUpdateSecretHandler(t *testing.T) { shouldAutoRestartDeploymentsGlobal: testData.globalAutoRestartEnabled, } - err := h.UpdateKubernetesSecretsTask() + err := h.UpdateKubernetesSecretsTask(ctx) assert.Equal(t, testData.expectedError, err) @@ -835,7 +835,7 @@ func TestUpdateSecretHandler(t *testing.T) { // Check if Secret has been created and has the correct data secret := &corev1.Secret{} - err = cl.Get(context.TODO(), types.NamespacedName{Name: expectedSecretName, Namespace: namespace}, secret) + err = cl.Get(ctx, types.NamespacedName{Name: expectedSecretName, Namespace: namespace}, secret) if testData.expectedResultSecret == nil { assert.Error(t, err) @@ -849,7 +849,7 @@ func TestUpdateSecretHandler(t *testing.T) { //check if deployment has been restarted deployment := &appsv1.Deployment{} - err = cl.Get(context.TODO(), types.NamespacedName{Name: testData.existingDeployment.Name, Namespace: namespace}, deployment) + err = cl.Get(ctx, types.NamespacedName{Name: testData.existingDeployment.Name, Namespace: namespace}, deployment) _, ok := deployment.Spec.Template.Annotations[RestartAnnotation] if ok {