feat(support-bundle): allow cluster resource to be overwrite by different spec or merging namespaces #17148
This file contains 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: build-test | |
on: | |
pull_request: | |
# pull_request_target: | |
# # This workflow trigger may lead to malicious PR authors being able to obtain repository write permissions or stealing repository secrets. | |
# # Please read https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ | |
# types: [ opened, synchronize, reopened, labeled ] | |
concurrency: | |
group: ${{ github.head_ref }} | |
cancel-in-progress: true | |
jobs: | |
can-run-ci: | |
runs-on: ubuntu-20.04 | |
# if the event is pull_request and: | |
# - it is not a fork OR | |
# - it has the label '@actions/safe-to-test' | |
# | |
# The 'pull_request_target' workflow trigger may lead to malicious PR authors being able to obtain repository write permissions or stealing repository secrets. | |
# Please read https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ | |
if: > | |
( github.event_name == 'pull_request' && | |
( github.event.pull_request.head.repo.full_name == github.repository || | |
contains(github.event.pull_request.labels.*.name, '@actions/safe-to-test' ) | |
) | |
) | |
steps: | |
- name: ok | |
run: echo "yes" | |
# Use this to disable tests when iteratig on a specific test to save time | |
enable-tests: | |
runs-on: ubuntu-20.04 | |
steps: | |
- name: ok | |
# change 0 to a positive interger to prevent all tests from running | |
run: exit 0 | |
generate-tag: | |
runs-on: ubuntu-20.04 | |
outputs: | |
tag: ${{ steps.get_tag.outputs.GIT_TAG }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Get tags | |
id: get_tag | |
uses: ./.github/actions/version-tag | |
deps-web: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: Setup Node.js environment | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '18.x' | |
cache: yarn | |
cache-dependency-path: web/yarn.lock | |
- name: Cache node_modules | |
uses: actions/cache@v4 | |
with: | |
path: ${{ github.workspace }}/web/node_modules | |
key: ${{ runner.os }}-${{ runner.arch }}-yarn-node_modules-${{ hashFiles('web/yarn.lock') }} | |
- name: Install web deps | |
run: make -C web deps | |
lint-web: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, deps-web ] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: Setup Node.js environment | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '18.x' | |
cache: yarn | |
cache-dependency-path: web/yarn.lock | |
- name: Cache node_modules | |
uses: actions/cache@v4 | |
with: | |
path: ${{ github.workspace }}/web/node_modules | |
key: ${{ runner.os }}-${{ runner.arch }}-yarn-node_modules-${{ hashFiles('web/yarn.lock') }} | |
- name: Lint | |
run: make -C web lint | |
unit-test-web: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, deps-web ] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: Setup Node.js environment | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '18.x' | |
cache: yarn | |
cache-dependency-path: web/yarn.lock | |
- name: Cache node_modules | |
uses: actions/cache@v4 | |
with: | |
path: ${{ github.workspace }}/web/node_modules | |
key: ${{ runner.os }}-${{ runner.arch }}-yarn-node_modules-${{ hashFiles('web/yarn.lock') }} | |
- name: Unit test | |
run: make -C web test-unit | |
build-web: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, deps-web, generate-tag ] | |
steps: | |
# This workflow trigger may lead to malicious PR authors being able to obtain repository write permissions or stealing repository secrets. | |
# Please read https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ | |
# this action checks out the remote branch and runs CI | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: Setup Node.js environment | |
uses: actions/setup-node@v4 | |
with: | |
node-version: '18.x' | |
cache: yarn | |
cache-dependency-path: web/yarn.lock | |
- name: Cache node_modules | |
uses: actions/cache@v4 | |
with: | |
path: ${{ github.workspace }}/web/node_modules | |
key: ${{ runner.os }}-${{ runner.arch }}-yarn-node_modules-${{ hashFiles('web/yarn.lock') }} | |
- name: Build web | |
env: | |
GIT_TAG: ${{ needs.generate-tag.outputs.tag }} | |
run: mapfile -t envs < <(grep -v '#.*' < .image.env) && export "${envs[@]}" && make -C web build-kotsadm | |
- name: Upload web artifact | |
uses: actions/upload-artifact@v4 | |
with: | |
name: web | |
path: ./web/dist | |
deps-kots: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: '^1.20.0' | |
cache: true | |
- run: go mod download | |
vet-kots: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, deps-kots ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: '^1.20.0' | |
cache: true | |
- name: vet | |
run: make vet | |
ci-test-kots: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, deps-kots ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: '^1.20.0' | |
cache: true | |
- name: test | |
run: make ci-test | |
build-kots: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, build-web, deps-kots, generate-tag ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: '^1.20.0' | |
cache: true | |
- name: Download web artifact | |
uses: actions/download-artifact@v4 | |
with: | |
name: web | |
path: ./web/dist | |
- name: Build kots | |
env: | |
GIT_TAG: ${{ needs.generate-tag.outputs.tag }} | |
run: mapfile -t envs < <(grep -v '#.*' < .image.env) && export "${envs[@]}" && make kots | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: kots | |
path: ./bin/kots | |
build-kotsadm-melange-packages: | |
needs: [ can-run-ci, generate-tag ] | |
strategy: | |
fail-fast: true | |
matrix: | |
runner: [ | |
{name: ubuntu-20.04, arch: amd64}, | |
{name: arm64-runner-set, arch: arm64} | |
] | |
runs-on: ${{ matrix.runner.name }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: ./.github/actions/build-custom-melange-package | |
with: | |
context: deploy | |
component: kotsadm | |
git-tag: ${{ needs.generate-tag.outputs.tag }} | |
arch: ${{ matrix.runner.arch }} | |
build-kotsadm: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, generate-tag, build-kotsadm-melange-packages ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: ./.github/actions/build-custom-image-with-apko | |
with: | |
context: deploy | |
component: kotsadm | |
git-tag: ${{ needs.generate-tag.outputs.tag }} | |
image-name: ttl.sh/automated-${{ github.run_id }}/kotsadm:24h | |
build-kots-helm: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: main | |
repository: replicatedhq/kots-helm | |
- name: Build KOTS Helm chart | |
env: | |
GIT_COMMIT: ${{ github.sha }} | |
run: | | |
curl -O -L "https://raw.githubusercontent.com/replicatedhq/kots/${GIT_COMMIT}/.image.env" | |
mapfile -t envs < <(grep -v '#.*' < .image.env) && export "${envs[@]}" | |
export CHART_VERSION=0.0.${{ github.run_id }}-automated | |
export KOTS_VERSION=24h | |
export KOTS_TAG=24h | |
export KOTSADM_REGISTRY=ttl.sh/automated-${{ github.run_id }} | |
envsubst < Chart.yaml.tmpl > Chart.yaml | |
envsubst < values.yaml.tmpl > values.yaml | |
CHART_NAME=$(helm package . | rev | cut -d/ -f1 | rev) | |
export CHART_NAME | |
helm push "$CHART_NAME" oci://ttl.sh/automated-${{ github.run_id }} | |
build-e2e: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
- uses: actions/setup-go@v5 | |
with: | |
go-version: '^1.20.0' | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: Cache Go modules | |
uses: actions/cache@v4 | |
with: | |
path: | | |
~/.cache/go-build | |
~/go/pkg/mod | |
key: ${{ runner.os }}-go-e2e-${{ hashFiles('**/go.sum') }} | |
restore-keys: | | |
${{ runner.os }}-go-e2e- | |
- run: make -C e2e build deps | |
- run: docker save e2e-deps -o e2e/bin/e2e-deps.tar | |
- uses: actions/upload-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
build-kurl-proxy-melange-packages: | |
needs: [ can-run-ci, generate-tag ] | |
strategy: | |
fail-fast: true | |
matrix: | |
runner: [ | |
{name: ubuntu-20.04, arch: amd64}, | |
{name: arm64-runner-set, arch: arm64} | |
] | |
runs-on: ${{ matrix.runner.name }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: ./.github/actions/build-custom-melange-package | |
with: | |
context: kurl_proxy/deploy | |
component: kurl-proxy | |
git-tag: ${{ needs.generate-tag.outputs.tag }} | |
arch: ${{ matrix.runner.arch }} | |
build-kurl-proxy: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, generate-tag, build-kurl-proxy-melange-packages ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: ./.github/actions/build-custom-image-with-apko | |
with: | |
context: kurl_proxy/deploy | |
component: kurl-proxy | |
git-tag: ${{ needs.generate-tag.outputs.tag }} | |
image-name: ttl.sh/automated-${{ github.run_id }}/kurl-proxy:24h | |
build-migrations-melange-packages: | |
needs: [ can-run-ci, generate-tag ] | |
strategy: | |
fail-fast: true | |
matrix: | |
runner: [ | |
{name: ubuntu-20.04, arch: amd64}, | |
{name: arm64-runner-set, arch: arm64} | |
] | |
runs-on: ${{ matrix.runner.name }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: ./.github/actions/build-custom-melange-package | |
with: | |
context: migrations/deploy | |
component: kotsadm-migrations | |
git-tag: ${{ needs.generate-tag.outputs.tag }} | |
arch: ${{ matrix.runner.arch }} | |
build-migrations: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, generate-tag, build-migrations-melange-packages ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- uses: ./.github/actions/build-custom-image-with-apko | |
with: | |
context: migrations/deploy | |
component: kotsadm-migrations | |
git-tag: ${{ needs.generate-tag.outputs.tag }} | |
image-name: ttl.sh/automated-${{ github.run_id }}/kotsadm-migrations:24h | |
push-minio: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
# This workflow trigger may lead to malicious PR authors being able to obtain repository write permissions or stealing repository secrets. | |
# Please read https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ | |
# this action creates a branch based on remote branch and runs the tests | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: load environment variables from .image.env | |
uses: falti/dotenv-action@v1 | |
id: dotenv | |
with: | |
path: .image.env | |
- name: push minio | |
run: skopeo copy --all docker://kotsadm/minio:${{ steps.dotenv.outputs.MINIO_TAG }} docker://ttl.sh/automated-${{ github.run_id }}/minio:${{ steps.dotenv.outputs.MINIO_TAG }} | |
push-rqlite: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
# This workflow trigger may lead to malicious PR authors being able to obtain repository write permissions or stealing repository secrets. | |
# Please read https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ | |
# this action creates a branch based on remote branch and runs the tests | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: load environment variables from .image.env | |
uses: falti/dotenv-action@v1 | |
id: dotenv | |
with: | |
path: .image.env | |
- name: push rqlite | |
run: skopeo copy --all docker://kotsadm/rqlite:${{ steps.dotenv.outputs.RQLITE_TAG }} docker://ttl.sh/automated-${{ github.run_id }}/rqlite:${{ steps.dotenv.outputs.RQLITE_TAG }} | |
push-dex: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci ] | |
steps: | |
# This workflow trigger may lead to malicious PR authors being able to obtain repository write permissions or stealing repository secrets. | |
# Please read https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ | |
# this action creates a branch based on remote branch and runs the tests | |
- uses: actions/checkout@v4 | |
with: | |
ref: ${{github.event.pull_request.head.ref}} | |
repository: ${{github.event.pull_request.head.repo.full_name}} | |
- name: load environment variables from .image.env | |
uses: falti/dotenv-action@v1 | |
id: dotenv | |
with: | |
path: .image.env | |
- name: push dex | |
run: skopeo copy --all docker://kotsadm/dex:${{ steps.dotenv.outputs.DEX_TAG }} docker://ttl.sh/automated-${{ github.run_id }}/dex:${{ steps.dotenv.outputs.DEX_TAG }} | |
# only run validate-kurl-addon if changes to "deploy/kurl/kotsadm/template/**" | |
kurl-addon-changes-filter: | |
runs-on: ubuntu-20.04 | |
needs: [ can-run-ci, enable-tests ] | |
outputs: | |
ok-to-test: ${{ steps.filter.outputs.kurl-addon }} | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: dorny/paths-filter@v3 | |
id: filter | |
with: | |
filters: | | |
kurl-addon: | |
- 'deploy/kurl/kotsadm/template/**' | |
- 'deploy/kurl/kotsadm/testgrid-os-spec.yaml' | |
validate-kurl-addon: | |
runs-on: ubuntu-20.04 | |
if: ${{ needs.kurl-addon-changes-filter.outputs.ok-to-test == 'true' }} | |
needs: [ can-run-ci, enable-tests, generate-tag, kurl-addon-changes-filter, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-dex ] | |
steps: | |
- name: checkout | |
uses: actions/checkout@v4 | |
- name: set outputs | |
id: vars | |
run: | | |
addon_version=${{ needs.generate-tag.outputs.tag }} | |
echo "addon_version=${addon_version#v}" >> "$GITHUB_OUTPUT" | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- name: prepare kots binary executable | |
run: | | |
chmod +x bin/* | |
tar -C bin/ -czvf bin/kots.tar.gz kots | |
- name: generate kurl add-on | |
id: addon-generate | |
uses: ./.github/actions/kurl-addon-kots-generate | |
env: | |
AWS_ACCESS_KEY_ID: ${{ secrets.KURL_ADDONS_AWS_ACCESS_KEY_ID }} | |
AWS_SECRET_ACCESS_KEY: ${{ secrets.KURL_ADDONS_AWS_SECRET_ACCESS_KEY }} | |
AWS_DEFAULT_REGION: us-east-1 | |
with: | |
addon_version: ${{ steps.vars.outputs.addon_version }} | |
kotsadm_image_registry: ttl.sh | |
kotsadm_image_namespace: automated-${{ github.run_id }} | |
kotsadm_image_tag: 24h | |
kotsadm_binary_override: bin/kots.tar.gz | |
- name: test kurl add-on | |
id: addon-test | |
uses: ./.github/actions/kurl-addon-kots-test | |
with: | |
addon_version: ${{ steps.vars.outputs.addon_version }} | |
addon_package_url: ${{ steps.addon-generate.outputs.addon_package_url }} | |
testgrid_api_token: ${{ secrets.TESTGRID_PROD_API_TOKEN }} | |
- name: comment testgrid url | |
uses: mshick/add-pr-comment@v2 | |
with: | |
message: ${{ steps.addon-test.outputs.testgrid_run_message }} | |
repo-token: ${{ secrets.GITHUB_TOKEN }} | |
allow-repeats: false | |
cmx-versions: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci ] | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: get CMX versions to test | |
id: cmx-versions-to-test | |
uses: ./.github/actions/cmx-versions | |
with: | |
replicated-api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
outputs: | |
versions-to-test: ${{ steps.cmx-versions-to-test.outputs.versions-to-test }} | |
validate-existing-online-install-minimal: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: | | |
docker load -i e2e/bin/e2e-deps.tar | |
chmod +x e2e/bin/* | |
chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
kots-namespace: 'qakotsregression' | |
test-id: '@regression' | |
k8s-distribution: k3s | |
k8s-version: v1.26 | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-smoke-test: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: ${{ fromJson(needs.cmx-versions.outputs.versions-to-test) }} | |
continue-on-error: ${{ matrix.cluster.stage != 'stable' }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@smoke-test' | |
kots-namespace: 'smoke-test' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
k8s-instance-type: ${{ matrix.cluster.instance_type }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-minimal-rbac: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0}, | |
{distribution: openshift, version: 4.15.0-okd} | |
] | |
env: | |
APP_SLUG: minimal-rbac | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.MINIMAL_RBAC_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--additional-labels testlabel1=testvalue1 \ | |
--additional-labels test.label/two=test.value.two \ | |
--additional-annotations testannotation1=testannotationvalue1 \ | |
--additional-annotations test.annotation/two=testannotation.value.two \ | |
--kotsadm-tag 24h | tee output.txt | |
if ! grep -q "The Kubernetes RBAC policy that the Admin Console is running with does not have access to complete the Preflight Checks. It's recommended that you run these manually before proceeding." output.txt; then | |
echo "Expected to see an RBAC error for preflight checks, but did not" | |
exit 1 | |
fi | |
if ! grep -q 'The app was not deployed.' output.txt; then | |
printf "Expected to see message about app not being deployed, but did not\n" | |
exit 1 | |
fi | |
if grep FAIL output.txt | grep -q 'This application requires at least 100 nodes'; then | |
printf "Did not expect to see a failure about number of nodes, but did\n" | |
exit 1 | |
fi | |
if ! kubectl get role -n "$APP_SLUG" | grep -q kotsadm; then | |
echo "kotsadm role not found in namespace $APP_SLUG" | |
kubectl get role -n "$APP_SLUG" | |
exit 1 | |
fi | |
if ! kubectl get rolebinding -n "$APP_SLUG" | grep -q kotsadm; then | |
echo "kotsadm rolebinding not found in namespace $APP_SLUG" | |
kubectl get rolebinding -n "$APP_SLUG" | |
exit 1 | |
fi | |
if kubectl get clusterrole | grep -q kotsadm; then | |
echo "found kotsadm clusterrole in minimal RBAC install" | |
kubectl get clusterrole | |
exit 1 | |
fi | |
if kubectl get clusterrolebinding | grep -q kotsadm; then | |
echo "found kotsadm clusterrolebinding in minimal RBAC install" | |
kubectl get clusterrolebinding | |
exit 1 | |
fi | |
echo "check that the kotsadm, minio and rqlite pods have the correct labels and annotations" | |
echo "label one" | |
if ! kubectl get pods -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.labels.testlabel1}' | grep -q testvalue1; then | |
echo "kotsadm pod does not have the correct testlabel1 label" | |
kubectl get pods -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.labels}' | |
exit 1 | |
fi | |
if ! kubectl get pods -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.labels.testlabel1}' | grep -q testvalue1; then | |
echo "kotsadm-minio pod does not have the correct testlabel1 label" | |
kubectl get pods -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.labels}' | |
exit 1 | |
fi | |
if ! kubectl get pods -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.labels.testlabel1}' | grep -q testvalue1; then | |
echo "kotsadm-rqlite pod does not have the correct testlabel1 label" | |
kubectl get pods -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.labels}' | |
exit 1 | |
fi | |
echo "annotation one" | |
if ! kubectl get pods -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.annotations.testannotation1}' | grep -q testannotationvalue1; then | |
echo "kotsadm pod does not have the correct testannotation1 annotation" | |
kubectl get pods -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.annotations}' | |
exit 1 | |
fi | |
if ! kubectl get pods -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.annotations.testannotation1}' | grep -q testannotationvalue1; then | |
echo "kotsadm-minio pod does not have the correct testannotation1 annotation" | |
kubectl get pods -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.annotations}' | |
exit 1 | |
fi | |
if ! kubectl get pods -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.annotations.testannotation1}' | grep -q testannotationvalue1; then | |
echo "kotsadm-rqlite pod does not have the correct testannotation1 annotation" | |
kubectl get pods -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.annotations}' | |
exit 1 | |
fi | |
echo "label two" | |
if ! kubectl get pod -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.labels.test\.label/two}' | grep -q 'test.value.two'; then | |
echo "kotsadm pod does not have the correct test.label/two label" | |
kubectl get pod -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.labels}' | |
exit 1 | |
fi | |
if ! kubectl get pod -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.labels.test\.label/two}' | grep -q 'test.value.two'; then | |
echo "kotsadm-minio pod does not have the correct test.label/two label" | |
kubectl get pod -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.labels}' | |
exit 1 | |
fi | |
if ! kubectl get pod -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.labels.test\.label/two}' | grep -q 'test.value.two'; then | |
echo "kotsadm-rqlite pod does not have the correct test.label/two label" | |
kubectl get pod -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.labels}' | |
exit 1 | |
fi | |
echo "annotation two" | |
if ! kubectl get pod -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.annotations.test\.annotation/two}' | grep -q 'testannotation.value.two'; then | |
echo "kotsadm pod does not have the correct test.annotation/two annotation" | |
kubectl get pod -n "$APP_SLUG" -l app=kotsadm -o jsonpath='{.items[0].metadata.annotations}' | |
exit 1 | |
fi | |
if ! kubectl get pod -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.annotations.test\.annotation/two}' | grep -q 'testannotation.value.two'; then | |
echo "kotsadm-minio pod does not have the correct test.annotation/two annotation" | |
kubectl get pod -n "$APP_SLUG" -l app=kotsadm-minio -o jsonpath='{.items[0].metadata.annotations}' | |
exit 1 | |
fi | |
if ! kubectl get pod -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.annotations.test\.annotation/two}' | grep -q 'testannotation.value.two'; then | |
echo "kotsadm-rqlite pod does not have the correct test.annotation/two annotation" | |
kubectl get pod -n "$APP_SLUG" -l app=kotsadm-rqlite -o jsonpath='{.items[0].metadata.annotations}' | |
exit 1 | |
fi | |
echo "additional pod labels and annotations are present" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-backup-and-restore: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: ${{ fromJson(needs.cmx-versions.outputs.versions-to-test) }} | |
continue-on-error: ${{ matrix.cluster.stage != 'stable' }} | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@backup-and-restore' | |
kots-namespace: 'backup-and-restore' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
k8s-instance-type: ${{ matrix.cluster.instance_type }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-no-required-config: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@no-required-config' | |
kots-namespace: 'no-required-config' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-strict-preflight-checks: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: strict-preflight-checks | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.STRICT_PREFLIGHT_CHECKS_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--skip-preflights \ | |
--kotsadm-tag 24h | tee output.txt | |
if ! grep -q 'The app was not deployed.' output.txt; then | |
printf "Expected to see message about app not being deployed, but did not\n" | |
exit 1 | |
fi | |
if ! grep FAIL output.txt | grep -q 'The application requires a Kubernetes 2.0.0 or later.'; then | |
printf "Expected to see a failure about kubernetes version, but did not\n" | |
exit 1 | |
fi | |
if ! kubectl logs deploy/kotsadm -n "$APP_SLUG" | grep -q "preflights will not be skipped, strict preflights are set to true"; then | |
echo "Failed to find a log line about strict preflights not being skipped in kotsadm logs" | |
echo "kotsadm logs:" | |
kubectl logs deploy/kotsadm -n "$APP_SLUG" | |
exit 1 | |
fi | |
# disable the strict preflight check and app should deploy successfully | |
./bin/kots set config "$APP_SLUG" enable_failing_strict_analyzers="0" --namespace "$APP_SLUG" --deploy | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs deploy/kotsadm --tail=100 -n "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
printf "App is installed successfully and is ready\n\n" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
# enable the failing non-strict preflight check | |
./bin/kots set config "$APP_SLUG" enable_failing_non_strict_analyzers="1" --namespace "$APP_SLUG" | |
# download the config | |
./bin/kots get config --namespace "$APP_SLUG" > config.yaml | |
# remove the app | |
./bin/kots remove "$APP_SLUG" --namespace "$APP_SLUG" --undeploy | |
# install the app and skip preflights | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--config-values config.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--skip-preflights \ | |
--kotsadm-tag 24h | |
if ! kubectl logs deploy/kotsadm -n "$APP_SLUG" | grep -q "preflights will not be skipped, strict preflights are set to true"; then | |
echo "Failed to find a log line about strict preflights not being skipped in kotsadm logs" | |
echo "kotsadm logs:" | |
kubectl logs deploy/kotsadm -n "$APP_SLUG" | |
exit 1 | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs deploy/kotsadm --tail=100 -n "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
printf "App is installed successfully and is ready\n\n" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-config: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@config-validation' | |
kots-namespace: 'config-validation' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-version-history-pagination: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: k3s-local, version: v1.27.1-k3s1} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@version-history-pagination' | |
kots-namespace: 'version-history-pagination' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-change-license: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@change-license' | |
kots-namespace: 'change-license' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-change-channel: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@change-channel' | |
kots-namespace: 'change-channel' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-minimal-rbac-override: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0}, | |
{distribution: openshift, version: 4.15.0-okd} | |
] | |
env: | |
APP_SLUG: minimal-rbac | |
APP_VERSION_LABEL: "0.0.1" | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: minimal rbac override on command line | |
run: | | |
set +e | |
echo ${{ secrets.MINIMAL_RBAC_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--app-version-label "$APP_VERSION_LABEL" \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h \ | |
--use-minimal-rbac | tee output.txt | |
if ! grep -q "The Kubernetes RBAC policy that the Admin Console is running with does not have access to complete the Preflight Checks. It's recommended that you run these manually before proceeding." output.txt; then | |
echo "Expected to see an RBAC error for preflight checks, but did not" | |
exit 1 | |
fi | |
if ! grep -q 'The app was not deployed.' output.txt; then | |
printf "Expected to see message about app not being deployed, but did not\n" | |
exit 1 | |
fi | |
if grep FAIL output.txt | grep -q 'This application requires at least 100 nodes'; then | |
printf "Did not expect to see a failure about number of nodes, but did\n" | |
exit 1 | |
fi | |
if ! kubectl get role -n "$APP_SLUG" | grep -q kotsadm; then | |
echo "kotsadm role not found in namespace $APP_SLUG" | |
kubectl get role -n "$APP_SLUG" | |
exit 1 | |
fi | |
if ! kubectl get rolebinding -n "$APP_SLUG" | grep -q kotsadm; then | |
echo "kotsadm rolebinding not found in namespace $APP_SLUG" | |
kubectl get rolebinding -n "$APP_SLUG" | |
exit 1 | |
fi | |
if kubectl get clusterrole | grep -q kotsadm; then | |
echo "found kotsadm clusterrole in minimal RBAC install" | |
kubectl get clusterrole | |
exit 1 | |
fi | |
if kubectl get clusterrolebinding | grep -q kotsadm; then | |
echo "found kotsadm clusterrolebinding in minimal RBAC install" | |
kubectl get clusterrolebinding | |
exit 1 | |
fi | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl delete ns "$APP_SLUG" --ignore-not-found | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: no minimal rbac override on command line | |
run: | | |
set +e | |
echo ${{ secrets.MINIMAL_RBAC_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--app-version-label "$APP_VERSION_LABEL" \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | tee output.txt | |
if grep -q "The Kubernetes RBAC policy that the Admin Console is running with does not have access to complete the Preflight Checks. It's recommended that you run these manually before proceeding." output.txt; then | |
echo "Did not expect to see an RBAC error for preflight checks, but did" | |
exit 1 | |
fi | |
if ! grep -q 'The app was not deployed.' output.txt; then | |
printf "Expected to see message about app not being deployed, but did not\n" | |
exit 1 | |
fi | |
if ! grep FAIL output.txt | grep -q 'This application requires at least 100 nodes'; then | |
printf "Expected to see a failure about number of nodes, but did not\n" | |
exit 1 | |
fi | |
if kubectl get role -n "$APP_SLUG" | grep -q kotsadm; then | |
echo "kotsadm role found in cluster scoped install" | |
kubectl get role -n "$APP_SLUG" | |
exit 1 | |
fi | |
if kubectl get rolebinding -n "$APP_SLUG" | grep -q kotsadm; then | |
echo "kotsadm rolebinding found in cluster scoped install" | |
kubectl get rolebinding -n "$APP_SLUG" | |
exit 1 | |
fi | |
if ! kubectl get clusterrole | grep -q kotsadm; then | |
echo "No kotsadm clusterrole found in cluster scoped install" | |
kubectl get clusterrole | |
exit 1 | |
fi | |
if ! kubectl get clusterrolebinding | grep -q kotsadm; then | |
echo "No kotsadm clusterrolebinding found in cluster scoped install" | |
kubectl get clusterrolebinding | |
exit 1 | |
fi | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-multi-namespace: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: ${{ fromJson(needs.cmx-versions.outputs.versions-to-test) }} | |
continue-on-error: ${{ matrix.cluster.stage != 'stable' }} | |
env: | |
APP_SLUG: multi-namespace-yeti | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- uses: azure/setup-helm@v4 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
instance-type: ${{ matrix.cluster.instance_type }} | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.MULTI_NAMESPACE_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h \ | |
--storage-class=${{ matrix.cluster.distribution == 'eks' && 'gp2' || '' }} | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 180 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# validate that helm charts installed using the native helm workflow were deployed via the helm CLI correctly | |
if ! helm ls -n postgres-test | awk 'NR>1{print $1}' | grep -q postgresql; then | |
printf "postgresql helm release not found in postgres-test namespace\n\n" | |
helm ls -n postgres-test | |
exit 1 | |
fi | |
if ! helm ls -n "$APP_SLUG" | awk 'NR>1{print $1}' | grep -q private-chart; then | |
printf "private-chart helm release not found in %s namespace\n\n" "$APP_SLUG" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-kots-pull: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: ${{ fromJson(needs.cmx-versions.outputs.versions-to-test) }} | |
continue-on-error: ${{ matrix.cluster.stage != 'stable' }} | |
env: | |
APP_NAME: multi-namespace-yeti | |
APP_SLUG: multi-namespace | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
instance-type: ${{ matrix.cluster.instance_type }} | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_NAME" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_NAME" | |
- name: run kots pull | |
run: | | |
set +e | |
echo ${{ secrets.MULTI_NAMESPACE_LICENSE }} | base64 -d > license.yaml | |
./bin/kots pull "$APP_NAME/automated" \ | |
--license-file license.yaml \ | |
--shared-password password \ | |
--namespace "$APP_NAME" \ | |
--exclude-admin-console | |
kubectl create ns "$APP_NAME" | |
kubectl create ns nginx-test | |
kubectl create ns redis-test | |
kubectl create ns postgres-test | |
# HACK: without operator, additonal namespaces don't get image pull secrets | |
echo ${{ secrets.MULTI_NAMESPACE_REGISTRY_AUTH }} | base64 -d > replicated-registry-auth.json | |
kubectl -n nginx-test create secret generic multi-namespace-yeti-registry --type=kubernetes.io/dockerconfigjson --from-file=.dockerconfigjson=./replicated-registry-auth.json | |
kubectl -n redis-test create secret generic multi-namespace-yeti-registry --type=kubernetes.io/dockerconfigjson --from-file=.dockerconfigjson=./replicated-registry-auth.json | |
kubectl -n redis-test create secret generic multi-namespace-yeti-redis-registry --type=kubernetes.io/dockerconfigjson --from-file=.dockerconfigjson=./replicated-registry-auth.json | |
kubectl -n postgres-test create secret generic multi-namespace-yeti-registry --type=kubernetes.io/dockerconfigjson --from-file=.dockerconfigjson=./replicated-registry-auth.json | |
kubectl -n default create secret generic multi-namespace-yeti-registry --type=kubernetes.io/dockerconfigjson --from-file=.dockerconfigjson=./replicated-registry-auth.json | |
kustomize build "$PWD/$APP_SLUG/overlays/midstream" | kubectl apply -f - | |
kustomize build "$PWD/$APP_SLUG/overlays/midstream/charts/redis" | kubectl apply -f - | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "Failed to apply spec" | |
echo "------pods:" | |
kubectl get pods -A | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
echo "Waiting for pods to start" | |
COUNTER=1 | |
while [ "$(kubectl get pods --no-headers | grep -v Running | grep -cv Completed)" -gt 0 ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for pods to start" | |
kubectl get pods -A | |
exit 1 | |
fi | |
sleep 1 | |
done | |
echo "All pods started" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_NAME" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-app-version-label: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: app-version-label | |
APP_VERSION_LABEL: v1.0.0 | |
LATEST_APP_VERSION_LABEL: v1.0.1 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: test kots install with version label | |
run: | | |
set +e | |
echo ${{ secrets.APP_VERSION_LABEL_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--app-version-label "$APP_VERSION_LABEL" \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $3}')" != "$APP_VERSION_LABEL" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be installed with correct version label: $APP_VERSION_LABEL" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
printf "App is installed successfully with the correct version label: %s\n\n" "$APP_VERSION_LABEL" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
# test setting DockerHub credentials | |
set +e | |
# TODO: deploy and check secrets are actually created and images are pulled | |
./bin/kots docker ensure-secret --dockerhub-username replicatedtests --dockerhub-password ${{ secrets.DOCKERHUB_RATELIMIT_PASSWORD }} -n "$APP_SLUG" | |
./bin/kots download -n "$APP_SLUG" --slug "$APP_SLUG" | |
if grep "${APP_SLUG}-kotsadm-dockerhub" -w "./${APP_SLUG}/overlays/midstream/secret.yaml"; then | |
echo "Found DockerHub secret in ${APP_SLUG} latest version" | |
else | |
echo "No DockerHub secret found in appication namespace" | |
exit 1 | |
fi | |
- name: remove the app | |
run: | | |
set +e | |
./bin/kots remove "$APP_SLUG" --namespace "$APP_SLUG" --force | |
- name: test kots install without version label | |
run: | | |
set +e | |
echo ${{ secrets.APP_VERSION_LABEL_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $3}')" != "$LATEST_APP_VERSION_LABEL" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be installed with latest version label: $LATEST_APP_VERSION_LABEL" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
printf "App is installed successfully with the correct version label: %s\n\n" "$LATEST_APP_VERSION_LABEL" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-helm-install-order: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: helm-install-order | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.HELM_INSTALL_ORDER_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--skip-preflights \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
printf "App is installed successfully and is ready\n\n" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-no-redeploy-on-restart: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: no-redeploy-on-restart | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.NO_REDEPLOY_ON_RESTART_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--skip-preflights \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
# wait for application job to be created | |
COUNTER=1 | |
while [ "$(kubectl get jobs -l app=example,component=job -n "$APP_SLUG" --ignore-not-found | awk 'NR>1' | wc -l)" == "0" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 60 ]; then | |
echo "Timed out waiting for job to be created" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# delete the application job and restart the admin console | |
kubectl delete jobs -n "$APP_SLUG" --all | |
kubectl delete pods -l app=kotsadm -n "$APP_SLUG" | |
# wait for old kotsadm pod to terminate | |
COUNTER=1 | |
while [ "$(kubectl get pods -l app=kotsadm -n "$APP_SLUG" | awk 'NR>1' | wc -l)" != "1" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 60 ]; then | |
echo "More than 1 kotsadm pod found" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# wait for new kotsadm pod to become ready | |
kubectl wait --for=condition=ready pod -l app=kotsadm -n "$APP_SLUG" --timeout=60s | |
# delay in case the app takes a bit to be deployed | |
sleep 20 | |
# validate that the application wasn't re-deployed and the job wasn't re-created | |
if [ "$(kubectl get jobs -l app=example,component=job -n "$APP_SLUG" --ignore-not-found | awk 'NR>1' | wc -l)" != "0" ]; then | |
echo "App should not be re-deployed after restart" | |
exit 1 | |
fi | |
printf "Success. App was not re-deployed after restart\n\n" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-kubernetes-installer-preflight: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: kubernetes-installer-preflight | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.KUBERNETES_INSTALLER_PREFLIGHT_LICENSE }} | base64 -d > license.yaml | |
# Fake kurl installation using the crd and installer spec from the application manifests: | |
# Pull application manifests | |
./bin/kots pull "$APP_SLUG/automated" --license-file license.yaml --shared-password password | |
# Apply installer crd | |
kubectl apply -f "$APP_SLUG/upstream/installer-crd.yaml" | |
# Wait for crd to be created | |
kubectl wait --for condition=established --timeout=60s crd/installers.cluster.kurl.sh | |
# Seems that the above does not always guarantee the crd exists? So just in case... | |
sleep 10 | |
# Apply installer | |
kubectl apply -f "$APP_SLUG/upstream/installer.yaml" | |
# Create kurl-config configmap in kube-system | |
kubectl create cm kurl-config -n kube-system --from-literal=installer_id=7cc8094 | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# try get apps without namespace (using kubeconfig) | |
# validate that output is the same as above | |
mkdir -p /tmp/.kube | |
sudo cp "$KUBECONFIG" /tmp/.kube/config | |
sudo chmod -R 777 /tmp/.kube | |
export KUBECONFIG=/tmp/.kube/config | |
kubectl config set-context --current --namespace="$APP_SLUG" | |
if [ "$(./bin/kots get apps | awk 'NR>1{print $2}')" != "ready" ]; then | |
echo "kots get apps output is not the same as above" | |
exit 1 | |
fi | |
printf "App is installed successfully and is ready\n\n" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-kots-push-images-anonymous: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: run kots admin-console push-images | |
run: | | |
set +e | |
./bin/kots admin-console push-images ./e2e/artifacts/small.airgap ttl.sh/automated-${{ github.run_id }} | |
validate-kots-admin-console-generate-manifests: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: minimal-rbac | |
BASE_KOTS_VERSION: v1.72.0 | |
NAMESPACE: generate-manifests | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: run kots admin-console generate-manifests without k8s context | |
run: | | |
set +e | |
./bin/kots admin-console generate-manifests -n "$NAMESPACE" --shared-password password | |
- name: validate that ./admin-console exists and is not empty | |
run: | | |
set +e | |
if [ ! -d ./admin-console ]; then | |
echo "admin-console directory does not exist" | |
exit 1 | |
fi | |
if [ -z "$(ls -A ./admin-console)" ]; then | |
echo "admin-console directory is empty" | |
exit 1 | |
fi | |
- name: remove admin-console directory | |
run: rm -rf ./admin-console | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download base kots version | |
run: | | |
curl -LO "https://github.com/replicatedhq/kots/releases/download/$BASE_KOTS_VERSION/kots_linux_amd64.tar.gz" \ | |
&& tar zxvf kots_linux_amd64.tar.gz \ | |
&& mv kots "kots-$BASE_KOTS_VERSION" | |
- name: create namespace | |
run: | | |
set +e | |
kubectl create namespace "$NAMESPACE" | |
- name: run kots admin-console generate-manifests using base kots version with k8s context | |
run: | | |
set +e | |
"./kots-$BASE_KOTS_VERSION" admin-console generate-manifests -n "$NAMESPACE" --shared-password password | |
- name: apply the generated manifests | |
run: | | |
set +e | |
kubectl apply -f ./admin-console -n "$NAMESPACE" | |
- name: wait for the kotsadm-minio-0 pod to be created | |
run: | | |
set +e | |
COUNTER=1 | |
while ! kubectl get pods -n "$NAMESPACE" | grep -q kotsadm-minio-0; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 30 ]; then | |
echo "timed out waiting for kotsadm-minio-0 pod to be created" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
- name: wait for kotsadm-minio-0 pod to be ready | |
run: | | |
set +e | |
kubectl wait --for=condition=ready --timeout=180s pod/kotsadm-minio-0 -n "$NAMESPACE" | |
- name: wait for the kotsadm deployment to be ready | |
run: | | |
set +e | |
kubectl wait --for=condition=available --timeout=300s deployment/kotsadm -n "$NAMESPACE" | |
- name: run kots admin-console generate-manifests using new kots version with k8s context | |
run: | | |
set +e | |
./bin/kots admin-console generate-manifests -n "$NAMESPACE" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
- name: validate that ./admin-console/minio-statefulset.yaml has initContainers since a migration is needed | |
run: | | |
set +e | |
if ! grep -qE 'initContainers' ./admin-console/minio-statefulset.yaml; then | |
echo "admin-console/minio-statefulset.yaml does not have initContainers" | |
exit 1 | |
fi | |
- name: apply the generated manifests | |
run: | | |
set +e | |
kubectl apply -f ./admin-console -n "$NAMESPACE" | |
- name: wait for kotsadm-minio-0 pod to be ready | |
run: | | |
set +e | |
sleep 10 | |
kubectl wait --for=condition=ready --timeout=180s pod/kotsadm-minio-0 -n "$NAMESPACE" | |
- name: wait for the kotsadm deployment to be ready | |
run: | | |
set +e | |
kubectl wait --for=condition=available --timeout=300s deployment/kotsadm -n "$NAMESPACE" | |
- name: run kots admin-console generate-manifests using new kots version with k8s context | |
run: | | |
set +e | |
./bin/kots admin-console generate-manifests -n "$NAMESPACE" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
- name: validate that ./admin-console/minio-statefulset.yaml does not have initContainers since a migration is not needed | |
run: | | |
set +e | |
if grep -qE 'initContainers' ./admin-console/minio-statefulset.yaml; then | |
echo "admin-console/minio-statefulset.yaml has initContainers" | |
exit 1 | |
fi | |
- name: apply the generated manifests | |
run: | | |
set +e | |
kubectl apply -f ./admin-console -n "$NAMESPACE" | |
- name: wait for kotsadm-minio-0 pod to be ready | |
run: | | |
set +e | |
sleep 10 | |
kubectl wait --for=condition=ready --timeout=180s pod/kotsadm-minio-0 -n "$NAMESPACE" | |
- name: wait for the kotsadm deployment to be ready | |
run: | | |
set +e | |
kubectl wait --for=condition=available --timeout=300s deployment/kotsadm -n "$NAMESPACE" | |
- name: print pods and logs on failure | |
if: failure() | |
run: | | |
echo "------pods:" | |
kubectl -n "$NAMESPACE" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$NAMESPACE" | |
echo "------kotsadm-minio logs" | |
kubectl logs -l app=kotsadm-minio --tail=100 --namespace "$NAMESPACE" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: automated-${{ github.run_id }} | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-min-kots-version: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-e2e, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite, generate-tag ] | |
env: | |
APP_SLUG: min-kots-version | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: | | |
docker load -i e2e/bin/e2e-deps.tar | |
chmod +x e2e/bin/* | |
chmod +x bin/* | |
cp ./bin/kots /usr/local/bin/kubectl-kots | |
sudo apt-get update -y && sudo apt-get install jq -y | |
- uses: ./.github/actions/kots-e2e | |
id: kots-e2e | |
with: | |
test-id: '@min-kots-version' | |
kots-namespace: 'min-kots-version' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
kotsadm-image-registry: ttl.sh | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
k8s-cluster-skip-teardown: true | |
- name: validate that kots install fails early | |
run: | | |
set +e | |
result=$(kubectl kots install "$APP_SLUG/automated" --no-port-forward --namespace "$APP_SLUG" --shared-password password 2>&1 >/dev/null) | |
echo "$result" | |
if [[ "$result" == *"requires"* ]] && [[ "$result" == *"10000.0.0"* ]]; then | |
exit 0 | |
else | |
exit 1 | |
fi | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.kots-e2e.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.kots-e2e.outputs.cluster-id }} | |
validate-target-kots-version: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-e2e, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite, generate-tag ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: | | |
docker load -i e2e/bin/e2e-deps.tar | |
chmod +x e2e/bin/* | |
chmod +x bin/* | |
cp ./bin/kots /usr/local/bin/kubectl-kots | |
sudo apt-get update -y && sudo apt-get install jq -y | |
- uses: ./.github/actions/kots-e2e | |
id: kots-e2e | |
with: | |
test-id: '@target-kots-version' | |
kots-namespace: 'target-kots-version' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
k8s-cluster-skip-teardown: true | |
- name: validate that kots install fails early | |
run: | | |
set +e | |
result=$(kubectl kots install target-kots-version/automated --no-port-forward --namespace target-kots-version --shared-password password 2>&1 >/dev/null) | |
echo "$result" | |
if [[ "$result" == *"requires"* ]] && [[ "$result" == *"1.0.0"* ]]; then | |
exit 0 | |
else | |
exit 1 | |
fi | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.kots-e2e.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.kots-e2e.outputs.cluster-id }} | |
validate-range-kots-version: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-e2e, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite, generate-tag ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: | | |
docker load -i e2e/bin/e2e-deps.tar | |
chmod +x e2e/bin/* | |
chmod +x bin/* | |
cp ./bin/kots /usr/local/bin/kubectl-kots | |
sudo apt-get update -y && sudo apt-get install jq -y | |
- uses: ./.github/actions/kots-e2e | |
id: kots-e2e | |
with: | |
test-id: '@range-kots-version' | |
kots-namespace: 'range-kots-version' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
k8s-cluster-skip-teardown: true | |
- name: validate that kots install fails early | |
run: | | |
set +e | |
result=$(kubectl kots install range-kots-version/automated --no-port-forward --namespace range-kots-version --shared-password password 2>&1 >/dev/null) | |
echo "$result" | |
if [[ "$result" == *"requires"* ]] && [[ "$result" == *"11000.0.0"* ]]; then | |
exit 0 | |
else | |
exit 1 | |
fi | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.kots-e2e.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.kots-e2e.outputs.cluster-id }} | |
validate-kots-upgrade: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, cmx-versions, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: ${{ fromJson(needs.cmx-versions.outputs.versions-to-test) }} | |
exclude: | |
- cluster: | |
instance_type: m7g.large # old kots versions do not support arm64 | |
continue-on-error: ${{ matrix.cluster.stage != 'stable' }} | |
env: | |
APP_SLUG: postgres-to-rqlite | |
BASE_KOTS_VERSION: v1.57.0 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
instance-type: ${{ matrix.cluster.instance_type }} | |
export-kubeconfig: true | |
- name: download base kots version | |
run: | | |
curl -LO "https://github.com/replicatedhq/kots/releases/download/$BASE_KOTS_VERSION/kots_linux_amd64.tar.gz" \ | |
&& tar zxvf kots_linux_amd64.tar.gz \ | |
&& mv kots "kots-$BASE_KOTS_VERSION" | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.POSTGRES_TO_RQLITE_LICENSE }} | base64 -d > license.yaml | |
# install using the base KOTS version | |
"./kots-$BASE_KOTS_VERSION" \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--port-forward=false \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$("./kots-$BASE_KOTS_VERSION" get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
"./kots-$BASE_KOTS_VERSION" get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# upgrade using the new KOTS version | |
./bin/kots admin-console upgrade \ | |
--namespace "$APP_SLUG" \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
# verify that the postgres to rqlite migration was successful | |
if ! kubectl logs -l app=kotsadm --namespace "$APP_SLUG" | grep -q "Migrated from Postgres to rqlite successfully"; then | |
echo "Failed to find a successful migration log line" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --all-containers --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
# verify that the minio migration happened | |
if [ -z "$(kubectl get statefulset kotsadm-minio -n "$APP_SLUG" -o jsonpath='{.spec.template.spec.initContainers}')" ]; then | |
echo "Failed to find initContainers in the kotsadm-minio statefulset" | |
echo "kotsadm-minio statefulset:" | |
kubectl get statefulset kotsadm-minio -n "$APP_SLUG" -o yaml | |
exit 1 | |
fi | |
# make sure app is still installed and ready | |
if [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; then | |
echo "App is not ready after the upgrade" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
printf "App is still installed and is ready after the migration\n\n" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-kots-helm-release-secret-migration: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: helm-release-secret-migration | |
RELEASE_NAME: helm-release-chart | |
RELEASE_NAMESPACE: helm-release | |
BASE_KOTS_VERSION: v1.94.0 | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download base kots version | |
run: | | |
curl -LO "https://github.com/replicatedhq/kots/releases/download/$BASE_KOTS_VERSION/kots_linux_amd64.tar.gz" \ | |
&& tar zxvf kots_linux_amd64.tar.gz \ | |
&& mv kots "kots-$BASE_KOTS_VERSION" | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.HELM_RELEASE_SECRET_MIGRATION_LICENSE }} | base64 -d > license.yaml | |
# install using the base KOTS version | |
"./kots-$BASE_KOTS_VERSION" \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward=true \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$("./kots-$BASE_KOTS_VERSION" get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
"./kots-$BASE_KOTS_VERSION" get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# verify that the helm release secret is created in the kotsadm namespace | |
releaseSecretName=$(kubectl get secret -n "$APP_SLUG" -l owner=helm,name="$RELEASE_NAME" -o jsonpath='{.items[*].metadata.name}') | |
if [ -z "$releaseSecretName" ]; then | |
echo "Failed to find the helm release secret in the $APP_SLUG namespace" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
# if there are more than one helm release secrets, fail | |
if [ "$(echo "$releaseSecretName" | wc -l)" -gt 1 ]; then | |
echo "Found more than one helm release secret in the $APP_SLUG namespace" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
# upgrade using the new KOTS version | |
./bin/kots admin-console upgrade \ | |
--namespace "$APP_SLUG" \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
# make a config change and redeploy the app | |
./bin/kots set config "$APP_SLUG" create_new_sequence=true --deploy --namespace "$APP_SLUG" | |
# make sure app is still installed and ready | |
if [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; then | |
echo "App is not ready after the upgrade" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
COUNTER=1 | |
while [ "$(helm ls -n "$RELEASE_NAMESPACE" | grep "$RELEASE_NAME" | awk 'NR>0{print $3}')" != "2" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for $RELEASE_NAME to be upgraded to revision 2" | |
helm ls -n "$RELEASE_NAMESPACE" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# verify that the helm release secret is created in the helm relase namespace | |
COUNT=1 | |
releaseSecret="" | |
while [ -z "$releaseSecret" ]; do | |
((COUNT += 1)) | |
if [ $COUNT -gt 10 ]; then | |
echo "Timed out waiting for the helm release secret to be migrated" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
releaseSecret=$(kubectl get secret "$releaseSecretName" -n "$RELEASE_NAMESPACE") | |
done | |
# verify that the release secret in app namepspace is deleted | |
oldReleaseSecret=$(kubectl get secret "$releaseSecretName" -n "$APP_SLUG") | |
if [ -n "$oldReleaseSecret" ]; then | |
echo "Found the helm release secret in the $APP_SLUG namespace" | |
echo "$oldReleaseSecret" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
# verify that there are two helm release secrets in the helm release namespace | |
releaseSecretNames=$(kubectl get secret -n "$RELEASE_NAMESPACE" -l owner=helm,name="$RELEASE_NAME" -o jsonpath='{.items[*].metadata.name}') | |
releaseSecretNamesCount=$(echo "$releaseSecretNames" | wc -w) | |
if [ "$releaseSecretNamesCount" -ne 2 ]; then | |
echo "Found $releaseSecretNamesCount helm release secrets in the $RELEASE_NAMESPACE namespace(Want: 2)" | |
kubectl get secret -n "$RELEASE_NAMESPACE" -l owner=helm,name="$RELEASE_NAME" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
printf "Helm release secret migration test passed\n\n" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-multi-app-backup-and-restore: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@multi-app-backup-and-restore' | |
kots-namespace: 'multi-app-backup-and-restore' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-multi-app-install: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@multi-app-install' | |
kots-namespace: 'multi-app-install' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-airgap-smoke-test: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@airgap-smoke-test' | |
kots-namespace: 'airgap-smoke-test' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
kots-airgap: true | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-remove-app: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0, instance_type: r1.medium} | |
] | |
env: | |
APP_SLUG: remove-app | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
instance-type: ${{ matrix.cluster.instance_type }} | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.REMOVE_APP_LICENSE }} | base64 -d > license.yaml | |
HELM_APP_NAMESPACES=(postgres-test redis-test "$APP_SLUG") | |
APP_NAMESPACES=(postgres-test redis-test nginx-test rabbitmq-system "$APP_SLUG") | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# test that --undeploy deletes application resources from the cluster | |
./bin/kots remove "$APP_SLUG" --namespace "$APP_SLUG" --undeploy | |
if [ "$(./bin/kots get apps --namespace "$APP_SLUG" --output=json | tr -d '\n')" != "[]" ]; then | |
printf "App reference was not removed\n\n" | |
exit 1 | |
fi | |
if [ "$(kubectl get all,secrets,configmap,pvc -A -l "kots.io/app-slug=$APP_SLUG" --ignore-not-found | wc -l | tr -d '\n')" != "0" ]; then | |
printf "Application resources are still found in the cluster\n\n" | |
kubectl get all,secrets,configmap,pvc -A -l "kots.io/app-slug=$APP_SLUG" | |
exit 1 | |
fi | |
if [ "$(kubectl get crd rabbitmqclusters.rabbitmq.com --ignore-not-found | wc -l | tr -d '\n')" != "0" ]; then | |
printf "rabbitmqclusters.rabbitmq.com CRD was not removed\n\n" | |
kubectl get crd rabbitmqclusters.rabbitmq.com | |
exit 1 | |
fi | |
for ns in "${HELM_APP_NAMESPACES[@]}"; do | |
if [ "$(kubectl get secret -n "$ns" --field-selector type=helm.sh/release.v1 --ignore-not-found | wc -l | tr -d '\n')" != "0" ]; then | |
printf "Application Helm release secrets are still found in the namepspace %s\n\n" "$ns" | |
kubectl get secret -n "$ns" --field-selector type=helm.sh/release.v1 | |
exit 1 | |
fi | |
done | |
# re-install and test that running the remove command without --undeploy does _not_ delete any resources from the cluster | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
./bin/kots remove "$APP_SLUG" --namespace "$APP_SLUG" --force | |
if [ "$(./bin/kots get apps --namespace "$APP_SLUG" --output=json | tr -d '\n')" != "[]" ]; then | |
printf "App reference was not removed\n\n" | |
exit 1 | |
fi | |
for ns in "${APP_NAMESPACES[@]}"; do | |
if [ "$(kubectl get all,secrets,configmap,pvc -n "$ns" -l "kots.io/app-slug=$APP_SLUG" --ignore-not-found | wc -l | tr -d '\n')" == "0" ]; then | |
printf "%s namespace does not contain any resources\n\n" "$ns" | |
kubectl get all,secrets,configmap,pvc -n "$ns" | |
exit 1 | |
fi | |
done | |
if [ "$(kubectl get crd rabbitmqclusters.rabbitmq.com --ignore-not-found | wc -l | tr -d '\n')" == "0" ]; then | |
printf "rabbitmqclusters.rabbitmq.com CRD was not found\n\n" | |
kubectl get crd rabbitmqclusters.rabbitmq.com | |
exit 1 | |
fi | |
if [ "$(kubectl get rabbitmqclusters.rabbitmq.com -n rabbitmq-system --ignore-not-found | wc -l | tr -d '\n')" == "0" ]; then | |
printf "rabbitmq-system namespace does not contain rabbitmqclusters\n\n" | |
kubectl get rabbitmqclusters.rabbitmq.com -n rabbitmq-system | |
exit 1 | |
fi | |
for ns in "${HELM_APP_NAMESPACES[@]}"; do | |
if [ "$(kubectl get secret -n "$ns" --field-selector type=helm.sh/release.v1 --ignore-not-found | wc -l | tr -d '\n')" == "0" ]; then | |
printf "Application Helm release secrets are not found in namepspace %s\n\n" "$ns" | |
kubectl get secret -n "$ns" --field-selector type=helm.sh/release.v1 | |
exit 1 | |
fi | |
done | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-registry-check: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: run the test | |
run: | | |
set +e | |
./bin/kots admin-console push-images \ | |
not-an-app.airgap localhost:1234/not-a-namespace \ | |
--registry-username not-a-username \ | |
--registry-password not-a-password > output.txt 2>&1 | |
if ! grep -q 'Failed to test access' output.txt; then | |
printf "Expected registry validation to fail before pushing images, but did not.\n\n" | |
cat output.txt | |
exit 1 | |
fi | |
rm output.txt | |
./bin/kots install not-an-app \ | |
--airgap-bundle not-an-app.airgap \ | |
--kotsadm-registry localhost:1234/not-a-namespace \ | |
--registry-username not-a-username \ | |
--registry-password not-a-password > output.txt 2>&1 | |
if ! grep -q 'Failed to test access' output.txt; then | |
printf "Expected registry validation to fail before installation, but did not.\n\n" | |
cat output.txt | |
exit 1 | |
fi | |
rm output.txt | |
./bin/kots upstream upgrade not-an-app \ | |
--airgap-bundle not-an-app.airgap \ | |
--kotsadm-registry localhost:1234/not-a-namespace \ | |
--registry-username not-a-username \ | |
--registry-password not-a-password \ | |
--namespace not-a-namespace > output.txt 2>&1 | |
if ! grep -q 'Failed to test access' output.txt; then | |
printf "Expected registry validation to fail before upgrading, but did not.\n\n" | |
cat output.txt | |
exit 1 | |
fi | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-native-helm-v2: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: native-helm-v2 | |
INITIAL_VERSION: '0.1.1' | |
UPGRADE_VERSION: '0.2.1' | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- uses: azure/setup-helm@v4 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.NATIVE_HELM_V2_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--app-version-label "$INITIAL_VERSION" \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $3}')" != "$INITIAL_VERSION" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# validate that helm charts installed using both native helm workflow were deployed via the helm CLI correctly | |
if ! helm ls -n "$APP_SLUG" | awk 'NR>1{print $1}' | grep -q my-chart-release; then | |
printf "my-chart-release helm release not found in %s namespace\n\n" "$APP_SLUG" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
if ! helm ls -n "$APP_SLUG" | awk 'NR>1{print $1}' | grep -q my-other-chart-release; then | |
printf "my-other-chart-release helm release not found in %s namespace\n\n" "$APP_SLUG" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
# validate that `helm get values` works for the v1beta2 chart | |
if ! helm get values my-chart-release -n "$APP_SLUG" | grep -q my-value; then | |
printf "my-value not found in helm values for my-chart-release in %s namespace\n\n" "$APP_SLUG" | |
helm get values my-chart-release -n "$APP_SLUG" | |
exit 1 | |
fi | |
# upgrade the app version | |
./bin/kots upstream upgrade "$APP_SLUG" -n "$APP_SLUG" --deploy | |
# wait for my-chart-release to be uninstalled and my-other-chart-release to be upgraded to revision 2 | |
COUNTER=1 | |
while [ "$(helm ls -n "$APP_SLUG" | awk 'NR>1{print $1}' | grep my-chart-release)" != "" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for my-chart-release to be uninstalled" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
COUNTER=1 | |
while [ "$(helm ls -n "$APP_SLUG" | grep my-other-chart-release | awk 'NR>0{print $3}')" != "2" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for my-other-chart-release to be upgraded to revision 2" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# validate that `helm get values` works for the upgraded v1beta2 chart | |
if ! helm get values my-other-chart-release -n "$APP_SLUG" | grep -q my-value; then | |
printf "my-value not found in helm values for my-chart-release in %s namespace\n\n" "$APP_SLUG" | |
helm get values my-chart-release -n "$APP_SLUG" | |
exit 1 | |
fi | |
# wait for the app to be ready again | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $3}')" != "$UPGRADE_VERSION" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# validate that the conditional chart is installed | |
COUNTER=1 | |
while [ "$(helm ls -n "$APP_SLUG" | awk 'NR>1{print $1}' | grep my-conditional-chart-release)" == "" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for my-conditional-chart-release to be installed" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# toggle the config option to exclude the conditional chart | |
./bin/kots set config "$APP_SLUG" install_conditional_chart=0 --deploy --namespace "$APP_SLUG" | |
# wait for my-conditional-chart-release to be uninstalled | |
COUNTER=1 | |
while [ "$(helm ls -n "$APP_SLUG" | awk 'NR>1{print $1}' | grep my-conditional-chart-release)" != "" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for my-conditional-chart-release to be uninstalled" | |
helm ls -n "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-deployment-orchestration: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: deployment-orchestration | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- uses: azure/setup-helm@v4 | |
with: | |
token: ${{ secrets.GITHUB_TOKEN }} | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: run the test | |
run: | | |
set +e | |
echo ${{ secrets.DEPLOYMENT_ORCHESTRATION_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$APP_SLUG" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit $EXIT_CODE | |
fi | |
function wait_for_log { | |
local counter=1 | |
local timeout=30 | |
local log_pattern="$1" | |
while ! kubectl logs deploy/kotsadm -c kotsadm -n "$APP_SLUG" | grep -i "$log_pattern"; do | |
((counter += 1)) | |
if [ $counter -gt $timeout ]; then | |
echo "Timed out waiting for log $log_pattern" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
} | |
wait_for_log "applying phase -9999" | |
wait_for_log "applying phase -3" | |
wait_for_log "waiting for resource apiextensions.k8s.io/v1/CustomResourceDefinition/myresources.example.com in namespace $APP_SLUG to be ready" | |
wait_for_log "applying phase -2" | |
# validate that phase -1 has not deployed yet since we're waiting on the CR status fields | |
if kubectl logs deploy/kotsadm -c kotsadm -n "$APP_SLUG" | grep -i "applying phase -1"; then | |
printf "phase -1 was deployed before phase -2 completed" | |
kubectl logs deploy/kotsadm -c kotsadm -n "$APP_SLUG" | |
exit 1 | |
fi | |
wait_for_log "waiting for resource example.com/v1beta1/MyResource/my-resource in namespace $APP_SLUG to have property .status.tasks.extract=true" | |
# set .status.tasks.extract=true | |
kubectl patch myresources.example.com my-resource -n "$APP_SLUG" -p '{"status": {"tasks": {"extract": true}}}' --type=merge | |
wait_for_log "waiting for resource example.com/v1beta1/MyResource/my-resource in namespace $APP_SLUG to have property .status.tasks.transform=true" | |
# set .status.tasks.transform=true | |
kubectl patch myresources.example.com my-resource -n "$APP_SLUG" -p '{"status": {"tasks": {"transform": true}}}' --type=merge | |
wait_for_log "waiting for resource example.com/v1beta1/MyResource/my-resource in namespace $APP_SLUG to have property .status.tasks.load=true" | |
# set .status.tasks.load=true | |
kubectl patch myresources.example.com my-resource -n "$APP_SLUG" -p '{"status": {"tasks": {"load": true}}}' --type=merge | |
# now validate that the remaining phases are deployed (-1, 0, and 1) | |
wait_for_log "applying phase -1" | |
wait_for_log "waiting for resource apps/v1/Deployment/nginx-1 in namespace $APP_SLUG to be ready" | |
wait_for_log "applying phase 0" | |
wait_for_log "waiting for resource apps/v1/Deployment/nginx-2 in namespace $APP_SLUG to be ready" | |
wait_for_log "applying phase 1" | |
wait_for_log "waiting for resource /v1/Service/nginx-2 in namespace $APP_SLUG to be ready" | |
# wait for the app to be ready | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$APP_SLUG" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$APP_SLUG" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$APP_SLUG" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# remove the app | |
./bin/kots remove "$APP_SLUG" -n "$APP_SLUG" --undeploy | |
wait_for_log "deleting resources in phase -1" | |
wait_for_log "deleting resources in phase 0" | |
wait_for_log "deleting resources in phase 1" | |
wait_for_log "deleting resources in phase 2" | |
wait_for_log "deleting resources in phase 3" | |
# validate that the app reference was removed | |
if [ "$(./bin/kots get apps --namespace "$APP_SLUG" --output=json | tr -d '\n')" != "[]" ]; then | |
printf "App reference was not removed\n\n" | |
exit 1 | |
fi | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-replicated-sdk: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0}, | |
{distribution: openshift, version: 4.15.0-okd} | |
] | |
env: | |
KOTS_NAMESPACE: replicated-sdk | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$KOTS_NAMESPACE" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$KOTS_NAMESPACE" | |
- name: run upgrade-to-replicated-sdk test | |
id: upgrade-to-replicated-sdk | |
env: | |
APP_SLUG: upgrade-to-replicated-sdk | |
run: | | |
set +e | |
echo ${{ secrets.UPGRADE_TO_REPLICATED_SDK_LICENSE }} | base64 -d > license.yaml | |
LICENSE_ID="$(grep -oP 'licenseID:\s*\K\w+' license.yaml)" | |
echo "license-id=$LICENSE_ID" >> "$GITHUB_OUTPUT" | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$KOTS_NAMESPACE" \ | |
--shared-password password \ | |
--app-version-label v1.0.0 \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$KOTS_NAMESPACE" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit $EXIT_CODE | |
fi | |
# wait for the app to be ready | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$KOTS_NAMESPACE" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# upgrade the app to the new version | |
./bin/kots upstream upgrade "$APP_SLUG" -n "$KOTS_NAMESPACE" --deploy | |
sleep 5 | |
# wait for the app to be ready again | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$KOTS_NAMESPACE" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# get the version of the replicated-sdk that is running and set it as an output | |
REPLICATED_SDK_VERSION=$(kubectl get deploy replicated -n "$KOTS_NAMESPACE" -o jsonpath='{.spec.template.spec.containers[0].image}' | grep -oE '[^:]+$') | |
echo "replicated-sdk-version=$REPLICATED_SDK_VERSION" >> "$GITHUB_OUTPUT" | |
- run: rm -rf ./replicated-sdk | |
- name: Checkout replicated-sdk | |
uses: actions/checkout@v4 | |
with: | |
repository: replicatedhq/replicated-sdk | |
path: replicated-sdk | |
ref: ${{ steps.upgrade-to-replicated-sdk.outputs.replicated-sdk-version }} | |
- name: Validate endpoints | |
uses: ./replicated-sdk/.github/actions/validate-endpoints | |
with: | |
license-id: ${{ steps.upgrade-to-replicated-sdk.outputs.license-id }} | |
license-fields: '[{"name":"expires_at","value": ""}]' | |
integration-enabled: true | |
namespace: "$KOTS_NAMESPACE" | |
- name: remove upgrade-to-replicated-sdk app | |
env: | |
APP_SLUG: upgrade-to-replicated-sdk | |
run: | | |
# remove the app | |
./bin/kots remove "$APP_SLUG" -n "$KOTS_NAMESPACE" --undeploy | |
# validate that the app reference was removed | |
if [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" --output=json | tr -d '\n')" != "[]" ]; then | |
printf "App reference was not removed\n\n" | |
exit 1 | |
fi | |
- name: run replicated-sdk-subchart-native-helm-v1 test | |
id: replicated-sdk-subchart-native-helm-v1 | |
env: | |
APP_SLUG: replicated-sdk-subchart-native-helm-v1 | |
run: | | |
set +e | |
echo ${{ secrets.REPLICATED_SDK_SUBCHART_NATIVE_HELM_V1 }} | base64 -d > license.yaml | |
LICENSE_ID="$(grep -oP 'licenseID:\s*\K\w+' license.yaml)" | |
echo "license-id=$LICENSE_ID" >> "$GITHUB_OUTPUT" | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$KOTS_NAMESPACE" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$KOTS_NAMESPACE" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit $EXIT_CODE | |
fi | |
# wait for the app to be ready | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$KOTS_NAMESPACE" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# get the version of the replicated-sdk that is running and set it as an output | |
REPLICATED_SDK_VERSION=$(kubectl get deploy replicated -n "$KOTS_NAMESPACE" -o jsonpath='{.spec.template.spec.containers[0].image}' | grep -oE '[^:]+$') | |
echo "replicated-sdk-version=$REPLICATED_SDK_VERSION" >> "$GITHUB_OUTPUT" | |
- run: rm -rf ./replicated-sdk | |
- name: Checkout replicated-sdk | |
uses: actions/checkout@v4 | |
with: | |
repository: replicatedhq/replicated-sdk | |
path: replicated-sdk | |
ref: ${{ steps.replicated-sdk-subchart-native-helm-v1.outputs.replicated-sdk-version }} | |
- name: Validate endpoints | |
uses: ./replicated-sdk/.github/actions/validate-endpoints | |
with: | |
license-id: ${{ steps.replicated-sdk-subchart-native-helm-v1.outputs.license-id }} | |
license-fields: '[{"name":"expires_at","value": ""}]' | |
integration-enabled: true | |
namespace: "$KOTS_NAMESPACE" | |
- name: remove replicated-sdk-subchart-native-helm-v1 app | |
env: | |
APP_SLUG: replicated-sdk-subchart-native-helm-v1 | |
run: | | |
# remove the app | |
./bin/kots remove "$APP_SLUG" -n "$KOTS_NAMESPACE" --undeploy | |
# validate that the app reference was removed | |
if [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" --output=json | tr -d '\n')" != "[]" ]; then | |
printf "App reference was not removed\n\n" | |
exit 1 | |
fi | |
- name: run replicated-sdk-subchart-replicated-helm test | |
id: replicated-sdk-subchart-replicated-helm | |
env: | |
APP_SLUG: replicated-sdk-subchart-replicated-helm | |
run: | | |
set +e | |
echo ${{ secrets.REPLICATED_SDK_SUBCHART_REPLICATED_HELM }} | base64 -d > license.yaml | |
LICENSE_ID="$(grep -oP 'licenseID:\s*\K\w+' license.yaml)" | |
echo "license-id=$LICENSE_ID" >> "$GITHUB_OUTPUT" | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$KOTS_NAMESPACE" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
EXIT_CODE=$? | |
if [ $EXIT_CODE -ne 0 ]; then | |
echo "------pods:" | |
kubectl -n "$KOTS_NAMESPACE" get pods | |
echo "------kotsadm logs" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit $EXIT_CODE | |
fi | |
# wait for the app to be ready | |
COUNTER=1 | |
while [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" | awk 'NR>1{print $2}')" != "ready" ]; do | |
((COUNTER += 1)) | |
if [ $COUNTER -gt 120 ]; then | |
echo "Timed out waiting for app to be ready" | |
./bin/kots get apps --namespace "$KOTS_NAMESPACE" | |
echo "kotsadm logs:" | |
kubectl logs -l app=kotsadm --tail=100 --namespace "$KOTS_NAMESPACE" | |
exit 1 | |
fi | |
sleep 1 | |
done | |
# get the version of the replicated-sdk that is running and set it as an output | |
REPLICATED_SDK_VERSION=$(kubectl get deploy replicated -n "$KOTS_NAMESPACE" -o jsonpath='{.spec.template.spec.containers[0].image}' | grep -oE '[^:]+$') | |
echo "replicated-sdk-version=$REPLICATED_SDK_VERSION" >> "$GITHUB_OUTPUT" | |
- run: rm -rf ./replicated-sdk | |
- name: Checkout replicated-sdk | |
uses: actions/checkout@v4 | |
with: | |
repository: replicatedhq/replicated-sdk | |
path: replicated-sdk | |
ref: ${{ steps.replicated-sdk-subchart-replicated-helm.outputs.replicated-sdk-version }} | |
- name: Validate endpoints | |
uses: ./replicated-sdk/.github/actions/validate-endpoints | |
with: | |
license-id: ${{ steps.replicated-sdk-subchart-replicated-helm.outputs.license-id }} | |
license-fields: '[{"name":"expires_at","value": ""}]' | |
integration-enabled: true | |
namespace: "$KOTS_NAMESPACE" | |
deployed-via-kubectl: true | |
- name: remove replicated-sdk-subchart-replicated-helm app | |
env: | |
APP_SLUG: replicated-sdk-subchart-replicated-helm | |
run: | | |
# remove the app | |
./bin/kots remove "$APP_SLUG" -n "$KOTS_NAMESPACE" --undeploy | |
# validate that the app reference was removed | |
if [ "$(./bin/kots get apps --namespace "$KOTS_NAMESPACE" --output=json | tr -d '\n')" != "[]" ]; then | |
printf "App reference was not removed\n\n" | |
exit 1 | |
fi | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-support-bundle: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0}, | |
{distribution: openshift, version: 4.15.0-okd} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@support-bundle' | |
kots-namespace: 'support-bundle' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-gitops: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-e2e, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: download e2e deps | |
uses: actions/download-artifact@v4 | |
with: | |
name: e2e | |
path: e2e/bin/ | |
- run: docker load -i e2e/bin/e2e-deps.tar | |
- run: chmod +x e2e/bin/* | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/* | |
- uses: ./.github/actions/kots-e2e | |
with: | |
test-id: '@gitops' | |
kots-namespace: 'gitops' | |
k8s-distribution: ${{ matrix.cluster.distribution }} | |
k8s-version: ${{ matrix.cluster.version }} | |
testim-access-token: '${{ secrets.TESTIM_ACCESS_TOKEN }}' | |
testim-branch: ${{ github.head_ref == 'main' && 'master' || github.head_ref }} | |
replicated-api-token: '${{ secrets.C11Y_MATRIX_TOKEN }}' | |
kots-dockerhub-username: '${{ secrets.E2E_DOCKERHUB_USERNAME }}' | |
kots-dockerhub-password: '${{ secrets.E2E_DOCKERHUB_PASSWORD }}' | |
validate-get-set-config: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: get-set-config | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: install yq | |
run: | | |
sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq | |
sudo chmod +x /usr/bin/yq | |
- name: run the test | |
run: | | |
set -e | |
echo ${{ secrets.GET_SET_CONFIG_LICENSE }} | base64 -d > license.yaml | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--kotsadm-tag 24h | |
function validate_configmap { | |
local key="$1" | |
local expected_value="$2" | |
if [ "$(kubectl get configmap config-values -n "$APP_SLUG" -o jsonpath="{.data.$key}")" != "$expected_value" ]; then | |
printf "expected %s value in configmap to be %s. got:\n\n" "$key" "$expected_value" | |
kubectl get configmap config-values -n "$APP_SLUG" -oyaml | |
exit 1 | |
fi | |
} | |
function validate_configvalues { | |
local config_values="$1" | |
local key="$2" | |
local expected_default="$3" | |
local expected_value="$4" | |
if [ "$(echo "$config_values" | yq -r ".spec.values.$key.default")" != "$expected_default" ]; then | |
printf "expected %s default in configvalues to be %s. got:\n\n" "$key" "$expected_default" | |
echo "$config_values" | |
exit 1 | |
fi | |
if [ "$(echo "$config_values" | yq -r ".spec.values.$key.value")" != "$expected_value" ]; then | |
printf "expected %s value in configvalues to be %s. got:\n\n" "$key" "$expected_value" | |
echo "$config_values" | |
exit 1 | |
fi | |
} | |
# give time for initial configmap to be created/deployed | |
sleep 5 | |
validate_configmap "username" "" | |
validate_configmap "email" "" | |
validate_configmap "password" "" | |
validate_configmap "sequence" "0" | |
./bin/kots set config "$APP_SLUG" --key=password --value=example-password --namespace "$APP_SLUG" # don't deploy | |
sleep 5 | |
validate_configmap "username" "" | |
validate_configmap "password" "" | |
validate_configmap "email" "" | |
validate_configmap "sequence" "0" | |
./bin/kots set config "$APP_SLUG" --key=username --value=example-username --namespace "$APP_SLUG" --deploy | |
sleep 5 | |
validate_configmap "username" "example-username" | |
validate_configmap "password" "example-password" | |
validate_configmap "email" "" | |
validate_configmap "sequence" "2" | |
./bin/kots set config "$APP_SLUG" --key=email --value=example-email --namespace "$APP_SLUG" # don't deploy | |
sleep 5 | |
validate_configmap "username" "example-username" | |
validate_configmap "password" "example-password" | |
validate_configmap "email" "" | |
validate_configmap "sequence" "2" | |
# validate getting config values (returned sequence is +1 for some reason :shrug:) | |
config_values=$(./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt --sequence=0) | |
validate_configvalues "$config_values" "username" "null" "null" | |
validate_configvalues "$config_values" "password" "null" "null" | |
validate_configvalues "$config_values" "email" "null" "null" | |
validate_configvalues "$config_values" "sequence" "1" "null" | |
config_values=$(./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt --sequence=1) | |
validate_configvalues "$config_values" "username" "null" "null" | |
validate_configvalues "$config_values" "password" "null" "example-password" | |
validate_configvalues "$config_values" "email" "null" "null" | |
validate_configvalues "$config_values" "sequence" "2" "null" | |
config_values=$(./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt --sequence=2) | |
validate_configvalues "$config_values" "username" "null" "example-username" | |
validate_configvalues "$config_values" "password" "null" "example-password" | |
validate_configvalues "$config_values" "email" "null" "null" | |
validate_configvalues "$config_values" "sequence" "3" "null" | |
config_values=$(./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt --sequence=3) | |
validate_configvalues "$config_values" "username" "null" "example-username" | |
validate_configvalues "$config_values" "password" "null" "example-password" | |
validate_configvalues "$config_values" "email" "null" "example-email" | |
validate_configvalues "$config_values" "sequence" "4" "null" | |
config_values=$(./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt) # latest sequence | |
validate_configvalues "$config_values" "username" "null" "example-username" | |
validate_configvalues "$config_values" "password" "null" "example-password" | |
validate_configvalues "$config_values" "email" "null" "example-email" | |
validate_configvalues "$config_values" "sequence" "4" "null" | |
config_values=$(./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt --current) # currently deployed sequence | |
validate_configvalues "$config_values" "username" "null" "example-username" | |
validate_configvalues "$config_values" "password" "null" "example-password" | |
validate_configvalues "$config_values" "email" "null" "null" | |
validate_configvalues "$config_values" "sequence" "3" "null" | |
# validate updating currently deployed config | |
./bin/kots set config "$APP_SLUG" --key=password --value=updated-password --namespace "$APP_SLUG" --current --deploy | |
sleep 5 | |
validate_configmap "username" "example-username" | |
validate_configmap "password" "updated-password" | |
validate_configmap "email" "" | |
validate_configmap "sequence" "4" | |
# validate updating specific sequence | |
./bin/kots set config "$APP_SLUG" --key=username --value=updated-username --namespace "$APP_SLUG" --sequence=0 --deploy | |
sleep 5 | |
validate_configmap "username" "updated-username" | |
validate_configmap "password" "" | |
validate_configmap "email" "" | |
validate_configmap "sequence" "5" | |
# should not be able to use --current and --sequence together | |
if ./bin/kots get config "$APP_SLUG" --namespace "$APP_SLUG" --decrypt --sequence=0 --current; then | |
echo "expected error when using --current and --sequence together in get config" | |
exit 1 | |
fi | |
if ./bin/kots set config "$APP_SLUG" --key=username --value=updated-username --namespace "$APP_SLUG" --sequence=0 --current --deploy; then | |
echo "expected error when using --current and --sequence together in set config" | |
exit 1 | |
fi | |
# ---- validate archives ---- # | |
function validate_configmap_in_archive { | |
local expected_value="$1" | |
if ! grep -q "$expected_value" get-set-config/base/configmap.yaml; then | |
echo "expected base/configmap.yaml to contain $expected_value:" | |
cat get-set-config/base/configmap.yaml | |
exit 1 | |
fi | |
} | |
# make latest different from current | |
./bin/kots set config "$APP_SLUG" --key=username --value=latest-username --namespace "$APP_SLUG" | |
# validate the archive for sequence 0 | |
./bin/kots download --namespace "$APP_SLUG" --slug "$APP_SLUG" --sequence=0 --decrypt-password-values --overwrite | |
validate_configmap_in_archive "username: ''" | |
validate_configmap_in_archive "password: ''" | |
validate_configmap_in_archive "email: ''" | |
validate_configmap_in_archive "sequence: '0'" | |
# validate the archive for sequence 2 | |
./bin/kots download --namespace "$APP_SLUG" --slug "$APP_SLUG" --sequence=2 --decrypt-password-values --overwrite | |
validate_configmap_in_archive "username: 'example-username'" | |
validate_configmap_in_archive "password: 'example-password'" | |
validate_configmap_in_archive "email: ''" | |
validate_configmap_in_archive "sequence: '2'" | |
# validate the archive for the currently deployed version | |
./bin/kots download --namespace "$APP_SLUG" --slug "$APP_SLUG" --current --decrypt-password-values --overwrite | |
validate_configmap_in_archive "username: 'updated-username'" | |
validate_configmap_in_archive "password: ''" | |
validate_configmap_in_archive "email: ''" | |
validate_configmap_in_archive "sequence: '5'" | |
# validate the archive for the latest version | |
./bin/kots download --namespace "$APP_SLUG" --slug "$APP_SLUG" --decrypt-password-values --overwrite | |
validate_configmap_in_archive "username: 'latest-username'" | |
validate_configmap_in_archive "password: ''" | |
validate_configmap_in_archive "email: ''" | |
validate_configmap_in_archive "sequence: '6'" | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-custom-cas: | |
runs-on: ubuntu-20.04 | |
needs: [ enable-tests, can-run-ci, build-kots, build-kotsadm, build-kurl-proxy, build-migrations, push-minio, push-rqlite ] | |
strategy: | |
fail-fast: false | |
matrix: | |
cluster: [ | |
{distribution: kind, version: v1.28.0} | |
] | |
env: | |
APP_SLUG: get-set-config | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
- name: Create Cluster | |
id: create-cluster | |
uses: replicatedhq/replicated-actions/create-cluster@v1 | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
kubernetes-distribution: ${{ matrix.cluster.distribution }} | |
kubernetes-version: ${{ matrix.cluster.version }} | |
cluster-name: automated-kots-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} | |
timeout-minutes: '120' | |
ttl: 2h | |
export-kubeconfig: true | |
- name: download kots binary | |
uses: actions/download-artifact@v4 | |
with: | |
name: kots | |
path: bin/ | |
- run: chmod +x bin/kots | |
- name: create namespace and dockerhub secret | |
run: | | |
kubectl create ns "$APP_SLUG" | |
kubectl create secret docker-registry kotsadm-dockerhub --docker-server index.docker.io --docker-username "${{ secrets.E2E_DOCKERHUB_USERNAME }}" --docker-password "${{ secrets.E2E_DOCKERHUB_PASSWORD }}" --namespace "$APP_SLUG" | |
- name: install yq | |
run: | | |
sudo wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq | |
sudo chmod +x /usr/bin/yq | |
- name: run the test | |
run: | | |
set -e | |
echo ${{ secrets.GET_SET_CONFIG_LICENSE }} | base64 -d > license.yaml | |
echo "test value" > ./ca.crt | |
kubectl create configmap -n "$APP_SLUG" custom-cas --from-file=ca.crt=./ca.crt | |
./bin/kots \ | |
install "$APP_SLUG/automated" \ | |
--license-file license.yaml \ | |
--no-port-forward \ | |
--namespace "$APP_SLUG" \ | |
--shared-password password \ | |
--kotsadm-registry ttl.sh \ | |
--kotsadm-namespace automated-${{ github.run_id }} \ | |
--private-ca-configmap custom-cas \ | |
--kotsadm-tag 24h | |
echo "exec into the deployment and check for the file and its contents" | |
if ! kubectl exec -n "$APP_SLUG" deployment/kotsadm -- cat /certs/ca.crt | grep "test value"; then | |
echo "expected /certs/ca.crt to contain 'test value'" | |
kubectl exec -n "$APP_SLUG" deployment/kotsadm -- cat /certs/ca.crt | |
exit 1 | |
fi | |
echo "check that the deployment has an environment variable pointing to the file" | |
if ! kubectl exec -n "$APP_SLUG" deployment/kotsadm -- env | grep "SSL_CERT_DIR" | grep "/certs"; then | |
echo "expected env output to contain SSL_CERT_DIR=/certs" | |
kubectl exec -n "$APP_SLUG" deployment/kotsadm -- env | |
exit 1 | |
fi | |
echo "check that the deployment has an environment variable with the configmap name" | |
if ! kubectl exec -n "$APP_SLUG" deployment/kotsadm -- env | grep "SSL_CERT_CONFIGMAP" | grep "custom-cas"; then | |
echo "expected env output to contain SSL_CERT_CONFIGMAP=custom-cas" | |
kubectl exec -n "$APP_SLUG" deployment/kotsadm -- env | |
exit 1 | |
fi | |
./bin/kots admin-console generate-manifests -n "$APP_SLUG" --shared-password password --private-ca-configmap generated-custom-cas | |
ls ./admin-console | |
if ! grep SSL_CERT_CONFIGMAP < ./admin-console/kotsadm-deployment.yaml; then | |
echo "expected generated kotsadm-deployment.yaml to contain SSL_CERT_CONFIGMAP" | |
cat ./admin-console/kotsadm-deployment.yaml | |
exit 1 | |
fi | |
if ! grep generated-custom-cas < ./admin-console/kotsadm-deployment.yaml; then | |
echo "expected generated kotsadm-deployment.yaml to contain generated-custom-cas" | |
cat ./admin-console/kotsadm-deployment.yaml | |
exit 1 | |
fi | |
- name: Generate support bundle on failure | |
if: failure() | |
uses: ./.github/actions/generate-support-bundle | |
with: | |
kots-namespace: "$APP_SLUG" | |
artifact-name: ${{ github.job }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}-support-bundle | |
- name: Remove Cluster | |
id: remove-cluster | |
uses: replicatedhq/replicated-actions/remove-cluster@v1 | |
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }} | |
continue-on-error: true | |
with: | |
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }} | |
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }} | |
validate-pr-tests: | |
runs-on: ubuntu-20.04 | |
needs: | |
# static and unit tests | |
- lint-web | |
- unit-test-web | |
- vet-kots | |
- ci-test-kots | |
# testim tests | |
- validate-existing-online-install-minimal | |
- validate-version-history-pagination | |
- validate-min-kots-version | |
- validate-target-kots-version | |
- validate-range-kots-version | |
- validate-airgap-smoke-test | |
- validate-support-bundle | |
- validate-gitops | |
# playwright tests | |
- validate-smoke-test | |
- validate-backup-and-restore | |
- validate-no-required-config | |
- validate-config | |
- validate-change-channel | |
- validate-multi-app-backup-and-restore | |
- validate-multi-app-install | |
- validate-change-license | |
# non-testim tests | |
- validate-minimal-rbac | |
- validate-minimal-rbac-override | |
- validate-multi-namespace | |
- validate-kots-pull | |
- validate-app-version-label | |
- validate-helm-install-order | |
- validate-no-redeploy-on-restart | |
- validate-kubernetes-installer-preflight | |
- validate-kots-upgrade | |
- validate-remove-app | |
- validate-registry-check | |
- validate-kots-helm-release-secret-migration | |
- validate-native-helm-v2 | |
- validate-deployment-orchestration | |
- validate-replicated-sdk | |
- validate-strict-preflight-checks | |
- validate-get-set-config | |
- validate-custom-cas | |
# cli-only tests | |
- validate-kots-push-images-anonymous | |
steps: | |
- run: echo "All PR tests passed" | |
# this job will validate that the kurl add-on validation did not fail and that all pr-tests succeed | |
# it is used for the github branch protection rule | |
validate-success: | |
runs-on: ubuntu-20.04 | |
needs: | |
- validate-kurl-addon | |
- validate-pr-tests | |
if: always() | |
steps: | |
# https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context | |
# if the validate-kurl-addon job failed or was cancelled, this job will fail. it's ok if this job was skipped | |
- name: fail if validate-kurl-addon job failed | |
if: needs.validate-kurl-addon.result == 'failure' || needs.validate-kurl-addon.result == 'cancelled' | |
run: exit 1 | |
# if the validate-pr-tests job was not successful, this job will fail | |
- name: fail if validate-pr-tests job was not successful | |
if: needs.validate-pr-tests.result != 'success' | |
run: exit 1 | |
# if the validate-pr-tests job was successful, this job will succeed | |
- name: succeed if validate-pr-tests job succeeded | |
if: needs.validate-pr-tests.result == 'success' | |
run: echo "Validation succeeded" |