diff --git a/pkg/testhelper/system/system.go b/pkg/testhelper/system/system.go index bded147..afc0a59 100644 --- a/pkg/testhelper/system/system.go +++ b/pkg/testhelper/system/system.go @@ -2,6 +2,7 @@ package system import ( "fmt" + "io" "os" "os/exec" "path/filepath" @@ -51,3 +52,32 @@ func GetProjectRoot() (string, error) { dir = parent } } + +func ReplaceFile(src, dst string) error { + rootDir, err := GetProjectRoot() + if err != nil { + return err + } + + // Open the source file + sourceFile, err := os.Open(filepath.Join(rootDir, src)) + if err != nil { + return err + } + defer sourceFile.Close() + + // Create (or overwrite) the destination file + destFile, err := os.Create(filepath.Join(rootDir, dst)) + if err != nil { + return err + } + defer destFile.Close() + + // Copy contents + if _, err = io.Copy(destFile, sourceFile); err != nil { + return err + } + + // Ensure data is written to disk + return destFile.Sync() +} diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 94208e4..4aa5664 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -60,39 +60,42 @@ var _ = Describe("Onepassword Operator e2e", Ordered, func() { kubeClient.Secret("onepassword-service-account-token").CreateFromEnvVar(ctx, "OP_SERVICE_ACCOUNT_TOKEN") kubeClient.Secret("onepassword-service-account-token").CheckIfExists(ctx) + By("Replace manager.yaml") + err = system.ReplaceFile("test/e2e/manifests/manager.yaml", "config/manager/manager.yaml") + Expect(err).NotTo(HaveOccurred()) + _, err = system.Run("make", "deploy") Expect(err).NotTo(HaveOccurred()) kubeClient.Pod(map[string]string{"name": "onepassword-connect-operator"}).WaitingForRunningPod(ctx) }) - Context("Use the operator with Connect", func() { - BeforeAll(func() { - kubeClient.Pod(map[string]string{"app": "onepassword-connect"}).WaitingForRunningPod(ctx) - }) - + Context("Use the operator with Service Account", func() { runCommonTestCases(ctx) }) - Context("Use the operator with Service Account", func() { + Context("Use the operator with Connect", func() { BeforeAll(func() { kubeClient.Deployment("onepassword-connect-operator").PatchEnvVars(ctx, []corev1.EnvVar{ - {Name: "MANAGE_CONNECT", Value: "false"}, + {Name: "MANAGE_CONNECT", Value: "true"}, + {Name: "OP_CONNECT_HOST", Value: "http://onepassword-connect:8080"}, { - Name: "OP_SERVICE_ACCOUNT_TOKEN", + Name: "OP_CONNECT_TOKEN", ValueFrom: &corev1.EnvVarSource{ SecretKeyRef: &corev1.SecretKeySelector{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "onepassword-service-account-token", + Name: "onepassword-token", }, Key: "token", }, }, }, - }, []string{"OP_CONNECT_HOST", "OP_CONNECT_TOKEN"}) + }, []string{"OP_SERVICE_ACCOUNT_TOKEN"}) kubeClient.Secret("login").Delete(ctx) // remove secret crated in previous test kubeClient.Secret("secret-ignored").Delete(ctx) // remove secret crated in previous test kubeClient.Secret("secret-for-update").Delete(ctx) // remove secret crated in previous test + + kubeClient.Pod(map[string]string{"app": "onepassword-connect"}).WaitingForRunningPod(ctx) }) runCommonTestCases(ctx) @@ -101,13 +104,13 @@ var _ = Describe("Onepassword Operator e2e", Ordered, func() { // runCommonTestCases contains test cases that are common to both Connect and Service Account authentication methods. func runCommonTestCases(ctx context.Context) { - It("Should create secret from manifest file", func() { + It("Should create kubernetes secret from manifest file", func() { By("Creating secret `login` from 1Password item") kubeClient.ApplyOnePasswordItem(ctx, "secret.yaml") kubeClient.Secret("login").CheckIfExists(ctx) }) - It("Secret is updated after POOLING_INTERVAL", func() { + It("Kubernetes secret is updated after POOLING_INTERVAL, when updating item in 1Password", func() { itemName := "secret-for-update" secretName := itemName @@ -139,7 +142,7 @@ func runCommonTestCases(ctx context.Context) { }, defaults.E2ETimeout, defaults.E2EInterval).Should(Succeed()) }) - It("1Password item with `ignore-secret` doesn't pull updates to kubernetes secret", func() { + It("1Password item with `ignore-secret` tag doesn't pull updates to kubernetes secret", func() { itemName := "secret-ignored" secretName := itemName diff --git a/test/e2e/manifests/manager.yaml b/test/e2e/manifests/manager.yaml new file mode 100644 index 0000000..d76b0d7 --- /dev/null +++ b/test/e2e/manifests/manager.yaml @@ -0,0 +1,99 @@ +# This manager file is used for e2e tests. +# It will be copied to `config/manager` and be used when deploying the operator in e2e tests +# The purpose of it is to increase e2e tests speed and do not introduce additional changes in original `manager.yaml` + +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: onepassword-connect-operator + app.kubernetes.io/name: namespace + app.kubernetes.io/instance: system + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: onepassword-connect-operator + app.kubernetes.io/part-of: onepassword-connect-operator + app.kubernetes.io/managed-by: kustomize + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: onepassword-connect-operator + namespace: system + labels: + control-plane: controller-manager + app.kubernetes.io/name: deployment + app.kubernetes.io/instance: controller-manager + app.kubernetes.io/component: manager + app.kubernetes.io/created-by: onepassword-connect-operator + app.kubernetes.io/part-of: onepassword-connect-operator + app.kubernetes.io/managed-by: kustomize +spec: + selector: + matchLabels: + name: onepassword-connect-operator + control-plane: onepassword-connect-operator + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + name: onepassword-connect-operator + control-plane: onepassword-connect-operator + spec: + securityContext: + runAsNonRoot: true + containers: + - command: + - /manager + args: + - --leader-elect + - --health-probe-bind-address=:8081 + image: 1password/onepassword-operator:latest + imagePullPolicy: Never + name: manager + env: + - name: OPERATOR_NAME + value: "onepassword-connect-operator" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: WATCH_NAMESPACE + value: "default" + - name: POLLING_INTERVAL + value: "10" + - name: AUTO_RESTART + value: "false" + - name: OP_SERVICE_ACCOUNT_TOKEN + valueFrom: + secretKeyRef: + name: onepassword-service-account-token + key: token + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 512Mi + requests: + cpu: 100m + memory: 128Mi + serviceAccountName: onepassword-connect-operator + terminationGracePeriodSeconds: 10