mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-22 15:38:06 +00:00
Move testhelper
package to pkg
so it can be installed as dependency in secrets injector repo
This commit is contained in:
8
pkg/testhelper/defaults/defaults.go
Normal file
8
pkg/testhelper/defaults/defaults.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package defaults
|
||||
|
||||
import "time"
|
||||
|
||||
const (
|
||||
E2EInterval = 1 * time.Second
|
||||
E2ETimeout = 1 * time.Minute
|
||||
)
|
23
pkg/testhelper/kind/kind.go
Normal file
23
pkg/testhelper/kind/kind.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package kind
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
//nolint:staticcheck // ST1001
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
//nolint:staticcheck // ST1001
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/1Password/onepassword-operator/pkg/testhelper/system"
|
||||
)
|
||||
|
||||
// LoadImageToKind loads a local docker image to the Kind cluster
|
||||
func LoadImageToKind(imageName string) {
|
||||
By("loading the operator image on Kind")
|
||||
clusterName := "kind"
|
||||
if value, ok := os.LookupEnv("KIND_CLUSTER"); ok {
|
||||
clusterName = value
|
||||
}
|
||||
_, err := system.Run("kind", "load", "docker-image", imageName, "--name", clusterName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
117
pkg/testhelper/kube/kube.go
Normal file
117
pkg/testhelper/kube/kube.go
Normal file
@@ -0,0 +1,117 @@
|
||||
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"
|
||||
)
|
||||
|
||||
func CreateSecretFromEnvVar(envVar, secretName string) {
|
||||
value, _ := os.LookupEnv(envVar)
|
||||
Expect(value).NotTo(BeEmpty())
|
||||
|
||||
_, err := system.Run("kubectl", "create", "secret", "generic", secretName, "--from-literal=token="+value)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
func CreateSecretFromFile(fileName, secretName string) {
|
||||
_, err := system.Run("kubectl", "create", "secret", "generic", secretName, "--from-file="+fileName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
func DeleteSecret(name string) {
|
||||
_, err := system.Run("kubectl", "delete", "secret", name, "--ignore-not-found=true")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
func CheckSecretExists(name string) {
|
||||
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 Apply(yamlPath string) {
|
||||
_, err := system.Run("kubectl", "apply", "-f", yamlPath)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
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())
|
||||
})
|
||||
|
||||
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())
|
||||
}
|
||||
}
|
50
pkg/testhelper/operator/operator.go
Normal file
50
pkg/testhelper/operator/operator.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package operator
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
//nolint:staticcheck // ST1001
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
//nolint:staticcheck // ST1001
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/1Password/onepassword-operator/pkg/testhelper/system"
|
||||
)
|
||||
|
||||
func BuildOperatorImage() {
|
||||
By("building the Operator image")
|
||||
_, err := system.Run("make", "docker-build")
|
||||
ExpectWithOffset(1, err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
// DeployOperator deploys the Onepassword Operator in the default namespace.
|
||||
// It waits for the operator pod to be in 'Running' state.
|
||||
// All the resources created using manifests in `config/` dir.
|
||||
// To make the operator use Connect or Service Accounts, patch `config/manager/manager.yaml`
|
||||
func DeployOperator() {
|
||||
By("deploying the Operator")
|
||||
_, err := system.Run("make", "deploy")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
func WaitingForOperatorPod() {
|
||||
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"))
|
||||
}, 30*time.Second, 1*time.Second).Should(Succeed())
|
||||
}
|
||||
|
||||
func WaitingForConnectPod() {
|
||||
By("Waiting for the Connect pod to be 'Running'")
|
||||
Eventually(func(g Gomega) {
|
||||
output, err := system.Run("kubectl", "get", "pods",
|
||||
"-l", "app=onepassword-connect",
|
||||
"-o", "jsonpath={.items[0].status.phase}")
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
g.Expect(output).To(ContainSubstring("Running"))
|
||||
}, 30*time.Second, 1*time.Second).Should(Succeed())
|
||||
}
|
53
pkg/testhelper/system/system.go
Normal file
53
pkg/testhelper/system/system.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Run executes the provided command within this context
|
||||
func Run(name string, args ...string) (string, error) {
|
||||
cmd := exec.Command(name, args...)
|
||||
|
||||
rootDir, err := GetProjectRoot()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Command will run from project root
|
||||
cmd.Dir = rootDir
|
||||
|
||||
command := strings.Join(cmd.Args, " ")
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
return string(output), fmt.Errorf("%s failed with error: (%v) %s", command, err, string(output))
|
||||
}
|
||||
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
func GetProjectRoot() (string, error) {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for {
|
||||
// check if go.mod exists in current dir
|
||||
modFile := filepath.Join(dir, "go.mod")
|
||||
if _, err := os.Stat(modFile); err == nil {
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
// move one level up
|
||||
parent := filepath.Dir(dir)
|
||||
if parent == dir {
|
||||
// reached filesystem root
|
||||
return "", fmt.Errorf("project root not found (no go.mod)")
|
||||
}
|
||||
dir = parent
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user