From a9a519221aecfd0e1b19708f0ece2bed8380240e Mon Sep 17 00:00:00 2001 From: Carlos Sanchez Date: Fri, 8 Mar 2024 20:04:54 +0000 Subject: [PATCH 01/13] docs: minor readability on migration (#3427) the ordered list was 1-2-3-1 fixed the indentation Signed-off-by: Carlos Sanchez --- docs/migrating.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/migrating.md b/docs/migrating.md index 3e1f85c461..524b67444d 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -55,10 +55,11 @@ Instead of removing Deployment you can scale it down to zero and reference it fr 1. Create a Rollout resource. 1. Reference an existing Deployment using `workloadRef` field. 1. In the `workloadRef` field set the `scaleDown` attribute, which specifies how the Deployment should be scaled down. There are three options available: -* "never": the Deployment is not scaled down -* "onsuccess": the Deployment is scaled down after the Rollout becomes healthy -* "progressively": as the Rollout is scaled up the Deployment is scaled down. -Alternatively, manually scale down an existing Deployment by changing replicas field of an existing Deployment to zero. + * `never`: the Deployment is not scaled down + * `onsuccess`: the Deployment is scaled down after the Rollout becomes healthy + * `progressively`: as the Rollout is scaled up the Deployment is scaled down. + + Alternatively, manually scale down an existing Deployment by changing replicas field of an existing Deployment to zero. 1. To perform an update, the change should be made to the Pod template field of the Deployment. Below is an example of a Rollout resource referencing a Deployment. From 0cfdf342ddea524d12f525d0dc91271207066a24 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 11:00:02 -0500 Subject: [PATCH 02/13] chore(deps): bump docker/build-push-action from 5.1.0 to 5.2.0 (#3439) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.1.0 to 5.2.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/4a13e500e55cf31b7a5d59a38ab2040ab0f42f56...af5a7ed5ba88268d5278f7203fb52cd833f66d6e) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/image-reuse.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index 17d77e86d5..197c0aa346 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -130,7 +130,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 #v5.1.0 + uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e #v5.2.0 with: context: . platforms: ${{ inputs.platforms }} From c6ba82cca216c7c9713c7cd69dae1ebe25ba33a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 17:14:47 -0500 Subject: [PATCH 03/13] chore(deps): bump softprops/action-gh-release from 1 to 2 (#3438) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 1 to 2. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/de2c0eb89ae2a093876385947365aca7b0e5f844...d99959edae48b5ffffd7b00da66dcdb0a33a52ee) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 53810510d3..562274096d 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -108,7 +108,7 @@ jobs: make manifests IMAGE_TAG=${{ github.ref_name }} - name: Draft release - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 + uses: softprops/action-gh-release@d99959edae48b5ffffd7b00da66dcdb0a33a52ee # v0.1.15 with: tag_name: ${{ github.event.inputs.tag }} draft: true @@ -214,7 +214,7 @@ jobs: /tmp/sbom.tar.gz - name: Upload SBOM and signature assets - uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 + uses: softprops/action-gh-release@d99959edae48b5ffffd7b00da66dcdb0a33a52ee # v0.1.15 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 46f14278eef6735498c33835e795b0315f33f948 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 12:29:35 -0500 Subject: [PATCH 04/13] chore(deps): bump softprops/action-gh-release from 2.0.2 to 2.0.3 (#3440) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.2 to 2.0.3. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/d99959edae48b5ffffd7b00da66dcdb0a33a52ee...3198ee18f814cdf787321b4a32a26ddbf37acc52) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 562274096d..38e7c73e0f 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -108,7 +108,7 @@ jobs: make manifests IMAGE_TAG=${{ github.ref_name }} - name: Draft release - uses: softprops/action-gh-release@d99959edae48b5ffffd7b00da66dcdb0a33a52ee # v0.1.15 + uses: softprops/action-gh-release@3198ee18f814cdf787321b4a32a26ddbf37acc52 # v0.1.15 with: tag_name: ${{ github.event.inputs.tag }} draft: true @@ -214,7 +214,7 @@ jobs: /tmp/sbom.tar.gz - name: Upload SBOM and signature assets - uses: softprops/action-gh-release@d99959edae48b5ffffd7b00da66dcdb0a33a52ee # v0.1.15 + uses: softprops/action-gh-release@3198ee18f814cdf787321b4a32a26ddbf37acc52 # v0.1.15 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 7012ed7d31885fcc2f7dc3978a9b6474ad1a6aa6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 09:15:08 -0500 Subject: [PATCH 05/13] chore(deps): bump softprops/action-gh-release from 2.0.3 to 2.0.4 (#3442) Bumps [softprops/action-gh-release](https://github.com/softprops/action-gh-release) from 2.0.3 to 2.0.4. - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/3198ee18f814cdf787321b4a32a26ddbf37acc52...9d7c94cfd0a1f3ed45544c887983e9fa900f0564) --- updated-dependencies: - dependency-name: softprops/action-gh-release dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 38e7c73e0f..58ad372eda 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -108,7 +108,7 @@ jobs: make manifests IMAGE_TAG=${{ github.ref_name }} - name: Draft release - uses: softprops/action-gh-release@3198ee18f814cdf787321b4a32a26ddbf37acc52 # v0.1.15 + uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v0.1.15 with: tag_name: ${{ github.event.inputs.tag }} draft: true @@ -214,7 +214,7 @@ jobs: /tmp/sbom.tar.gz - name: Upload SBOM and signature assets - uses: softprops/action-gh-release@3198ee18f814cdf787321b4a32a26ddbf37acc52 # v0.1.15 + uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v0.1.15 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From d510545bf5b7015f6c6897ef390c7dc552c1927b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:28:22 -0500 Subject: [PATCH 06/13] chore(deps): bump golang.org/x/oauth2 from 0.17.0 to 0.18.0 (#3422) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.17.0 to 0.18.0. - [Commits](https://github.com/golang/oauth2/compare/v0.17.0...v0.18.0) --- updated-dependencies: - dependency-name: golang.org/x/oauth2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index 2a2575d20f..e719a2fdc9 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( 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.17.0 + golang.org/x/oauth2 v0.18.0 google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80 google.golang.org/grpc v1.62.1 google.golang.org/protobuf v1.32.0 @@ -173,11 +173,11 @@ require ( github.com/xlab/treeprint v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect - golang.org/x/crypto v0.19.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect + golang.org/x/net v0.22.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/time v0.3.0 // indirect golang.org/x/tools v0.12.0 // indirect diff --git a/go.sum b/go.sum index 1ce6a216b4..59643ebf01 100644 --- a/go.sum +++ b/go.sum @@ -699,8 +699,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.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +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/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= @@ -784,8 +784,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.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +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/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= @@ -793,8 +793,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.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= -golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= 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= @@ -876,8 +876,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.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/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= @@ -885,8 +885,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.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +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/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= From 5f6142c1907ec02f7f352b23211868981f36bbc4 Mon Sep 17 00:00:00 2001 From: kevinqian-db <151585552+kevinqian-db@users.noreply.github.com> Date: Fri, 15 Mar 2024 06:32:32 -0700 Subject: [PATCH 07/13] fix(controller): treat spec.canary.analysis.template empty list as spec.canary.analysis not set (#3446) Treat spec.canary.analysis.template empty list as spec.canary.analysis not set Signed-off-by: Kevin Qian --- rollout/analysis.go | 2 +- rollout/analysis_test.go | 42 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/rollout/analysis.go b/rollout/analysis.go index 5c5c5f8aec..26205235a1 100644 --- a/rollout/analysis.go +++ b/rollout/analysis.go @@ -313,7 +313,7 @@ func (c *rolloutContext) reconcilePostPromotionAnalysisRun() (*v1alpha1.Analysis func (c *rolloutContext) reconcileBackgroundAnalysisRun() (*v1alpha1.AnalysisRun, error) { currentAr := c.currentArs.CanaryBackground - if c.rollout.Spec.Strategy.Canary.Analysis == nil { + if c.rollout.Spec.Strategy.Canary.Analysis == nil || len(c.rollout.Spec.Strategy.Canary.Analysis.Templates) == 0 { err := c.cancelAnalysisRuns([]*v1alpha1.AnalysisRun{currentAr}) return nil, err } diff --git a/rollout/analysis_test.go b/rollout/analysis_test.go index 624134fbb6..4b5d5d72d7 100644 --- a/rollout/analysis_test.go +++ b/rollout/analysis_test.go @@ -2468,3 +2468,45 @@ func TestCreateAnalysisRunWithCustomAnalysisRunMetadataAndROCopyLabels(t *testin assert.Equal(t, "testLabelValue", createdAr.Labels["testLabelKey"]) assert.Equal(t, "1234", createdAr.Labels["my-label"]) } + +func TestCancelBackgroundAnalysisRunWhenRolloutAnalysisHasNoTemplate(t *testing.T) { + f := newFixture(t) + defer f.Close() + + at := analysisTemplate("bar") + steps := []v1alpha1.CanaryStep{ + {SetWeight: pointer.Int32Ptr(10)}, + } + + r1 := newCanaryRollout("foo", 1, nil, steps, pointer.Int32Ptr(1), intstr.FromInt(0), intstr.FromInt(1)) + rs1 := newReplicaSetWithStatus(r1, 1, 1) + rs1PodHash := rs1.Labels[v1alpha1.DefaultRolloutUniqueLabelKey] + r1 = updateCanaryRolloutStatus(r1, rs1PodHash, 1, 1, 1, false) + ar := analysisRun(at, v1alpha1.RolloutTypeStepLabel, r1) + r1.Status.Canary.CurrentBackgroundAnalysisRunStatus = &v1alpha1.RolloutAnalysisRunStatus{ + Name: ar.Name, + Status: v1alpha1.AnalysisPhaseRunning, + } + + r2 := bumpVersion(r1) + r2.Spec.Strategy.Canary.Analysis = &v1alpha1.RolloutAnalysisBackground{ + RolloutAnalysis: v1alpha1.RolloutAnalysis{}, // No templates provided. + } + rs2 := newReplicaSetWithStatus(r2, 0, 0) + + f.kubeobjects = append(f.kubeobjects, rs1, rs2) + f.replicaSetLister = append(f.replicaSetLister, rs1, rs2) + f.rolloutLister = append(f.rolloutLister, r2) + f.analysisTemplateLister = append(f.analysisTemplateLister, at) + f.analysisRunLister = append(f.analysisRunLister, ar) + f.objects = append(f.objects, r2, at, ar) + + _ = f.expectPatchAnalysisRunAction(ar) + patchIndex := f.expectPatchRolloutAction(r2) + _ = f.expectUpdateReplicaSetAction(rs1) + f.run(getKey(r2, t)) + + patch := f.getPatchedRollout(patchIndex) + + assert.Contains(t, patch, `"currentBackgroundAnalysisRunStatus":null`) +} From be8487f0bf4cd335b61f5236ed162bd49c76dbf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 08:32:55 -0500 Subject: [PATCH 08/13] chore(deps): bump docker/setup-buildx-action from 3.1.0 to 3.2.0 (#3449) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/0d103c3126aa41d772a8362f6aa67afac040f80c...2b51285047da1547ffb1b2203d8be4c0af6b1f20) --- updated-dependencies: - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/image-reuse.yaml | 2 +- .github/workflows/release.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index 197c0aa346..0939529053 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -79,7 +79,7 @@ jobs: cosign-release: 'v2.2.0' - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - - uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0 + - uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 - name: Setup tags for container image as a CSV type run: | diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 58ad372eda..d76724b1d7 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -99,7 +99,7 @@ jobs: uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0 + uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3.2.0 - name: Generate release artifacts run: | From eede5df165cd33d4bf196db5af902911f0a4d05b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 08:33:56 -0500 Subject: [PATCH 09/13] chore(deps): bump github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 from 1.30.1 to 1.30.3 (#3447) chore(deps): bump github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 Bumps [github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2](https://github.com/aws/aws-sdk-go-v2) from 1.30.1 to 1.30.3. - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/service/s3/v1.30.1...service/s3/v1.30.3) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index e719a2fdc9..836c7c447f 100644 --- a/go.mod +++ b/go.mod @@ -6,10 +6,10 @@ 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.25.2 + github.com/aws/aws-sdk-go-v2 v1.25.3 github.com/aws/aws-sdk-go-v2/config v1.27.5 github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.36.1 - github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.1 + github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.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 @@ -79,8 +79,8 @@ require ( github.com/aws/aws-sdk-go v1.44.116 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.5 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3 // 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.1 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.3 // indirect diff --git a/go.sum b/go.sum index 59643ebf01..94a8e016bc 100644 --- a/go.sum +++ b/go.sum @@ -92,24 +92,24 @@ 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.25.2 h1:/uiG1avJRgLGiQM9X3qJM8+Qa6KRGK5rRPuXE0HUM+w= -github.com/aws/aws-sdk-go-v2 v1.25.2/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= +github.com/aws/aws-sdk-go-v2 v1.25.3 h1:xYiLpZTQs1mzvz5PaI6uR0Wh57ippuEthxS4iK5v0n0= +github.com/aws/aws-sdk-go-v2 v1.25.3/go.mod h1:35hUlJVYd+M++iLI3ALmVwMOyRYMmRqUXpTtRGW+K9I= github.com/aws/aws-sdk-go-v2/config v1.27.5 h1:brBPsyRFQn97M1ZhQ9tLXkO7Zytiar0NS06FGmEJBdg= github.com/aws/aws-sdk-go-v2/config v1.27.5/go.mod h1:I53uvsfddRRTG5YcC4n5Z3aOD1BU8hYCoIG7iEJG4wM= github.com/aws/aws-sdk-go-v2/credentials v1.17.5 h1:yn3zSvIKC2NZIs40cY3kckcy9Zma96PrRR07N54PCvY= github.com/aws/aws-sdk-go-v2/credentials v1.17.5/go.mod h1:8JcKPAGZVnDWuR5lusAwmrSDtZnDIAnpQWaDC9RFt2g= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 h1:AK0J8iYBFeUk2Ax7O8YpLtFsfhdOByh2QIkHmigpRYk= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2/go.mod h1:iRlGzMix0SExQEviAyptRWRGdYNo3+ufW/lCzvKVTUc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 h1:bNo4LagzUKbjdxE0tIcR9pMzLR2U/Tgie1Hq1HQ3iH8= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2/go.mod h1:wRQv0nN6v9wDXuWThpovGQjqF1HFdcgWjporw14lS8k= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 h1:EtOU5jsPdIQNP+6Q2C5e3d65NKT1PeCiQk+9OdzO12Q= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2/go.mod h1:tyF5sKccmDz0Bv4NrstEr+/9YkSPJHrcO7UsUKf7pWM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3 h1:ifbIbHZyGl1alsAhPIYsHOg5MuApgqOvVeI8wIugXfs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.3/go.mod h1:oQZXg3c6SNeY6OZrDY+xHcF4VGIEoNotX2B4PrDeoJI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3 h1:Qvodo9gHG9F3E8SfYOspPeBt0bjSbsevK8WhRAUHcoY= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.3/go.mod h1:vCKrdLXtybdf/uQd/YfVR2r5pcbNuEYKzMQpcxmeSJw= 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.36.1 h1:mQySuI87thHtcbZvEDjwUROGWikU6fqgpHklCBXpJU4= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.36.1/go.mod h1:Z1ThUUTuCO9PArtiQsTmBGBv+38NGj+795Zl0n1jgiM= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.1 h1:eDD7nyDlMxlkGhWu0n92LYkuSQIIEwN5CffwiMDohh0= -github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.1/go.mod h1:DGUI2cbxu24m0rNOm7DDmrCtTzR0U0FqE3XpBkR8+r8= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.3 h1:RdYkpKdapqc29UYKw7mGrDLpLRPJPERFO/ugLEMIhr8= +github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.3/go.mod h1:e0zaDIcMOQ48klOQQRw6xJJyi3F2zwmOUer8gHEFSbo= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.3 h1:x0N5ftQzgcfRpCpTiyZC40pvNUJYhzf4UgCsAyO6/P8= From 8191ad86e724c638c860eab44ffae31cff78e67d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 08:34:15 -0500 Subject: [PATCH 10/13] chore(deps): bump docker/login-action from 3.0.0 to 3.1.0 (#3443) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.0.0 to 3.1.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/343f7c4344506bcbf9b4de18042ae17996df046d...e92390c5fb421da1463c202d546fed0ec5c39f20) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/image-reuse.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index 0939529053..b937a163e9 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@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.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@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.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@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 with: username: ${{ secrets.docker_username }} password: ${{ secrets.docker_password }} From 5018705fde564c0718f094a29ff5a26b01e4e10d Mon Sep 17 00:00:00 2001 From: AS <11219262+ashutosh16@users.noreply.github.com> Date: Fri, 15 Mar 2024 06:40:06 -0700 Subject: [PATCH 11/13] feat: add Analysis run to rollout notifications (#3296) * add analysisRun to the rollout notification Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * add analysisRun to the rollout notification Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * add analysisRun to the rollout notification Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * add analysisRun to the rollout notification Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * small changes Signed-off-by: Zach Aller --------- Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: Zach Aller Co-authored-by: Zach Aller --- controller/controller.go | 2 +- controller/controller_test.go | 2 +- pkg/kubectl-argo-rollouts/cmd/cmd.go | 3 +- utils/annotations/annotations.go | 24 +++- utils/annotations/annotations_test.go | 12 ++ utils/record/record.go | 79 ++++++++++- utils/record/record_test.go | 184 ++++++++++++++++++++++++-- 7 files changed, 285 insertions(+), 21 deletions(-) diff --git a/controller/controller.go b/controller/controller.go index 9aaf8ee09f..e9509cd78e 100644 --- a/controller/controller.go +++ b/controller/controller.go @@ -304,7 +304,7 @@ func NewManager( ingressWorkqueue := workqueue.NewNamedRateLimitingQueue(queue.DefaultArgoRolloutsRateLimiter(), "Ingresses") refResolver := rollout.NewInformerBasedWorkloadRefResolver(namespace, dynamicclientset, discoveryClient, argoprojclientset, rolloutsInformer.Informer()) - apiFactory := notificationapi.NewFactory(record.NewAPIFactorySettings(), defaults.Namespace(), notificationSecretInformerFactory.Core().V1().Secrets().Informer(), notificationConfigMapInformerFactory.Core().V1().ConfigMaps().Informer()) + apiFactory := notificationapi.NewFactory(record.NewAPIFactorySettings(analysisRunInformer), defaults.Namespace(), notificationSecretInformerFactory.Core().V1().Secrets().Informer(), notificationConfigMapInformerFactory.Core().V1().ConfigMaps().Informer()) recorder := record.NewEventRecorder(kubeclientset, metrics.MetricRolloutEventsTotal, metrics.MetricNotificationFailedTotal, metrics.MetricNotificationSuccessTotal, metrics.MetricNotificationSend, apiFactory) notificationsController := notificationcontroller.NewControllerWithNamespaceSupport(dynamicclientset.Resource(v1alpha1.RolloutGVR), rolloutsInformer.Informer(), apiFactory, notificationcontroller.WithToUnstructured(func(obj metav1.Object) (*unstructured.Unstructured, error) { diff --git a/controller/controller_test.go b/controller/controller_test.go index f724ef0712..0f94131c96 100644 --- a/controller/controller_test.go +++ b/controller/controller_test.go @@ -205,7 +205,7 @@ func (f *fixture) newManager(t *testing.T) *Manager { Recorder: record.NewFakeEventRecorder(), }) - apiFactory := notificationapi.NewFactory(record.NewAPIFactorySettings(), "default", k8sI.Core().V1().Secrets().Informer(), k8sI.Core().V1().ConfigMaps().Informer()) + apiFactory := notificationapi.NewFactory(record.NewAPIFactorySettings(i.Argoproj().V1alpha1().AnalysisRuns()), "default", k8sI.Core().V1().Secrets().Informer(), k8sI.Core().V1().ConfigMaps().Informer()) // rolloutsInformer := rolloutinformers.NewRolloutInformer(f.client, "", time.Minute, cache.Indexers{}) cm.notificationsController = notificationcontroller.NewController(dynamicClient.Resource(v1alpha1.RolloutGVR), i.Argoproj().V1alpha1().Rollouts().Informer(), apiFactory, notificationcontroller.WithToUnstructured(func(obj metav1.Object) (*unstructured.Unstructured, error) { diff --git a/pkg/kubectl-argo-rollouts/cmd/cmd.go b/pkg/kubectl-argo-rollouts/cmd/cmd.go index 53adf27b5d..372f8c434d 100644 --- a/pkg/kubectl-argo-rollouts/cmd/cmd.go +++ b/pkg/kubectl-argo-rollouts/cmd/cmd.go @@ -56,6 +56,7 @@ func NewCmdArgoRollouts(o *options.ArgoRolloutsOptions) *cobra.Command { return o.UsageErr(c) }, } + o.AddKubectlFlags(cmd) cmd.AddCommand(create.NewCmdCreate(o)) cmd.AddCommand(get.NewCmdGet(o)) @@ -72,7 +73,7 @@ func NewCmdArgoRollouts(o *options.ArgoRolloutsOptions) *cobra.Command { cmd.AddCommand(undo.NewCmdUndo(o)) cmd.AddCommand(dashboard.NewCmdDashboard(o)) cmd.AddCommand(status.NewCmdStatus(o)) - cmd.AddCommand(notificationcmd.NewToolsCommand("notifications", "kubectl argo rollouts notifications", v1alpha1.RolloutGVR, record.NewAPIFactorySettings())) + cmd.AddCommand(notificationcmd.NewToolsCommand("notifications", "kubectl argo rollouts notifications", v1alpha1.RolloutGVR, record.NewAPIFactorySettings(nil))) cmd.AddCommand(completion.NewCmdCompletion(o)) return cmd diff --git a/utils/annotations/annotations.go b/utils/annotations/annotations.go index 80cec5ce2a..121c6c0803 100644 --- a/utils/annotations/annotations.go +++ b/utils/annotations/annotations.go @@ -8,6 +8,7 @@ import ( log "github.com/sirupsen/logrus" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" "github.com/argoproj/argo-rollouts/utils/defaults" @@ -52,17 +53,30 @@ func GetWorkloadGenerationAnnotation(ro *v1alpha1.Rollout) (int32, bool) { } // GetRevisionAnnotation returns revision of rollout -func GetRevisionAnnotation(ro *v1alpha1.Rollout) (int32, bool) { - if ro == nil { +func GetRevisionAnnotation(anyObj metav1.Object) (int32, bool) { + + if anyObj == nil { + return 0, false + } + var obj interface{} + switch anyObj.(type) { + case *v1alpha1.Rollout: + obj = anyObj.(*v1alpha1.Rollout) + case *v1alpha1.AnalysisRun: + obj = anyObj.(*v1alpha1.AnalysisRun) + default: + log.Warnf("object not supported type: %T", anyObj) return 0, false } - annotationValue, ok := ro.Annotations[RevisionAnnotation] + + annotationValue, ok := obj.(metav1.Object).GetAnnotations()[RevisionAnnotation] if !ok { - return int32(0), false + return 0, false } + intValue, err := strconv.ParseInt(annotationValue, 10, 32) if err != nil { - log.Warnf("Cannot convert the value %q with annotation key %q for the replica set %q", annotationValue, RevisionAnnotation, ro.Name) + log.Warnf("Cannot convert the value %q with annotation key %q for the object %q", annotationValue, RevisionAnnotation, anyObj.GetName()) return int32(0), false } return int32(intValue), true diff --git a/utils/annotations/annotations_test.go b/utils/annotations/annotations_test.go index 3ad136fd7e..239ab83fd3 100644 --- a/utils/annotations/annotations_test.go +++ b/utils/annotations/annotations_test.go @@ -483,4 +483,16 @@ func TestGetRevisionAnnotation(t *testing.T) { }) assert.False(t, found) assert.Equal(t, int32(0), rev) + + revAR, found := GetRevisionAnnotation(&v1alpha1.AnalysisRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: metav1.NamespaceDefault, + Annotations: map[string]string{ + RevisionAnnotation: "1", + }, + }, + }) + assert.True(t, found) + assert.Equal(t, int32(1), revAR) } diff --git a/utils/record/record.go b/utils/record/record.go index 9e50f3ba65..801db089b6 100644 --- a/utils/record/record.go +++ b/utils/record/record.go @@ -7,11 +7,12 @@ import ( "encoding/json" "fmt" "regexp" + "sort" "strings" "time" + argoinformers "github.com/argoproj/argo-rollouts/pkg/client/informers/externalversions/rollouts/v1alpha1" timeutil "github.com/argoproj/argo-rollouts/utils/time" - "github.com/argoproj/notifications-engine/pkg/api" "github.com/argoproj/notifications-engine/pkg/services" "github.com/argoproj/notifications-engine/pkg/subscriptions" @@ -20,6 +21,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" k8sinformers "k8s.io/client-go/informers" @@ -32,6 +34,7 @@ import ( "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" rolloutscheme "github.com/argoproj/argo-rollouts/pkg/client/clientset/versioned/scheme" + "github.com/argoproj/argo-rollouts/utils/annotations" logutil "github.com/argoproj/argo-rollouts/utils/log" ) @@ -235,13 +238,83 @@ func (e *EventRecorderAdapter) K8sRecorder() record.EventRecorder { return e.Recorder } -func NewAPIFactorySettings() api.Settings { +func getAnalysisRunsFilterWithLabels(ro v1alpha1.Rollout, arInformer argoinformers.AnalysisRunInformer) (any, error) { + + set := labels.Set(map[string]string{ + v1alpha1.DefaultRolloutUniqueLabelKey: ro.Status.CurrentPodHash, + }) + + revision, _ := annotations.GetRevisionAnnotation(&ro) + ars, err := arInformer.Lister().AnalysisRuns(ro.Namespace).List(labels.SelectorFromSet(set)) + if err != nil { + return nil, fmt.Errorf("error getting analysisruns from informer for namespace: %s error: %w", ro.Namespace, err) + } + if len(ars) == 0 { + return nil, nil + } + + filteredArs := make([]*v1alpha1.AnalysisRun, 0, len(ars)) + for _, ar := range ars { + arRevision, _ := annotations.GetRevisionAnnotation(ar) + if arRevision == revision { + filteredArs = append(filteredArs, ar) + } + } + + sort.Slice(filteredArs, func(i, j int) bool { + ts1 := filteredArs[i].ObjectMeta.CreationTimestamp.Time + ts2 := filteredArs[j].ObjectMeta.CreationTimestamp.Time + return ts1.After(ts2) + }) + + var arsObj any + arBytes, err := json.Marshal(filteredArs) + + if err != nil { + return nil, fmt.Errorf("Failed to marshal analysisRuns for rollout revision: %s, err: %w", string(revision), err) + } + + err = json.Unmarshal(arBytes, &arsObj) + if err != nil { + return nil, fmt.Errorf("Failed to unmarshal analysisRuns for rollout revision: %s, err: %w", string(revision), err) + } + + return arsObj, nil +} + +func NewAPIFactorySettings(arInformer argoinformers.AnalysisRunInformer) api.Settings { return api.Settings{ SecretName: NotificationSecret, ConfigMapName: NotificationConfigMap, InitGetVars: func(cfg *api.Config, configMap *corev1.ConfigMap, secret *corev1.Secret) (api.GetVars, error) { return func(obj map[string]any, dest services.Destination) map[string]any { - return map[string]any{"rollout": obj, "time": timeExprs} + + var vars = map[string]any{"rollout": obj, "time": timeExprs} + + if arInformer == nil { + log.Infof("Notification is not set for analysisRun Informer: %s", dest) + return vars + } + + var ro v1alpha1.Rollout + err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj, &ro) + + if err != nil { + log.Errorf("unable to send notification: bad rollout object: %v", err) + return vars + } + + arsObj, err := getAnalysisRunsFilterWithLabels(ro, arInformer) + + if err != nil { + log.Errorf("Error calling getAnalysisRunsFilterWithLabels for namespace: %s", + ro.Namespace) + return vars + + } + + vars = map[string]any{"rollout": obj, "analysisRuns": arsObj, "time": timeExprs} + return vars }, nil }, } diff --git a/utils/record/record_test.go b/utils/record/record_test.go index 97f4452441..2cc7afd12c 100644 --- a/utils/record/record_test.go +++ b/utils/record/record_test.go @@ -2,6 +2,7 @@ package record import ( "bytes" + "encoding/json" "errors" "fmt" "strings" @@ -9,7 +10,11 @@ import ( "time" "github.com/argoproj/argo-rollouts/pkg/apis/rollouts/v1alpha1" + argofake "github.com/argoproj/argo-rollouts/pkg/client/clientset/versioned/fake" + argoinformersfactory "github.com/argoproj/argo-rollouts/pkg/client/informers/externalversions" + argoinformers "github.com/argoproj/argo-rollouts/pkg/client/informers/externalversions/rollouts/v1alpha1" "github.com/argoproj/argo-rollouts/utils/defaults" + timeutil "github.com/argoproj/argo-rollouts/utils/time" "github.com/argoproj/notifications-engine/pkg/api" notificationapi "github.com/argoproj/notifications-engine/pkg/api" "github.com/argoproj/notifications-engine/pkg/mocks" @@ -21,13 +26,19 @@ import ( dto "github.com/prometheus/client_model/go" log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes/fake" ) +var ( + noResyncPeriodFunc = func() time.Duration { return 0 } +) + func TestRecordLog(t *testing.T) { prevOutput := log.StandardLogger().Out defer func() { @@ -178,13 +189,18 @@ func TestSendNotificationsWhenConditionTime(t *testing.T) { k8sClient := fake.NewSimpleClientset() sharedInformers := informers.NewSharedInformerFactory(k8sClient, 0) + + f := argofake.NewSimpleClientset() + rolloutsI := argoinformersfactory.NewSharedInformerFactory(f, noResyncPeriodFunc()) + arInformer := rolloutsI.Argoproj().V1alpha1().AnalysisRuns() + cmInformer := sharedInformers.Core().V1().ConfigMaps().Informer() secretInformer := sharedInformers.Core().V1().Secrets().Informer() secretInformer.GetIndexer().Add(secret) cmInformer.GetIndexer().Add(cm) - apiFactory := notificationapi.NewFactory(NewAPIFactorySettings(), defaults.Namespace(), secretInformer, cmInformer) + apiFactory := notificationapi.NewFactory(NewAPIFactorySettings(arInformer), defaults.Namespace(), secretInformer, cmInformer) api, err := apiFactory.GetAPI() assert.NoError(t, err) @@ -224,8 +240,11 @@ func TestSendNotificationsWhenConditionTime(t *testing.T) { secretInformer.GetIndexer().Add(secret) cmInformer.GetIndexer().Add(cm) + f := argofake.NewSimpleClientset() + rolloutsI := argoinformersfactory.NewSharedInformerFactory(f, noResyncPeriodFunc()) + arInformer := rolloutsI.Argoproj().V1alpha1().AnalysisRuns() - apiFactory := notificationapi.NewFactory(NewAPIFactorySettings(), defaults.Namespace(), secretInformer, cmInformer) + apiFactory := notificationapi.NewFactory(NewAPIFactorySettings(arInformer), defaults.Namespace(), secretInformer, cmInformer) api, err := apiFactory.GetAPI() assert.NoError(t, err) @@ -422,17 +441,162 @@ func TestSendNotificationsNoTrigger(t *testing.T) { assert.Len(t, err, 1) } +func createAnalysisRunInformer(ars []*v1alpha1.AnalysisRun) argoinformers.AnalysisRunInformer { + f := argofake.NewSimpleClientset() + rolloutsI := argoinformersfactory.NewSharedInformerFactory(f, noResyncPeriodFunc()) + arInformer := rolloutsI.Argoproj().V1alpha1().AnalysisRuns() + for _, ar := range ars { + _ = arInformer.Informer().GetStore().Add(ar) + } + return arInformer +} + func TestNewAPIFactorySettings(t *testing.T) { - settings := NewAPIFactorySettings() - assert.Equal(t, NotificationConfigMap, settings.ConfigMapName) - assert.Equal(t, NotificationSecret, settings.SecretName) - getVars, err := settings.InitGetVars(nil, nil, nil) - assert.NoError(t, err) - rollout := map[string]any{"name": "hello"} - vars := getVars(rollout, services.Destination{}) + ars := []*v1alpha1.AnalysisRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "analysis-run-1", + CreationTimestamp: metav1.NewTime(timeutil.Now().Add(-1 * time.Hour)), + Namespace: "default", + Labels: map[string]string{"rollouts-pod-template-hash": "85659df978"}, + Annotations: map[string]string{"rollout.argoproj.io/revision": "1"}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "analysis-run-2", + CreationTimestamp: metav1.NewTime(timeutil.Now().Add(-2 * time.Hour)), + Namespace: "default", + Labels: map[string]string{"rollouts-pod-template-hash": "85659df978"}, + Annotations: map[string]string{"rollout.argoproj.io/revision": "1"}, + }, + }, + } + ro := v1alpha1.Rollout{ + ObjectMeta: metav1.ObjectMeta{ + Name: "rollout", + Namespace: "default", + Annotations: map[string]string{"rollout.argoproj.io/revision": "1"}, + }, + Status: v1alpha1.RolloutStatus{ + CurrentPodHash: "85659df978", + }, + } + + type expectedFunc func(obj map[string]interface{}, ar any) map[string]interface{} + type arInformerFunc func([]*v1alpha1.AnalysisRun) argoinformers.AnalysisRunInformer + + testcase := []struct { + name string + arInformer arInformerFunc + rollout v1alpha1.Rollout + ars []*v1alpha1.AnalysisRun + expected expectedFunc + }{ + { + name: "Send notification with rollout and analysisRun", + arInformer: func(ars []*v1alpha1.AnalysisRun) argoinformers.AnalysisRunInformer { + return createAnalysisRunInformer(ars) + }, + rollout: ro, + ars: ars, + expected: func(obj map[string]interface{}, ar any) map[string]interface{} { + return map[string]interface{}{ + "rollout": obj, + "analysisRuns": ar, + "time": timeExprs, + } + }, + }, + { + name: "Send notification rollout when revision and label doesn't match", + arInformer: func(ars []*v1alpha1.AnalysisRun) argoinformers.AnalysisRunInformer { + return createAnalysisRunInformer(ars) + }, + rollout: ro, + ars: []*v1alpha1.AnalysisRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "analysis-run-3", + CreationTimestamp: metav1.NewTime(timeutil.Now().Add(-2 * time.Hour)), + Namespace: "default", + Labels: map[string]string{"rollouts-pod-template-hash": "1234"}, + Annotations: map[string]string{"rollout.argoproj.io/revision": "2"}, + }, + }, + }, + expected: func(obj map[string]interface{}, ar any) map[string]interface{} { + return map[string]interface{}{ + "rollout": obj, + "analysisRuns": nil, + "time": timeExprs, + } + }, + }, + { + name: "arInformer is nil", + arInformer: func(ars []*v1alpha1.AnalysisRun) argoinformers.AnalysisRunInformer { + return nil + }, + rollout: ro, + ars: nil, + expected: func(obj map[string]interface{}, ar any) map[string]interface{} { + return map[string]interface{}{ + "rollout": obj, + "time": timeExprs, + } + }, + }, + { + name: "analysisRuns nil for no matching namespace", + arInformer: func(ars []*v1alpha1.AnalysisRun) argoinformers.AnalysisRunInformer { + return createAnalysisRunInformer(ars) + }, + rollout: ro, + ars: []*v1alpha1.AnalysisRun{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "analysis-run-1", + CreationTimestamp: metav1.NewTime(timeutil.Now().Add(-2 * time.Hour)), + Namespace: "default-1", + Labels: map[string]string{"rollouts-pod-template-hash": "1234"}, + Annotations: map[string]string{"rollout.argoproj.io/revision": "2"}, + }, + }, + }, + expected: func(obj map[string]interface{}, ar any) map[string]interface{} { + return map[string]interface{}{ + "rollout": obj, + "analysisRuns": nil, + "time": timeExprs, + } + }, + }, + } - assert.Equal(t, map[string]any{"rollout": rollout, "time": timeExprs}, vars) + for _, test := range testcase { + t.Run(test.name, func(t *testing.T) { + + settings := NewAPIFactorySettings(test.arInformer(test.ars)) + getVars, err := settings.InitGetVars(nil, nil, nil) + require.NoError(t, err) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + obj, _ := runtime.DefaultUnstructuredConverter.ToUnstructured(&test.rollout) + + arBytes, err := json.Marshal(test.ars) + var arsObj any + _ = json.Unmarshal(arBytes, &arsObj) + vars := getVars(obj, services.Destination{}) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + assert.Equal(t, test.expected(obj, arsObj), vars) + }) + } } func TestWorkloadRefObjectMap(t *testing.T) { From 383f719e6d411d5163a7e832f02f39146789adf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 13:41:50 +0000 Subject: [PATCH 12/13] chore(deps): bump docker/build-push-action from 5.2.0 to 5.3.0 (#3448) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/af5a7ed5ba88268d5278f7203fb52cd833f66d6e...2cdde995de11925a030ce8070c3d77a52ffcf1c0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/image-reuse.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index b937a163e9..970080e845 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -130,7 +130,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@af5a7ed5ba88268d5278f7203fb52cd833f66d6e #v5.2.0 + uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 #v5.3.0 with: context: . platforms: ${{ inputs.platforms }} From 0f52c932e46b12f63546e6ebe8a91281fb6c46a6 Mon Sep 17 00:00:00 2001 From: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> Date: Fri, 15 Mar 2024 20:35:02 +0530 Subject: [PATCH 13/13] fix: job metrics owner ref when using custom job kubeconfig/ns (#3425) * fix: job metrcis owner ref when using custom job kubeconfig/ns Signed-off-by: Soumya Ghosh Dastidar * fix: job metrcis owner ref when using custom job kubeconfig/ns Signed-off-by: Soumya Ghosh Dastidar * revert: go mod change Signed-off-by: Soumya Ghosh Dastidar --------- Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: Zach Aller Co-authored-by: Zach Aller --- analysis/controller.go | 29 ++++++++++++++++--- cmd/rollouts-controller/main.go | 2 +- go.mod | 2 +- metricproviders/job/job.go | 45 ++++++++++++++++++++---------- metricproviders/job/job_test.go | 4 +-- metricproviders/metricproviders.go | 13 +++++---- utils/controller/controller.go | 23 ++++++++++----- 7 files changed, 83 insertions(+), 35 deletions(-) diff --git a/analysis/controller.go b/analysis/controller.go index e8dcb8601a..1afa6ab556 100644 --- a/analysis/controller.go +++ b/analysis/controller.go @@ -7,6 +7,9 @@ import ( "github.com/argoproj/argo-rollouts/metric" jobProvider "github.com/argoproj/argo-rollouts/metricproviders/job" + "github.com/aws/smithy-go/ptr" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" unstructuredutil "github.com/argoproj/argo-rollouts/utils/unstructured" @@ -32,6 +35,10 @@ import ( timeutil "github.com/argoproj/argo-rollouts/utils/time" ) +var ( + analysisRunGVK = v1alpha1.SchemeGroupVersion.WithKind("AnalysisRun") +) + // Controller is the controller implementation for Analysis resources type Controller struct { // kubeclientset is a standard kubernetes clientset @@ -187,10 +194,24 @@ func (c *Controller) syncHandler(ctx context.Context, key string) error { return c.persistAnalysisRunStatus(run, newRun.Status) } -func (c *Controller) jobParentNamespace(obj any) string { +func (c *Controller) jobParentReference(obj any) (*v1.OwnerReference, string) { job, ok := obj.(*batchv1.Job) if !ok { - return "" + return nil, "" + } + // if it has owner reference, return it as is + ownerRef := v1.GetControllerOf(job) + // else if it's missing owner reference check if analysis run uid is set and + // if it is there use labels/annotations to create owner reference + if ownerRef == nil && job.Labels[jobProvider.AnalysisRunUIDLabelKey] != "" { + ownerRef = &v1.OwnerReference{ + APIVersion: analysisRunGVK.GroupVersion().String(), + Kind: analysisRunGVK.Kind, + Name: job.Annotations[jobProvider.AnalysisRunNameAnnotationKey], + UID: types.UID(job.Labels[jobProvider.AnalysisRunUIDLabelKey]), + BlockOwnerDeletion: ptr.Bool(true), + Controller: ptr.Bool(true), + } } ns := job.GetNamespace() if job.Annotations != nil { @@ -198,7 +219,7 @@ func (c *Controller) jobParentNamespace(obj any) string { ns = job.Annotations[jobProvider.AnalysisRunNamespaceAnnotationKey] } } - return ns + return ownerRef, ns } func (c *Controller) enqueueJobIfCompleted(obj any) { @@ -209,7 +230,7 @@ func (c *Controller) enqueueJobIfCompleted(obj any) { for _, condition := range job.Status.Conditions { switch condition.Type { case batchv1.JobFailed, batchv1.JobComplete: - controllerutil.EnqueueParentObject(job, register.AnalysisRunKind, c.enqueueAnalysis, c.jobParentNamespace) + controllerutil.EnqueueParentObject(job, register.AnalysisRunKind, c.enqueueAnalysis, c.jobParentReference) return } } diff --git a/cmd/rollouts-controller/main.go b/cmd/rollouts-controller/main.go index d198db3c31..4b058b09a7 100644 --- a/cmd/rollouts-controller/main.go +++ b/cmd/rollouts-controller/main.go @@ -142,7 +142,7 @@ func newCommand() *cobra.Command { instanceIDTweakListFunc := func(options *metav1.ListOptions) { options.LabelSelector = instanceIDSelector.String() } - jobKubeClient, err := metricproviders.GetAnalysisJobClientset(kubeClient) + jobKubeClient, _, err := metricproviders.GetAnalysisJobClientset(kubeClient) checkError(err) jobNs := metricproviders.GetAnalysisJobNamespace() if jobNs == "" { diff --git a/go.mod b/go.mod index 836c7c447f..b27a612a96 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/aws/aws-sdk-go-v2/config v1.27.5 github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.36.1 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.30.3 + github.com/aws/smithy-go v1.20.1 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 @@ -88,7 +89,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.28.2 // indirect - github.com/aws/smithy-go v1.20.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect diff --git a/metricproviders/job/job.go b/metricproviders/job/job.go index 8d76302149..5a85c5c71e 100644 --- a/metricproviders/job/job.go +++ b/metricproviders/job/job.go @@ -43,18 +43,20 @@ var ( ) type JobProvider struct { - kubeclientset kubernetes.Interface - jobLister batchlisters.JobLister - logCtx log.Entry - jobNamespace string + kubeclientset kubernetes.Interface + jobLister batchlisters.JobLister + logCtx log.Entry + jobNamespace string + customJobKubeconfig bool } -func NewJobProvider(logCtx log.Entry, kubeclientset kubernetes.Interface, jobLister batchlisters.JobLister, jobNS string) *JobProvider { +func NewJobProvider(logCtx log.Entry, kubeclientset kubernetes.Interface, jobLister batchlisters.JobLister, jobNS string, customJobKubeconfig bool) *JobProvider { return &JobProvider{ - kubeclientset: kubeclientset, - logCtx: logCtx, - jobLister: jobLister, - jobNamespace: jobNS, + kubeclientset: kubeclientset, + logCtx: logCtx, + jobLister: jobLister, + jobNamespace: jobNS, + customJobKubeconfig: customJobKubeconfig, } } @@ -85,7 +87,7 @@ func getJobIDSuffix(run *v1alpha1.AnalysisRun, metricName string) int { return int(res.Count + res.Error + 1) } -func newMetricJob(run *v1alpha1.AnalysisRun, metric v1alpha1.Metric, jobNS string) (*batchv1.Job, error) { +func newMetricJob(run *v1alpha1.AnalysisRun, metric v1alpha1.Metric, jobNS string, customJobKubeconfig bool) (*batchv1.Job, error) { ns := run.Namespace if jobNS != "" { ns = jobNS @@ -102,11 +104,17 @@ func newMetricJob(run *v1alpha1.AnalysisRun, metric v1alpha1.Metric, jobNS strin jobAnnotations[AnalysisRunNameAnnotationKey] = run.Name jobAnnotations[AnalysisRunNamespaceAnnotationKey] = run.Namespace jobAnnotations[AnalysisRunMetricAnnotationKey] = metric.Name + + ownerRef := []metav1.OwnerReference{*metav1.NewControllerRef(run, analysisRunGVK)} + + if ns != run.Namespace || customJobKubeconfig { + ownerRef = nil + } job := batchv1.Job{ ObjectMeta: metav1.ObjectMeta{ Name: newJobName(run, metric), Namespace: ns, - OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(run, analysisRunGVK)}, + OwnerReferences: ownerRef, Annotations: jobAnnotations, Labels: jobLabels, }, @@ -122,7 +130,7 @@ func (p *JobProvider) Run(run *v1alpha1.AnalysisRun, metric v1alpha1.Metric) v1a StartedAt: &now, Phase: v1alpha1.AnalysisPhaseRunning, } - job, err := newMetricJob(run, metric, p.jobNamespace) + job, err := newMetricJob(run, metric, p.jobNamespace, p.customJobKubeconfig) if err != nil { p.logCtx.Errorf("job initialization failed: %v", err) return metricutil.MarkMeasurementError(measurement, err) @@ -139,8 +147,17 @@ func (p *JobProvider) Run(run *v1alpha1.AnalysisRun, metric v1alpha1.Metric) v1a p.logCtx.Errorf("job create (verify) %s failed: %v", job.Name, createErr) return metricutil.MarkMeasurementError(measurement, createErr) } - controllerRef := metav1.GetControllerOf(existingJob) - if run.UID != controllerRef.UID { + ownerUID := "" + // if custom kubeconfig or different namespace is used owner ref is absent, + // use run uid label to get owner analysis run uid + if p.customJobKubeconfig || job.Namespace != run.Namespace { + ownerUID = job.Labels[AnalysisRunUIDLabelKey] + } else { + controllerRef := metav1.GetControllerOf(existingJob) + ownerUID = string(controllerRef.UID) + } + + if string(run.UID) != ownerUID { // NOTE: we don't bother to check for semantic equality. UID is good enough p.logCtx.Errorf("job create (uid check) %s failed: %v", job.Name, createErr) return metricutil.MarkMeasurementError(measurement, createErr) diff --git a/metricproviders/job/job_test.go b/metricproviders/job/job_test.go index c8ef2af3a0..80fdb28342 100644 --- a/metricproviders/job/job_test.go +++ b/metricproviders/job/job_test.go @@ -36,7 +36,7 @@ func newTestJobProvider(objects ...runtime.Object) *JobProvider { cancel() jobLister := k8sI.Batch().V1().Jobs().Lister() - return NewJobProvider(*logCtx, kubeclient, jobLister, "") + return NewJobProvider(*logCtx, kubeclient, jobLister, "", false) } func newRunWithJobMetric() *v1alpha1.AnalysisRun { @@ -193,7 +193,7 @@ func TestRunCreateCollision(t *testing.T) { p := newTestJobProvider() run := newRunWithJobMetric() - existingJob, err := newMetricJob(run, run.Spec.Metrics[0], p.jobNamespace) + existingJob, err := newMetricJob(run, run.Spec.Metrics[0], p.jobNamespace, p.customJobKubeconfig) assert.NoError(t, err) fakeClient := p.kubeclientset.(*k8sfake.Clientset) fakeClient.Tracker().Add(existingJob) diff --git a/metricproviders/metricproviders.go b/metricproviders/metricproviders.go index db135b82ca..916fc85aa2 100644 --- a/metricproviders/metricproviders.go +++ b/metricproviders/metricproviders.go @@ -52,12 +52,12 @@ func (f *ProviderFactory) NewProvider(logCtx log.Entry, metric v1alpha1.Metric) } return prometheus.NewPrometheusProvider(api, logCtx, metric) case job.ProviderType: - kubeClient, err := GetAnalysisJobClientset(f.KubeClient) + kubeClient, customKubeconfig, err := GetAnalysisJobClientset(f.KubeClient) if err != nil { return nil, err } - return job.NewJobProvider(logCtx, kubeClient, f.JobLister, GetAnalysisJobNamespace()), nil + return job.NewJobProvider(logCtx, kubeClient, f.JobLister, GetAnalysisJobNamespace(), customKubeconfig), nil case kayenta.ProviderType: c := kayenta.NewHttpClient() return kayenta.NewKayentaProvider(logCtx, c), nil @@ -154,7 +154,7 @@ func Type(metric v1alpha1.Metric) string { // if the AnalysisJobKubeconfigEnv is set to InclusterKubeconfig, it will return the incluster client // else if it's set to a kubeconfig file it will return the clientset corresponding to the kubeconfig file. // If empty it returns the provided defaultClientset -func GetAnalysisJobClientset(defaultClientset kubernetes.Interface) (kubernetes.Interface, error) { +func GetAnalysisJobClientset(defaultClientset kubernetes.Interface) (kubernetes.Interface, bool, error) { customJobKubeconfig := os.Getenv(AnalysisJobKubeconfigEnv) if customJobKubeconfig != "" { var ( @@ -167,11 +167,12 @@ func GetAnalysisJobClientset(defaultClientset kubernetes.Interface) (kubernetes. cfg, err = clientcmd.BuildConfigFromFlags("", customJobKubeconfig) } if err != nil { - return nil, err + return nil, true, err } - return kubernetes.NewForConfig(cfg) + clientSet, err := kubernetes.NewForConfig(cfg) + return clientSet, true, err } - return defaultClientset, nil + return defaultClientset, false, nil } func GetAnalysisJobNamespace() string { diff --git a/utils/controller/controller.go b/utils/controller/controller.go index 9c4b05cf26..2530e1d5fa 100644 --- a/utils/controller/controller.go +++ b/utils/controller/controller.go @@ -222,7 +222,7 @@ func EnqueueRateLimited(obj any, q workqueue.RateLimitingInterface) { // It then enqueues that ownerType resource to be processed. If the object does not // have an appropriate OwnerReference, it will simply be skipped. // This function assumes parent object is in the same namespace as the child -func EnqueueParentObject(obj any, ownerType string, enqueue func(obj any), parentNamespaceGetter ...func(any) string) { +func EnqueueParentObject(obj any, ownerType string, enqueue func(obj any), parentGetter ...func(any) (*metav1.OwnerReference, string)) { var object metav1.Object var ok bool if object, ok = obj.(metav1.Object); !ok { @@ -239,16 +239,25 @@ func EnqueueParentObject(obj any, ownerType string, enqueue func(obj any), paren log.Infof("Recovered deleted object '%s' from tombstone", object.GetName()) } - if ownerRef := metav1.GetControllerOf(object); ownerRef != nil { + var ( + ownerRef *metav1.OwnerReference + namespace string + ) + + if len(parentGetter) > 0 { + ownerRef, namespace = parentGetter[0](obj) + } else { + ownerRef = metav1.GetControllerOf(object) + } + + if ownerRef != nil { // If this object is not owned by the ownerType, we should not do anything more with it. if ownerRef.Kind != ownerType { return } - namespace := object.GetNamespace() - if len(parentNamespaceGetter) > 0 { - // If the parentNamespaceGetter is provided, use it to get the parent namespace - // only uses the first parentNamespaceGetter func - namespace = parentNamespaceGetter[0](obj) + // if namespace not set by parentGetter use object namespace + if namespace == "" { + namespace = object.GetNamespace() } parent := cache.ExplicitKey(namespace + "/" + ownerRef.Name) log.Infof("Enqueueing parent of %s/%s: %s %s", namespace, object.GetName(), ownerRef.Kind, parent)