diff --git a/controllers/deployment_controller_test.go b/controllers/deployment_controller_test.go index 509e8d6..1481d79 100644 --- a/controllers/deployment_controller_test.go +++ b/controllers/deployment_controller_test.go @@ -2,10 +2,10 @@ package controllers import ( "context" - "github.com/1Password/connect-sdk-go/onepassword" "github.com/1Password/onepassword-operator/pkg/mocks" op "github.com/1Password/onepassword-operator/pkg/onepassword" + "time" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -19,100 +19,115 @@ import ( onepasswordv1 "github.com/1Password/onepassword-operator/api/v1" ) +const ( + deploymentKind = "Deployment" + deploymentAPIVersion = "v1" + deploymentName = "test-deployment" +) + var _ = Describe("Deployment controller", func() { - const ( - deploymentKind = "Deployment" - deploymentAPIVersion = "v1" - deploymentName = "test-deployment" - ) + var ctx context.Context + var deploymentKey types.NamespacedName + var secretKey types.NamespacedName + var deploymentResource *appsv1.Deployment + createdSecret := &v1.Secret{} - BeforeEach(func() { + makeDeployment := func() { + ctx = context.Background() + + deploymentKey = types.NamespacedName{ + Name: deploymentName, + Namespace: namespace, + } + + secretKey = types.NamespacedName{ + Name: item1.Name, + Namespace: namespace, + } + + By("Deploying a pod with proper annotations successfully") + deploymentResource = &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: deploymentKind, + APIVersion: deploymentAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentKey.Name, + Namespace: deploymentKey.Namespace, + Annotations: map[string]string{ + op.ItemPathAnnotation: item1.Path, + op.NameAnnotation: item1.Name, + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": deploymentName}, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: deploymentName, + Image: "eu.gcr.io/kyma-project/example/http-db-service:0.0.6", + ImagePullPolicy: "IfNotPresent", + }, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": deploymentName}, + }, + }, + } + Expect(k8sClient.Create(ctx, deploymentResource)).Should(Succeed()) + + By("Creating the K8s secret successfully") + time.Sleep(time.Millisecond * 100) + Eventually(func() bool { + err := k8sClient.Get(ctx, secretKey, createdSecret) + if err != nil { + return false + } + return true + }, timeout, interval).Should(BeTrue()) + Expect(createdSecret.Data).Should(Equal(item1.SecretData)) + } + + cleanK8sResources := func() { // failed test runs that don't clean up leave resources behind. - k8sClient.DeleteAllOf(context.Background(), &onepasswordv1.OnePasswordItem{}, client.InNamespace(namespace)) - k8sClient.DeleteAllOf(context.Background(), &v1.Secret{}, client.InNamespace(namespace)) - k8sClient.DeleteAllOf(context.Background(), &appsv1.Deployment{}, client.InNamespace(namespace)) + err := k8sClient.DeleteAllOf(context.Background(), &onepasswordv1.OnePasswordItem{}, client.InNamespace(namespace)) + Expect(err).ToNot(HaveOccurred()) + err = k8sClient.DeleteAllOf(context.Background(), &v1.Secret{}, client.InNamespace(namespace)) + Expect(err).ToNot(HaveOccurred()) + + err = k8sClient.DeleteAllOf(context.Background(), &appsv1.Deployment{}, client.InNamespace(namespace)) + Expect(err).ToNot(HaveOccurred()) + } + + mockGetItemFunc := func() { mocks.DoGetItemFunc = func(uuid string, vaultUUID string) (*onepassword.Item, error) { - item := onepassword.Item{} item.Fields = []*onepassword.ItemField{} - for k, v := range itemData { + for k, v := range item1.Data { item.Fields = append(item.Fields, &onepassword.ItemField{Label: k, Value: v}) } - item.Version = version + item.Version = item1.Version item.Vault.ID = vaultUUID item.ID = uuid return &item, nil } + } + + BeforeEach(func() { + cleanK8sResources() + mockGetItemFunc() + time.Sleep(time.Second) // TODO: can we achieve that with ginkgo? + makeDeployment() }) - // TODO: Implement the following test cases: - // - Updating Existing K8s Secret using Deployment - // - Do not update if Annotations have not changed - // - Delete Deployment where secret is being used in another deployment's container - // - Delete Deployment where secret is being used in another deployment's volumes - Context("Deployment with secrets from 1Password", func() { - It("Should Handle a deployment correctly", func() { - ctx := context.Background() - - deploymentKey := types.NamespacedName{ - Name: deploymentName, - Namespace: namespace, - } - - secretKey := types.NamespacedName{ - Name: ItemName, - Namespace: namespace, - } - - By("Deploying a pod with proper annotations successfully") - deploymentResource := &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: deploymentKind, - APIVersion: deploymentAPIVersion, - }, - ObjectMeta: metav1.ObjectMeta{ - Name: deploymentKey.Name, - Namespace: deploymentKey.Namespace, - Annotations: map[string]string{ - op.ItemPathAnnotation: itemPath, - op.NameAnnotation: ItemName, - }, - }, - Spec: appsv1.DeploymentSpec{ - Template: v1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": deploymentName}, - }, - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Name: deploymentName, - Image: "eu.gcr.io/kyma-project/example/http-db-service:0.0.6", - ImagePullPolicy: "IfNotPresent", - }, - }, - }, - }, - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": deploymentName}, - }, - }, - } - Expect(k8sClient.Create(ctx, deploymentResource)).Should(Succeed()) - - By("Creating the K8s secret successfully") - createdSecret := &v1.Secret{} - Eventually(func() bool { - err := k8sClient.Get(ctx, secretKey, createdSecret) - if err != nil { - return false - } - return true - }, timeout, interval).Should(BeTrue()) - Expect(createdSecret.Data).Should(Equal(expectedSecretData)) - + It("Should delete secret if deployment is deleted", func() { By("Deleting the pod") Eventually(func() error { f := &appsv1.Deployment{} @@ -133,5 +148,271 @@ var _ = Describe("Deployment controller", func() { return k8sClient.Get(ctx, secretKey, f) }, timeout, interval).ShouldNot(Succeed()) }) + + It("Should update existing K8s Secret using deployment", func() { + By("Updating secret") + mocks.DoGetItemFunc = func(uuid string, vaultUUID string) (*onepassword.Item, error) { + item := onepassword.Item{} + item.Fields = []*onepassword.ItemField{} + for k, v := range item2.Data { + item.Fields = append(item.Fields, &onepassword.ItemField{Label: k, Value: v}) + } + item.Version = item2.Version + item.Vault.ID = vaultUUID + item.ID = uuid + return &item, nil + } + Eventually(func() error { + updatedDeployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: deploymentKind, + APIVersion: deploymentAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentKey.Name, + Namespace: deploymentKey.Namespace, + Annotations: map[string]string{ + op.ItemPathAnnotation: item2.Path, + op.NameAnnotation: item1.Name, + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": deploymentName}, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: deploymentName, + Image: "eu.gcr.io/kyma-project/example/http-db-service:0.0.6", + ImagePullPolicy: "IfNotPresent", + }, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": deploymentName}, + }, + }, + } + err := k8sClient.Update(ctx, updatedDeployment) + if err != nil { + return err + } + return nil + }, timeout, interval).Should(Succeed()) + + // TODO: can we achieve the same without sleep? + time.Sleep(time.Millisecond * 10) + By("Reading updated K8s secret") + updatedSecret := &v1.Secret{} + Eventually(func() bool { + err := k8sClient.Get(ctx, secretKey, updatedSecret) + if err != nil { + return false + } + return true + }, timeout, interval).Should(BeTrue()) + Expect(updatedSecret.Data).Should(Equal(item2.SecretData)) + }) + + It("Should not update secret if Annotations have not changed", func() { + By("Updating secret without changing annotations") + Eventually(func() error { + updatedDeployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: deploymentKind, + APIVersion: deploymentAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: deploymentKey.Name, + Namespace: deploymentKey.Namespace, + Annotations: map[string]string{ + op.ItemPathAnnotation: item1.Path, + op.NameAnnotation: item1.Name, + }, + }, + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": deploymentName}, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: deploymentName, + Image: "eu.gcr.io/kyma-project/example/http-db-service:0.0.6", + ImagePullPolicy: "IfNotPresent", + }, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": deploymentName}, + }, + }, + } + err := k8sClient.Update(ctx, updatedDeployment) + if err != nil { + return err + } + return nil + }, timeout, interval).Should(Succeed()) + + // TODO: can we achieve the same without sleep? + time.Sleep(time.Millisecond * 10) + By("Reading updated K8s secret") + updatedSecret := &v1.Secret{} + Eventually(func() bool { + err := k8sClient.Get(ctx, secretKey, updatedSecret) + if err != nil { + return false + } + return true + }, timeout, interval).Should(BeTrue()) + Expect(updatedSecret.Data).Should(Equal(item1.SecretData)) + }) + + It("Should not delete secret created via deployment if it's used in another container", func() { + By("Creating another POD with created secret") + anotherDeploymentKey := types.NamespacedName{ + Name: "other-deployment", + Namespace: namespace, + } + Eventually(func() error { + anotherDeployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: deploymentKind, + APIVersion: deploymentAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: anotherDeploymentKey.Name, + Namespace: anotherDeploymentKey.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": anotherDeploymentKey.Name}, + }, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + { + Name: anotherDeploymentKey.Name, + Image: "eu.gcr.io/kyma-project/example/http-db-service:0.0.6", + ImagePullPolicy: "IfNotPresent", + Env: []v1.EnvVar{ + { + Name: anotherDeploymentKey.Name, + ValueFrom: &v1.EnvVarSource{ + SecretKeyRef: &v1.SecretKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: secretKey.Name, + }, + Key: "password", + }, + }, + }, + }, + }, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": anotherDeploymentKey.Name}, + }, + }, + } + err := k8sClient.Create(ctx, anotherDeployment) + if err != nil { + return err + } + return nil + }, timeout, interval).Should(Succeed()) + + By("Deleting the pod") + Eventually(func() error { + f := &appsv1.Deployment{} + err := k8sClient.Get(ctx, deploymentKey, f) + if err != nil { + return err + } + return k8sClient.Delete(ctx, f) + }, timeout, interval).Should(Succeed()) + + Eventually(func() error { + f := &v1.Secret{} + return k8sClient.Get(ctx, secretKey, f) + }, timeout, interval).Should(Succeed()) + }) + + It("Should not delete secret created via deployment if it's used in another volume", func() { + By("Creating another POD with created secret") + anotherDeploymentKey := types.NamespacedName{ + Name: "other-deployment", + Namespace: namespace, + } + Eventually(func() error { + anotherDeployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: deploymentKind, + APIVersion: deploymentAPIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + Name: anotherDeploymentKey.Name, + Namespace: anotherDeploymentKey.Namespace, + }, + Spec: appsv1.DeploymentSpec{ + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": anotherDeploymentKey.Name}, + }, + Spec: v1.PodSpec{ + Volumes: []v1.Volume{ + { + Name: anotherDeploymentKey.Name, + VolumeSource: v1.VolumeSource{ + Secret: &v1.SecretVolumeSource{ + SecretName: secretKey.Name, + }, + }, + }, + }, + Containers: []v1.Container{ + { + Name: anotherDeploymentKey.Name, + Image: "eu.gcr.io/kyma-project/example/http-db-service:0.0.6", + ImagePullPolicy: "IfNotPresent", + }, + }, + }, + }, + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": anotherDeploymentKey.Name}, + }, + }, + } + err := k8sClient.Create(ctx, anotherDeployment) + if err != nil { + return err + } + return nil + }, timeout, interval).Should(Succeed()) + + By("Deleting the pod") + Eventually(func() error { + f := &appsv1.Deployment{} + err := k8sClient.Get(ctx, deploymentKey, f) + if err != nil { + return err + } + return k8sClient.Delete(ctx, f) + }, timeout, interval).Should(Succeed()) + + Eventually(func() error { + f := &v1.Secret{} + return k8sClient.Get(ctx, secretKey, f) + }, timeout, interval).Should(Succeed()) + }) }) }) diff --git a/controllers/onepassworditem_controller_test.go b/controllers/onepassworditem_controller_test.go index 3971482..7a1f01d 100644 --- a/controllers/onepassworditem_controller_test.go +++ b/controllers/onepassworditem_controller_test.go @@ -27,39 +27,33 @@ const ( var _ = Describe("OnePasswordItem controller", func() { BeforeEach(func() { // failed test runs that don't clean up leave resources behind. - k8sClient.DeleteAllOf(context.Background(), &onepasswordv1.OnePasswordItem{}, client.InNamespace(namespace)) - k8sClient.DeleteAllOf(context.Background(), &v1.Secret{}, client.InNamespace(namespace)) + err := k8sClient.DeleteAllOf(context.Background(), &onepasswordv1.OnePasswordItem{}, client.InNamespace(namespace)) + Expect(err).ToNot(HaveOccurred()) + err = k8sClient.DeleteAllOf(context.Background(), &v1.Secret{}, client.InNamespace(namespace)) + Expect(err).ToNot(HaveOccurred()) mocks.DoGetItemFunc = func(uuid string, vaultUUID string) (*onepassword.Item, error) { - item := onepassword.Item{} item.Fields = []*onepassword.ItemField{} - for k, v := range itemData { + for k, v := range item1.Data { item.Fields = append(item.Fields, &onepassword.ItemField{Label: k, Value: v}) } - item.Version = version + item.Version = item1.Version item.Vault.ID = vaultUUID item.ID = uuid return &item, nil } }) - // TODO: Implement the following missing tests: - // - K8s secret is not updated if OnePasswordItem Version or VaultPath has not changed - // - Update type of existing K8s Secret using OnePasswordItem - // - Create a custom K8s Secret type using OnePasswordItem (e.g. .dockerconfigjson) - // - Operator should throw an error if secret type is changed - // - Secret from 1Password item with `-`, `_` and `.` - Context("Happy path", func() { It("Should handle 1Password Item and secret correctly", func() { ctx := context.Background() spec := onepasswordv1.OnePasswordItemSpec{ - ItemPath: itemPath, + ItemPath: item1.Path, } key := types.NamespacedName{ - Name: ItemName, + Name: item1.Name, Namespace: namespace, } @@ -92,7 +86,7 @@ var _ = Describe("OnePasswordItem controller", func() { } return true }, timeout, interval).Should(BeTrue()) - Expect(createdSecret.Data).Should(Equal(expectedSecretData)) + Expect(createdSecret.Data).Should(Equal(item1.SecretData)) By("Updating existing secret successfully") newData := map[string]string{ @@ -111,7 +105,7 @@ var _ = Describe("OnePasswordItem controller", func() { for k, v := range newData { item.Fields = append(item.Fields, &onepassword.ItemField{Label: k, Value: v}) } - item.Version = version + 1 + item.Version = item1.Version + 1 item.Vault.ID = vaultUUID item.ID = uuid return &item, nil @@ -153,7 +147,7 @@ var _ = Describe("OnePasswordItem controller", func() { It("Should handle 1Password Item with fields and sections that have invalid K8s labels correctly", func() { ctx := context.Background() spec := onepasswordv1.OnePasswordItemSpec{ - ItemPath: itemPath, + ItemPath: item1.Path, } key := types.NamespacedName{ @@ -163,7 +157,7 @@ var _ = Describe("OnePasswordItem controller", func() { toCreate := &onepasswordv1.OnePasswordItem{ ObjectMeta: metav1.ObjectMeta{ - Name: "my-secret-it3m", + Name: key.Name, Namespace: key.Namespace, }, Spec: spec, @@ -191,7 +185,7 @@ var _ = Describe("OnePasswordItem controller", func() { for k, v := range testData { item.Fields = append(item.Fields, &onepassword.ItemField{Label: k, Value: v}) } - item.Version = version + 1 + item.Version = item1.Version + 1 item.Vault.ID = vaultUUID item.ID = uuid return &item, nil @@ -240,5 +234,193 @@ var _ = Describe("OnePasswordItem controller", func() { return k8sClient.Get(ctx, key, f) }, timeout, interval).ShouldNot(Succeed()) }) + + It("Should not update K8s secret if OnePasswordItem Version or VaultPath has not changed", func() { + ctx := context.Background() + spec := onepasswordv1.OnePasswordItemSpec{ + ItemPath: item1.Path, + } + + key := types.NamespacedName{ + Name: item1.Name, + Namespace: namespace, + } + + toCreate := &onepasswordv1.OnePasswordItem{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: spec, + } + + By("Creating a new OnePasswordItem successfully") + Expect(k8sClient.Create(ctx, toCreate)).Should(Succeed()) + + item := &onepasswordv1.OnePasswordItem{} + Eventually(func() bool { + err := k8sClient.Get(ctx, key, item) + return err == nil + }, timeout, interval).Should(BeTrue()) + + By("Creating the K8s secret successfully") + createdSecret := &v1.Secret{} + Eventually(func() bool { + err := k8sClient.Get(ctx, key, createdSecret) + return err == nil + }, timeout, interval).Should(BeTrue()) + Expect(createdSecret.Data).Should(Equal(item1.SecretData)) + + By("Updating OnePasswordItem type") + Eventually(func() bool { + err1 := k8sClient.Get(ctx, key, item) + if err1 != nil { + return false + } + item.Type = string(v1.SecretTypeOpaque) + err := k8sClient.Update(ctx, item) + return err == nil + }, timeout, interval).Should(BeTrue()) + + By("Reading K8s secret") + secret := &v1.Secret{} + Eventually(func() bool { + err := k8sClient.Get(ctx, key, secret) + return err == nil + }, timeout, interval).Should(BeTrue()) + Expect(secret.Data).Should(Equal(item1.SecretData)) + }) + + It("Should create custom K8s Secret type using OnePasswordItem", func() { + const customType = "CustomType" + ctx := context.Background() + spec := onepasswordv1.OnePasswordItemSpec{ + ItemPath: item1.Path, + } + + key := types.NamespacedName{ + Name: "test6", + Namespace: namespace, + } + + toCreate := &onepasswordv1.OnePasswordItem{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: spec, + Type: customType, + } + + By("Creating a new OnePasswordItem successfully") + Expect(k8sClient.Create(ctx, toCreate)).Should(Succeed()) + + By("Reading K8s secret") + secret := &v1.Secret{} + Eventually(func() bool { + err := k8sClient.Get(ctx, key, secret) + if err != nil { + return false + } + return true + }, timeout, interval).Should(BeTrue()) + Expect(secret.Type).Should(Equal(v1.SecretType(customType))) + }) + }) + + Context("Unhappy path", func() { + It("Should throw an error if K8s Secret type is changed", func() { + ctx := context.Background() + spec := onepasswordv1.OnePasswordItemSpec{ + ItemPath: item1.Path, + } + + key := types.NamespacedName{ + Name: "test7", + Namespace: namespace, + } + + toCreate := &onepasswordv1.OnePasswordItem{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: spec, + } + + By("Creating a new OnePasswordItem successfully") + Expect(k8sClient.Create(ctx, toCreate)).Should(Succeed()) + + By("Reading K8s secret") + secret := &v1.Secret{} + Eventually(func() bool { + err := k8sClient.Get(ctx, key, secret) + if err != nil { + return false + } + return true + }, timeout, interval).Should(BeTrue()) + + By("Failing to update K8s secret") + Eventually(func() bool { + secret.Type = v1.SecretTypeBasicAuth + err := k8sClient.Update(ctx, secret) + if err != nil { + return false + } + return true + }, timeout, interval).Should(BeFalse()) + }) + + When("OnePasswordItem resource name contains `_`", func() { + It("Should fail creating a OnePasswordItem resource", func() { + ctx := context.Background() + spec := onepasswordv1.OnePasswordItemSpec{ + ItemPath: item1.Path, + } + + key := types.NamespacedName{ + Name: "invalid_name", + Namespace: namespace, + } + + toCreate := &onepasswordv1.OnePasswordItem{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: spec, + } + + By("Creating a new OnePasswordItem") + Expect(k8sClient.Create(ctx, toCreate)).To(HaveOccurred()) + + }) + }) + + When("OnePasswordItem resource name contains capital letters", func() { + It("Should fail creating a OnePasswordItem resource", func() { + ctx := context.Background() + spec := onepasswordv1.OnePasswordItemSpec{ + ItemPath: item1.Path, + } + + key := types.NamespacedName{ + Name: "invalidName", + Namespace: namespace, + } + + toCreate := &onepasswordv1.OnePasswordItem{ + ObjectMeta: metav1.ObjectMeta{ + Name: key.Name, + Namespace: key.Namespace, + }, + Spec: spec, + } + + By("Creating a new OnePasswordItem") + Expect(k8sClient.Create(ctx, toCreate)).To(HaveOccurred()) + }) + }) }) }) diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 1d1a5c5..6c6b632 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -26,7 +26,6 @@ package controllers import ( "context" - "fmt" "path/filepath" "regexp" "testing" @@ -52,25 +51,12 @@ import ( // These tests use Ginkgo (BDD-style Go testing framework). Refer to // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. -var ( - cfg *rest.Config - k8sClient client.Client - testEnv *envtest.Environment - ctx context.Context - cancel context.CancelFunc - - itemData = map[string]string{ - "username": username, - "password": password, - } -) - const ( - vaultId = "hfnjvi6aymbsnfc2xeeoheizda" - itemId = "nwrhuano7bcwddcviubpp4mhfq" username = "test-user" password = "QmHumKc$mUeEem7caHtbaBaJ" - version = 123 + + username2 = "test-user2" + password2 = "4zotzqDqXKasLFT2jzTs" annotationRegExpString = "^operator.1password.io\\/[a-zA-Z\\.]+" ) @@ -78,7 +64,6 @@ const ( // Define utility constants for object names and testing timeouts/durations and intervals. const ( namespace = "default" - ItemName = "test-item" timeout = time.Second * 10 duration = time.Second * 10 @@ -86,16 +71,51 @@ const ( ) var ( + cfg *rest.Config + k8sClient client.Client + testEnv *envtest.Environment + ctx context.Context + cancel context.CancelFunc onePasswordItemReconciler *OnePasswordItemReconciler deploymentReconciler *DeploymentReconciler - itemPath = fmt.Sprintf("vaults/%v/items/%v", vaultId, itemId) - expectedSecretData = map[string][]byte{ - "password": []byte(password), - "username": []byte(username), + item1 = &TestItem{ + Name: "test-item", + Version: 123, + Path: "vaults/hfnjvi6aymbsnfc2xeeoheizda/items/nwrhuano7bcwddcviubpp4mhfq", + Data: map[string]string{ + "username": username, + "password": password, + }, + SecretData: map[string][]byte{ + "password": []byte(password), + "username": []byte(username), + }, + } + + item2 = &TestItem{ + Name: "test-item2", + Path: "vaults/hfnjvi6aymbsnfc2xeeoheizd2/items/nwrhuano7bcwddcviubpp4mhf2", + Version: 456, + Data: map[string]string{ + "username": username2, + "password": password2, + }, + SecretData: map[string][]byte{ + "password": []byte(password2), + "username": []byte(username2), + }, } ) +type TestItem struct { + Name string + Version int + Path string + Data map[string]string + SecretData map[string][]byte +} + func TestAPIs(t *testing.T) { RegisterFailHandler(Fail)