diff --git a/.dockerignore b/.dockerignore index 00b5d1a..3683f8d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,4 +2,6 @@ # Ignore build and test binaries. bin/ -bundle.Dockerfile \ No newline at end of file +bundle.Dockerfile + +kind-kubeconfig diff --git a/.gitignore b/.gitignore index 7166688..c8a59ad 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ Dockerfile.cross **/__debug_* bundle* + +kind-kubeconfig diff --git a/Makefile b/Makefile index 943a168..d30792c 100644 --- a/Makefile +++ b/Makefile @@ -329,3 +329,88 @@ catalog-build: opm ## Build a catalog image. .PHONY: catalog-push catalog-push: ## Push a catalog image. $(MAKE) docker-push IMG=$(CATALOG_IMG) + + +##@ E2E + +# kind +KIND_VERSION ?= v0.22.0 + +KIND_KUBECONFIG ?= ./kind-kubeconfig +KIND_CLUSTER_NAME ?= listener-operator + +.PHONY: kind +KIND = $(LOCALBIN)/kind +kind: ## Download kind locally if necessary. +ifeq (,$(shell which $(KIND))) +ifeq (,$(shell which kind 2>/dev/null)) + @{ \ + set -e ;\ + go install sigs.k8s.io/kind@$(KIND_VERSION) ;\ + } +KIND = $(GOBIN)/bin/kind +else +KIND = $(shell which kind) +endif +endif + +OLM_VERSION ?= v0.27.0 + +# Create a kind cluster, install ingress-nginx, and wait for it to be available. +.PHONY: kind-create +kind-create: kind ## Create a kind cluster. + $(KIND) create cluster --config test/e2e/kind.yaml --name $(KIND_CLUSTER_NAME) --kubeconfig $(KIND_KUBECONFIG) --wait 120s + # make kind-setup KUBECONFIG=$(KIND_KUBECONFIG) + +.PHONY: kind-setup +kind-setup: kind ## setup kind cluster base environment + @echo "\nSetup kind cluster base environment, install ingress-nginx and OLM" + kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml + kubectl -n ingress-nginx wait deployment ingress-nginx-controller --for=condition=available --timeout=300s + curl -sSL https://github.com/operator-framework/operator-lifecycle-manager/releases/download/$(OLM_VERSION)/install.sh | bash -s $(OLM_VERSION) + +.PHONY: kind-delete +kind-delete: kind ## Delete a kind cluster. + $(KIND) delete cluster --name $(KIND_CLUSTER_NAME) + +# chainsaw + +CHAINSAW_VERSION ?= v0.1.8 + +.PHONY: chainsaw +CHAINSAW = $(LOCALBIN)/chainsaw +chainsaw: ## Download chainsaw locally if necessary. +ifeq (,$(shell which $(CHAINSAW))) +ifeq (,$(shell which chainsaw 2>/dev/null)) + @{ \ + set -e ;\ + go install github.com/kyverno/chainsaw@$(CHAINSAW_VERSION) ;\ + } +CHAINSAW = $(GOBIN)/chainsaw +else +CHAINSAW = $(shell which chainsaw) +endif +endif + +# chainsaw setup logical +# - Build the operator docker image +# - Load the operator docker image into the kind cluster. When create +# operator deployment, it will use the image in the kind cluster. +# - Rebuild the bundle. If override VERSION / REGISTRY or other variables, +# we need to rebuild the bundle to use the new image, or other changes. +.PHONY: chainsaw-setup +chainsaw-setup: manifests kustomize ## Run the chainsaw setup + @echo "\nSetup chainsaw test environment" + make docker-build + make csi-docker-build + $(KIND) --name $(KIND_CLUSTER_NAME) load docker-image $(IMG) $(CSIDRIVER_IMG) + make deploy KUBECONFIG=$(KIND_KUBECONFIG) + +.PHONY: chainsaw-test +chainsaw-test: chainsaw ## Run the chainsaw test + $(CHAINSAW) test --cluster cluster-1=$(KIND_KUBECONFIG) --test-dir ./test/e2e --assert-timeout 120s --cleanup-timeout 120s --delete-timeout 120s + + +.PHONY: chainsaw-cleanup +chainsaw-cleanup: manifests kustomize ## Run the chainsaw cleanup + make undeploy KUBECONFIG=$(KIND_KUBECONFIG) diff --git a/test/e2e/kind.yaml b/test/e2e/kind.yaml new file mode 100644 index 0000000..8622c51 --- /dev/null +++ b/test/e2e/kind.yaml @@ -0,0 +1,17 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + extraPortMappings: + - containerPort: 80 + hostPort: 18080 + protocol: TCP + - containerPort: 443 + hostPort: 18443 + protocol: TCP diff --git a/test/e2e/sample/00-assert.yaml b/test/e2e/sample/00-assert.yaml new file mode 100644 index 0000000..4cb39be --- /dev/null +++ b/test/e2e/sample/00-assert.yaml @@ -0,0 +1,7 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: listenercsi-sample-csi +status: + (numberReady >= `1`): true + diff --git a/test/e2e/sample/00-listenercsi.yaml b/test/e2e/sample/00-listenercsi.yaml new file mode 100644 index 0000000..15c51be --- /dev/null +++ b/test/e2e/sample/00-listenercsi.yaml @@ -0,0 +1,35 @@ +apiVersion: listeners.zncdata.dev/v1alpha1 +kind: ListenerCSI +metadata: + labels: + app.kubernetes.io/name: listenercsi + app.kubernetes.io/instance: listenercsi-sample + app.kubernetes.io/part-of: listener-operator + app.kubernetes.io/managed-by: kustomize + app.kubernetes.io/created-by: listener-operator + name: listenercsi-sample +spec: + csiDriver: + repository: quay.io/zncdata/listener-csi-driver + tag: 0.0.1 + pullPolicy: IfNotPresent + logging: + level: "10" + nodeDriverRegistrar: + repository: registry.k8s.io/sig-storage/csi-node-driver-registrar + tag: v2.8.0 + pullPolicy: IfNotPresent + logging: + level: "10" + csiProvisioner: + repository: registry.k8s.io/sig-storage/csi-provisioner + tag: v3.5.0 + pullPolicy: IfNotPresent + logging: + level: "10" + livenessProbe: + repository: registry.k8s.io/sig-storage/livenessprobe + tag: v2.11.0 + pullPolicy: IfNotPresent + logging: + level: "10" diff --git a/test/e2e/sample/01-assert.yaml b/test/e2e/sample/01-assert.yaml new file mode 100644 index 0000000..91f5ea7 --- /dev/null +++ b/test/e2e/sample/01-assert.yaml @@ -0,0 +1,12 @@ + +apiVersion: v1 +kind: Pod +metadata: + name: nginx-pod +status: + phase: Running + containerStatuses: + - name: nginx-pod + ready: true + restartCount: 0 + started: true diff --git a/test/e2e/sample/01-pod.yaml b/test/e2e/sample/01-pod.yaml new file mode 100644 index 0000000..59964ee --- /dev/null +++ b/test/e2e/sample/01-pod.yaml @@ -0,0 +1,38 @@ +apiVersion: v1 +kind: Pod +metadata: + name: nginx-pod + labels: + name: nginx-pod +spec: + containers: + - name: nginx-pod + image: nginx:1.25 + resources: + limits: + memory: "128Mi" + cpu: "500m" + ports: + - containerPort: 80 + name: http + volumeMounts: + - name: listener + mountPath: /opt/zncdata/ + readinessProbe: + exec: + command: ["sh", "-c", "ls /opt/zncdata/addresses | grep -q ."] + initialDelaySeconds: 1 + periodSeconds: 5 + volumes: + - name: listener + ephemeral: + volumeClaimTemplate: + metadata: + annotations: + listeners.zncdata.dev/listener-class: cluster-internal + spec: + accessModes: ["ReadWriteOnce"] + storageClassName: listeners.zncdata.dev + resources: + requests: + storage: 1Mi