Kubernetes integration test suite #148
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Operator Integration Test | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| branches: | |
| - main | |
| paths: | |
| - 'gateway/**' | |
| - 'kubernetes/**' | |
| - '.github/workflows/operator-integration-test.yml' | |
| env: | |
| DOCKER_REGISTRY: localhost | |
| VERSION: test | |
| KIND_CLUSTER_NAME: operator-test | |
| jobs: | |
| integration-test: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: '1.23' | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| with: | |
| platforms: linux/amd64,linux/arm64 | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Create Kind cluster | |
| uses: helm/kind-action@v1 | |
| with: | |
| cluster_name: ${{ env.KIND_CLUSTER_NAME }} | |
| wait: 300s | |
| - name: Build Gateway Controller image | |
| run: | | |
| cd gateway/gateway-controller | |
| DOCKER_REGISTRY=${{ env.DOCKER_REGISTRY }} VERSION=${{ env.VERSION }} make build-local | |
| - name: Build Policy Engine image | |
| run: | | |
| cd gateway/policy-engine | |
| DOCKER_REGISTRY=${{ env.DOCKER_REGISTRY }} VERSION=${{ env.VERSION }} make build-local | |
| - name: Build Router image | |
| run: | | |
| cd gateway/router | |
| DOCKER_REGISTRY=${{ env.DOCKER_REGISTRY }} VERSION=${{ env.VERSION }} make build-local | |
| - name: Build Operator image | |
| run: | | |
| cd kubernetes/gateway-operator | |
| IMG=${{ env.DOCKER_REGISTRY }}/gateway-operator:${{ env.VERSION }} make docker-build | |
| - name: Build Mock JWKS image | |
| run: | | |
| cd tests/mock-servers/mock-jwks | |
| docker build -t ${{ env.DOCKER_REGISTRY }}/mock-jwks:${{ env.VERSION }} . | |
| - name: Load images into Kind | |
| run: | | |
| kind load docker-image ${{ env.DOCKER_REGISTRY }}/gateway-controller:${{ env.VERSION }} --name ${{ env.KIND_CLUSTER_NAME }} | |
| kind load docker-image ${{ env.DOCKER_REGISTRY }}/policy-engine:${{ env.VERSION }} --name ${{ env.KIND_CLUSTER_NAME }} | |
| kind load docker-image ${{ env.DOCKER_REGISTRY }}/gateway-router:${{ env.VERSION }} --name ${{ env.KIND_CLUSTER_NAME }} | |
| kind load docker-image ${{ env.DOCKER_REGISTRY }}/gateway-operator:${{ env.VERSION }} --name ${{ env.KIND_CLUSTER_NAME }} | |
| kind load docker-image ${{ env.DOCKER_REGISTRY }}/mock-jwks:${{ env.VERSION }} --name ${{ env.KIND_CLUSTER_NAME }} | |
| - name: Deploy OCI Registry (HTTP) | |
| run: | | |
| # Create namespace | |
| kubectl create namespace registry | |
| # Deploy registry without TLS (plain HTTP for testing) | |
| cat <<EOF | kubectl apply -f - | |
| apiVersion: apps/v1 | |
| kind: Deployment | |
| metadata: | |
| name: registry | |
| namespace: registry | |
| spec: | |
| replicas: 1 | |
| selector: | |
| matchLabels: | |
| app: registry | |
| template: | |
| metadata: | |
| labels: | |
| app: registry | |
| spec: | |
| containers: | |
| - name: registry | |
| image: registry:2 | |
| ports: | |
| - containerPort: 5000 | |
| --- | |
| apiVersion: v1 | |
| kind: Service | |
| metadata: | |
| name: registry | |
| namespace: registry | |
| spec: | |
| selector: | |
| app: registry | |
| ports: | |
| - port: 5000 | |
| targetPort: 5000 | |
| EOF | |
| kubectl wait --for=condition=available deployment/registry -n registry --timeout=120s | |
| kubectl wait --for=condition=ready pod -l app=registry -n registry --timeout=120s | |
| - name: Package and push Gateway Helm chart to OCI Registry | |
| run: | | |
| cd kubernetes/helm/gateway-helm-chart | |
| helm package . --version 0.0.0-test | |
| # Port forward registry to push chart (plain HTTP) | |
| kubectl port-forward svc/registry -n registry 5000:5000 & | |
| sleep 5 | |
| # Push chart to OCI registry (plain HTTP, use insecure flag) | |
| helm push gateway-0.0.0-test.tgz oci://localhost:5000/charts --plain-http | |
| # Kill port forward | |
| pkill -f "kubectl port-forward.*registry" || true | |
| - name: Deploy mock httpbin backend | |
| run: | | |
| cat <<EOF | kubectl apply -f - | |
| apiVersion: apps/v1 | |
| kind: Deployment | |
| metadata: | |
| name: httpbin | |
| namespace: default | |
| spec: | |
| replicas: 1 | |
| selector: | |
| matchLabels: | |
| app: httpbin | |
| template: | |
| metadata: | |
| labels: | |
| app: httpbin | |
| spec: | |
| containers: | |
| - name: httpbin | |
| image: kennethreitz/httpbin:latest | |
| ports: | |
| - containerPort: 80 | |
| --- | |
| apiVersion: v1 | |
| kind: Service | |
| metadata: | |
| name: httpbin | |
| namespace: default | |
| spec: | |
| selector: | |
| app: httpbin | |
| ports: | |
| - port: 80 | |
| targetPort: 80 | |
| EOF | |
| kubectl wait --for=condition=ready pod -l app=httpbin --timeout=120s | |
| - name: Deploy Mock JWKS Service | |
| run: | | |
| cat <<EOF | kubectl apply -f - | |
| apiVersion: apps/v1 | |
| kind: Deployment | |
| metadata: | |
| name: mock-jwks | |
| namespace: default | |
| spec: | |
| replicas: 1 | |
| selector: | |
| matchLabels: | |
| app: mock-jwks | |
| template: | |
| metadata: | |
| labels: | |
| app: mock-jwks | |
| spec: | |
| containers: | |
| - name: mock-jwks | |
| image: ${{ env.DOCKER_REGISTRY }}/mock-jwks:${{ env.VERSION }} | |
| ports: | |
| - containerPort: 8080 | |
| --- | |
| apiVersion: v1 | |
| kind: Service | |
| metadata: | |
| name: mock-jwks | |
| namespace: default | |
| spec: | |
| selector: | |
| app: mock-jwks | |
| ports: | |
| - port: 8080 | |
| targetPort: 8080 | |
| EOF | |
| kubectl wait --for=condition=ready pod -l app=mock-jwks --timeout=120s | |
| - name: Install cert-manager | |
| run: | | |
| helm upgrade --install cert-manager oci://quay.io/jetstack/charts/cert-manager \ | |
| --version v1.17.2 \ | |
| --namespace cert-manager \ | |
| --create-namespace \ | |
| --set crds.enabled=true \ | |
| --wait --timeout 5m | |
| - name: Run Operator Integration Tests | |
| run: | | |
| set -o pipefail | |
| cd kubernetes/it | |
| echo "Running Cucumber integration tests..." | |
| GOWORK=off go run ./cmd/... 2>&1 | tee test-output.log | |
| env: | |
| # Configuration for the test suite | |
| DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }} | |
| IMAGE_TAG: ${{ env.VERSION }} | |
| OPERATOR_CHART_PATH: ${{ github.workspace }}/kubernetes/helm/operator-helm-chart | |
| GATEWAY_CHART_PATH: ${{ github.workspace }}/kubernetes/helm/gateway-helm-chart | |
| GATEWAY_CHART_NAME: oci://registry.registry.svc.cluster.local:5000/charts/gateway | |
| GATEWAY_CHART_VERSION: 0.0.0-test | |
| - name: Upload test results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: integration-test-results | |
| path: kubernetes/it/test-output.log | |
| - name: Debug on failure - Dump logs | |
| if: failure() | |
| run: | | |
| echo "=== Operator Logs ===" | |
| kubectl logs -n operator -l app.kubernetes.io/name=gateway-operator --tail=200 || true | |
| echo "" | |
| echo "=== Scoped Operator Logs ===" | |
| kubectl logs -n scoped-test -l app.kubernetes.io/name=gateway-operator --tail=200 || true | |
| echo "" | |
| echo "=== Gateway Status ===" | |
| kubectl describe gateway test-gateway || true | |
| echo "" | |
| echo "=== Scoped Gateway Status ===" | |
| kubectl describe gateway scoped-gateway -n scoped-test || true | |
| echo "" | |
| echo "=== RestApi Status ===" | |
| kubectl describe restapi test-api || true | |
| echo "" | |
| echo "=== Scoped RestApi Status ===" | |
| kubectl describe restapi scoped-api -n scoped-test || true | |
| echo "" | |
| echo "=== All Pods Description ===" | |
| kubectl describe pods --all-namespaces || true | |
| echo "" | |
| echo "=== Gateway Controller Logs ===" | |
| kubectl logs -l app.kubernetes.io/component=controller --tail=200 || true | |
| echo "" | |
| echo "=== Scoped Gateway Controller Logs ===" | |
| kubectl logs -n scoped-test -l app.kubernetes.io/component=controller --tail=200 || true | |
| echo "" | |
| echo "=== Router Logs ===" | |
| kubectl logs -l app.kubernetes.io/component=router --tail=200 || true | |
| echo "" | |
| echo "=== Scoped Router Logs ===" | |
| kubectl logs -n scoped-test -l app.kubernetes.io/component=router --tail=200 || true | |
| echo "" | |
| echo "=== Policy Engine Logs ===" | |
| kubectl logs -l app.kubernetes.io/component=policy-engine --tail=200 || true | |
| echo "" | |
| echo "=== Scoped Policy Engine Logs ===" | |
| kubectl logs -n scoped-test -l app.kubernetes.io/component=policy-engine --tail=200 || true | |
| echo "" | |
| echo "=== All Pods ===" | |
| kubectl get pods -A | |
| echo "" | |
| echo "=== All Services ===" | |
| kubectl get svc -A | |