diff --git a/Dockerfile b/Dockerfile index d8ce770..14d6fb7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,6 +8,9 @@ WORKDIR /workspace COPY go.mod go.mod COPY go.sum go.sum +# Copy the testhelper module (needed for replace directive) +COPY pkg/testhelper/ pkg/testhelper/ + # Download dependencies RUN go mod download diff --git a/docs/testing.md b/docs/testing.md index 9380407..cd04575 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -16,7 +16,5 @@ 1. [Install `kind`](https://kind.sigs.k8s.io/docs/user/quick-start/#installing-with-a-package-manager) to spin up local Kubernetes cluster. 2. `export OP_CONNECT_TOKEN=` 3. `export OP_SERVICE_ACCOUNT_TOKEN=` -4. `make test-e2e` -5. Put `1password-credentials.json` into project root. - -**Run**: `make test-e2e` +4. Put `1password-credentials.json` into project root. +5. `make test-e2e` diff --git a/go.mod b/go.mod index bcb22b7..2b6c9dc 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,18 @@ go 1.24.0 toolchain go1.24.5 +// In main go.mod, add this replace directive: +replace github.com/1Password/onepassword-operator/pkg/testhelper => ./pkg/testhelper + require ( github.com/1Password/connect-sdk-go v1.5.3 + github.com/1Password/onepassword-operator/pkg/testhelper v0.0.0-00010101000000-000000000000 github.com/1password/onepassword-sdk-go v0.3.1 github.com/go-logr/logr v1.4.2 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 github.com/stretchr/testify v1.10.0 k8s.io/api v0.33.0 - k8s.io/apiextensions-apiserver v0.33.0 k8s.io/apimachinery v0.33.0 k8s.io/client-go v0.33.0 k8s.io/kubectl v0.29.0 @@ -103,6 +106,7 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apiextensions-apiserver v0.33.0 // indirect k8s.io/apiserver v0.33.0 // indirect k8s.io/component-base v0.33.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect diff --git a/pkg/testhelper/README.md b/pkg/testhelper/README.md new file mode 100644 index 0000000..cc161b1 --- /dev/null +++ b/pkg/testhelper/README.md @@ -0,0 +1,115 @@ +# OnePassword Operator Test Helper + +This is a standalone Go module that provides testing utilities for Kubernetes operators, specifically designed for testing OnePassword operators but can be used for any Kubernetes operator testing. + +## Installation + +To use this module in your project, add it as a dependency: + +```bash +go get github.com/1Password/onepassword-operator/pkg/testhelper@ +``` + +### Basic Setup + +```go +import ( + "github.com/1Password/onepassword-operator/pkg/testhelper/kube" + "github.com/1Password/onepassword-operator/pkg/testhelper/defaults" +) + +// Create a kube client for testing +kubeClient := kube.NewKubeClient(&kube.Config{ + Namespace: "default", + ManifestsDir: "manifests", + TestConfig: &kube.TestConfig{ + Timeout: defaults.E2ETimeout, + Interval: defaults.E2EInterval, + }, + CRDs: []string{ + "path/to/your/crd.yaml", + }, +}) +``` + +### Working with Secrets + +```go +// Create a secret from environment variable +secret := kubeClient.Secret("my-secret") +secret.CreateFromEnvVar(ctx, "MY_ENV_VAR") + +// Create a secret from file +data := []byte("secret content") +secret.CreateFromFile(ctx, "filename", data) + +// Check if secret exists +secret.CheckIfExists(ctx) + +// Get secret +secretObj := secret.Get(ctx) +``` + +### Working with Deployments + +```go +deployment := kubeClient.Deployment("my-deployment") + +// Read environment variable from deployment +envVar := deployment.ReadEnvVar(ctx, "MY_ENV_VAR") + +// Patch environment variables +deployment.PatchEnvVars(ctx, + []corev1.EnvVar{ + {Name: "NEW_VAR", Value: "new_value"}, + }, + []string{"OLD_VAR"}, // variables to remove +) + +// Wait for deployment rollout +deployment.WaitDeploymentRolledOut(ctx) +``` + +### Working with Pods + +```go +pod := kubeClient.Pod(map[string]string{"app": "my-app"}) +pod.WaitingForRunningPod(ctx) +``` + +### Working with Namespaces + +```go +namespace := kubeClient.Namespace("my-namespace") +namespace.LabelNamespace(ctx, map[string]string{ + "environment": "test", +}) +``` + +### System Utilities + +```go +import "github.com/1Password/onepassword-operator/pkg/testhelper/system" + +// Run shell commands +output, err := system.Run("kubectl", "get", "pods") + +// Get project root directory +rootDir, err := system.GetProjectRoot() + +// Replace files +err := system.ReplaceFile("source.yaml", "dest.yaml") +``` + +### Kind Integration + +```go +import "github.com/1Password/onepassword-operator/pkg/testhelper/kind" + +// Load Docker image to Kind cluster +kind.LoadImageToKind("my-image:latest") +``` + +## License + +MIT License - see the main project LICENSE file for details. diff --git a/pkg/testhelper/go.mod b/pkg/testhelper/go.mod new file mode 100644 index 0000000..0b4c861 --- /dev/null +++ b/pkg/testhelper/go.mod @@ -0,0 +1,59 @@ +module github.com/1Password/onepassword-operator/pkg/testhelper + +go 1.24.0 + +toolchain go1.24.5 + +require ( + github.com/onsi/ginkgo/v2 v2.22.0 + github.com/onsi/gomega v1.36.1 + k8s.io/api v0.33.0 + k8s.io/apiextensions-apiserver v0.33.0 + k8s.io/apimachinery v0.33.0 + k8s.io/client-go v0.33.0 + sigs.k8s.io/controller-runtime v0.21.0 +) + +require ( + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.12.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/net v0.41.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sys v0.33.0 // indirect + golang.org/x/term v0.32.0 // indirect + golang.org/x/text v0.26.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.33.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/pkg/testhelper/kube/kube.go b/pkg/testhelper/kube/kube.go index 77bbe68..e8ef275 100644 --- a/pkg/testhelper/kube/kube.go +++ b/pkg/testhelper/kube/kube.go @@ -27,7 +27,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/apiutil" - apiv1 "github.com/1Password/onepassword-operator/api/v1" "github.com/1Password/onepassword-operator/pkg/testhelper/defaults" ) @@ -73,7 +72,6 @@ func NewKubeClient(config *Config) *Kube { scheme := runtime.NewScheme() utilruntime.Must(corev1.AddToScheme(scheme)) utilruntime.Must(appsv1.AddToScheme(scheme)) - utilruntime.Must(apiv1.AddToScheme(scheme)) // add OnePasswordItem to scheme kubernetesClient, err := client.New(restConfig, client.Options{ Scheme: scheme,