diff --git a/.github/workflows/cleanup-e2e-images.yml b/.github/workflows/cleanup-e2e-images.yml index 6510b60..650f53d 100644 --- a/.github/workflows/cleanup-e2e-images.yml +++ b/.github/workflows/cleanup-e2e-images.yml @@ -19,7 +19,13 @@ jobs: with: persist-credentials: false + - name: Install regctl + run: | + curl -sL https://github.com/regclient/regclient/releases/download/v0.11.2/regctl-linux-amd64 -o /usr/local/bin/regctl + chmod +x /usr/local/bin/regctl + - name: Clean up e2e-* tags from capcs-staging env: - QUAY_E2E_TOKEN: ${{ secrets.QUAY_E2E_TOKEN }} + QUAY_E2E_USERNAME: ${{ secrets.QUAY_E2E_USERNAME }} + QUAY_E2E_PASSWORD: ${{ secrets.QUAY_E2E_PASSWORD }} run: make clean-e2e-images diff --git a/.github/workflows/e2e-biweekly.yml b/.github/workflows/e2e-biweekly.yml index 8fdab53..276c220 100644 --- a/.github/workflows/e2e-biweekly.yml +++ b/.github/workflows/e2e-biweekly.yml @@ -33,6 +33,12 @@ jobs: TAG: e2e-conformance-${{ github.sha }} run: make test-e2e-conformance + - name: Redact secrets from artifacts + if: always() + env: + CLOUDSCALE_API_TOKEN: ${{ secrets.CLOUDSCALE_API_TOKEN }} + run: hack/log/redact.sh || true + - name: Upload test artifacts if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 diff --git a/.github/workflows/e2e-nightly.yml b/.github/workflows/e2e-nightly.yml index 61713b4..93437bf 100644 --- a/.github/workflows/e2e-nightly.yml +++ b/.github/workflows/e2e-nightly.yml @@ -33,6 +33,12 @@ jobs: TAG: e2e-nightly-${{ github.sha }} run: make test-e2e-lifecycle + - name: Redact secrets from artifacts + if: always() + env: + CLOUDSCALE_API_TOKEN: ${{ secrets.CLOUDSCALE_API_TOKEN }} + run: hack/log/redact.sh || true + - name: Upload test artifacts if: always() uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 diff --git a/.github/workflows/e2e-weekly.yml b/.github/workflows/e2e-weekly.yml index 5d8f26e..49a620c 100644 --- a/.github/workflows/e2e-weekly.yml +++ b/.github/workflows/e2e-weekly.yml @@ -43,15 +43,23 @@ jobs: GINKGO_LABEL_FILTER="ha || upgrade || self-hosted || kcp-remediation || conformance" \ KUBETEST_CONFIGURATION=./data/kubetest/conformance-fast.yaml + - name: Install regctl + if: always() + run: | + curl -sL https://github.com/regclient/regclient/releases/download/v0.11.2/regctl-linux-amd64 -o /usr/local/bin/regctl + chmod +x /usr/local/bin/regctl + - name: Clean up e2e image if: always() - env: - QUAY_E2E_TOKEN: ${{ secrets.QUAY_E2E_TOKEN }} - TAG: e2e-weekly-${{ github.sha }} run: | - curl -s -X DELETE \ - -H "Authorization: Bearer ${QUAY_E2E_TOKEN}" \ - "https://quay.io/api/v1/repository/cloudscalech/capcs-staging/tag/${TAG}" + TAG="e2e-$(git rev-parse --short HEAD)" + regctl tag delete "quay.io/cloudscalech/capcs-staging:${TAG}" || true + + - name: Redact secrets from artifacts + if: always() + env: + CLOUDSCALE_API_TOKEN: ${{ secrets.CLOUDSCALE_API_TOKEN }} + run: hack/log/redact.sh || true - name: Upload test artifacts if: always() diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml index 8409b5c..a72c2ce 100644 --- a/.github/workflows/test-e2e.yml +++ b/.github/workflows/test-e2e.yml @@ -57,17 +57,27 @@ jobs: TEST_TARGET: ${{ github.event.inputs.test_target }} run: make $TEST_TARGET + - name: Install regctl + if: >- + github.event.inputs.test_target == 'test-e2e-self-hosted' || + github.event.inputs.test_target == 'test-e2e' + run: | + curl -sL https://github.com/regclient/regclient/releases/download/v0.11.2/regctl-linux-amd64 -o /usr/local/bin/regctl + chmod +x /usr/local/bin/regctl + - name: Clean up e2e image if: >- github.event.inputs.test_target == 'test-e2e-self-hosted' || github.event.inputs.test_target == 'test-e2e' - env: - QUAY_E2E_TOKEN: ${{ secrets.QUAY_E2E_TOKEN }} - TAG: e2e-manual-${{ github.sha }} run: | - curl -s -X DELETE \ - -H "Authorization: Bearer ${QUAY_E2E_TOKEN}" \ - "https://quay.io/api/v1/repository/cloudscalech/capcs-staging/tag/${TAG}" + TAG="e2e-$(git rev-parse --short HEAD)" + regctl tag delete "quay.io/cloudscalech/capcs-staging:${TAG}" || true + + - name: Redact secrets from artifacts + if: always() + env: + CLOUDSCALE_API_TOKEN: ${{ secrets.CLOUDSCALE_API_TOKEN }} + run: hack/log/redact.sh || true - name: Upload test artifacts if: always() diff --git a/Makefile b/Makefile index 7b93c11..524e5bc 100644 --- a/Makefile +++ b/Makefile @@ -271,7 +271,7 @@ docker-push: ## Push docker image with the manager. $(CONTAINER_TOOL) push ${IMG} .PHONY: clean-e2e-images -clean-e2e-images: ## Delete e2e-* tags older than 7 days from capcs-staging (requires QUAY_E2E_TOKEN) +clean-e2e-images: ## Delete e2e-* tags older than 7 days from capcs-staging (requires regctl + quay.io auth) @./hack/clean-e2e-images.sh # PLATFORMS defines the target platforms for the manager image be built to provide support to multiple diff --git a/go.mod b/go.mod index b0f2c95..96c1b7c 100644 --- a/go.mod +++ b/go.mod @@ -16,8 +16,8 @@ require ( k8s.io/client-go v0.35.2 k8s.io/klog/v2 v2.130.1 k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 - sigs.k8s.io/cluster-api v1.12.4 - sigs.k8s.io/cluster-api/test v1.12.4 + sigs.k8s.io/cluster-api v1.13.0-beta.0 + sigs.k8s.io/cluster-api/test v1.13.0-beta.0 sigs.k8s.io/controller-runtime v0.23.3 ) @@ -31,14 +31,12 @@ require ( github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Microsoft/go-winio v0.5.0 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/adrg/xdg v0.5.3 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cloudflare/circl v1.6.3 // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -65,7 +63,7 @@ require ( github.com/google/cel-go v0.26.0 // indirect github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/go-github/v53 v53.2.0 // indirect + github.com/google/go-github/v82 v82.0.0 // indirect github.com/google/go-querystring v1.2.0 // indirect github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect github.com/google/uuid v1.6.0 // indirect diff --git a/go.sum b/go.sum index 40146b4..b6aaff9 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,6 @@ github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Microsoft/go-winio v0.5.0 h1:Elr9Wn+sGKPlkaBvwu4mTrxtmOp3F3yV9qhaHbXGjwU= github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78= github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= @@ -28,14 +26,10 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= -github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= -github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= -github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= github.com/cloudscale-ch/cloudscale-go-sdk/v8 v8.0.0 h1:XP3thdgotNVpPF27568RYHt9kqosVm8eJznJ+X4PJIk= github.com/cloudscale-ch/cloudscale-go-sdk/v8 v8.0.0/go.mod h1:H4qxiHJof+IdwvaV26ZcmNR39EyggnKIcDfLYcYnBCI= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= @@ -46,8 +40,8 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coredns/caddy v1.1.1 h1:2eYKZT7i6yxIfGP3qLJoJ7HAsDJqYB+X68g4NYjSrE0= github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/coredns/corefile-migration v1.0.30 h1:ljZNPGgna+4yKv81gfkvkgLEWdtz0NjBR1glaiPI140= -github.com/coredns/corefile-migration v1.0.30/go.mod h1:56DPqONc3njpVPsdilEnfijCwNGC3/kTJLl7i7SPavY= +github.com/coredns/corefile-migration v1.0.31 h1:f7WGhY8M2Jn8P2dVO0p7wSQ1QKsMARl6WEyUjCb/V38= +github.com/coredns/corefile-migration v1.0.31/go.mod h1:56DPqONc3njpVPsdilEnfijCwNGC3/kTJLl7i7SPavY= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= @@ -128,8 +122,8 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI= -github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao= +github.com/google/go-github/v82 v82.0.0 h1:OH09ESON2QwKCUVMYmMcVu1IFKFoaZHwqYaUtr/MVfk= +github.com/google/go-github/v82 v82.0.0/go.mod h1:hQ6Xo0VKfL8RZ7z1hSfB4fvISg0QqHOqe9BP0qo+WvM= github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0= github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -286,12 +280,12 @@ github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADT github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -go.etcd.io/etcd/api/v3 v3.6.6 h1:mcaMp3+7JawWv69p6QShYWS8cIWUOl32bFLb6qf8pOQ= -go.etcd.io/etcd/api/v3 v3.6.6/go.mod h1:f/om26iXl2wSkcTA1zGQv8reJRSLVdoEBsi4JdfMrx4= -go.etcd.io/etcd/client/pkg/v3 v3.6.6 h1:uoqgzSOv2H9KlIF5O1Lsd8sW+eMLuV6wzE3q5GJGQNs= -go.etcd.io/etcd/client/pkg/v3 v3.6.6/go.mod h1:YngfUVmvsvOJ2rRgStIyHsKtOt9SZI2aBJrZiWJhCbI= -go.etcd.io/etcd/client/v3 v3.6.6 h1:G5z1wMf5B9SNexoxOHUGBaULurOZPIgGPsW6CN492ec= -go.etcd.io/etcd/client/v3 v3.6.6/go.mod h1:36Qv6baQ07znPR3+n7t+Rk5VHEzVYPvFfGmfF4wBHV8= +go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= +go.etcd.io/etcd/api/v3 v3.6.8/go.mod h1:qyQj1HZPUV3B5cbAL8scG62+fyz5dSxxu0w8pn28N6Q= +go.etcd.io/etcd/client/pkg/v3 v3.6.8 h1:Qs/5C0LNFiqXxYf2GU8MVjYUEXJ6sZaYOz0zEqQgy50= +go.etcd.io/etcd/client/pkg/v3 v3.6.8/go.mod h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw= +go.etcd.io/etcd/client/v3 v3.6.8 h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY= +go.etcd.io/etcd/client/v3 v3.6.8/go.mod h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.65.0 h1:XmiuHzgJt067+a6kwyAzkhXooYVv3/TOw9cM2VfJgUM= @@ -326,14 +320,12 @@ go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= @@ -341,22 +333,16 @@ golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7 golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0= @@ -405,10 +391,10 @@ k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzk k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/cluster-api v1.12.4 h1:usvoZ+Nblfu//l31hm1B1WUdigb6OnGAJqwt8qWq/iA= -sigs.k8s.io/cluster-api v1.12.4/go.mod h1:ePDeVCVaW6SGxRgDeLt5+KK4TigEnF0LPV6ztEzRzlI= -sigs.k8s.io/cluster-api/test v1.12.4 h1:I1x28SO54mAv3hk/ZQFKr7PKyAviAfil2YpdD9g2OeQ= -sigs.k8s.io/cluster-api/test v1.12.4/go.mod h1:+3Xo0ZughngvRVKKYyq6oL7qgRp9Sdl/6qQ+lkoO6ME= +sigs.k8s.io/cluster-api v1.13.0-beta.0 h1:RmnhP+XWKABSQcW86WVGNIFg8bUPUKvEKfD9ucKLmNQ= +sigs.k8s.io/cluster-api v1.13.0-beta.0/go.mod h1:gNQrTS/VtkwT7ItKf5+eUj6uiTjzb5fwF8ksVKHA2Gk= +sigs.k8s.io/cluster-api/test v1.13.0-beta.0 h1:kOMfJG9NgVAS7a675NnwAsr1JxH1yGq9IB+o+AWKbF8= +sigs.k8s.io/cluster-api/test v1.13.0-beta.0/go.mod h1:ESHqwOD5qkZbwguMeGRVALCzdVVjf4dGyoJnLZQgL0s= sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80= sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= diff --git a/hack/clean-e2e-images.sh b/hack/clean-e2e-images.sh index d5e9a83..0ef4a82 100755 --- a/hack/clean-e2e-images.sh +++ b/hack/clean-e2e-images.sh @@ -1,20 +1,26 @@ #!/usr/bin/env bash # Delete e2e-* image tags older than 7 days from capcs-staging on quay.io. -# Requires QUAY_E2E_TOKEN environment variable (OAuth token with repo:admin scope). +# Requires regctl to be installed and authenticated (via docker login or regctl registry login). +# If QUAY_E2E_USERNAME and QUAY_E2E_PASSWORD are set, the script logs in automatically. # Set DRY_RUN=true to list tags without deleting them. set -euo pipefail -REPO="cloudscalech/capcs-staging" -API="https://quay.io/api/v1/repository/${REPO}/tag/" +REPO="quay.io/cloudscalech/capcs-staging" MAX_AGE_DAYS="${MAX_AGE_DAYS:-7}" DRY_RUN="${DRY_RUN:-false}" -if [[ -z "${QUAY_E2E_TOKEN:-}" ]]; then - echo "Error: QUAY_E2E_TOKEN environment variable is required" >&2 +if ! command -v regctl &>/dev/null; then + echo "Error: regctl is not installed" >&2 exit 1 fi +# Login if credentials are provided +if [[ -n "${QUAY_E2E_USERNAME:-}" && -n "${QUAY_E2E_PASSWORD:-}" ]]; then + echo "${QUAY_E2E_PASSWORD}" | regctl registry login quay.io --user "${QUAY_E2E_USERNAME}" --pass-stdin +fi + +# Calculate cutoff timestamp cutoff=$(date -u -v-${MAX_AGE_DAYS}d +%s 2>/dev/null || date -u -d "${MAX_AGE_DAYS} days ago" +%s) if [[ "${DRY_RUN}" == "true" ]]; then @@ -22,37 +28,46 @@ if [[ "${DRY_RUN}" == "true" ]]; then fi echo "Listing e2e-* tags older than ${MAX_AGE_DAYS} days..." -page=1 +# List all tags and filter for e2e-* prefix +tags=$(regctl tag ls "${REPO}" | grep '^e2e-' || true) + +if [[ -z "${tags}" ]]; then + echo "No e2e-* tags found." + exit 0 +fi + deleted=0 -while true; do - response=$(curl -s -H "Authorization: Bearer ${QUAY_E2E_TOKEN}" \ - "${API}?filter_tag_name=like:e2e-%25&limit=100&page=${page}") +while IFS= read -r name; do + # Get the image creation timestamp (RFC3339 format) + created=$(regctl image config "${REPO}:${name}" --format '{{.Created}}' 2>/dev/null || true) + + if [[ -z "${created}" ]]; then + echo "Warning: could not get creation time for tag ${name}, skipping" + continue + fi - tags=$(echo "${response}" | jq -r '.tags // [] | .[] | select(.end_ts == null) | "\(.name) \(.start_ts)"') + # Convert RFC3339 to epoch (strip fractional seconds and Z suffix for macOS compatibility) + stripped=$(echo "${created}" | sed 's/\.[0-9]*Z$//' | sed 's/Z$//') + created_ts=$(date -u -jf "%Y-%m-%dT%H:%M:%S" "${stripped}" +%s 2>/dev/null \ + || date -u -d "${created}" +%s 2>/dev/null \ + || true) - if [[ -z "${tags}" ]]; then - break + if [[ -z "${created_ts}" ]]; then + echo "Warning: could not parse creation time '${created}' for tag ${name}, skipping" + continue fi - while IFS=' ' read -r name start_ts; do - if [[ "${start_ts}" -lt "${cutoff}" ]]; then - created=$(date -u -r "${start_ts}" 2>/dev/null || date -u -d "@${start_ts}") - if [[ "${DRY_RUN}" == "true" ]]; then - echo "Would delete tag: ${name} (created ${created})" - else - echo "Deleting tag: ${name} (created ${created})" - curl -s -X DELETE -H "Authorization: Bearer ${QUAY_E2E_TOKEN}" "${API}${name}" > /dev/null - fi - deleted=$((deleted + 1)) + if [[ "${created_ts}" -lt "${cutoff}" ]]; then + created_human=$(date -u -r "${created_ts}" 2>/dev/null || date -u -d "@${created_ts}") + if [[ "${DRY_RUN}" == "true" ]]; then + echo "Would delete tag: ${name} (created ${created_human})" + else + echo "Deleting tag: ${name} (created ${created_human})" + regctl tag delete "${REPO}:${name}" fi - done <<< "${tags}" - - has_more=$(echo "${response}" | jq -r '.has_additional') - if [[ "${has_more}" != "true" ]]; then - break + deleted=$((deleted + 1)) fi - page=$((page + 1)) -done +done <<< "${tags}" if [[ "${DRY_RUN}" == "true" ]]; then echo "Would delete ${deleted} e2e tag(s)." diff --git a/hack/log/redact.sh b/hack/log/redact.sh new file mode 100755 index 0000000..6f26e2a --- /dev/null +++ b/hack/log/redact.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# Copyright 2026 cloudscale.ch. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -o errexit +set -o nounset +set -o pipefail + +echo "================ REDACTING LOGS ================" +# shellcheck disable=SC2207 +log_files=($(find "${ARTIFACTS:-${PWD}/_artifacts}" -type f)) +redact_vars=( + "${CLOUDSCALE_API_TOKEN:-}" + "$(echo -n "${CLOUDSCALE_API_TOKEN:-}" | base64 | tr -d '\n')" +) + +for log_file in "${log_files[@]}"; do + for redact_var in "${redact_vars[@]}"; do + if [ -z "${redact_var}" ]; then + continue + fi + # LC_CTYPE=C and LANG=C will prevent "illegal byte sequence" error from sed + if [[ "$(uname)" == "Darwin" ]]; then + # sed on Mac OS requires an empty string for -i flag + LC_CTYPE=C LANG=C sed -i "" "s|${redact_var}|===REDACTED===|g" "${log_file}" &>/dev/null || true + else + LC_CTYPE=C LANG=C sed -i "s|${redact_var}|===REDACTED===|g" "${log_file}" &>/dev/null || true + fi + done +done + +echo "All sensitive variables are redacted"