Skip to content

Commit 2d9d4be

Browse files
authored
ROX-27073: github action for multicluster test (#2158)
* implemented ginkgo e2e test for cluster migration * small bugfixes for test implementation, tested against infra * chore: upgrade stackrox go.mod ref to 4.6.1 (#2142) upgrade stackrox go.mod ref to 4.6.1 * add GHA definition for multicluster test workflow * adjust setup and test scripts to make e2e test setup succeed * PR feedback
1 parent 93e81c9 commit 2d9d4be

File tree

10 files changed

+194
-19
lines changed

10 files changed

+194
-19
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
name: Multicluster E2E tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'fleetshard/pkg/runtime/**'
9+
- 'fleetshard/pkg/reconciler/**'
10+
- '.github/workflows/multicluster-e2e.yaml'
11+
- 'scripts/ci/**'
12+
- 'scripts/lib/**'
13+
- 'internal/pkg/handlers/admin_dinosaur.go'
14+
- 'internal/dinosaur/pkg/services/dinosaur.go'
15+
16+
pull_request:
17+
types: [opened, synchronize, reopened, ready_for_review]
18+
paths:
19+
- 'fleetshard/pkg/runtime/**'
20+
- 'fleetshard/pkg/reconciler/**'
21+
- '.github/workflows/multicluster-e2e.yaml'
22+
- 'scripts/ci/**'
23+
- 'scripts/lib/**'
24+
- 'internal/pkg/handlers/admin_dinosaur.go'
25+
- 'internal/dinosaur/pkg/services/dinosaur.go'
26+
27+
jobs:
28+
create-cluster:
29+
name: "Create Test Infra Clusters"
30+
runs-on: ubuntu-latest
31+
if: ${{ !github.event.pull_request.head.repo.fork && !github.event.pull_request.draft }} # do not run for PRs from forks and drafts
32+
environment: development
33+
strategy:
34+
matrix:
35+
name: [acscs1, acscs2]
36+
steps:
37+
- name: Create cluster
38+
uses: stackrox/actions/infra/create-cluster@v1
39+
with:
40+
token: ${{ secrets.INFRA_TOKEN }}
41+
flavor: osd-on-aws
42+
name: ${{ matrix.name }}-${{ github.run_id }}${{ github.run_attempt }}
43+
lifespan: 3h
44+
args: nodes=3,machine-type=m5.2xlarge
45+
wait: true
46+
47+
e2e-test:
48+
name: "Multicluster e2e tests"
49+
runs-on: ubuntu-latest
50+
if: ${{ !github.event.pull_request.head.repo.fork && !github.event.pull_request.draft }} # do not run for PRs from forks and drafts
51+
needs: [create-cluster]
52+
environment: development
53+
env:
54+
INFRA_TOKEN: ${{ secrets.INFRA_TOKEN }}
55+
AWS_AUTH_HELPER: "none"
56+
permissions:
57+
id-token: write
58+
contents: read
59+
steps:
60+
- name: Install infractl
61+
uses: stackrox/actions/infra/install-infractl@v1
62+
- name: Install oc
63+
uses: redhat-actions/oc-installer@v1
64+
- name: Check out code
65+
uses: actions/checkout@v4
66+
- name: Set cluster credentials
67+
run: |
68+
set -eo pipefail
69+
mkdir kube
70+
cluster1Conf="$(pwd)/kube/cluster1"
71+
url=$(infractl artifacts "acscs1-${{ github.run_id }}${{ github.run_attempt }}" --json | jq '.Artifacts[] | select(.Name=="kubeconfig") | .URL' -r)
72+
wget -O "$cluster1Conf" "$url"
73+
74+
cluster2Conf="$(pwd)/kube/cluster2"
75+
url=$(infractl artifacts "acscs2-${{ github.run_id }}${{ github.run_attempt }}" --json | jq '.Artifacts[] | select(.Name=="kubeconfig") | .URL' -r)
76+
wget -O "$cluster2Conf" "$url"
77+
78+
echo "CLUSTER_1_KUBECONFIG=$cluster1Conf" >> "$GITHUB_ENV"
79+
echo "CLUSTER_2_KUBECONFIG=$cluster2Conf" >> "$GITHUB_ENV"
80+
- name: Configure AWS credentials
81+
uses: aws-actions/[email protected]
82+
with:
83+
aws-region: ${{ secrets.AWS_REGION }}
84+
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github
85+
- name: Set registry.redhat.io credentials
86+
run: |
87+
set -eo pipefail
88+
89+
KUBECONFIG=$CLUSTER_1_KUBECONFIG oc get secret/pull-secret -n openshift-config --template='{{index .data ".dockerconfigjson" | base64decode}}' > dockercfg
90+
creds=$(jq '.auths."registry.redhat.io".auth' -r < dockercfg | base64 -d)
91+
user=$(echo "$creds" | cut -d':' -f1)
92+
pw=$(echo "$creds" | cut -d':' -f2)
93+
echo "RH_REGISTRY_USER=$user" >> "$GITHUB_ENV"
94+
echo "RH_REGISTRY_PW=$pw" >> "$GITHUB_ENV"
95+
- name: "Run"
96+
env:
97+
RUN_MULTICLUSTER_E2E: "true"
98+
ENABLE_CENTRAL_EXTERNAL_CERTIFICATE: "true"
99+
run: "scripts/ci/multicluster_tests/entrypoint.sh"
100+
101+
cleanup-clusters:
102+
name: "Cleanup Test Infra Clusters"
103+
runs-on: ubuntu-latest
104+
needs: [create-cluster, e2e-test]
105+
if: ${{ !github.event.pull_request.head.repo.fork && !github.event.pull_request.draft && always() }} # do not run for PRs from forks
106+
environment: development
107+
env:
108+
INFRA_TOKEN: ${{ secrets.INFRA_TOKEN }}
109+
steps:
110+
- name: Install infractl
111+
uses: stackrox/actions/infra/install-infractl@v1
112+
- name: Delete test clusters
113+
run: |
114+
set -o pipefail
115+
infractl delete "acscs1-${{ github.run_id }}${{ github.run_attempt }}"
116+
infractl delete "acscs2-${{ github.run_id }}${{ github.run_attempt }}"
117+
exit 0

.secrets.baseline

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@
259259
"filename": "e2e/e2e_test.go",
260260
"hashed_secret": "7f38822bc2b03e97325ff310099f457f6f788daf",
261261
"is_verified": false,
262-
"line_number": 298
262+
"line_number": 299
263263
}
264264
],
265265
"internal/dinosaur/pkg/api/public/api/openapi.yaml": [
@@ -416,5 +416,5 @@
416416
}
417417
]
418418
},
419-
"generated_at": "2025-01-22T08:55:38Z"
419+
"generated_at": "2025-01-22T14:22:15Z"
420420
}

Makefile

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ test/e2e/multicluster: $(GINKGO_BIN)
374374
CLUSTER_ID=1234567890abcdef1234567890abcdef \
375375
ENABLE_CENTRAL_EXTERNAL_CERTIFICATE=$(ENABLE_CENTRAL_EXTERNAL_CERTIFICATE) \
376376
GITOPS_CONFIG_PATH=$(GITOPS_CONFIG_FILE) \
377-
RUN_MULTICLUSTER_E2E=true
377+
RUN_MULTICLUSTER_E2E=true \
378378
$(GINKGO_BIN) -r $(GINKGO_FLAGS) \
379379
--randomize-suites \
380380
--fail-on-pending --keep-going \
@@ -383,7 +383,7 @@ test/e2e/multicluster: $(GINKGO_BIN)
383383
--json-report=e2e-report.json \
384384
--timeout=$(TEST_TIMEOUT) \
385385
--poll-progress-after=5m \
386-
./e2e/multicluster
386+
./e2e/multicluster/...
387387
.PHONY: test/e2e/multicluster
388388

389389
# Deploys the necessary applications to the selected cluster and runs e2e tests inside the container
@@ -525,9 +525,14 @@ db/generate/insert/cluster:
525525

526526
# Login to the OpenShift internal registry
527527
docker/login/internal:
528-
$(DOCKER) login -u kubeadmin --password-stdin <<< $(shell oc whoami -t) $(shell oc get route default-route -n openshift-image-registry -o jsonpath="{.spec.host}")
528+
@$(DOCKER) login -u kubeadmin --password-stdin <<< $(shell oc whoami -t) $(shell oc get route default-route -n openshift-image-registry -o jsonpath="{.spec.host}")
529529
.PHONY: docker/login/internal
530530

531+
# Login to registry.redhat.io
532+
docker/login/rh-registry:
533+
@$(DOCKER) login -u "${RH_REGISTRY_USER}" --password-stdin <<< "${RH_REGISTRY_PW}" registry.redhat.io
534+
.PHONY: docker/login/rh-registry
535+
531536
# Build the image
532537
image/build:
533538
$(DOCKER) buildx build -t $(SHORT_IMAGE_REF) . --load
@@ -798,7 +803,7 @@ endif
798803
-p QUOTA_TYPE="${QUOTA_TYPE}" \
799804
-p DATAPLANE_CLUSTER_SCALING_TYPE="${DATAPLANE_CLUSTER_SCALING_TYPE}" \
800805
-p CENTRAL_REQUEST_EXPIRATION_TIMEOUT="${CENTRAL_REQUEST_EXPIRATION_TIMEOUT}" \
801-
-p CLUSTER_LIST='$(shell make cluster-list)' \
806+
-p CLUSTER_LIST='$(shell make -s cluster-list)' \
802807
-p ENABLE_HTTPS="$(ENABLE_HTTPS)" \
803808
-p HEALTH_CHECK_SCHEME="$(HEALTH_CHECK_SCHEME)" \
804809
-p CPU_REQUEST="$(CPU_REQUEST)" \

dev/env/defaults/cluster-type-infra-openshift/env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export EXPOSE_OPENSHIFT_ROUTER_DEFAULT="true"
33
export ENABLE_EXTERNAL_CONFIG_DEFAULT="true"
44
export AWS_AUTH_HELPER_DEFAULT="aws-saml"
55
export INHERIT_IMAGEPULLSECRETS_DEFAULT="true" # pragma: allowlist secret
6+
export ENABLE_CENTRAL_EXTERNAL_CERTIFICATE_DEFAULT="true"

dev/env/scripts/docker.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@ ensure_fleetshard_operator_image_exists() {
7070
fi
7171

7272
if [[ -z "${FLEETSHARD_OPERATOR_IMAGE:-}" ]]; then
73-
FLEETSHARD_OPERATOR_IMAGE="fleetshard-operator:$(make tag)"
73+
FLEETSHARD_OPERATOR_IMAGE="fleetshard-operator:$(make -s tag)"
7474
export FLEETSHARD_OPERATOR_IMAGE
7575
if [[ "$CLUSTER_TYPE" == "infra-openshift" ]]; then
76+
if [[ -n "$RH_REGISTRY_USER" && -n "$RH_REGISTRY_PW" ]]; then
77+
make -C "${GITROOT}" docker/login/rh-registry
78+
fi
7679
log "Building fleetshard operator image ${FLEETSHARD_OPERATOR_IMAGE} and pushing it to internal registry"
7780
make -C "${GITROOT}" image/push/fleetshard-operator/internal
7881
else

e2e/e2e_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@ import (
66
"encoding/hex"
77
"errors"
88
"fmt"
9-
"github.com/stackrox/acs-fleet-manager/internal/dinosaur/pkg/gitops"
109
"net"
1110
"net/url"
1211
"os"
1312
"time"
1413

14+
"github.com/stackrox/acs-fleet-manager/internal/dinosaur/pkg/gitops"
15+
1516
. "github.com/onsi/ginkgo/v2"
1617
. "github.com/onsi/gomega"
1718
openshiftRouteV1 "github.com/openshift/api/route/v1"

e2e/testutil/testutil.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func DNSConfiguration(routesEnabled bool) (dnsEnabled bool, accessKey string, se
4141
enableExternal := os.Getenv("ENABLE_CENTRAL_EXTERNAL_CERTIFICATE")
4242
dnsEnabled = accessKey != "" &&
4343
secretKey != "" &&
44-
enableExternal != "" && routesEnabled
44+
enableExternal == "true" && routesEnabled
4545
return dnsEnabled, accessKey, secretKey
4646
}
4747

fleetshard/pkg/central/reconciler/reconciler.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import (
88
"encoding/base64"
99
"encoding/json"
1010
"fmt"
11-
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1211
"sort"
1312
"sync/atomic"
1413
"time"
1514

15+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
16+
1617
"github.com/golang/glog"
1718
"github.com/hashicorp/go-multierror"
1819
openshiftRouteV1 "github.com/openshift/api/route/v1"

scripts/ci/multicluster_tests/deploy.sh

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
set -e
2+
set -eo pipefail
33
# This script assumes that there were two clusters created before execution.
44
# It expects that those clusters are accessible through kubeconfig files at the path
55
# value stored in following environment variables:
@@ -10,13 +10,9 @@ export CLUSTER_2_KUBECONFIG=${CLUSTER_2_KUBECONFIG:-"$HOME/.kube/cluster2"}
1010

1111
# Bootstrap C1
1212
export KUBECONFIG="$CLUSTER_1_KUBECONFIG"
13+
export INHERIT_IMAGEPULLSECRETS="true" # pragma: allowlist secret
14+
export ENABLE_CENTRAL_EXTERNAL_CERTIFICATE="true"
1315

14-
# TODO: Double check how setup is done in OSCI so that we
15-
# Get the propper certificates to allow enabling creation of routes and DNS entries
16-
# Get the propper secrets to allow communication of FM to Route 53
17-
# Get the quay configuration to pull images
18-
# Maybe we wanna rely on prebuild images instead of building them ourselves, which might
19-
# as well need additional / other commands
2016
make deploy/bootstrap
2117
make deploy/dev
2218

@@ -30,7 +26,7 @@ export FM_URL
3026
kubectl get cm -n rhacs fleet-manager-dataplane-cluster-scaling-config -o yaml > fm-dataplane-config.yaml
3127
yq '.data."dataplane-cluster-configuration.yaml"' fm-dataplane-config.yaml | yq .clusters > cluster-list.json
3228

33-
KUBECONFIG="$CLUSTER_2_KUBECONFIG" make cluster-list \
29+
KUBECONFIG="$CLUSTER_2_KUBECONFIG" make -s cluster-list \
3430
| jq '.[0] | .name="dev2" | .cluster_id="1234567890abcdef1234567890abcdeg"' \
3531
| jq --slurp . > cluster-list2.json
3632

scripts/ci/multicluster_tests/entrypoint.sh

100644100755
Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,61 @@ source "$ROOT_DIR/scripts/ci/lib.sh"
99
source "$ROOT_DIR/scripts/lib/log.sh"
1010
source "$ROOT_DIR/dev/env/scripts/lib.sh"
1111

12+
acscs_namespace="rhacs"
13+
14+
log_common_cluster_resources() {
15+
local cluster_name=$1
16+
17+
log "***** START logging resources for: $cluster_name *****"
18+
kubectl describe deploy -n "$acscs_namespace"
19+
kubectl describe pods -n "$acscs_namespace"
20+
kubectl get routes -n "$acscs_namespace"
21+
kubectl logs -n "$acscs_namespace" --prefix --all-containers -l app=fleetshard-sync
22+
log "***** END logging resources for: $cluster_name *****"
23+
}
24+
25+
log_failure() {
26+
local step_name=$1
27+
log "$step_name Failed with status: $EXIT_CODE"
28+
log "Starting to log cluster resources and container logs"
29+
30+
export KUBECONFIG=$CLUSTER_1_KUBECONFIG
31+
log_common_cluster_resources "CLUSTER_1"
32+
kubectl logs -n "$acscs_namespace" --prefix --all-containers -l app=fleet-manager
33+
34+
export KUBECONFIG=$CLUSTER_2_KUBECONFIG
35+
log_common_cluster_resources "CLUSTER_2"
36+
}
37+
38+
39+
# shellcheck source=scripts/lib/external_config.sh
40+
source "${ROOT_DIR}/scripts/lib/external_config.sh"
41+
42+
# Executing this with all necessary credentials stored in AWS secretsmanager on ACSCS dev account
43+
# Name: "github-multicluster-test"
44+
# created and updated only manually by ACSCS engineerse
45+
init_chamber
46+
secrets=$(chamber env "github-multicluster-test" --backend secretsmanager)
47+
eval "$secrets"
48+
49+
KUBECTL="$(which kubectl)"
50+
export KUBECTL
51+
1252
bash "$SOURCE_DIR/deploy.sh"
1353
EXIT_CODE="$?"
1454
if [ "$EXIT_CODE" -ne "0" ]; then
15-
echo "TODO(ROX-27073): add additional logging required here, once tests are actually executed"
55+
log_failure Deploy
56+
stat /tmp/pids-port-forward > /dev/null 2>&1 && xargs kill < /tmp/pids-port-forward
57+
exit 1
58+
fi
59+
60+
FM_URL="https://$(KUBECONFIG=$CLUSTER_1_KUBECONFIG kubectl get routes -n rhacs fleet-manager -o yaml | yq .spec.host)"
61+
export FM_URL
62+
63+
make test/e2e/multicluster
64+
EXIT_CODE="$?"
65+
if [ "$EXIT_CODE" -ne "0" ]; then
66+
log_failure Test
1667
fi
1768

1869
stat /tmp/pids-port-forward > /dev/null 2>&1 && xargs kill < /tmp/pids-port-forward

0 commit comments

Comments
 (0)