diff --git a/.codecov.yml b/.codecov.yml index a8e52fbeca..2758a60933 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -19,3 +19,5 @@ ignore: - 'pkg/client/.*' - 'vendor/.*' - '**/mocks/*' + - 'hack/gen-crd-spec/main.go' + - 'hack/gen-docs/main.go' diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 7b7b2c5300..0b7aca1509 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -95,4 +95,4 @@ jobs: with: name: e2e-controller-k8s-${{ matrix.kubernetes-minor-version }}.log path: /tmp/e2e-controller.log - if: ${{ failure() }} + if: ${{ always() }} diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 959ea6e835..4e89aadfdf 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -42,7 +42,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - name: Run golangci-lint - uses: golangci/golangci-lint-action@v5 + uses: golangci/golangci-lint-action@v6 with: version: v1.57.2 args: --timeout 6m @@ -90,9 +90,12 @@ jobs: path: coverage.out - name: Upload code coverage information to codecov.io - uses: codecov/codecov-action@v4.3.1 + uses: codecov/codecov-action@v4.5.0 with: file: coverage.out + fail_ci_if_error: false + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} codegen: name: Verify Codegen diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index b78d72a061..cd46e06705 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -106,7 +106,7 @@ jobs: echo 'EOF' >> $GITHUB_ENV - name: Login to Quay.io - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: registry: quay.io username: ${{ secrets.quay_username }} @@ -114,7 +114,7 @@ jobs: if: ${{ inputs.quay_image_name && inputs.push }} - name: Login to GitHub Container Registry - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: registry: ghcr.io username: ${{ secrets.ghcr_username }} @@ -122,7 +122,7 @@ jobs: if: ${{ inputs.ghcr_image_name && inputs.push }} - name: Login to dockerhub Container Registry - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: username: ${{ secrets.docker_username }} password: ${{ secrets.docker_password }} @@ -130,7 +130,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 #v5.3.0 + uses: docker/build-push-action@15560696de535e4014efeff63c48f16952e52dd1 #v6.2.0 with: context: . platforms: ${{ inputs.platforms }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c9e2ca60b8..ef35402a72 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -107,7 +107,7 @@ jobs: make manifests IMAGE_TAG=${{ github.ref_name }} - name: Draft release - uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v0.1.15 + uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 # v0.1.15 with: tag_name: ${{ github.event.inputs.tag }} draft: true @@ -212,7 +212,7 @@ jobs: /tmp/sbom.tar.gz - name: Upload SBOM and signature assets - uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v0.1.15 + uses: softprops/action-gh-release@a74c6b72af54cfa997e81df42d94703d6313a2d0 # v0.1.15 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/CHANGELOG.md b/CHANGELOG.md index 48a46a8bad..263680f07d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ + +## [v1.7.1](https://github.com/argoproj/argo-rollouts/compare/v1.7.0...v1.7.1) (2024-06-22) + +### Fix + +* docs site version selector broken ([#3590](https://github.com/argoproj/argo-rollouts/issues/3590)) +* don't default datadog aggregator ([#3643](https://github.com/argoproj/argo-rollouts/issues/3643)) +* Add volume for plugin and tmp folder ([#3546](https://github.com/argoproj/argo-rollouts/issues/3546)) + + + +## [v1.7.0](https://github.com/argoproj/argo-rollouts/compare/v1.7.0-rc1...v1.7.0) (2024-06-12) + +### Fix + +* verify the weight of the alb at the end of the rollout ([#3627](https://github.com/argoproj/argo-rollouts/issues/3627)) +* when Rollout has pingpong and stable/canary service defined, only alb traffic management uses pingpong. ([#3628](https://github.com/argoproj/argo-rollouts/issues/3628)) +* protocol missing in ambassador canary mapping creation. Fixes [#3593](https://github.com/argoproj/argo-rollouts/issues/3593) ([#3603](https://github.com/argoproj/argo-rollouts/issues/3603)) +* rs conflict with fallback to patch ([#3559](https://github.com/argoproj/argo-rollouts/issues/3559)) +* **controller:** Corrects the logic of comparing sha256 has. Fixes [#3519](https://github.com/argoproj/argo-rollouts/issues/3519) ([#3520](https://github.com/argoproj/argo-rollouts/issues/3520)) + ## [v1.7.0-rc1](https://github.com/argoproj/argo-rollouts/compare/v1.6.6...v1.7.0-rc1) (2024-04-03) diff --git a/Makefile b/Makefile index fd5736aa15..609cb724d9 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEV_IMAGE ?= false E2E_INSTANCE_ID ?= argo-rollouts-e2e E2E_TEST_OPTIONS ?= E2E_PARALLEL ?= 1 -E2E_WAIT_TIMEOUT ?= 120 +E2E_WAIT_TIMEOUT ?= 90 GOPATH ?= $(shell go env GOPATH) # Global toolchain configuration diff --git a/docs/assets/versions.js b/docs/assets/versions.js index 1336443d1a..fe0aeb1d3c 100644 --- a/docs/assets/versions.js +++ b/docs/assets/versions.js @@ -1,15 +1,40 @@ -setTimeout(function() { - const callbackName = 'callback_' + new Date().getTime(); - window[callbackName] = function (response) { - const div = document.createElement('div'); - div.innerHTML = response.html; - document.querySelector(".md-header__inner > .md-header__title").appendChild(div); - const container = div.querySelector('.rst-versions'); - var caret = document.createElement('div'); - caret.innerHTML = "" - caret.classList.add('dropdown-caret') - div.querySelector('.rst-current-version').appendChild(caret); +const targetNode = document.querySelector('.md-header__inner'); +const observerOptions = { + childList: true, + subtree: true +}; + +const observerCallback = function(mutationsList, observer) { + for (let mutation of mutationsList) { + if (mutation.type === 'childList') { + const titleElement = document.querySelector('.md-header__inner > .md-header__title'); + if (titleElement) { + initializeVersionDropdown(); + observer.disconnect(); + } + } } +}; + +const observer = new MutationObserver(observerCallback); +observer.observe(targetNode, observerOptions); + +function initializeVersionDropdown() { + const callbackName = 'callback_' + new Date().getTime(); + window[callbackName] = function(response) { + const div = document.createElement('div'); + div.innerHTML = response.html; + document.querySelector(".md-header__inner > .md-header__title").appendChild(div); + const container = div.querySelector('.rst-versions'); + var caret = document.createElement('div'); + caret.innerHTML = ""; + caret.classList.add('dropdown-caret'); + div.querySelector('.rst-current-version').appendChild(caret); + + div.querySelector('.rst-current-version').addEventListener('click', function() { + container.classList.toggle('shift-up'); + }); + }; var CSSLink = document.createElement('link'); CSSLink.rel='stylesheet'; @@ -20,6 +45,31 @@ setTimeout(function() { script.src = 'https://argo-rollouts.readthedocs.io/_/api/v2/footer_html/?'+ 'callback=' + callbackName + '&project=argo-rollouts&page=&theme=mkdocs&format=jsonp&docroot=docs&source_suffix=.md&version=' + (window['READTHEDOCS_DATA'] || { version: 'latest' }).version; document.getElementsByTagName('head')[0].appendChild(script); -}, 0); - +} +// VERSION WARNINGS +window.addEventListener("DOMContentLoaded", function() { + var currentVersion = window.location.href.match(/\/en\/(release-(?:v\d+|\w+)|latest|stable)\//); + var margin = 30; + var headerHeight = document.getElementsByClassName("md-header")[0].offsetHeight; + if (currentVersion && currentVersion.length > 1) { + currentVersion = currentVersion[1]; + if (currentVersion === "latest") { + document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for an unreleased version of Argo Rollouts, click here to go to the latest stable version.
"; + var bannerHeight = document.getElementById('announce-msg').offsetHeight + margin; + document.querySelector("header.md-header").style.top = bannerHeight + "px"; + document.querySelector('style').textContent += + "@media screen and (min-width: 76.25em){ .md-sidebar { height: 0; top:" + (bannerHeight + headerHeight) + "px !important; }}"; + document.querySelector('style').textContent += + "@media screen and (min-width: 60em){ .md-sidebar--secondary { height: 0; top:" + (bannerHeight + headerHeight) + "px !important; }}"; + } else if (currentVersion !== "stable") { + document.querySelector("div[data-md-component=announce]").innerHTML = "
You are viewing the docs for a previous version of Argo Rollouts, click here to go to the latest stable version.
"; + var bannerHeight = document.getElementById('announce-msg').offsetHeight + margin; + document.querySelector("header.md-header").style.top = bannerHeight + "px"; + document.querySelector('style').textContent += + "@media screen and (min-width: 76.25em){ .md-sidebar { height: 0; top:" + (bannerHeight + headerHeight) + "px !important; }}"; + document.querySelector('style').textContent += + "@media screen and (min-width: 60em){ .md-sidebar--secondary { height: 0; top:" + (bannerHeight + headerHeight) + "px !important; }}"; + } + } +}); \ No newline at end of file diff --git a/docs/features/kustomize/rollout_cr_schema.json b/docs/features/kustomize/rollout_cr_schema.json index 038ebebf89..b7ca35204f 100644 --- a/docs/features/kustomize/rollout_cr_schema.json +++ b/docs/features/kustomize/rollout_cr_schema.json @@ -244,7 +244,6 @@ "datadog": { "properties": { "aggregator": { - "default": "last", "enum": [ "avg", "min", @@ -5082,7 +5081,6 @@ "datadog": { "properties": { "aggregator": { - "default": "last", "enum": [ "avg", "min", @@ -9933,7 +9931,6 @@ "datadog": { "properties": { "aggregator": { - "default": "last", "enum": [ "avg", "min", diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_dashboard.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_dashboard.md index eb6ee9e6fc..ad99bfb5ca 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_dashboard.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_dashboard.md @@ -10,6 +10,16 @@ Start UI dashboard kubectl argo rollouts dashboard [flags] ``` +## Examples + +```shell +# Start UI dashboard +kubectl argo rollouts dashboard + +# Start UI dashboard on a specific port +kubectl argo rollouts dashboard --port 8080 +``` + ## Options ``` diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_get_rollout.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_get_rollout.md index 77b04d2217..4654f2f9c5 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_get_rollout.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_get_rollout.md @@ -30,6 +30,9 @@ kubectl argo rollouts get rollout guestbook # Watch progress of a rollout kubectl argo rollouts get rollout guestbook -w + +# Watch the rollout, fail if it takes more than 60 seconds +kubectl argo rollouts get rollout guestbook -w --timeout-seconds 60 ``` ## Options diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_experiments.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_experiments.md index 4add56c247..39d9f902bb 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_experiments.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_experiments.md @@ -26,7 +26,7 @@ kubectl argo rollouts list experiments --watch ## Options ``` - --all-namespaces Include all namespaces + -A, --all-namespaces Include all namespaces -h, --help help for experiments ``` diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_rollouts.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_rollouts.md index e861ca20c8..7382d88185 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_rollouts.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_list_rollouts.md @@ -16,6 +16,9 @@ kubectl argo rollouts list rollouts [flags] # List rollouts kubectl argo rollouts list rollouts +# List rollouts with a specific name +kubectl argo rollouts list rollouts --name my-rollout + # List rollouts from all namespaces kubectl argo rollouts list rollouts --all-namespaces diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_set_image.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_set_image.md index 5f89a6a506..a25acaa730 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_set_image.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_set_image.md @@ -13,8 +13,11 @@ kubectl argo rollouts set image ROLLOUT_NAME CONTAINER=IMAGE [flags] ## Examples ```shell -# Set rollout image -kubectl argo rollouts set image my-rollout www=image:v2 +# Set rollout image (containers contains 'initContainer', 'container', 'ephemeralContainer') +kubectl argo rollouts set image my-rollout containerName=imageName + +# Set rollout image for all containers +kubectl argo rollouts set image my-rollout *=imageName ``` ## Options diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_status.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_status.md index e1221d4056..4bfff8b586 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_status.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_status.md @@ -17,6 +17,9 @@ kubectl argo rollouts status ROLLOUT_NAME [flags] # Watch the rollout until it succeeds kubectl argo rollouts status guestbook +# Show the rollout status +kubectl argo rollouts status guestbook --watch false + # Watch the rollout until it succeeds, fail if it takes more than 60 seconds kubectl argo rollouts status --timeout 60s guestbook diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate.md index 4491cca5fe..21881976dc 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate.md @@ -13,7 +13,7 @@ kubectl argo rollouts terminate RESOURCE_NAME [flags] ## Examples ```shell -# Terminate an analysisRun +# Terminate an AnalysisRun kubectl argo rollouts terminate analysisrun guestbook-877894d5b-4-success-rate.1 # Terminate a failed experiment diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate_analysisrun.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate_analysisrun.md index 268b7a0150..3ff552e97a 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate_analysisrun.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_terminate_analysisrun.md @@ -14,7 +14,7 @@ kubectl argo rollouts terminate analysisrun ANALYSISRUN_NAME [flags] ```shell # Terminate an AnalysisRun -kubectl argo rollouts terminate analysis guestbook-877894d5b-4-success-rate.1 +kubectl argo rollouts terminate analysisrun guestbook-877894d5b-4-success-rate.1 ``` ## Options diff --git a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_undo.md b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_undo.md index 0ddf539dc9..e6d95a203b 100644 --- a/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_undo.md +++ b/docs/generated/kubectl-argo-rollouts/kubectl-argo-rollouts_undo.md @@ -16,7 +16,7 @@ kubectl argo rollouts undo ROLLOUT_NAME [flags] # Undo a rollout kubectl argo rollouts undo guestbook -# Undo a rollout revision 3 +# Undo a rollout to revision 3 kubectl argo rollouts undo guestbook --to-revision=3 ``` diff --git a/go.mod b/go.mod index 20585676c7..c970f0110c 100644 --- a/go.mod +++ b/go.mod @@ -8,11 +8,11 @@ require ( github.com/antonmedv/expr v1.15.5 github.com/argoproj/notifications-engine v0.4.1-0.20240219110818-7a069766e954 github.com/argoproj/pkg v0.13.6 - github.com/aws/aws-sdk-go-v2 v1.26.1 - github.com/aws/aws-sdk-go-v2/config v1.27.11 - github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.38.0 - github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.5 - github.com/aws/smithy-go v1.20.2 + github.com/aws/aws-sdk-go-v2 v1.30.1 + github.com/aws/aws-sdk-go-v2/config v1.27.23 + github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.40.1 + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.31.3 + github.com/aws/smithy-go v1.20.3 github.com/blang/semver v3.5.1+incompatible github.com/bombsimon/logrusr/v4 v4.1.0 github.com/evanphx/json-patch/v5 v5.9.0 @@ -20,7 +20,7 @@ require ( github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 github.com/grpc-ecosystem/grpc-gateway v1.16.0 - github.com/hashicorp/go-plugin v1.6.0 + github.com/hashicorp/go-plugin v1.6.1 github.com/influxdata/influxdb-client-go/v2 v2.13.0 github.com/juju/ansiterm v1.0.0 github.com/machinebox/graphql v0.2.2 @@ -35,14 +35,14 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/soheilhy/cmux v0.1.5 github.com/spaceapegames/go-wavefront v1.8.1 - github.com/spf13/cobra v1.8.0 + github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 github.com/tj/assert v0.0.3 github.com/valyala/fasttemplate v1.2.2 - golang.org/x/oauth2 v0.19.0 - google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de - google.golang.org/grpc v1.63.2 - google.golang.org/protobuf v1.34.0 + golang.org/x/oauth2 v0.21.0 + google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 + google.golang.org/grpc v1.65.0 + google.golang.org/protobuf v1.34.2 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.29.3 k8s.io/apiextensions-apiserver v0.29.3 @@ -61,8 +61,7 @@ require ( ) require ( - cloud.google.com/go/compute v1.24.0 // indirect - cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/compute/metadata v0.3.0 // indirect github.com/PagerDuty/go-pagerduty v1.7.0 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.5.0 // indirect github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect @@ -83,21 +82,21 @@ require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/aws/aws-sdk-go v1.44.116 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.11 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.23 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 // indirect github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/coreos/go-semver v0.3.1 // indirect @@ -118,7 +117,7 @@ require ( github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.1.2 // indirect github.com/google/cel-go v0.17.7 // indirect @@ -202,21 +201,21 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.19.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + golang.org/x/crypto v0.23.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.22.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.16.1 // indirect gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/notify v0.1.1 // indirect google.golang.org/api v0.162.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/inf.v0 v0.9.1 // indirect diff --git a/go.sum b/go.sum index 818c7d0638..8fbb1d8576 100644 --- a/go.sum +++ b/go.sum @@ -19,11 +19,9 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= +cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -98,38 +96,38 @@ github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2z github.com/aws/aws-sdk-go v1.44.39/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.116 h1:NpLIhcvLWXJZAEwvPj3TDHeqp7DleK6ZUVYyW01WNHY= github.com/aws/aws-sdk-go v1.44.116/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA= -github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= -github.com/aws/aws-sdk-go-v2/config v1.27.11 h1:f47rANd2LQEYHda2ddSCKYId18/8BhSRM4BULGmfgNA= -github.com/aws/aws-sdk-go-v2/config v1.27.11/go.mod h1:SMsV78RIOYdve1vf36z8LmnszlRWkwMQtomCAI0/mIE= -github.com/aws/aws-sdk-go-v2/credentials v1.17.11 h1:YuIB1dJNf1Re822rriUOTxopaHHvIq0l/pX3fwO+Tzs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.11/go.mod h1:AQtFPsDH9bI2O+71anW6EKL+NcD7LG3dpKGMV4SShgo= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5 h1:aw39xVGeRWlWx9EzGVnhOR4yOjQDHPQ6o6NmBlscyQg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.5/go.mod h1:FSaRudD0dXiMPK2UjknVwwTYyZMRsHv3TtkabsZih5I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5 h1:PG1F3OD1szkuQPzDw3CIQsRIrtTlUC3lP84taWzHlq0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.5/go.mod h1:jU1li6RFryMz+so64PpKtudI+QzbKoIEivqdf6LNpOc= +github.com/aws/aws-sdk-go-v2 v1.30.1 h1:4y/5Dvfrhd1MxRDD77SrfsDaj8kUkkljU7XE83NPV+o= +github.com/aws/aws-sdk-go-v2 v1.30.1/go.mod h1:nIQjQVp5sfpQcTc9mPSr1B0PaWK5ByX9MOoDadSN4lc= +github.com/aws/aws-sdk-go-v2/config v1.27.23 h1:Cr/gJEa9NAS7CDAjbnB7tHYb3aLZI2gVggfmSAasDac= +github.com/aws/aws-sdk-go-v2/config v1.27.23/go.mod h1:WMMYHqLCFu5LH05mFOF5tsq1PGEMfKbu083VKqLCd0o= +github.com/aws/aws-sdk-go-v2/credentials v1.17.23 h1:G1CfmLVoO2TdQ8z9dW+JBc/r8+MqyPQhXCafNZcXVZo= +github.com/aws/aws-sdk-go-v2/credentials v1.17.23/go.mod h1:V/DvSURn6kKgcuKEk4qwSwb/fZ2d++FFARtWSbXnLqY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9 h1:Aznqksmd6Rfv2HQN9cpqIV/lQRMaIpJkLLaJ1ZI76no= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.9/go.mod h1:WQr3MY7AxGNxaqAtsDWn+fBxmd4XvLkzeqQ8P1VM0/w= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13 h1:5SAoZ4jYpGH4721ZNoS1znQrhOfZinOhc4XuTXx/nVc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.13/go.mod h1:+rdA6ZLpaSeM7tSg/B0IEDinCIBJGmW8rKDFkYpP04g= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13 h1:WIijqeaAO7TYFLbhsZmi2rgLEAtWOC1LhxCAVTJlSKw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.13/go.mod h1:i+kbfa76PQbWw/ULoWnp51EYVWH4ENln76fLQE3lXT8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.38.0 h1:vAfGwYFCcPDS9Bg7ckfMBer6olJLOHsOAVoKWpPIirs= -github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.38.0/go.mod h1:U12sr6Lt14X96f16t+rR52+2BdqtydwN7DjEEHRMjO0= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.5 h1:/x2u/TOx+n17U+gz98TOw1HKJom0EOqrhL4SjrHr0cQ= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.5/go.mod h1:e1McVqsud0JOERidvppLEHnuCdh/X6MRyL5L0LseAUk= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.40.1 h1:8OMF4iAIxBNN5UOob6yNsYM+HomJeNwVN7Sqn2eL2cg= +github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.40.1/go.mod h1:5BOwwahrrkipxamulWdV15zlwDHyxRXUBtWZX8cjZnA= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.31.3 h1:Avh8YS+sgb2OKRht0wdNwY8tqtsCzVrmc8dG8Wfy9LI= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.31.3/go.mod h1:HbtHaw/hnNPaiqcyYnheILVyn81wOZiX9n2gYF5tPmM= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3 h1:dT3MqvGhSoaIhRseqw2I0yH81l7wiR2vjs57O51EAm8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.3/go.mod h1:GlAeCkHwugxdHaueRr4nhPuY+WW+gR8UjlcqzPr1SPI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15 h1:I9zMeF107l0rJrpnHpjEiiTSCKYAIw8mALiXcPsGBiA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.15/go.mod h1:9xWJ3Q/S6Ojusz1UIkfycgD1mGirJfLLKqq3LPT7WN8= github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7 h1:tRNrFDGRm81e6nTX5Q4CFblea99eAfm0dxXazGpLceU= github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7/go.mod h1:8GWUDux5Z2h6z2efAtr54RdHXtLm8sq7Rg85ZNY/CZM= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 h1:vN8hEbpRnL7+Hopy9dzmRle1xmDc7o8tmY0klsr175w= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.5/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 h1:Jux+gDDyi1Lruk+KHF91tK2KCuY61kzoCpvtvJJBtOE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 h1:cwIxeBttqPN3qkaAjcEcsh8NYr8n2HZPkcKgPAi1phU= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.6/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw= -github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= -github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.1 h1:p1GahKIjyMDZtiKoIn0/jAj/TkMzfzndDv5+zi2Mhgc= +github.com/aws/aws-sdk-go-v2/service/sso v1.22.1/go.mod h1:/vWdhoIoYA5hYoPZ6fm7Sv4d8701PiG5VKe8/pPJL60= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1 h1:lCEv9f8f+zJ8kcFeAjRZsekLd/x5SAm96Cva+VbUdo8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.26.1/go.mod h1:xyFHA4zGxgYkdD73VeezHt3vSKEG9EmFnGwoKlP00u4= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.1 h1:+woJ607dllHJQtsnJLi52ycuqHMwlW+Wqm2Ppsfp4nQ= +github.com/aws/aws-sdk-go-v2/service/sts v1.30.1/go.mod h1:jiNR3JqT15Dm+QWq2SRgh0x0bCNSRP2L25+CqPNpJlQ= +github.com/aws/smithy-go v1.20.3 h1:ryHwveWzPV5BIof6fyDvor6V3iUL7nTfiTKXHiW05nE= +github.com/aws/smithy-go v1.20.3/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= @@ -156,8 +154,8 @@ github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqy github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -168,8 +166,8 @@ github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtM github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= -github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= +github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b h1:ga8SEFjZ60pxLcmhnThWgvH2wg8376yUJmPhEH4H3kw= +github.com/cncf/xds/go v0.0.0-20240423153145-555b57ec207b/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/codeskyblue/go-sh v0.0.0-20190412065543-76bd3d59ff27/go.mod h1:VQx0hjo2oUeQkQUET7wRwradO6f+fN5jzXgB/zROxxE= github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4= @@ -177,7 +175,7 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= @@ -286,8 +284,8 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69 github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.1 h1:OptwRhECazUx5ix5TTWC3EZhsZEHWcYWY4FQHTIubm4= +github.com/golang/glog v1.2.1/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -416,8 +414,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A= -github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI= +github.com/hashicorp/go-plugin v1.6.1 h1:P7MR2UP6gNKGPp+y7EZw2kOiq4IR9WiqLvp0XOsVdwI= +github.com/hashicorp/go-plugin v1.6.1/go.mod h1:XPHFku2tFo3o3QKFgSYo+cghcUhw1NA1hZyMK0PWAw0= github.com/hashicorp/go-retryablehttp v0.5.1/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= @@ -661,8 +659,8 @@ github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= -github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= +github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -785,8 +783,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -871,8 +869,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -880,8 +878,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= -golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -895,8 +893,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -963,8 +961,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -973,8 +971,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -987,8 +985,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1114,10 +1112,10 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de h1:jFNzHPIeuzhdRwVhbZdiym9q0ory/xY3sA+v2wPg8I0= -google.golang.org/genproto/googleapis/api v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:5iCWqnniDlqZHrd3neWVTOwvh/v6s3232omMecelax8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de h1:cZGRis4/ot9uVm639a+rHCUaG0JJHEsdyzSQTMX+suY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:H4O17MA/PE9BsGx3w+a+W2VOLLD1Qf7oJneAoU6WktY= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= +google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157 h1:Zy9XzmMEflZ/MAaA7vNcoebnRAld7FsPW1EeBB7V0m8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240528184218-531527333157/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1132,8 +1130,8 @@ google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= +google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1147,8 +1145,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= diff --git a/hack/gen-crd-spec/main.go b/hack/gen-crd-spec/main.go index a3e31d92b8..60c1bde9d7 100644 --- a/hack/gen-crd-spec/main.go +++ b/hack/gen-crd-spec/main.go @@ -96,11 +96,12 @@ func NewCustomResourceDefinition() []*extensionsobj.CustomResourceDefinition { // clean up stuff left by controller-gen deleteFile("config/webhook/manifests.yaml") deleteFile("config/webhook") - deleteFile("config/argoproj.io_analysisruns.yaml") - deleteFile("config/argoproj.io_analysistemplates.yaml") - deleteFile("config/argoproj.io_clusteranalysistemplates.yaml") - deleteFile("config/argoproj.io_experiments.yaml") - deleteFile("config/argoproj.io_rollouts.yaml") + deleteFile("config/crd/argoproj.io_analysisruns.yaml") + deleteFile("config/crd/argoproj.io_analysistemplates.yaml") + deleteFile("config/crd/argoproj.io_clusteranalysistemplates.yaml") + deleteFile("config/crd/argoproj.io_experiments.yaml") + deleteFile("config/crd/argoproj.io_rollouts.yaml") + deleteFile("config/crd") deleteFile("config") crds := []*extensionsobj.CustomResourceDefinition{} diff --git a/manifests/base/argo-rollouts-deployment.yaml b/manifests/base/argo-rollouts-deployment.yaml index 046a1a0bba..285617fde4 100644 --- a/manifests/base/argo-rollouts-deployment.yaml +++ b/manifests/base/argo-rollouts-deployment.yaml @@ -52,7 +52,20 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault + resources: + limits: + ephemeral-storage: 1Gi + volumeMounts: + - name: plugin-bin + mountPath: /home/argo-rollouts/plugin-bin + - name: tmp + mountPath: /tmp securityContext: runAsNonRoot: true + volumes: + - name: plugin-bin + emptyDir: {} + - name: tmp + emptyDir: {} strategy: type: RollingUpdate diff --git a/manifests/crds/analysis-run-crd.yaml b/manifests/crds/analysis-run-crd.yaml index c8088911b6..816702aa04 100644 --- a/manifests/crds/analysis-run-crd.yaml +++ b/manifests/crds/analysis-run-crd.yaml @@ -179,7 +179,6 @@ spec: datadog: properties: aggregator: - default: last enum: - avg - min diff --git a/manifests/crds/analysis-template-crd.yaml b/manifests/crds/analysis-template-crd.yaml index 3cd6ec81a4..3bcf3855ad 100644 --- a/manifests/crds/analysis-template-crd.yaml +++ b/manifests/crds/analysis-template-crd.yaml @@ -175,7 +175,6 @@ spec: datadog: properties: aggregator: - default: last enum: - avg - min diff --git a/manifests/crds/cluster-analysis-template-crd.yaml b/manifests/crds/cluster-analysis-template-crd.yaml index ab4d887d23..1f97c14bd8 100644 --- a/manifests/crds/cluster-analysis-template-crd.yaml +++ b/manifests/crds/cluster-analysis-template-crd.yaml @@ -175,7 +175,6 @@ spec: datadog: properties: aggregator: - default: last enum: - avg - min diff --git a/manifests/install.yaml b/manifests/install.yaml index dfb8d18768..1b8eec6d69 100755 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -180,7 +180,6 @@ spec: datadog: properties: aggregator: - default: last enum: - avg - min @@ -3470,7 +3469,6 @@ spec: datadog: properties: aggregator: - default: last enum: - avg - min @@ -6638,7 +6636,6 @@ spec: datadog: properties: aggregator: - default: last enum: - avg - min @@ -16420,6 +16417,7 @@ rules: - get - list - watch + - update - apiGroups: - "" resources: @@ -16757,6 +16755,9 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 4 + resources: + limits: + ephemeral-storage: 1Gi securityContext: allowPrivilegeEscalation: false capabilities: @@ -16765,6 +16766,16 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault + volumeMounts: + - mountPath: /home/argo-rollouts/plugin-bin + name: plugin-bin + - mountPath: /tmp + name: tmp securityContext: runAsNonRoot: true serviceAccountName: argo-rollouts + volumes: + - emptyDir: {} + name: plugin-bin + - emptyDir: {} + name: tmp diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 0a7adf80ed..16ea68f99c 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -75,6 +75,7 @@ rules: - get - list - watch + - update - apiGroups: - "" resources: @@ -413,6 +414,9 @@ spec: periodSeconds: 5 successThreshold: 1 timeoutSeconds: 4 + resources: + limits: + ephemeral-storage: 1Gi securityContext: allowPrivilegeEscalation: false capabilities: @@ -421,6 +425,16 @@ spec: readOnlyRootFilesystem: true seccompProfile: type: RuntimeDefault + volumeMounts: + - mountPath: /home/argo-rollouts/plugin-bin + name: plugin-bin + - mountPath: /tmp + name: tmp securityContext: runAsNonRoot: true serviceAccountName: argo-rollouts + volumes: + - emptyDir: {} + name: plugin-bin + - emptyDir: {} + name: tmp diff --git a/manifests/role/argo-rollouts-clusterrole.yaml b/manifests/role/argo-rollouts-clusterrole.yaml index aab253e5ea..b43ed1adef 100644 --- a/manifests/role/argo-rollouts-clusterrole.yaml +++ b/manifests/role/argo-rollouts-clusterrole.yaml @@ -67,6 +67,7 @@ rules: - get - list - watch + - update # services patch needed to update selector of canary/stable/active/preview services # services create needed to create and delete services for experiments - apiGroups: diff --git a/metricproviders/datadog/datadog_test.go b/metricproviders/datadog/datadog_test.go index fe817f385e..ed81977296 100644 --- a/metricproviders/datadog/datadog_test.go +++ b/metricproviders/datadog/datadog_test.go @@ -66,12 +66,6 @@ func TestDatadogSpecDefaults(t *testing.T) { assert.Equal(t, "\"l2norm\"", string(aggregatorEnums[7].Raw), "\"l2norm\" expected, got %s", string(aggregatorEnums[7].Raw)) assert.Equal(t, "\"area\"", string(aggregatorEnums[8].Raw), "\"area\" expected, got %s", string(aggregatorEnums[8].Raw)) }) - - t.Run("aggregator: Validate default is last", func(t *testing.T) { - defaultAggregator := string(ddSpec.Properties["aggregator"].Default.Raw) - assert.Equal(t, "\"last\"", defaultAggregator, "Default aggregator should be \"last\" ") - }) - } func TestValidateIncomingProps(t *testing.T) { diff --git a/pkg/apiclient/rollout/rollout.swagger.json b/pkg/apiclient/rollout/rollout.swagger.json index b3c10e03f8..3a74f48a24 100755 --- a/pkg/apiclient/rollout/rollout.swagger.json +++ b/pkg/apiclient/rollout/rollout.swagger.json @@ -1205,7 +1205,7 @@ }, "aggregator": { "type": "string", - "title": "+kubebuilder:default=\"last\"\n+kubebuilder:validation:Enum=avg;min;max;sum;last;percentile;mean;l2norm;area\nAggregator is a type of aggregator to use for metrics-based queries (default: last). Used for v2" + "title": "+kubebuilder:validation:Enum=avg;min;max;sum;last;percentile;mean;l2norm;area\nAggregator is a type of aggregator to use for metrics-based queries (default: \"\"). Used for v2" } } }, diff --git a/pkg/apis/rollouts/v1alpha1/analysis_types.go b/pkg/apis/rollouts/v1alpha1/analysis_types.go index 08ef18071f..3a287ec856 100644 --- a/pkg/apis/rollouts/v1alpha1/analysis_types.go +++ b/pkg/apis/rollouts/v1alpha1/analysis_types.go @@ -601,8 +601,7 @@ type DatadogMetric struct { // +kubebuilder:validation:Enum=v1;v2 // +kubebuilder:default=v1 ApiVersion string `json:"apiVersion,omitempty" protobuf:"bytes,5,opt,name=apiVersion"` - // +kubebuilder:default="last" // +kubebuilder:validation:Enum=avg;min;max;sum;last;percentile;mean;l2norm;area - // Aggregator is a type of aggregator to use for metrics-based queries (default: last). Used for v2 + // Aggregator is a type of aggregator to use for metrics-based queries (default: ""). Used for v2 Aggregator string `json:"aggregator,omitempty" protobuf:"bytes,6,opt,name=aggregator"` } diff --git a/pkg/apis/rollouts/v1alpha1/generated.proto b/pkg/apis/rollouts/v1alpha1/generated.proto index 0ea0a7bc2c..eebb4453cc 100644 --- a/pkg/apis/rollouts/v1alpha1/generated.proto +++ b/pkg/apis/rollouts/v1alpha1/generated.proto @@ -655,9 +655,8 @@ message DatadogMetric { // +kubebuilder:default=v1 optional string apiVersion = 5; - // +kubebuilder:default="last" // +kubebuilder:validation:Enum=avg;min;max;sum;last;percentile;mean;l2norm;area - // Aggregator is a type of aggregator to use for metrics-based queries (default: last). Used for v2 + // Aggregator is a type of aggregator to use for metrics-based queries (default: ""). Used for v2 optional string aggregator = 6; } diff --git a/pkg/apis/rollouts/v1alpha1/openapi_generated.go b/pkg/apis/rollouts/v1alpha1/openapi_generated.go index 2d4d68ff1e..6c18e64a2b 100644 --- a/pkg/apis/rollouts/v1alpha1/openapi_generated.go +++ b/pkg/apis/rollouts/v1alpha1/openapi_generated.go @@ -1935,7 +1935,7 @@ func schema_pkg_apis_rollouts_v1alpha1_DatadogMetric(ref common.ReferenceCallbac }, "aggregator": { SchemaProps: spec.SchemaProps{ - Description: "Aggregator is a type of aggregator to use for metrics-based queries (default: last). Used for v2", + Description: "Aggregator is a type of aggregator to use for metrics-based queries (default: \"\"). Used for v2", Type: []string{"string"}, Format: "", }, diff --git a/pkg/kubectl-argo-rollouts/cmd/dashboard/dashboard.go b/pkg/kubectl-argo-rollouts/cmd/dashboard/dashboard.go index f0c720df72..468d0437c6 100644 --- a/pkg/kubectl-argo-rollouts/cmd/dashboard/dashboard.go +++ b/pkg/kubectl-argo-rollouts/cmd/dashboard/dashboard.go @@ -8,12 +8,22 @@ import ( "github.com/spf13/cobra" ) +var ( + dashBoardExample = ` + # Start UI dashboard + %[1]s dashboard + + # Start UI dashboard on a specific port + %[1]s dashboard --port 8080` +) + func NewCmdDashboard(o *options.ArgoRolloutsOptions) *cobra.Command { var rootPath string var port int var cmd = &cobra.Command{ - Use: "dashboard", - Short: "Start UI dashboard", + Use: "dashboard", + Short: "Start UI dashboard", + Example: o.Example(dashBoardExample), RunE: func(c *cobra.Command, args []string) error { namespace := o.Namespace() kubeclientset := o.KubeClientset() diff --git a/pkg/kubectl-argo-rollouts/cmd/get/get_rollout.go b/pkg/kubectl-argo-rollouts/cmd/get/get_rollout.go index f5b0719509..dd56693a45 100644 --- a/pkg/kubectl-argo-rollouts/cmd/get/get_rollout.go +++ b/pkg/kubectl-argo-rollouts/cmd/get/get_rollout.go @@ -25,7 +25,10 @@ const ( %[1]s get rollout guestbook # Watch progress of a rollout - %[1]s get rollout guestbook -w` + %[1]s get rollout guestbook -w + + # Watch the rollout, fail if it takes more than 60 seconds + %[1]s get rollout guestbook -w --timeout-seconds 60` ) // NewCmdGetRollout returns a new instance of an `rollouts get rollout` command diff --git a/pkg/kubectl-argo-rollouts/cmd/lint/lint.go b/pkg/kubectl-argo-rollouts/cmd/lint/lint.go index 810abf2c8e..4d8a268994 100644 --- a/pkg/kubectl-argo-rollouts/cmd/lint/lint.go +++ b/pkg/kubectl-argo-rollouts/cmd/lint/lint.go @@ -53,12 +53,7 @@ func NewCmdLint(o *options.ArgoRolloutsOptions) *cobra.Command { return o.UsageErr(c) } - err := lintOptions.lintResource(lintOptions.File) - if err != nil { - return err - } - - return nil + return lintOptions.lintResource(lintOptions.File) }, } cmd.Flags().StringVarP(&lintOptions.File, "filename", "f", "", "File to lint") diff --git a/pkg/kubectl-argo-rollouts/cmd/list/list_experiments.go b/pkg/kubectl-argo-rollouts/cmd/list/list_experiments.go index cb83a157fa..962b4d6ce4 100644 --- a/pkg/kubectl-argo-rollouts/cmd/list/list_experiments.go +++ b/pkg/kubectl-argo-rollouts/cmd/list/list_experiments.go @@ -62,7 +62,7 @@ func NewCmdListExperiments(o *options.ArgoRolloutsOptions) *cobra.Command { return nil }, } - cmd.Flags().BoolVar(&listOptions.allNamespaces, "all-namespaces", false, "Include all namespaces") + cmd.Flags().BoolVarP(&listOptions.allNamespaces, "all-namespaces", "A", false, "Include all namespaces") return cmd } diff --git a/pkg/kubectl-argo-rollouts/cmd/list/list_rollouts.go b/pkg/kubectl-argo-rollouts/cmd/list/list_rollouts.go index 6746876767..c233776c6d 100644 --- a/pkg/kubectl-argo-rollouts/cmd/list/list_rollouts.go +++ b/pkg/kubectl-argo-rollouts/cmd/list/list_rollouts.go @@ -18,6 +18,9 @@ const ( listRolloutsExample = ` # List rollouts %[1]s list rollouts + + # List rollouts with a specific name + %[1]s list rollouts --name my-rollout # List rollouts from all namespaces %[1]s list rollouts --all-namespaces diff --git a/pkg/kubectl-argo-rollouts/cmd/set/set_image.go b/pkg/kubectl-argo-rollouts/cmd/set/set_image.go index 1a5b5dce24..942db298bc 100644 --- a/pkg/kubectl-argo-rollouts/cmd/set/set_image.go +++ b/pkg/kubectl-argo-rollouts/cmd/set/set_image.go @@ -19,8 +19,11 @@ import ( const ( setImageExample = ` - # Set rollout image - %[1]s set image my-rollout www=image:v2` + # Set rollout image (containers contains 'initContainer', 'container', 'ephemeralContainer') + %[1]s set image my-rollout containerName=imageName + + # Set rollout image for all containers + %[1]s set image my-rollout *=imageName` ) const ( diff --git a/pkg/kubectl-argo-rollouts/cmd/status/status.go b/pkg/kubectl-argo-rollouts/cmd/status/status.go index 79d7272d88..33d6652900 100644 --- a/pkg/kubectl-argo-rollouts/cmd/status/status.go +++ b/pkg/kubectl-argo-rollouts/cmd/status/status.go @@ -20,6 +20,9 @@ the rollout is healthy upon completion and an error otherwise.` # Watch the rollout until it succeeds %[1]s status guestbook + # Show the rollout status + %[1]s status guestbook --watch false + # Watch the rollout until it succeeds, fail if it takes more than 60 seconds %[1]s status --timeout 60s guestbook ` diff --git a/pkg/kubectl-argo-rollouts/cmd/terminate/terminate.go b/pkg/kubectl-argo-rollouts/cmd/terminate/terminate.go index f0dd7e91b1..c4123f0e78 100644 --- a/pkg/kubectl-argo-rollouts/cmd/terminate/terminate.go +++ b/pkg/kubectl-argo-rollouts/cmd/terminate/terminate.go @@ -18,7 +18,7 @@ const ( const ( terminateExample = ` - # Terminate an analysisRun + # Terminate an AnalysisRun %[1]s terminate analysisrun guestbook-877894d5b-4-success-rate.1 # Terminate a failed experiment @@ -26,7 +26,7 @@ const ( terminateAnalysisRunExample = ` # Terminate an AnalysisRun - %[1]s terminate analysis guestbook-877894d5b-4-success-rate.1` + %[1]s terminate analysisrun guestbook-877894d5b-4-success-rate.1` terminateExperimentExample = ` # Terminate an experiment diff --git a/pkg/kubectl-argo-rollouts/cmd/undo/undo.go b/pkg/kubectl-argo-rollouts/cmd/undo/undo.go index d3a78d15f2..be9d0289d7 100644 --- a/pkg/kubectl-argo-rollouts/cmd/undo/undo.go +++ b/pkg/kubectl-argo-rollouts/cmd/undo/undo.go @@ -32,7 +32,7 @@ const ( # Undo a rollout %[1]s undo guestbook - # Undo a rollout revision 3 + # Undo a rollout to revision 3 %[1]s undo guestbook --to-revision=3` ) diff --git a/rollout/analysis.go b/rollout/analysis.go index 7bb0d47f1f..f23f680ce0 100644 --- a/rollout/analysis.go +++ b/rollout/analysis.go @@ -74,8 +74,9 @@ func (c *rolloutContext) reconcileAnalysisRuns() error { isAborted := c.pauseContext.IsAborted() rollbackToScaleDownDelay := replicasetutil.HasScaleDownDeadline(c.newRS) initialDeploy := c.rollout.Status.StableRS == "" - if isAborted || c.rollout.Status.PromoteFull || rollbackToScaleDownDelay || initialDeploy { - c.log.Infof("Skipping analysis: isAborted: %v, promoteFull: %v, rollbackToScaleDownDelay: %v, initialDeploy: %v", isAborted, c.rollout.Status.PromoteFull, rollbackToScaleDownDelay, initialDeploy) + isRollbackWithinWindow := c.isRollbackWithinWindow() + if isAborted || c.rollout.Status.PromoteFull || rollbackToScaleDownDelay || initialDeploy || isRollbackWithinWindow { + c.log.Infof("Skipping analysis: isAborted: %v, promoteFull: %v, rollbackToScaleDownDelay: %v, initialDeploy: %v, isRollbackWithinWindow: %v", isAborted, c.rollout.Status.PromoteFull, rollbackToScaleDownDelay, initialDeploy, isRollbackWithinWindow) allArs := append(c.currentArs.ToArray(), c.otherArs...) c.SetCurrentAnalysisRuns(c.currentArs) return c.cancelAnalysisRuns(allArs) diff --git a/rollout/analysis_test.go b/rollout/analysis_test.go index 46a741bd63..e12a898c1a 100644 --- a/rollout/analysis_test.go +++ b/rollout/analysis_test.go @@ -1918,6 +1918,47 @@ func TestDoNotCreateBackgroundAnalysisRunOnNewCanaryRolloutStableRSEmpty(t *test f.run(getKey(r1, t)) } +func TestDoNotCreateBackgroundAnalysisRunWhenWithinRollbackWindow(t *testing.T) { + f := newFixture(t) + defer f.Close() + + at := analysisTemplate("bar") + + r1 := newCanaryRollout("foo", 1, nil, nil, pointer.Int32Ptr(0), intstr.FromInt(0), intstr.FromInt(1)) + r1.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ + RolloutAnalysis: v1alpha1.RolloutAnalysis{ + Templates: []v1alpha1.AnalysisTemplateRef{ + { + TemplateName: at.Name, + }, + }, + }, + } + r1.Spec.RollbackWindow = &v1alpha1.RollbackWindowSpec{Revisions: 1} + + r2 := bumpVersion(r1) + rs1 := newReplicaSetWithStatus(r1, 1, 1) + rs2 := newReplicaSetWithStatus(r2, 0, 0) + + rs2.CreationTimestamp = timeutil.MetaTime(time.Now().Add(-1 * time.Hour)) + rs1.CreationTimestamp = timeutil.MetaNow() + + f.kubeobjects = append(f.kubeobjects, rs1, rs2) + f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) + + rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + + r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 1, 0, 1, false) + + f.rolloutLister = append(f.rolloutLister, r2) + f.analysisTemplateLister = append(f.analysisTemplateLister, at) + f.objects = append(f.objects, r2, at) + + f.expectUpdateReplicaSetAction(rs2) + f.expectPatchRolloutAction(r2) + f.run(getKey(r2, t)) +} + func TestCreatePrePromotionAnalysisRun(t *testing.T) { f := newFixture(t) defer f.Close() diff --git a/rollout/canary.go b/rollout/canary.go index ed27bd0a79..a3033fea02 100644 --- a/rollout/canary.go +++ b/rollout/canary.go @@ -112,7 +112,7 @@ func (c *rolloutContext) reconcileCanaryStableReplicaSet() (bool, error) { } scaled, _, err := c.scaleReplicaSetAndRecordEvent(c.stableRS, desiredStableRSReplicaCount) if err != nil { - return scaled, fmt.Errorf("failed to scaleReplicaSetAndRecordEvent in reconcileCanaryStableReplicaSet:L %w", err) + return scaled, fmt.Errorf("failed to scaleReplicaSetAndRecordEvent in reconcileCanaryStableReplicaSet: %w", err) } return scaled, err } @@ -296,7 +296,7 @@ func (c *rolloutContext) canProceedWithScaleDownAnnotation(oldRSs []*appsv1.Repl // AWS API calls. return true, nil } - stableSvcName, _ := trafficrouting.GetStableAndCanaryServices(c.rollout) + stableSvcName, _ := trafficrouting.GetStableAndCanaryServices(c.rollout, true) stableSvc, err := c.servicesLister.Services(c.rollout.Namespace).Get(stableSvcName) if err != nil { return false, err diff --git a/rollout/canary_test.go b/rollout/canary_test.go index 56b05c7177..3d1eec9d14 100644 --- a/rollout/canary_test.go +++ b/rollout/canary_test.go @@ -4,10 +4,16 @@ import ( "context" "encoding/json" "fmt" + "os" "strconv" "testing" "time" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + k8stesting "k8s.io/client-go/testing" + "github.com/stretchr/testify/assert" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/apps/v1" @@ -2141,3 +2147,106 @@ func TestCanaryReplicaAndSpecChangedTogether(t *testing.T) { // check the canary one is updated assert.NotEqual(t, originReplicas, int(*updated.Spec.Replicas)) } + +func TestSyncRolloutWithConflictInScaleReplicaSet(t *testing.T) { + os.Setenv("ARGO_ROLLOUTS_LOG_RS_DIFF_CONFLICT", "true") + defer os.Unsetenv("ARGO_ROLLOUTS_LOG_RS_DIFF_CONFLICT") + + f := newFixture(t) + defer f.Close() + + steps := []v1alpha1.CanaryStep{ + { + SetWeight: int32Ptr(10), + }, { + Pause: &v1alpha1.RolloutPause{ + Duration: v1alpha1.DurationFromInt(10), + }, + }, + } + r1 := newCanaryRollout("foo", 10, nil, steps, int32Ptr(1), intstr.FromInt(1), intstr.FromInt(0)) + r1.Spec.Template.Labels["rollout.argoproj.io/foo"] = "bar" + + rs1 := newReplicaSetWithStatus(r1, 10, 10) + r1.Spec.Replicas = pointer.Int32(2) + f.kubeobjects = append(f.kubeobjects, rs1) + f.replicaSetLister = append(f.replicaSetLister, rs1) + + f.rolloutLister = append(f.rolloutLister, r1) + f.objects = append(f.objects, r1) + + f.expectPatchRolloutAction(r1) + f.expectUpdateReplicaSetAction(rs1) // attempt to scale replicaset but conflict + patchIndex := f.expectPatchReplicaSetAction(rs1) // instead of update patch replicaset + + key := fmt.Sprintf("%s/%s", r1.Namespace, r1.Name) + c, i, k8sI := f.newController(func() time.Duration { return 30 * time.Minute }) + + f.kubeclient.PrependReactor("update", "replicasets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { + return true, action.(k8stesting.UpdateAction).GetObject(), errors.NewConflict(schema.GroupResource{ + Group: "Apps", + Resource: "ReplicaSet", + }, action.(k8stesting.UpdateAction).GetObject().(*appsv1.ReplicaSet).Name, fmt.Errorf("test error")) + }) + + f.runController(key, true, false, c, i, k8sI) + + updatedRs := f.getPatchedReplicaSet(patchIndex) // minus one because update did not happen because conflict + assert.Equal(t, int32(2), *updatedRs.Spec.Replicas) +} + +func TestSyncRolloutWithConflictInSyncReplicaSetRevision(t *testing.T) { + os.Setenv("ARGO_ROLLOUTS_LOG_RS_DIFF_CONFLICT", "true") + defer os.Unsetenv("ARGO_ROLLOUTS_LOG_RS_DIFF_CONFLICT") + + f := newFixture(t) + defer f.Close() + + steps := []v1alpha1.CanaryStep{ + { + SetWeight: int32Ptr(10), + }, { + Pause: &v1alpha1.RolloutPause{ + Duration: v1alpha1.DurationFromInt(10), + }, + }, + } + r1 := newCanaryRollout("foo", 3, nil, steps, int32Ptr(1), intstr.FromInt(1), intstr.FromInt(0)) + r2 := bumpVersion(r1) + + rs1 := newReplicaSetWithStatus(r1, 3, 3) + rs2 := newReplicaSetWithStatus(r2, 3, 3) + rs2.Annotations["rollout.argoproj.io/revision"] = "1" + + f.kubeobjects = append(f.kubeobjects, rs1, rs2) + f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) + + f.rolloutLister = append(f.rolloutLister, r2) + f.objects = append(f.objects, r2) + + key := fmt.Sprintf("%s/%s", r1.Namespace, r1.Name) + c, i, k8sI := f.newController(func() time.Duration { return 30 * time.Minute }) + + f.kubeclient.PrependReactor("update", "replicasets", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) { + return true, &appsv1.ReplicaSet{}, errors.NewConflict(schema.GroupResource{ + Group: "Apps", + Resource: "ReplicaSet", + }, action.(k8stesting.UpdateAction).GetObject().(*appsv1.ReplicaSet).Name, fmt.Errorf("test error")) + }) + + f.expectPatchRolloutAction(r2) + f.expectUpdateReplicaSetAction(rs1) // attempt to update replicaset revision but conflict + patchIndex1 := f.expectPatchReplicaSetAction(rs1) // instead of update patch replicaset + + f.expectUpdateReplicaSetAction(rs2) // attempt to scale replicaset but conflict + patchIndex2 := f.expectPatchReplicaSetAction(rs2) // instead of update patch replicaset + + f.runController(key, true, false, c, i, k8sI) + + updatedRs1 := f.getPatchedReplicaSet(patchIndex1) + assert.Equal(t, "2", updatedRs1.Annotations["rollout.argoproj.io/revision"]) + assert.Equal(t, int32(3), *updatedRs1.Spec.Replicas) + + updatedRs2 := f.getPatchedReplicaSet(patchIndex2) + assert.Equal(t, int32(0), *updatedRs2.Spec.Replicas) +} diff --git a/rollout/controller.go b/rollout/controller.go index 972cea882c..23f7f340dd 100644 --- a/rollout/controller.go +++ b/rollout/controller.go @@ -4,11 +4,16 @@ import ( "context" "encoding/json" "fmt" + "os" "reflect" "strconv" + "strings" "sync" "time" + "github.com/argoproj/argo-rollouts/utils/annotations" + + "github.com/argoproj/argo-rollouts/utils/diff" "k8s.io/apimachinery/pkg/runtime/schema" "github.com/argoproj/argo-rollouts/pkg/apis/rollouts" @@ -16,11 +21,13 @@ import ( log "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + patchtypes "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/dynamic" @@ -937,3 +944,92 @@ func remarshalRollout(r *v1alpha1.Rollout) *v1alpha1.Rollout { } return &remarshalled } + +// updateReplicaSetWithPatch updates the replicaset using Update and on failure falls back to a patch this function only exists to make sure we always can update +// replicasets and to not get into an conflict loop updating replicasets. We should really look into a complete refactor of how rollouts handles replicasets such +// that we do not keep a fully replicaset on the rollout context under newRS and instead switch to a patch only based approach. +func (c *rolloutContext) updateReplicaSetFallbackToPatch(ctx context.Context, rs *appsv1.ReplicaSet) (*appsv1.ReplicaSet, error) { + updatedRS, err := c.kubeclientset.AppsV1().ReplicaSets(rs.Namespace).Update(ctx, rs, metav1.UpdateOptions{}) + if err != nil { + if errors.IsConflict(err) { + if os.Getenv("ARGO_ROLLOUTS_LOG_RS_DIFF_CONFLICT") == "true" { + rsGet, err := c.replicaSetLister.ReplicaSets(rs.Namespace).Get(rs.Name) + if err != nil { + return nil, fmt.Errorf("error getting replicaset in updateReplicaSetFallbackToPatch %s: %w", rs.Name, err) + } + rsGetJson, err := json.Marshal(rsGet) + if err != nil { + return nil, fmt.Errorf("error marshalling informer replicaset in updateReplicaSetFallbackToPatch %s: %w", rs.Name, err) + } + rsCopyJson, err := json.Marshal(rs) + if err != nil { + return nil, fmt.Errorf("error marshalling memory replicaset in updateReplicaSetFallbackToPatch %s: %w", rs.Name, err) + } + c.log.Infof("Informer RS: %s", rsGetJson) + c.log.Infof("Memory RS: %s", rsCopyJson) + } + + c.log.Infof("Conflict when updating replicaset %s, falling back to patch", rs.Name) + + patchRS := appsv1.ReplicaSet{} + patchRS.Spec.Replicas = rs.Spec.Replicas + patchRS.Spec.Template.Labels = rs.Spec.Template.Labels + patchRS.Spec.Template.Annotations = rs.Spec.Template.Annotations + + patchRS.Annotations = make(map[string]string) + patchRS.Labels = make(map[string]string) + patchRS.Spec.Selector = &metav1.LabelSelector{ + MatchLabels: make(map[string]string), + } + + if _, found := rs.Labels[v1alpha1.DefaultRolloutUniqueLabelKey]; found { + patchRS.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] = rs.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + } + + if _, found := rs.Annotations[v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey]; found { + patchRS.Annotations[v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey] = rs.Labels[v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey] + } + + if _, found := rs.Spec.Selector.MatchLabels[v1alpha1.DefaultRolloutUniqueLabelKey]; found { + patchRS.Spec.Selector.MatchLabels[v1alpha1.DefaultRolloutUniqueLabelKey] = rs.Spec.Selector.MatchLabels[v1alpha1.DefaultRolloutUniqueLabelKey] + } + + for key, value := range rs.Annotations { + if strings.HasPrefix(key, annotations.RolloutLabel) || + strings.HasPrefix(key, "argo-rollouts.argoproj.io") || + strings.HasPrefix(key, "experiment.argoproj.io") { + patchRS.Annotations[key] = value + } + } + for key, value := range rs.Labels { + if strings.HasPrefix(key, annotations.RolloutLabel) || + strings.HasPrefix(key, "argo-rollouts.argoproj.io") || + strings.HasPrefix(key, "experiment.argoproj.io") { + patchRS.Labels[key] = value + } + } + + patch, _, err := diff.CreateTwoWayMergePatch(appsv1.ReplicaSet{}, patchRS, appsv1.ReplicaSet{}) + if err != nil { + return nil, fmt.Errorf("error creating patch for conflict log in updateReplicaSetFallbackToPatch %s: %w", rs.Name, err) + } + + c.log.Infof("Patching replicaset with patch: %s", string(patch)) + updatedRS, err = c.kubeclientset.AppsV1().ReplicaSets(rs.Namespace).Patch(ctx, rs.Name, patchtypes.StrategicMergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + return nil, fmt.Errorf("error patching replicaset in updateReplicaSetFallbackToPatch %s: %w", rs.Name, err) + } + + err = c.replicaSetInformer.GetIndexer().Update(updatedRS) + if err != nil { + return nil, fmt.Errorf("error updating replicaset informer in updateReplicaSetFallbackToPatch %s: %w", rs.Name, err) + } + + return updatedRS, err + } + } + if updatedRS != nil { + updatedRS.DeepCopyInto(rs) + } + return rs, err +} diff --git a/rollout/controller_test.go b/rollout/controller_test.go index 892a2be64f..e38fca79c5 100644 --- a/rollout/controller_test.go +++ b/rollout/controller_test.go @@ -792,6 +792,12 @@ func (f *fixture) expectPatchServiceAction(s *corev1.Service, newLabel string) i return len } +func (f *fixture) expectGetReplicaSetAction(r *appsv1.ReplicaSet) int { //nolint:unused + len := len(f.kubeactions) + f.kubeactions = append(f.kubeactions, core.NewGetAction(schema.GroupVersionResource{Resource: "replicasets"}, r.Namespace, r.Name)) + return len +} + func (f *fixture) expectCreateReplicaSetAction(r *appsv1.ReplicaSet) int { len := len(f.kubeactions) f.kubeactions = append(f.kubeactions, core.NewCreateAction(schema.GroupVersionResource{Resource: "replicasets"}, r.Namespace, r)) @@ -950,6 +956,21 @@ func (f *fixture) getUpdatedReplicaSet(index int) *appsv1.ReplicaSet { return rs } +func (f *fixture) getPatchedReplicaSet(index int) *appsv1.ReplicaSet { + action := filterInformerActions(f.kubeclient.Actions())[index] + patchAction, ok := action.(core.PatchAction) + if !ok { + f.t.Fatalf("Expected Patch action, not %s", action.GetVerb()) + } + + rs := appsv1.ReplicaSet{} + err := json.Unmarshal(patchAction.GetPatch(), &rs) + if err != nil { + panic(err) + } + return &rs +} + func (f *fixture) verifyPatchedReplicaSet(index int, scaleDownDelaySeconds int32) { action := filterInformerActions(f.kubeclient.Actions())[index] patchAction, ok := action.(core.PatchAction) diff --git a/rollout/ephemeralmetadata.go b/rollout/ephemeralmetadata.go index 60b745ed29..4f502a78ab 100644 --- a/rollout/ephemeralmetadata.go +++ b/rollout/ephemeralmetadata.go @@ -82,14 +82,12 @@ func (c *rolloutContext) syncEphemeralMetadata(ctx context.Context, rs *appsv1.R } // 2. Update ReplicaSet so that any new pods it creates will have the metadata - rs, err = c.kubeclientset.AppsV1().ReplicaSets(modifiedRS.Namespace).Update(ctx, modifiedRS, metav1.UpdateOptions{}) + rs, err = c.updateReplicaSetFallbackToPatch(ctx, modifiedRS) if err != nil { - return fmt.Errorf("error updating replicaset in syncEphemeralMetadata: %w", err) - } - err = c.replicaSetInformer.GetIndexer().Update(rs) - if err != nil { - return fmt.Errorf("error updating replicaset informer in syncEphemeralMetadata: %w", err) + c.log.Infof("failed to sync ephemeral metadata %v to ReplicaSet %s: %v", podMetadata, rs.Name, err) + return fmt.Errorf("failed to sync ephemeral metadata: %w", err) } + c.log.Infof("synced ephemeral metadata %v to ReplicaSet %s", podMetadata, rs.Name) return nil } diff --git a/rollout/service.go b/rollout/service.go index 69739b9315..c0904ffd23 100644 --- a/rollout/service.go +++ b/rollout/service.go @@ -243,7 +243,7 @@ func (c *rolloutContext) getPreviewAndActiveServices() (*corev1.Service, *corev1 func (c *rolloutContext) reconcilePingAndPongService() error { if trafficrouting.IsPingPongEnabled(c.rollout) && !rolloututils.IsFullyPromoted(c.rollout) { - _, canaryService := trafficrouting.GetStableAndCanaryServices(c.rollout) + _, canaryService := trafficrouting.GetStableAndCanaryServices(c.rollout, true) return c.ensureSVCTargets(canaryService, c.newRS, false) } return nil diff --git a/rollout/sync.go b/rollout/sync.go index 875949ee55..6d656e2d5a 100644 --- a/rollout/sync.go +++ b/rollout/sync.go @@ -83,17 +83,13 @@ func (c *rolloutContext) syncReplicaSetRevision() (*appsv1.ReplicaSet, error) { affinityNeedsUpdate := replicasetutil.IfInjectedAntiAffinityRuleNeedsUpdate(rsCopy.Spec.Template.Spec.Affinity, *c.rollout) if annotationsUpdated || minReadySecondsNeedsUpdate || affinityNeedsUpdate { + rsCopy.Spec.MinReadySeconds = c.rollout.Spec.MinReadySeconds rsCopy.Spec.Template.Spec.Affinity = replicasetutil.GenerateReplicaSetAffinity(*c.rollout) - rs, err := c.kubeclientset.AppsV1().ReplicaSets(rsCopy.ObjectMeta.Namespace).Update(ctx, rsCopy, metav1.UpdateOptions{}) - if err != nil { - c.log.WithError(err).Error("Error: updating replicaset revision") - return nil, fmt.Errorf("error updating replicaset revision: %v", err) - } - c.log.Infof("Synced revision on ReplicaSet '%s' to '%s'", rs.Name, newRevision) - err = c.replicaSetInformer.GetIndexer().Update(rs) + + rs, err := c.updateReplicaSetFallbackToPatch(ctx, rsCopy) if err != nil { - return nil, fmt.Errorf("error updating replicaset informer in syncReplicaSetRevision: %w", err) + return nil, fmt.Errorf("failed to update replicaset revision on %s: %w", rsCopy.Name, err) } return rs, nil } @@ -113,7 +109,7 @@ func (c *rolloutContext) syncReplicaSetRevision() (*appsv1.ReplicaSet, error) { conditions.SetRolloutCondition(&c.rollout.Status, *condition) updatedRollout, err := c.argoprojclientset.ArgoprojV1alpha1().Rollouts(c.rollout.Namespace).UpdateStatus(ctx, c.rollout, metav1.UpdateOptions{}) if err != nil { - c.log.WithError(err).Error("Error: updating rollout revision") + c.log.WithError(err).Error("Error: updating rollout status in syncReplicaSetRevision") return nil, err } c.rollout = updatedRollout @@ -245,7 +241,7 @@ func (c *rolloutContext) createDesiredReplicaSet() (*appsv1.ReplicaSet, error) { cond := conditions.NewRolloutCondition(v1alpha1.RolloutProgressing, corev1.ConditionFalse, conditions.FailedRSCreateReason, msg) patchErr := c.patchCondition(c.rollout, newStatus, cond) if patchErr != nil { - c.log.Warnf("Error Patching Rollout: %s", patchErr.Error()) + c.log.Warnf("Error Patching Rollout Conditions: %s", patchErr.Error()) } return nil, err default: @@ -370,25 +366,21 @@ func (c *rolloutContext) scaleReplicaSet(rs *appsv1.ReplicaSet, newScale int32, rolloutReplicas := defaults.GetReplicasOrDefault(rollout.Spec.Replicas) annotationsNeedUpdate := annotations.ReplicasAnnotationsNeedUpdate(rs, rolloutReplicas) - scaled := false var err error + scaled := false if sizeNeedsUpdate || annotationsNeedUpdate { rsCopy := rs.DeepCopy() oldScale := defaults.GetReplicasOrDefault(rs.Spec.Replicas) *(rsCopy.Spec.Replicas) = newScale annotations.SetReplicasAnnotations(rsCopy, rolloutReplicas) if fullScaleDown && !c.shouldDelayScaleDownOnAbort() { + // This bypasses the normal call to removeScaleDownDelay and then depends on the removal via an update in updateReplicaSetFallbackToPatch delete(rsCopy.Annotations, v1alpha1.DefaultReplicaSetScaleDownDeadlineAnnotationKey) } - rs, err = c.kubeclientset.AppsV1().ReplicaSets(rsCopy.Namespace).Update(ctx, rsCopy, metav1.UpdateOptions{}) - if err != nil { - return scaled, rs, fmt.Errorf("error updating replicaset %s: %w", rsCopy.Name, err) - } - err = c.replicaSetInformer.GetIndexer().Update(rs) + rs, err = c.updateReplicaSetFallbackToPatch(ctx, rsCopy) if err != nil { - err = fmt.Errorf("error updating replicaset informer in scaleReplicaSet: %w", err) - return scaled, rs, err + return scaled, rs, fmt.Errorf("failed to updateReplicaSetFallbackToPatch in scaleReplicaSet: %w", err) } if sizeNeedsUpdate { diff --git a/rollout/trafficrouting.go b/rollout/trafficrouting.go index f8b01951a4..e992277a57 100644 --- a/rollout/trafficrouting.go +++ b/rollout/trafficrouting.go @@ -288,6 +288,12 @@ func (c *rolloutContext) reconcileTrafficRouting() error { } else { c.log.Infof("Desired weight (stepIdx: %s) %d not yet verified", indexString, desiredWeight) c.enqueueRolloutAfter(c.rollout, defaults.GetRolloutVerifyRetryInterval()) + // At the end of the rollout we need to verify the weight is correct, and return an error if not because we don't want the rest of the + // reconcile process to continue. We don't need to do this if we are in the middle of the rollout because the rest of the reconcile + // process won't scale down the old replicasets yet due to being in the middle of some steps. + if desiredWeight == weightutil.MaxTrafficWeight(c.rollout) && len(c.rollout.Spec.Strategy.Canary.Steps) >= int(*c.rollout.Status.CurrentStepIndex) { + return fmt.Errorf("end of rollout, desired weight %d not yet verified", desiredWeight) + } } } } diff --git a/rollout/trafficrouting/alb/alb.go b/rollout/trafficrouting/alb/alb.go index 8e81b113c7..0a053857d6 100644 --- a/rollout/trafficrouting/alb/alb.go +++ b/rollout/trafficrouting/alb/alb.go @@ -202,7 +202,7 @@ func (r *Reconciler) VerifyWeight(desiredWeight int32, additionalDestinations .. return nil, nil } - if !rolloututil.ShouldVerifyWeight(r.cfg.Rollout) { + if !rolloututil.ShouldVerifyWeight(r.cfg.Rollout, desiredWeight) { // If we should not verify weight but the ALB status has not been set yet due to a Rollout resource just being // installed in the cluster we want to actually run the rest of the function, so we do not return if // r.cfg.Rollout.Status.ALB is nil. However, if we should not verify, and we have already updated the status once @@ -242,7 +242,7 @@ func (r *Reconciler) VerifyWeightPerIngress(desiredWeight int32, ingresses []str } resourceIDToDest := map[string]v1alpha1.WeightDestination{} - stableService, canaryService := trafficrouting.GetStableAndCanaryServices(rollout) + stableService, canaryService := trafficrouting.GetStableAndCanaryServices(rollout, true) canaryResourceID := aws.BuildTargetGroupResourceID(rollout.Namespace, ingress.GetName(), canaryService, rollout.Spec.Strategy.Canary.TrafficRouting.ALB.ServicePort) stableResourceID := aws.BuildTargetGroupResourceID(rollout.Namespace, ingress.GetName(), stableService, rollout.Spec.Strategy.Canary.TrafficRouting.ALB.ServicePort) @@ -347,7 +347,7 @@ func updateTargetGroupStatus(status *v1alpha1.ALBStatus, tg *aws.TargetGroupMeta } func getForwardActionString(r *v1alpha1.Rollout, port int32, desiredWeight int32, additionalDestinations ...v1alpha1.WeightDestination) (string, error) { - stableService, canaryService := trafficrouting.GetStableAndCanaryServices(r) + stableService, canaryService := trafficrouting.GetStableAndCanaryServices(r, true) portStr := strconv.Itoa(int(port)) stableWeight := int32(100) targetGroups := make([]ingressutil.ALBTargetGroup, 0) @@ -479,7 +479,7 @@ func removeValue(array []string, key string) []string { } func getTrafficForwardActionString(r *v1alpha1.Rollout, port int32) (string, error) { - _, canaryService := trafficrouting.GetStableAndCanaryServices(r) + _, canaryService := trafficrouting.GetStableAndCanaryServices(r, true) portStr := strconv.Itoa(int(port)) weight := int64(100) targetGroups := make([]ingressutil.ALBTargetGroup, 0) diff --git a/rollout/trafficrouting/alb/alb_test.go b/rollout/trafficrouting/alb/alb_test.go index fb131849d4..faa798e524 100644 --- a/rollout/trafficrouting/alb/alb_test.go +++ b/rollout/trafficrouting/alb/alb_test.go @@ -918,6 +918,7 @@ func TestVerifyWeight(t *testing.T) { { var status v1alpha1.RolloutStatus r, fakeClient := newFakeReconciler(&status) + fakeClient.loadBalancers = []*elbv2types.LoadBalancer{ { LoadBalancerName: pointer.StringPtr("lb-abc123-name"), @@ -955,6 +956,48 @@ func TestVerifyWeight(t *testing.T) { assert.Equal(t, *status.ALB, *fakeClient.getAlbStatus("ingress")) } + // LoadBalancer found, at max weight, end of rollout + { + var status v1alpha1.RolloutStatus + status.CurrentStepIndex = pointer.Int32Ptr(2) + r, fakeClient := newFakeReconciler(&status) + fakeClient.loadBalancers = []*elbv2types.LoadBalancer{ + { + LoadBalancerName: pointer.StringPtr("lb-abc123-name"), + LoadBalancerArn: pointer.StringPtr("arn:aws:elasticloadbalancing:us-east-2:123456789012:loadbalancer/app/lb-abc123-name/1234567890123456"), + DNSName: pointer.StringPtr("verify-weight-test-abc-123.us-west-2.elb.amazonaws.com"), + }, + } + fakeClient.targetGroups = []aws.TargetGroupMeta{ + { + TargetGroup: elbv2types.TargetGroup{ + TargetGroupName: pointer.StringPtr("canary-tg-abc123-name"), + TargetGroupArn: pointer.StringPtr("arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/canary-tg-abc123-name/1234567890123456"), + }, + Weight: pointer.Int32Ptr(100), + Tags: map[string]string{ + aws.AWSLoadBalancerV2TagKeyResourceID: "default/ingress-canary-svc:443", + }, + }, + { + TargetGroup: elbv2types.TargetGroup{ + TargetGroupName: pointer.StringPtr("stable-tg-abc123-name"), + TargetGroupArn: pointer.StringPtr("arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/stable-tg-abc123-name/1234567890123456"), + }, + Weight: pointer.Int32Ptr(0), + Tags: map[string]string{ + aws.AWSLoadBalancerV2TagKeyResourceID: "default/ingress-stable-svc:443", + }, + }, + } + + weightVerified, err := r.VerifyWeight(100) + assert.NoError(t, err) + assert.True(t, *weightVerified) + assert.Equal(t, status.ALBs[0], *status.ALB) + assert.Equal(t, *status.ALB, *fakeClient.getAlbStatus("ingress")) + } + // LoadBalancer found, but ARNs are unparsable { var status v1alpha1.RolloutStatus diff --git a/rollout/trafficrouting/ambassador/ambassador.go b/rollout/trafficrouting/ambassador/ambassador.go index 5c50f38f26..ceb389c81a 100644 --- a/rollout/trafficrouting/ambassador/ambassador.go +++ b/rollout/trafficrouting/ambassador/ambassador.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strconv" "strings" "sync" "time" @@ -218,7 +217,8 @@ func (r *Reconciler) createCanaryMapping(ctx context.Context, } canarySvc := r.Rollout.Spec.Strategy.Canary.CanaryService - canaryMapping := buildCanaryMapping(baseMapping, canarySvc, desiredWeight) + stableService := r.Rollout.Spec.Strategy.Canary.StableService + canaryMapping := buildCanaryMapping(baseMapping, canarySvc, stableService, desiredWeight) _, err = client.Create(ctx, canaryMapping, metav1.CreateOptions{}) if err != nil { msg := fmt.Sprintf("Error creating canary mapping: %s", err) @@ -227,9 +227,9 @@ func (r *Reconciler) createCanaryMapping(ctx context.Context, return err } -func buildCanaryMapping(baseMapping *unstructured.Unstructured, canarySvc string, desiredWeight int32) *unstructured.Unstructured { +func buildCanaryMapping(baseMapping *unstructured.Unstructured, canarySvc string, stableService string, desiredWeight int32) *unstructured.Unstructured { canaryMapping := baseMapping.DeepCopy() - svc := buildCanaryService(baseMapping, canarySvc) + svc := buildCanaryService(baseMapping, canarySvc, stableService) unstructured.RemoveNestedField(canaryMapping.Object, "metadata") cMappingName := buildCanaryMappingName(baseMapping.GetName()) canaryMapping.SetName(cMappingName) @@ -239,19 +239,9 @@ func buildCanaryMapping(baseMapping *unstructured.Unstructured, canarySvc string return canaryMapping } -func buildCanaryService(baseMapping *unstructured.Unstructured, canarySvc string) string { +func buildCanaryService(baseMapping *unstructured.Unstructured, canarySvc string, stableService string) string { curSvc := GetMappingService(baseMapping) - parts := strings.Split(curSvc, ":") - if len(parts) < 2 { - return canarySvc - } - // Check if the last part is a valid int that can be used as the port - port := parts[len(parts)-1] - if _, err := strconv.Atoi(port); err != nil { - return canarySvc - - } - return fmt.Sprintf("%s:%s", canarySvc, port) + return strings.Replace(curSvc, stableService, canarySvc, 1) } func (r *Reconciler) VerifyWeight(desiredWeight int32, additionalDestinations ...v1alpha1.WeightDestination) (*bool, error) { diff --git a/rollout/trafficrouting/ambassador/ambassador_test.go b/rollout/trafficrouting/ambassador/ambassador_test.go index 66d193b83a..ee1ac347e3 100644 --- a/rollout/trafficrouting/ambassador/ambassador_test.go +++ b/rollout/trafficrouting/ambassador/ambassador_test.go @@ -31,7 +31,7 @@ metadata: spec: prefix: /myapp/ rewrite: /myapp/ - service: myapp:8080` + service: main-service:8080` baseMappingNoPort = ` apiVersion: getambassador.io/v2 @@ -42,7 +42,7 @@ metadata: spec: prefix: /myapp/ rewrite: /myapp/ - service: myapp` + service: main-service` baseMappingWithWeight = ` apiVersion: getambassador.io/v2 @@ -53,7 +53,7 @@ metadata: spec: prefix: /myapp/ rewrite: /myapp/ - service: myapp:8080 + service: main-service:8080 weight: 20` baseV3Mapping = ` @@ -66,7 +66,7 @@ spec: hostname: 'example.com' prefix: /myapp/ rewrite: /myapp/ - service: myapp:8080` + service: main-service:8080` canaryMapping = ` apiVersion: getambassador.io/v2 @@ -77,7 +77,7 @@ metadata: spec: prefix: /myapp/ rewrite: /myapp/ - service: myapp:8080 + service: main-service:8080 weight: 20` canaryMappingWithZeroWeight = ` @@ -89,7 +89,7 @@ metadata: spec: prefix: /myapp/ rewrite: /myapp/ - service: myapp:8080 + service: main-service:8080 weight: 0` ) diff --git a/rollout/trafficrouting/istio/istio.go b/rollout/trafficrouting/istio/istio.go index 5308d59a42..bb9a15eb5e 100644 --- a/rollout/trafficrouting/istio/istio.go +++ b/rollout/trafficrouting/istio/istio.go @@ -125,7 +125,7 @@ func (patches virtualServicePatches) patchVirtualService(httpRoutes []any, tlsRo } func (r *Reconciler) generateVirtualServicePatches(rolloutVsvcRouteNames []string, httpRoutes []VirtualServiceHTTPRoute, rolloutVsvcTLSRoutes []v1alpha1.TLSRoute, tlsRoutes []VirtualServiceTLSRoute, rolloutVsvcTCPRoutes []v1alpha1.TCPRoute, tcpRoutes []VirtualServiceTCPRoute, desiredWeight int64, additionalDestinations ...v1alpha1.WeightDestination) virtualServicePatches { - stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r.rollout) + stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r.rollout, false) canarySubset := "" stableSubset := "" if r.rollout.Spec.Strategy.Canary.TrafficRouting.Istio.DestinationRule != nil { @@ -718,7 +718,7 @@ func (r *Reconciler) reconcileVirtualServiceHeaderRoutes(virtualService v1alpha1 return err } - _, canarySvc := trafficrouting.GetStableAndCanaryServices(r.rollout) + _, canarySvc := trafficrouting.GetStableAndCanaryServices(r.rollout, false) if destRuleHost != "" { canarySvc = destRuleHost } @@ -1023,7 +1023,7 @@ func searchTcpRoute(tcpRoute v1alpha1.TCPRoute, istioTcpRoutes []VirtualServiceT // ValidateHTTPRoutes ensures that all the routes in the rollout exist func ValidateHTTPRoutes(r *v1alpha1.Rollout, routeNames []string, httpRoutes []VirtualServiceHTTPRoute) error { - stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r) + stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r, false) routeIndexesToPatch, err := getHttpRouteIndexesToPatch(routeNames, httpRoutes) if err != nil { @@ -1060,7 +1060,7 @@ func ValidateHTTPRoutes(r *v1alpha1.Rollout, routeNames []string, httpRoutes []V // ValidateTlsRoutes ensures that all the routes in the rollout exist and they only have two destinations func ValidateTlsRoutes(r *v1alpha1.Rollout, vsvcTLSRoutes []v1alpha1.TLSRoute, tlsRoutes []VirtualServiceTLSRoute) error { - stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r) + stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r, false) routeIndexesToPatch, err := getTlsRouteIndexesToPatch(vsvcTLSRoutes, tlsRoutes) if err != nil { @@ -1081,7 +1081,7 @@ func ValidateTlsRoutes(r *v1alpha1.Rollout, vsvcTLSRoutes []v1alpha1.TLSRoute, t // ValidateTcpRoutes ensures that all the routes in the rollout exist and they only have two destinations func ValidateTcpRoutes(r *v1alpha1.Rollout, vsvcTCPRoutes []v1alpha1.TCPRoute, tcpRoutes []VirtualServiceTCPRoute) error { - stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r) + stableSvc, canarySvc := trafficrouting.GetStableAndCanaryServices(r, false) routeIndexesToPatch, err := getTcpRouteIndexesToPatch(vsvcTCPRoutes, tcpRoutes) if err != nil { @@ -1189,7 +1189,7 @@ func (r *Reconciler) reconcileVirtualServiceMirrorRoutes(virtualService v1alpha1 if err != nil { return fmt.Errorf("[reconcileVirtualServiceMirrorRoutes] failed to get destination rule host: %w", err) } - _, canarySvc := trafficrouting.GetStableAndCanaryServices(r.rollout) + _, canarySvc := trafficrouting.GetStableAndCanaryServices(r.rollout, false) if destRuleHost != "" { canarySvc = destRuleHost } diff --git a/rollout/trafficrouting/service_helper.go b/rollout/trafficrouting/service_helper.go index 15d03cad53..8bae069fe7 100644 --- a/rollout/trafficrouting/service_helper.go +++ b/rollout/trafficrouting/service_helper.go @@ -7,17 +7,26 @@ import ( // GetStableAndCanaryServices return a service names for current stable and canary services. // If ping-pong feature enabled then the current ping or pong service will be returned. Which is a stable is defined // based on a rollout status field Status.Canary.StablePingPong -func GetStableAndCanaryServices(ro *v1alpha1.Rollout) (string, string) { - if IsPingPongEnabled(ro) { + +// isPingpongPreferred is needed when Rollout uses both pingpong service and stable/canary service +// for ALB trafficRouting, isPingpongPreferred is true. It uses pingpong service as priority +// for other trafficRouting, isPingpongPrefrered is false. It uses stable/canary service +// This is to ensure it is compatible with previous release. + +func GetStableAndCanaryServices(ro *v1alpha1.Rollout, isPingpongPreferred bool) (string, string) { + pingPongNotPreferredOtherServiceNotDefined := !isPingpongPreferred && ro.Spec.Strategy.Canary.StableService == "" && ro.Spec.Strategy.Canary.CanaryService == "" + if IsPingPongEnabled(ro) && + (isPingpongPreferred || pingPongNotPreferredOtherServiceNotDefined) { canary := ro.Spec.Strategy.Canary if IsStablePing(ro) { return canary.PingPong.PingService, canary.PingPong.PongService } else { return canary.PingPong.PongService, canary.PingPong.PingService } - } else { - return ro.Spec.Strategy.Canary.StableService, ro.Spec.Strategy.Canary.CanaryService } + + return ro.Spec.Strategy.Canary.StableService, ro.Spec.Strategy.Canary.CanaryService + } // IsStablePing return true if the 'ping' service is pointing to the stable replica set. diff --git a/rollout/trafficrouting/service_helper_test.go b/rollout/trafficrouting/service_helper_test.go new file mode 100644 index 0000000000..cc0634eb6f --- /dev/null +++ b/rollout/trafficrouting/service_helper_test.go @@ -0,0 +1,82 @@ +package trafficrouting + +import ( + "testing" + + "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const PING_SVC = "ping-service" +const PONG_SVC = "pong-service" + +func fakeRollout(stableSvc, canarySvc string, pingPong *v1alpha1.PingPongSpec, stableIng string, port int32) *v1alpha1.Rollout { + return &v1alpha1.Rollout{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rollout", + Namespace: metav1.NamespaceDefault, + }, + Spec: v1alpha1.RolloutSpec{ + Strategy: v1alpha1.RolloutStrategy{ + Canary: &v1alpha1.CanaryStrategy{ + StableService: stableSvc, + CanaryService: canarySvc, + PingPong: pingPong, + TrafficRouting: &v1alpha1.RolloutTrafficRouting{ + ALB: &v1alpha1.ALBTrafficRouting{ + Ingress: stableIng, + ServicePort: port, + }, + Istio: &v1alpha1.IstioTrafficRouting{ + VirtualService: &v1alpha1.IstioVirtualService{ + Name: "istio-vsvc", + }, + DestinationRule: &v1alpha1.IstioDestinationRule{ + Name: "istio-destrule", + CanarySubsetName: "canary", + StableSubsetName: "stable", + }, + }, + }, + }, + }, + }, + } +} + +func TestGetStableAndCanaryServices(t *testing.T) { + // Rollout has no pingPong + rollout := fakeRollout("stable-service", "canary-service", nil, "stable-ingress", 443) + + stableService, canaryService := GetStableAndCanaryServices(rollout, true) + assert.Equal(t, "stable-service", stableService) + assert.Equal(t, "canary-service", canaryService) + + stableService, canaryService = GetStableAndCanaryServices(rollout, false) + assert.Equal(t, "stable-service", stableService) + assert.Equal(t, "canary-service", canaryService) + + // Rollout has pingPong and stable/canary + pp := &v1alpha1.PingPongSpec{PingService: PING_SVC, PongService: PONG_SVC} + rollout = fakeRollout("stable-service", "canary-service", pp, "stable-ingress", 443) + + stableService, canaryService = GetStableAndCanaryServices(rollout, true) + assert.Equal(t, PONG_SVC, stableService) + assert.Equal(t, PING_SVC, canaryService) + + stableService, canaryService = GetStableAndCanaryServices(rollout, false) + assert.Equal(t, "stable-service", stableService) + assert.Equal(t, "canary-service", canaryService) + + // Rollout has pingPong, no stable/canary + rollout = fakeRollout("", "", pp, "stable-ingress", 443) + + stableService, canaryService = GetStableAndCanaryServices(rollout, true) + assert.Equal(t, PONG_SVC, stableService) + assert.Equal(t, PING_SVC, canaryService) + + stableService, canaryService = GetStableAndCanaryServices(rollout, false) + assert.Equal(t, PONG_SVC, stableService) + assert.Equal(t, PING_SVC, canaryService) +} diff --git a/rollout/trafficrouting_test.go b/rollout/trafficrouting_test.go index f7dd459964..f358a18f64 100644 --- a/rollout/trafficrouting_test.go +++ b/rollout/trafficrouting_test.go @@ -130,6 +130,53 @@ func TestReconcileTrafficRoutingVerifyWeightFalse(t *testing.T) { assert.True(t, enqueued) } +func TestReconcileTrafficRoutingVerifyWeightEndOfRollout(t *testing.T) { + f := newFixture(t) + defer f.Close() + + steps := []v1alpha1.CanaryStep{ + { + SetWeight: pointer.Int32Ptr(10), + }, + { + Pause: &v1alpha1.RolloutPause{}, + }, + } + r1 := newCanaryRollout("foo", 10, nil, steps, pointer.Int32Ptr(2), intstr.FromInt(1), intstr.FromInt(0)) + r2 := bumpVersion(r1) + r2.Spec.Strategy.Canary.TrafficRouting = &v1alpha1.RolloutTrafficRouting{} + r2.Spec.Strategy.Canary.CanaryService = "canary" + r2.Spec.Strategy.Canary.StableService = "stable" + + rs1 := newReplicaSetWithStatus(r1, 10, 10) + rs2 := newReplicaSetWithStatus(r2, 10, 10) + + rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + rs2PodHash := rs2.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + canarySelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs2PodHash} + stableSelector := map[string]string{v1alpha1.DefaultRolloutUniqueLabelKey: rs1PodHash} + canarySvc := newService("canary", 80, canarySelector, r2) + stableSvc := newService("stable", 80, stableSelector, r2) + + f.kubeobjects = append(f.kubeobjects, rs1, rs2, canarySvc, stableSvc) + f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) + + r2 = updateCanaryRolloutStatus(r2, rs1PodHash, 10, 0, 10, false) + f.rolloutLister = append(f.rolloutLister, r2) + f.objects = append(f.objects, r2) + + f.fakeTrafficRouting = newUnmockedFakeTrafficRoutingReconciler() + f.fakeTrafficRouting.On("UpdateHash", mock.Anything, mock.Anything, mock.Anything).Return(nil) + f.fakeTrafficRouting.On("SetWeight", mock.Anything, mock.Anything).Return(func(desiredWeight int32, additionalDestinations ...v1alpha1.WeightDestination) error { + // make sure SetWeight was called with correct value + assert.Equal(t, int32(100), desiredWeight) + return nil + }) + f.fakeTrafficRouting.On("SetHeaderRoute", mock.Anything, mock.Anything).Return(nil) + f.fakeTrafficRouting.On("VerifyWeight", mock.Anything).Return(pointer.BoolPtr(false), nil) + f.runExpectError(getKey(r2, t), true) +} + func TestRolloutUseDesiredWeight(t *testing.T) { f := newFixture(t) defer f.Close() diff --git a/test/e2e/aws_test.go b/test/e2e/aws_test.go index f8b0553fe2..fcbb1a2ef5 100644 --- a/test/e2e/aws_test.go +++ b/test/e2e/aws_test.go @@ -94,6 +94,71 @@ func (s *AWSSuite) TestALBPingPongUpdate() { Assert(assertWeights(s, "ping-service", "pong-service", 100, 0)) } +// Rollout uses both alb and mesh for trafficRouting. +// also uses both pingpong service and stable/canary services +// Expecting: * alb is using pingpong +// - mesh is using stable/canary +func (s *AWSSuite) TestALBMesh_PingPong_StableCanary_Update() { + s.Given(). + RolloutObjects("@functional/albmesh-pingpong-stablecanary-rollout.yaml"). + When().ApplyManifests().WaitForRolloutStatus("Healthy"). + Then(). + Assert(assertWeights(s, "ping-service", "pong-service", 100, 0)). + Assert(func(t *fixtures.Then) { + vsvc := t.GetVirtualService() + assert.Equal(s.T(), int64(100), vsvc.Spec.HTTP[0].Route[0].Weight) + assert.Equal(s.T(), int64(0), vsvc.Spec.HTTP[0].Route[1].Weight) + assert.Equal(s.T(), "stable-service", vsvc.Spec.HTTP[0].Route[0].Destination.Host) + assert.Equal(s.T(), "canary-service", vsvc.Spec.HTTP[0].Route[1].Destination.Host) + }). + // Update 1. Test the weight switch from ping => pong + When().UpdateSpec(). + WaitForRolloutCanaryStepIndex(1).Sleep(1 * time.Second).Then(). + Assert(assertWeights(s, "ping-service", "pong-service", 75, 25)). + Assert(func(t *fixtures.Then) { + vsvc := t.GetVirtualService() + assert.Equal(s.T(), int64(75), vsvc.Spec.HTTP[0].Route[0].Weight) + assert.Equal(s.T(), int64(25), vsvc.Spec.HTTP[0].Route[1].Weight) + assert.Equal(s.T(), "stable-service", vsvc.Spec.HTTP[0].Route[0].Destination.Host) + assert.Equal(s.T(), "canary-service", vsvc.Spec.HTTP[0].Route[1].Destination.Host) + }). + When().PromoteRollout(). + WaitForRolloutStatus("Healthy"). + Sleep(1 * time.Second). + Then(). + Assert(assertWeights(s, "ping-service", "pong-service", 0, 100)). + Assert(func(t *fixtures.Then) { + vsvc := t.GetVirtualService() + assert.Equal(s.T(), int64(100), vsvc.Spec.HTTP[0].Route[0].Weight) + assert.Equal(s.T(), int64(0), vsvc.Spec.HTTP[0].Route[1].Weight) + assert.Equal(s.T(), "stable-service", vsvc.Spec.HTTP[0].Route[0].Destination.Host) + assert.Equal(s.T(), "canary-service", vsvc.Spec.HTTP[0].Route[1].Destination.Host) + }). + // Update 2. Test the weight switch from pong => ping + When().UpdateSpec(). + WaitForRolloutCanaryStepIndex(1).Sleep(1 * time.Second).Then(). + Assert(assertWeights(s, "ping-service", "pong-service", 25, 75)). + Assert(func(t *fixtures.Then) { + vsvc := t.GetVirtualService() + assert.Equal(s.T(), int64(75), vsvc.Spec.HTTP[0].Route[0].Weight) + assert.Equal(s.T(), int64(25), vsvc.Spec.HTTP[0].Route[1].Weight) + assert.Equal(s.T(), "stable-service", vsvc.Spec.HTTP[0].Route[0].Destination.Host) + assert.Equal(s.T(), "canary-service", vsvc.Spec.HTTP[0].Route[1].Destination.Host) + }). + When().PromoteRollout(). + WaitForRolloutStatus("Healthy"). + Sleep(1 * time.Second). + Then(). + Assert(assertWeights(s, "ping-service", "pong-service", 100, 0)). + Assert(func(t *fixtures.Then) { + vsvc := t.GetVirtualService() + assert.Equal(s.T(), int64(100), vsvc.Spec.HTTP[0].Route[0].Weight) + assert.Equal(s.T(), int64(0), vsvc.Spec.HTTP[0].Route[1].Weight) + assert.Equal(s.T(), "stable-service", vsvc.Spec.HTTP[0].Route[0].Destination.Host) + assert.Equal(s.T(), "canary-service", vsvc.Spec.HTTP[0].Route[1].Destination.Host) + }) +} + func (s *AWSSuite) TestALBPingPongUpdateMultiIngress() { s.Given(). RolloutObjects("@functional/alb-pingpong-multi-ingress-rollout.yaml"). @@ -239,6 +304,7 @@ func (s *AWSSuite) TestALBExperimentStepMultiIngress() { } func (s *AWSSuite) TestALBExperimentStepNoSetWeight() { + //TODO: this test is flaky s.Given(). RolloutObjects("@alb/rollout-alb-experiment-no-setweight.yaml"). When(). @@ -272,6 +338,7 @@ func (s *AWSSuite) TestALBExperimentStepNoSetWeight() { } func (s *AWSSuite) TestALBExperimentStepNoSetWeightMultiIngress() { + //TODO: this test is flaky s.Given(). RolloutObjects("@alb/rollout-alb-multi-ingress-experiment-no-setweight.yaml"). When(). diff --git a/test/e2e/canary_test.go b/test/e2e/canary_test.go index 2c68ec8bd7..8656aa5c4d 100644 --- a/test/e2e/canary_test.go +++ b/test/e2e/canary_test.go @@ -149,7 +149,10 @@ spec: spec: containers: - name: updatescaling - command: [/bad-command]`). + resources: + requests: + memory: 16Mi + cpu: 2m`). WaitForRolloutReplicas(7). Then(). ExpectCanaryStablePodCount(4, 3). @@ -658,6 +661,7 @@ func (s *CanarySuite) TestCanaryDynamicStableScale() { When(). MarkPodsReady("1", 1). // mark last remaining stable pod as ready (4/4 stable are ready) WaitForRevisionPodCount("2", 0). + Sleep(2*time.Second). //WaitForRevisionPodCount does not wait for terminating pods and so ExpectServiceSelector fails sleep a bit for the terminating pods to be deleted Then(). // Expect that the canary service selector is now set to stable because of dynamic stable scale is over and we have all pods up on stable rs ExpectServiceSelector("dynamic-stable-scale-canary", map[string]string{"app": "dynamic-stable-scale", "rollouts-pod-template-hash": "868d98995b"}, false). diff --git a/test/e2e/functional/albmesh-pingpong-stablecanary-rollout.yaml b/test/e2e/functional/albmesh-pingpong-stablecanary-rollout.yaml new file mode 100644 index 0000000000..0476b1076e --- /dev/null +++ b/test/e2e/functional/albmesh-pingpong-stablecanary-rollout.yaml @@ -0,0 +1,139 @@ +--- +apiVersion: v1 +kind: Service +metadata: + name: ping-service +spec: + type: NodePort + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: alb-canary +--- +apiVersion: v1 +kind: Service +metadata: + name: pong-service +spec: + type: NodePort + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: alb-canary +--- +--- +apiVersion: v1 +kind: Service +metadata: + name: stable-service +spec: + type: NodePort + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: alb-canary +--- +apiVersion: v1 +kind: Service +metadata: + name: canary-service +spec: + type: NodePort + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + selector: + app: alb-canary +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: alb-canary-ingress + annotations: + kubernetes.io/ingress.class: alb +spec: + rules: + - http: + paths: + - path: /* + backend: + service: + name: alb-rollout-root + port: + name: use-annotation + pathType: ImplementationSpecific +--- +apiVersion: argoproj.io/v1alpha1 +kind: Rollout +metadata: + name: alb-canary +spec: + replicas: 2 + selector: + matchLabels: + app: alb-canary + template: + metadata: + labels: + app: alb-canary + spec: + containers: + - name: alb-canary + image: "argoproj/rollouts-demo:red" + ports: + - name: http + containerPort: 80 + protocol: TCP + resources: + requests: + memory: 16Mi + cpu: 5m + strategy: + canary: + scaleDownDelaySeconds: 2 + canaryService: canary-service + stableService: stable-service + pingPong: + pingService: ping-service + pongService: pong-service + trafficRouting: + alb: + ingress: alb-canary-ingress + rootService: alb-rollout-root + servicePort: 80 + istio: + virtualService: + name: istio-host-split-vsvc + routes: + - primary + steps: + - setWeight: 25 + - pause: {} +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: istio-host-split-vsvc +spec: + hosts: + - istio-host-split + http: + - name: primary + route: + - destination: + host: stable-service + weight: 100 + - destination: + host: canary-service + weight: 0 diff --git a/test/e2e/functional/analysistemplate-sleep-job.yaml b/test/e2e/functional/analysistemplate-sleep-job.yaml index 86faa2c877..4fdd369dee 100644 --- a/test/e2e/functional/analysistemplate-sleep-job.yaml +++ b/test/e2e/functional/analysistemplate-sleep-job.yaml @@ -6,7 +6,7 @@ metadata: spec: args: - name: duration - value: 0s + value: "0" - name: exit-code value: "0" - name: count diff --git a/test/e2e/functional_test.go b/test/e2e/functional_test.go index 930c7d0c61..668c75bb0c 100644 --- a/test/e2e/functional_test.go +++ b/test/e2e/functional_test.go @@ -166,13 +166,14 @@ spec: UpdateSpec(). WaitForRolloutStatus("Paused"). // At step 1 (pause: {duration: 24h}) PromoteRollout(). - Sleep(2*time.Second). + Sleep(3*time.Second). + WaitForInlineAnalysisRunPhase("Running"). Then(). + ExpectRolloutStatus("Progressing"). // At step 2 (analysis: sleep-job - 24h) + ExpectAnalysisRunCount(1). ExpectRollout("status.currentStepIndex == 1", func(r *v1alpha1.Rollout) bool { return *r.Status.CurrentStepIndex == 1 }). - ExpectRolloutStatus("Progressing"). // At step 2 (analysis: sleep-job - 24h) - ExpectAnalysisRunCount(1). When(). PromoteRollout(). Sleep(2 * time.Second). @@ -205,6 +206,9 @@ spec: prePromotionAnalysis: templates: - templateName: sleep-job + args: + - name: duration + value: "10" postPromotionAnalysis: templates: - templateName: sleep-job @@ -228,7 +232,8 @@ spec: ApplyManifests(). WaitForRolloutStatus("Healthy"). UpdateSpec(). - Sleep(3 * time.Second). + Sleep(5 * time.Second). + WaitForPrePromotionAnalysisRunPhase("Running"). PromoteRolloutFull(). WaitForRolloutStatus("Healthy"). Then(). diff --git a/test/fixtures/e2e_suite.go b/test/fixtures/e2e_suite.go index a774afcf94..e78ae1aa68 100644 --- a/test/fixtures/e2e_suite.go +++ b/test/fixtures/e2e_suite.go @@ -54,7 +54,7 @@ const ( ) var ( - E2EWaitTimeout time.Duration = time.Second * 120 + E2EWaitTimeout time.Duration = time.Second * 90 E2EPodDelay = 0 E2EALBIngressAnnotations map[string]string @@ -143,8 +143,8 @@ func (s *E2ESuite) SetupSuite() { restConfig, err := config.ClientConfig() s.CheckError(err) s.Common.kubernetesHost = restConfig.Host - restConfig.Burst = defaults.DefaultBurst * 2 - restConfig.QPS = defaults.DefaultQPS * 2 + restConfig.Burst = defaults.DefaultBurst * 10 + restConfig.QPS = defaults.DefaultQPS * 10 s.namespace, _, err = config.Namespace() s.CheckError(err) s.kubeClient, err = kubernetes.NewForConfig(restConfig) diff --git a/ui/yarn.lock b/ui/yarn.lock index 2ef9058665..628cb5963f 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -10217,16 +10217,7 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== -loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -loader-utils@^2.0.4: +loader-utils@^2.0.0, loader-utils@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== diff --git a/utils/annotations/annotations.go b/utils/annotations/annotations.go index 121c6c0803..067492bc2b 100644 --- a/utils/annotations/annotations.go +++ b/utils/annotations/annotations.go @@ -28,6 +28,8 @@ const ( DesiredReplicasAnnotation = RolloutLabel + "/desired-replicas" // WorkloadGenerationAnnotation is the generation of the referenced workload WorkloadGenerationAnnotation = RolloutLabel + "/workload-generation" + // NotificationEngineAnnotation the annotation notification engine uses to determine if it should notify + NotificationEngineAnnotation = "notified.notifications.argoproj.io" ) // GetDesiredReplicasAnnotation returns the number of desired replicas @@ -219,6 +221,7 @@ var annotationsToSkip = map[string]bool{ RevisionAnnotation: true, RevisionHistoryAnnotation: true, DesiredReplicasAnnotation: true, + NotificationEngineAnnotation: true, } // skipCopyAnnotation returns true if we should skip copying the annotation with the given annotation key diff --git a/utils/controller/controller.go b/utils/controller/controller.go index 2530e1d5fa..b5c1fc875b 100644 --- a/utils/controller/controller.go +++ b/utils/controller/controller.go @@ -6,6 +6,8 @@ import ( "runtime/debug" "time" + "k8s.io/apimachinery/pkg/api/errors" + log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -157,6 +159,11 @@ func processNextWorkItem(ctx context.Context, workqueue workqueue.RateLimitingIn if err := runSyncHandler(); err != nil { logCtx.Errorf("%s syncHandler error: %v", objType, err) metricsServer.IncError(namespace, name, objType) + + if errors.IsNotFound(err) { + workqueue.Forget(obj) + return nil + } // Put the item back on // the workqueue to handle any transient errors. workqueue.AddRateLimited(key) diff --git a/utils/replicaset/canary.go b/utils/replicaset/canary.go old mode 100755 new mode 100644 index cf41e6baa5..f8fd8fe869 --- a/utils/replicaset/canary.go +++ b/utils/replicaset/canary.go @@ -4,6 +4,8 @@ import ( "encoding/json" "math" + "github.com/argoproj/argo-rollouts/utils/annotations" + log "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -15,7 +17,7 @@ import ( const ( // EphemeralMetadataAnnotation denotes pod metadata which is ephemerally injected to canary/stable pods - EphemeralMetadataAnnotation = "rollout.argoproj.io/ephemeral-metadata" + EphemeralMetadataAnnotation = annotations.RolloutLabel + "/ephemeral-metadata" ) func allDesiredAreAvailable(rs *appsv1.ReplicaSet, desired int32) bool { diff --git a/utils/rollout/rolloututil.go b/utils/rollout/rolloututil.go index 0b7df7ff38..5411f3f58c 100644 --- a/utils/rollout/rolloututil.go +++ b/utils/rollout/rolloututil.go @@ -4,6 +4,8 @@ import ( "fmt" "strconv" + "github.com/argoproj/argo-rollouts/utils/weightutil" + replicasetutil "github.com/argoproj/argo-rollouts/utils/replicaset" "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" @@ -184,13 +186,13 @@ func CanaryStepString(c v1alpha1.CanaryStep) string { // ShouldVerifyWeight We use this to test if we should verify weights because weight verification could involve // API calls to the cloud provider which could incur rate limiting -func ShouldVerifyWeight(ro *v1alpha1.Rollout) bool { +func ShouldVerifyWeight(ro *v1alpha1.Rollout, desiredWeight int32) bool { currentStep, _ := replicasetutil.GetCurrentCanaryStep(ro) // If we are in the middle of an update at a setWeight step, also perform weight verification. // Note that we don't do this every reconciliation because weight verification typically involves // API calls to the cloud provider which could incur rate limitingq - shouldVerifyWeight := ro.Status.StableRS != "" && - !IsFullyPromoted(ro) && - currentStep != nil && currentStep.SetWeight != nil + shouldVerifyWeight := (ro.Status.StableRS != "" && !IsFullyPromoted(ro) && currentStep != nil && currentStep.SetWeight != nil) || + (ro.Status.StableRS != "" && !IsFullyPromoted(ro) && currentStep == nil && desiredWeight == weightutil.MaxTrafficWeight(ro)) // We are at end of rollout + return shouldVerifyWeight } diff --git a/utils/rollout/rolloututil_test.go b/utils/rollout/rolloututil_test.go index 37c1810f00..d88f080f64 100644 --- a/utils/rollout/rolloututil_test.go +++ b/utils/rollout/rolloututil_test.go @@ -422,15 +422,21 @@ func TestShouldVerifyWeight(t *testing.T) { ro.Spec.Strategy.Canary.Steps = []v1alpha1.CanaryStep{{ SetWeight: pointer.Int32Ptr(20), }} - assert.Equal(t, true, ShouldVerifyWeight(ro)) + assert.Equal(t, true, ShouldVerifyWeight(ro, 20)) ro.Status.StableRS = "" - assert.Equal(t, false, ShouldVerifyWeight(ro)) + assert.Equal(t, false, ShouldVerifyWeight(ro, 20)) ro.Status.StableRS = "34feab23f" ro.Status.CurrentStepIndex = nil ro.Spec.Strategy.Canary.Steps = nil - assert.Equal(t, false, ShouldVerifyWeight(ro)) + assert.Equal(t, false, ShouldVerifyWeight(ro, 20)) + + // Test when the weight is 100, because we are at end of rollout + ro.Status.StableRS = "34feab23f" + ro.Status.CurrentStepIndex = nil + ro.Spec.Strategy.Canary.Steps = nil + assert.Equal(t, true, ShouldVerifyWeight(ro, 100)) } func Test_isGenerationObserved(t *testing.T) {