package kube import ( "encoding/base64" "os" "path/filepath" "time" //nolint:staticcheck // ST1001 . "github.com/onsi/ginkgo/v2" //nolint:staticcheck // ST1001 . "github.com/onsi/gomega" "github.com/1Password/onepassword-operator/pkg/testhelper/defaults" "github.com/1Password/onepassword-operator/pkg/testhelper/system" ) // CreateSecretFromEnvVar creates a kubernetes secret from an environment variable func CreateSecretFromEnvVar(envVar, secretName string) { By("Creating '" + secretName + "' secret") value, _ := os.LookupEnv(envVar) Expect(value).NotTo(BeEmpty()) _, err := system.Run("kubectl", "create", "secret", "generic", secretName, "--from-literal=token="+value) Expect(err).NotTo(HaveOccurred()) } // CreateSecretFromFile creates a kubernetes secret from a file func CreateSecretFromFile(fileName, secretName string) { By("Creating '" + secretName + "' secret from file") _, err := system.Run("kubectl", "create", "secret", "generic", secretName, "--from-file="+fileName) Expect(err).NotTo(HaveOccurred()) } // CreateOpCredentialsSecret creates a kubernetes secret from 1password-credentials.json file // encodes it in base64 and saves it to op-session file func CreateOpCredentialsSecret() { rootDir, err := system.GetProjectRoot() Expect(err).NotTo(HaveOccurred()) credentialsFilePath := filepath.Join(rootDir, "1password-credentials.json") data, err := os.ReadFile(credentialsFilePath) Expect(err).NotTo(HaveOccurred()) encoded := base64.RawURLEncoding.EncodeToString(data) // create op-session file in project root sessionFilePath := filepath.Join(rootDir, "op-session") err = os.WriteFile(sessionFilePath, []byte(encoded), 0o600) Expect(err).NotTo(HaveOccurred()) CreateSecretFromFile("op-session", "op-credentials") } // DeleteSecret deletes a kubernetes secret func DeleteSecret(name string) { By("Deleting '" + name + "' secret") _, err := system.Run("kubectl", "delete", "secret", name, "--ignore-not-found=true") Expect(err).NotTo(HaveOccurred()) } // CheckSecretExists checks if a kubernetes secret exists func CheckSecretExists(name string) { By("Checking '" + name + "' secret exists") Eventually(func(g Gomega) { output, err := system.Run("kubectl", "get", "secret", name, "-o", "jsonpath={.metadata.name}") g.Expect(err).NotTo(HaveOccurred()) g.Expect(output).To(Equal(name)) }, defaults.E2ETimeout, defaults.E2EInterval).Should(Succeed()) } func ReadingSecretData(name, key string) (string, error) { return system.Run("kubectl", "get", "secret", name, "-o", "jsonpath={.data."+key+"}") } func CheckSecretPasswordWasUpdated(name, oldPassword string) { By("Checking '" + name + "' secret password was updated") Eventually(func(g Gomega) { newPassword, err := ReadingSecretData(name, "password") g.Expect(err).NotTo(HaveOccurred()) g.Expect(newPassword).NotTo(Equal(oldPassword)) }, defaults.E2ETimeout, defaults.E2EInterval).Should(Succeed()) } // Apply applies a kubernetes manifest file func Apply(yamlPath string) { _, err := system.Run("kubectl", "apply", "-f", yamlPath) Expect(err).NotTo(HaveOccurred()) } // SetContextNamespace sets the current kubernetes context namespace func SetContextNamespace(namespace string) { By("Set namespace to " + namespace) _, err := system.Run("kubectl", "config", "set-context", "--current", "--namespace="+namespace) Expect(err).NotTo(HaveOccurred()) } // PatchOperatorToUseServiceAccount sets `OP_SERVICE_ACCOUNT_TOKEN` env variable var PatchOperatorToUseServiceAccount = withOperatorRestart(func() { By("patching the operator deployment with service account token") _, err := system.Run( "kubectl", "patch", "deployment", "onepassword-connect-operator", "--type=json", `-p=[{"op":"replace","path":"/spec/template/spec/containers/0/env","value":[ {"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", }, }, }, {"name":"MANAGE_CONNECT","value":"false"} ]}]`, ) Expect(err).NotTo(HaveOccurred()) }) // withOperatorRestart is a helper function that restarts the operator deployment func withOperatorRestart(operation func()) func() { return func() { operation() _, err := system.Run("kubectl", "rollout", "status", "deployment/onepassword-connect-operator", "-n", "default", "--timeout=120s") Expect(err).NotTo(HaveOccurred()) By("Waiting for the operator pod to be 'Running'") Eventually(func(g Gomega) { output, err := system.Run("kubectl", "get", "pods", "-l", "name=onepassword-connect-operator", "-o", "jsonpath={.items[0].status.phase}") g.Expect(err).NotTo(HaveOccurred()) g.Expect(output).To(ContainSubstring("Running")) }, 120*time.Second, 1*time.Second).Should(Succeed()) } }