From f8f9ae9accd413b417be1d188418f2b3b7c25e63 Mon Sep 17 00:00:00 2001 From: Joseph Lombrozo Date: Thu, 12 Oct 2023 13:31:22 -0400 Subject: [PATCH 001/269] fix: update docs for ApplicationService.Get to reflect reality (#15927) Signed-off-by: Joe Lombrozo --- assets/swagger.json | 6 +++--- pkg/apiclient/application/application.pb.go | 2 +- server/application/application.proto | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/swagger.json b/assets/swagger.json index c97e0a3c78239..ae4688966dd0c 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -234,7 +234,7 @@ }, { "type": "string", - "description": "forces application reconciliation if set to true.", + "description": "forces application reconciliation if set to 'hard'.", "name": "refresh", "in": "query" }, @@ -573,7 +573,7 @@ }, { "type": "string", - "description": "forces application reconciliation if set to true.", + "description": "forces application reconciliation if set to 'hard'.", "name": "refresh", "in": "query" }, @@ -3816,7 +3816,7 @@ }, { "type": "string", - "description": "forces application reconciliation if set to true.", + "description": "forces application reconciliation if set to 'hard'.", "name": "refresh", "in": "query" }, diff --git a/pkg/apiclient/application/application.pb.go b/pkg/apiclient/application/application.pb.go index 8fd016ee36f68..70c63c36bc333 100644 --- a/pkg/apiclient/application/application.pb.go +++ b/pkg/apiclient/application/application.pb.go @@ -44,7 +44,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type ApplicationQuery struct { // the application's name Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - // forces application reconciliation if set to true + // forces application reconciliation if set to 'hard' Refresh *string `protobuf:"bytes,2,opt,name=refresh" json:"refresh,omitempty"` // the project names to restrict returned list applications Projects []string `protobuf:"bytes,3,rep,name=projects" json:"projects,omitempty"` diff --git a/server/application/application.proto b/server/application/application.proto index 53f161795902d..4736219cb4594 100644 --- a/server/application/application.proto +++ b/server/application/application.proto @@ -21,7 +21,7 @@ import "github.com/argoproj/argo-cd/v2/reposerver/repository/repository.proto"; message ApplicationQuery { // the application's name optional string name = 1; - // forces application reconciliation if set to true + // forces application reconciliation if set to 'hard' optional string refresh = 2; // the project names to restrict returned list applications repeated string projects = 3; From af44ffb0210f9b8b36844abbf85331221f7dafd5 Mon Sep 17 00:00:00 2001 From: smriti0710 Date: Fri, 13 Oct 2023 22:37:12 +0530 Subject: [PATCH 002/269] fix(ui): pod count tooltip (#15928) Signed-off-by: Smriti Prakash Co-authored-by: Smriti Prakash --- .../components/application-details/application-details.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 3a556dd0b2524..3f12660fb0191 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -459,7 +459,8 @@ export class ApplicationDetails extends React.Component + duration={showToolTip?.duration} + zIndex={1}> Date: Fri, 13 Oct 2023 13:09:40 -0400 Subject: [PATCH 003/269] chore(deps): bump github.com/google/go-cmp from 0.5.9 to 0.6.0 (#15919) Bumps [github.com/google/go-cmp](https://github.com/google/go-cmp) from 0.5.9 to 0.6.0. - [Release notes](https://github.com/google/go-cmp/releases) - [Commits](https://github.com/google/go-cmp/compare/v0.5.9...v0.6.0) --- updated-dependencies: - dependency-name: github.com/google/go-cmp 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 | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 3bc74be5d54de..c1d4232baeec5 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/protobuf v1.5.3 - github.com/google/go-cmp v0.5.9 + github.com/google/go-cmp v0.6.0 github.com/google/go-github/v35 v35.3.0 github.com/google/go-jsonnet v0.20.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 diff --git a/go.sum b/go.sum index 6945483f1f5a2..d243c179785b4 100644 --- a/go.sum +++ b/go.sum @@ -1196,8 +1196,9 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v35 v35.3.0 h1:fU+WBzuukn0VssbayTT+Zo3/ESKX9JYWjbZTLOTEyho= github.com/google/go-github/v35 v35.3.0/go.mod h1:yWB7uCcVWaUbUP74Aq3whuMySRMatyRmq5U9FTNlbio= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= From b6e8c23fad80a4f19043975ce44d3ef1c28a7280 Mon Sep 17 00:00:00 2001 From: Joseph Perez Date: Fri, 13 Oct 2023 13:13:40 -0400 Subject: [PATCH 004/269] feat(cli): Add examples to projectwindows.go (#15860) * feat(cli): Add some examples to projectwindows.go Signed-off-by: Joseph Perez * switch order of short and example Signed-off-by: Joseph Perez * remove accidental add Signed-off-by: Joseph Perez --------- Signed-off-by: Joseph Perez --- cmd/argocd/commands/projectwindows.go | 23 ++++++++++++++++++- .../commands/argocd_proj_windows_add.md | 22 ++++++++++++++++++ .../commands/argocd_proj_windows_update.md | 9 ++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go index 0bc867cc6cf68..76679b5dc3eae 100644 --- a/cmd/argocd/commands/projectwindows.go +++ b/cmd/argocd/commands/projectwindows.go @@ -125,6 +125,23 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) * var command = &cobra.Command{ Use: "add PROJECT", Short: "Add a sync window to a project", + Example: `# Add a 1 hour allow sync window +argocd proj windows add PROJECT \ + --kind allow \ + --schedule "0 22 * * *" \ + --duration 1h \ + --applications "*" + +# Add a deny sync window with the ability to manually sync. +argocd proj windows add PROJECT \ + --kind deny \ + --schedule "30 10 * * *" \ + --duration 30m \ + --applications "prod-\\*,website" \ + --namespaces "default,\\*-prod" \ + --clusters "prod,staging" \ + --manual-sync + `, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -158,7 +175,7 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) * return command } -// NewProjectWindowsAddWindowCommand returns a new instance of an `argocd proj windows delete` command +// NewProjectWindowsDeleteCommand returns a new instance of an `argocd proj windows delete` command func NewProjectWindowsDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "delete PROJECT ID", @@ -205,6 +222,10 @@ func NewProjectWindowsUpdateCommand(clientOpts *argocdclient.ClientOptions) *cob Use: "update PROJECT ID", Short: "Update a project sync window", Long: "Update a project sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: `# Change a sync window's schedule +argocd proj windows update PROJECT ID \ + --schedule "0 20 * * *" +`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index 72d916b114910..7f9eb50af8f5b 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -8,6 +8,28 @@ Add a sync window to a project argocd proj windows add PROJECT [flags] ``` +### Examples + +``` +# Add a 1 hour allow sync window +argocd proj windows add PROJECT \ + --kind allow \ + --schedule "0 22 * * *" \ + --duration 1h \ + --applications "*" + +# Add a deny sync window with the ability to manually sync. +argocd proj windows add PROJECT \ + --kind deny \ + --schedule "30 10 * * *" \ + --duration 30m \ + --applications "prod-\\*,website" \ + --namespaces "default,\\*-prod" \ + --clusters "prod,staging" \ + --manual-sync + +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_update.md b/docs/user-guide/commands/argocd_proj_windows_update.md index 2d9f4f2dbb8a7..e01e3787d51a2 100644 --- a/docs/user-guide/commands/argocd_proj_windows_update.md +++ b/docs/user-guide/commands/argocd_proj_windows_update.md @@ -12,6 +12,15 @@ Update a project sync window. Requires ID which can be found by running "argocd argocd proj windows update PROJECT ID [flags] ``` +### Examples + +``` +# Change a sync window's schedule +argocd proj windows update PROJECT ID \ + --schedule "0 20 * * *" + +``` + ### Options ``` From 6dbd47e632c999aa6c18a8f36a2bbe16de3c71be Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 13 Oct 2023 14:36:44 -0400 Subject: [PATCH 005/269] [Bot] docs: Update Snyk reports (#15867) Signed-off-by: CI Co-authored-by: CI --- docs/snyk/index.md | 19 +- docs/snyk/master/argocd-iac-install.html | 86 +- .../master/argocd-iac-namespace-install.html | 68 +- docs/snyk/master/argocd-test.html | 12 +- .../master/ghcr.io_dexidp_dex_v2.37.0.html | 8 +- docs/snyk/master/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_latest.html | 13 +- docs/snyk/master/redis_7.0.11-alpine.html | 8 +- docs/snyk/v2.6.15/argocd-iac-install.html | 10 +- .../v2.6.15/argocd-iac-namespace-install.html | 10 +- docs/snyk/v2.6.15/argocd-test.html | 2 +- .../v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html | 8 +- docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.6.15.html | 455 +- docs/snyk/v2.6.15/redis_7.0.11-alpine.html | 8 +- docs/snyk/v2.7.14/argocd-iac-install.html | 10 +- .../v2.7.14/argocd-iac-namespace-install.html | 10 +- docs/snyk/v2.7.14/argocd-test.html | 2 +- .../v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html | 8 +- docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.7.14.html | 455 +- docs/snyk/v2.7.14/redis_7.0.11-alpine.html | 8 +- docs/snyk/v2.8.4/argocd-iac-install.html | 10 +- .../v2.8.4/argocd-iac-namespace-install.html | 10 +- docs/snyk/v2.8.4/argocd-test.html | 2 +- .../v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html | 8 +- docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.8.4.html | 455 +- docs/snyk/v2.8.4/redis_7.0.11-alpine.html | 8 +- docs/snyk/v2.9.0-rc2/argocd-iac-install.html | 2679 ++++++++++++ .../argocd-iac-namespace-install.html | 2679 ++++++++++++ docs/snyk/v2.9.0-rc2/argocd-test.html | 972 +++++ .../ghcr.io_dexidp_dex_v2.37.0.html | 2521 +++++++++++ .../v2.9.0-rc2/haproxy_2.6.14-alpine.html | 492 +++ .../quay.io_argoproj_argocd_v2.9.0-rc2.html | 3698 +++++++++++++++++ docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html | 1144 +++++ 36 files changed, 15718 insertions(+), 168 deletions(-) create mode 100644 docs/snyk/v2.9.0-rc2/argocd-iac-install.html create mode 100644 docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html create mode 100644 docs/snyk/v2.9.0-rc2/argocd-test.html create mode 100644 docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html create mode 100644 docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html create mode 100644 docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html create mode 100644 docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html diff --git a/docs/snyk/index.md b/docs/snyk/index.md index 0803b8ab69ef0..f4e0bb57e59b0 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -22,6 +22,19 @@ recent minor releases. | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | +### v2.9.0-rc2 + +| | Critical | High | Medium | Low | +|---:|:--------:|:----:|:------:|:---:| +| [go.mod](v2.9.0-rc2/argocd-test.html) | 0 | 0 | 5 | 0 | +| [ui/yarn.lock](v2.9.0-rc2/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.37.0](v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | +| [haproxy:2.6.14-alpine](v2.9.0-rc2/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | +| [argocd:v2.9.0-rc2](v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html) | 0 | 1 | 6 | 17 | +| [redis:7.0.11-alpine](v2.9.0-rc2/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | +| [install.yaml](v2.9.0-rc2/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.9.0-rc2/argocd-iac-namespace-install.html) | - | - | - | - | + ### v2.8.4 | | Critical | High | Medium | Low | @@ -30,7 +43,7 @@ recent minor releases. | [ui/yarn.lock](v2.8.4/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.8.4/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 0 | 3 | 17 | +| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 1 | 6 | 17 | | [redis:7.0.11-alpine](v2.8.4/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.8.4/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.8.4/argocd-iac-namespace-install.html) | - | - | - | - | @@ -43,7 +56,7 @@ recent minor releases. | [ui/yarn.lock](v2.7.14/argocd-test.html) | 0 | 1 | 0 | 0 | | [dex:v2.37.0](v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.7.14/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 0 | 3 | 17 | +| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 1 | 6 | 17 | | [redis:7.0.11-alpine](v2.7.14/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.7.14/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.7.14/argocd-iac-namespace-install.html) | - | - | - | - | @@ -56,7 +69,7 @@ recent minor releases. | [ui/yarn.lock](v2.6.15/argocd-test.html) | 0 | 1 | 0 | 0 | | [dex:v2.37.0](v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.6.15/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 0 | 3 | 17 | +| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 1 | 6 | 17 | | [redis:7.0.11-alpine](v2.6.15/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.6.15/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.6.15/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index 3fb0b8186141a..327eefb575940 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

Snyk test report

-

September 17th 2023, 12:18:15 am (UTC+00:00)

+

October 8th 2023, 12:18:32 am (UTC+00:00)

Scanned the following path: @@ -507,7 +507,7 @@

Role with dangerous permissions

  • - Line number: 18488 + Line number: 20316
  • @@ -553,7 +553,7 @@

    Role with dangerous permissions

  • - Line number: 18565 + Line number: 20393
  • @@ -599,7 +599,7 @@

    Role with dangerous permissions

  • - Line number: 18593 + Line number: 20421
  • @@ -645,7 +645,7 @@

    Role with dangerous permissions

  • - Line number: 18641 + Line number: 20469
  • @@ -691,7 +691,7 @@

    Role with dangerous permissions

  • - Line number: 18623 + Line number: 20451
  • @@ -737,7 +737,7 @@

    Role with dangerous permissions

  • - Line number: 18657 + Line number: 20485
  • @@ -789,7 +789,7 @@

    Container could be running with outdated image

  • - Line number: 19790 + Line number: 21630
  • @@ -847,7 +847,7 @@

    Container has no CPU limit

  • - Line number: 19141 + Line number: 20969
  • @@ -905,7 +905,7 @@

    Container has no CPU limit

  • - Line number: 19386 + Line number: 21220
  • @@ -963,7 +963,7 @@

    Container has no CPU limit

  • - Line number: 19352 + Line number: 21186
  • @@ -1021,7 +1021,7 @@

    Container has no CPU limit

  • - Line number: 19446 + Line number: 21280
  • @@ -1079,7 +1079,7 @@

    Container has no CPU limit

  • - Line number: 19533 + Line number: 21373
  • @@ -1137,7 +1137,7 @@

    Container has no CPU limit

  • - Line number: 19790 + Line number: 21630
  • @@ -1195,7 +1195,7 @@

    Container has no CPU limit

  • - Line number: 19590 + Line number: 21430
  • @@ -1253,7 +1253,7 @@

    Container has no CPU limit

  • - Line number: 19875 + Line number: 21715
  • @@ -1311,7 +1311,7 @@

    Container has no CPU limit

  • - Line number: 20191 + Line number: 22031
  • @@ -1363,7 +1363,7 @@

    Container is running with multiple open ports

  • - Line number: 19366 + Line number: 21200
  • @@ -1415,7 +1415,7 @@

    Container is running without liveness probe

  • - Line number: 19141 + Line number: 20969
  • @@ -1460,14 +1460,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 19352 + Line number: 21220
  • @@ -1512,14 +1512,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 19386 + Line number: 21186
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 19533 + Line number: 21373
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 19790 + Line number: 21630
  • @@ -1681,7 +1681,7 @@

    Container is running without memory limit

  • - Line number: 19141 + Line number: 20969
  • @@ -1739,7 +1739,7 @@

    Container is running without memory limit

  • - Line number: 19352 + Line number: 21186
  • @@ -1797,7 +1797,7 @@

    Container is running without memory limit

  • - Line number: 19386 + Line number: 21220
  • @@ -1855,7 +1855,7 @@

    Container is running without memory limit

  • - Line number: 19446 + Line number: 21280
  • @@ -1913,7 +1913,7 @@

    Container is running without memory limit

  • - Line number: 19533 + Line number: 21373
  • @@ -1971,7 +1971,7 @@

    Container is running without memory limit

  • - Line number: 19790 + Line number: 21630
  • @@ -2029,7 +2029,7 @@

    Container is running without memory limit

  • - Line number: 19590 + Line number: 21430
  • @@ -2087,7 +2087,7 @@

    Container is running without memory limit

  • - Line number: 19875 + Line number: 21715
  • @@ -2145,7 +2145,7 @@

    Container is running without memory limit

  • - Line number: 20191 + Line number: 22031
  • @@ -2201,7 +2201,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19276 + Line number: 21110
  • @@ -2257,7 +2257,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19394 + Line number: 21228
  • @@ -2313,7 +2313,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19369 + Line number: 21203
  • @@ -2369,7 +2369,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19467 + Line number: 21307
  • @@ -2425,7 +2425,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19543 + Line number: 21383
  • @@ -2481,7 +2481,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19797 + Line number: 21637
  • @@ -2537,7 +2537,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19763 + Line number: 21603
  • @@ -2593,7 +2593,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 20101 + Line number: 21941
  • @@ -2649,7 +2649,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 20339 + Line number: 22179
  • diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index 389ef692caaa1..632fa36c65e03 100644 --- a/docs/snyk/master/argocd-iac-namespace-install.html +++ b/docs/snyk/master/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:18:27 am (UTC+00:00)

    +

    October 8th 2023, 12:18:42 am (UTC+00:00)

    Scanned the following path: @@ -789,7 +789,7 @@

    Container could be running with outdated image

  • - Line number: 1274 + Line number: 1286
  • @@ -905,7 +905,7 @@

    Container has no CPU limit

  • - Line number: 870 + Line number: 876
  • @@ -963,7 +963,7 @@

    Container has no CPU limit

  • - Line number: 836 + Line number: 842
  • @@ -1021,7 +1021,7 @@

    Container has no CPU limit

  • - Line number: 930 + Line number: 936
  • @@ -1079,7 +1079,7 @@

    Container has no CPU limit

  • - Line number: 1017 + Line number: 1029
  • @@ -1137,7 +1137,7 @@

    Container has no CPU limit

  • - Line number: 1274 + Line number: 1286
  • @@ -1195,7 +1195,7 @@

    Container has no CPU limit

  • - Line number: 1074 + Line number: 1086
  • @@ -1253,7 +1253,7 @@

    Container has no CPU limit

  • - Line number: 1359 + Line number: 1371
  • @@ -1311,7 +1311,7 @@

    Container has no CPU limit

  • - Line number: 1675 + Line number: 1687
  • @@ -1363,7 +1363,7 @@

    Container is running with multiple open ports

  • - Line number: 850 + Line number: 856
  • @@ -1460,14 +1460,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 836 + Line number: 876
  • @@ -1512,14 +1512,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 870 + Line number: 842
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 1017 + Line number: 1029
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 1274 + Line number: 1286
  • @@ -1739,7 +1739,7 @@

    Container is running without memory limit

  • - Line number: 836 + Line number: 842
  • @@ -1797,7 +1797,7 @@

    Container is running without memory limit

  • - Line number: 870 + Line number: 876
  • @@ -1855,7 +1855,7 @@

    Container is running without memory limit

  • - Line number: 930 + Line number: 936
  • @@ -1913,7 +1913,7 @@

    Container is running without memory limit

  • - Line number: 1017 + Line number: 1029
  • @@ -1971,7 +1971,7 @@

    Container is running without memory limit

  • - Line number: 1274 + Line number: 1286
  • @@ -2029,7 +2029,7 @@

    Container is running without memory limit

  • - Line number: 1074 + Line number: 1086
  • @@ -2087,7 +2087,7 @@

    Container is running without memory limit

  • - Line number: 1359 + Line number: 1371
  • @@ -2145,7 +2145,7 @@

    Container is running without memory limit

  • - Line number: 1675 + Line number: 1687
  • @@ -2201,7 +2201,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 760 + Line number: 766
  • @@ -2257,7 +2257,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 878 + Line number: 884
  • @@ -2313,7 +2313,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 853 + Line number: 859
  • @@ -2369,7 +2369,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 951 + Line number: 963
  • @@ -2425,7 +2425,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1027 + Line number: 1039
  • @@ -2481,7 +2481,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1281 + Line number: 1293
  • @@ -2537,7 +2537,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1247 + Line number: 1259
  • @@ -2593,7 +2593,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1585 + Line number: 1597
  • @@ -2649,7 +2649,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1823 + Line number: 1835
  • diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index 4f0797405d6bb..950841ba92087 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:15:18 am (UTC+00:00)

    +

    October 8th 2023, 12:16:00 am (UTC+00:00)

    Scanned the following paths: @@ -468,7 +468,7 @@

    Snyk test report

    5 known vulnerabilities
    18 vulnerable dependency paths
    -
    1919 dependencies
    +
    1920 dependencies
    @@ -662,7 +662,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf @@ -677,7 +677,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf @@ -824,7 +824,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf @@ -841,7 +841,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@0.0.0 - github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf diff --git a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html index 5362d9f1153db..56de2da104ac4 100644 --- a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:15:34 am (UTC+00:00)

    +

    October 8th 2023, 12:16:18 am (UTC+00:00)

    Scanned the following paths: @@ -852,7 +852,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1015,7 +1015,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1050,6 +1050,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/master/haproxy_2.6.14-alpine.html b/docs/snyk/master/haproxy_2.6.14-alpine.html index 6ba6ea51ffc0a..224d53a9e1a8a 100644 --- a/docs/snyk/master/haproxy_2.6.14-alpine.html +++ b/docs/snyk/master/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:15:44 am (UTC+00:00)

    +

    October 8th 2023, 12:16:26 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index dac774d0f0d30..7df0b350478fe 100644 --- a/docs/snyk/master/quay.io_argoproj_argocd_latest.html +++ b/docs/snyk/master/quay.io_argoproj_argocd_latest.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:16:14 am (UTC+00:00)

    +

    October 8th 2023, 12:16:47 am (UTC+00:00)

    Scanned the following paths: @@ -468,7 +468,7 @@

    Snyk test report

    27 known vulnerabilities
    102 vulnerable dependency paths
    -
    2170 dependencies
    +
    2270 dependencies
    @@ -614,7 +614,7 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream xz-utils package and not the xz-utils package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the software maintainers are unable to reproduce this as of 2023-09-12 because the example crafted file is temporarily offline.

    +

    ** DISPUTED ** An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    Remediation

    There is no fixed version for Ubuntu:22.04 xz-utils.

    References

    @@ -626,6 +626,7 @@

    References

  • cve@mitre.org
  • cve@mitre.org
  • cve@mitre.org
  • +
  • cve@mitre.org

  • @@ -2851,7 +2852,7 @@

    Allocation of Resources Without Limits or Throttling

    Introduced through: - docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.35-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.35-0ubuntu3.4 @@ -2866,7 +2867,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - glibc/libc-bin@2.35-0ubuntu3.3 + glibc/libc-bin@2.35-0ubuntu3.4 @@ -2875,7 +2876,7 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@latest - glibc/libc6@2.35-0ubuntu3.3 + glibc/libc6@2.35-0ubuntu3.4 diff --git a/docs/snyk/master/redis_7.0.11-alpine.html b/docs/snyk/master/redis_7.0.11-alpine.html index 3c8e68ad964d9..a47b1c9a5220b 100644 --- a/docs/snyk/master/redis_7.0.11-alpine.html +++ b/docs/snyk/master/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:16:22 am (UTC+00:00)

    +

    October 8th 2023, 12:16:54 am (UTC+00:00)

    Scanned the following path: @@ -905,7 +905,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1090,7 +1090,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1125,6 +1125,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.6.15/argocd-iac-install.html b/docs/snyk/v2.6.15/argocd-iac-install.html index bf9ee4f20bde5..a292f7164db2f 100644 --- a/docs/snyk/v2.6.15/argocd-iac-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:28:14 am (UTC+00:00)

    +

    October 8th 2023, 12:29:23 am (UTC+00:00)

    Scanned the following path: @@ -1514,14 +1514,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 15951 + Line number: 15985
  • @@ -1566,14 +1566,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 15985 + Line number: 15951
  • diff --git a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html index 3b6b2fbd7b92b..3023cbb54080e 100644 --- a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:28:28 am (UTC+00:00)

    +

    October 8th 2023, 12:29:32 am (UTC+00:00)

    Scanned the following path: @@ -1514,14 +1514,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 755 + Line number: 789
  • @@ -1566,14 +1566,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 789 + Line number: 755
  • diff --git a/docs/snyk/v2.6.15/argocd-test.html b/docs/snyk/v2.6.15/argocd-test.html index b643763bc9443..493a8e13b30f3 100644 --- a/docs/snyk/v2.6.15/argocd-test.html +++ b/docs/snyk/v2.6.15/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:25:21 am (UTC+00:00)

    +

    October 8th 2023, 12:26:40 am (UTC+00:00)

    Scanned the following paths: diff --git a/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html index cbb0ecd603903..7c5ad90a6c26b 100644 --- a/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:25:29 am (UTC+00:00)

    +

    October 8th 2023, 12:26:49 am (UTC+00:00)

    Scanned the following paths: @@ -852,7 +852,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1015,7 +1015,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1050,6 +1050,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html index 4f717f2c05aab..a36fe3fd870af 100644 --- a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:25:35 am (UTC+00:00)

    +

    October 8th 2023, 12:26:53 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html index 71e5552f26c97..cbc03e2824255 100644 --- a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html +++ b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:26:27 am (UTC+00:00)

    +

    October 8th 2023, 12:28:02 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    36 known vulnerabilities
    -
    114 vulnerable dependency paths
    +
    40 known vulnerabilities
    +
    134 vulnerable dependency paths
    2063 dependencies
    @@ -877,6 +877,99 @@

    References

    More about this vulnerability

    +
    +
    +

    Out-of-bounds Write

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and glibc/libc-bin@2.35-0ubuntu3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + glibc/libc-bin@2.35-0ubuntu3.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + glibc/libc6@2.35-0ubuntu3.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A buffer overflow was discovered in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment variable. This issue could allow a local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when launching binaries with SUID permission to execute code with elevated privileges.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 glibc to version 2.35-0ubuntu3.4 or higher.

    +

    References

    + + +
    + + +

    Directory Traversal

    @@ -1025,7 +1118,7 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream xz-utils package and not the xz-utils package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the software maintainers are unable to reproduce this as of 2023-09-12 because the example crafted file is temporarily offline.

    +

    ** DISPUTED ** An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    Remediation

    There is no fixed version for Ubuntu:22.04 xz-utils.

    References

    @@ -1037,6 +1130,7 @@

    References

  • cve@mitre.org
  • cve@mitre.org
  • cve@mitre.org
  • +
  • cve@mitre.org

  • @@ -1165,6 +1259,357 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-43785

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43786

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43787

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + +

    Access of Uninitialized Pointer

    diff --git a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html index ec20676ee2756..29faf943e9997 100644 --- a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:26:33 am (UTC+00:00)

    +

    October 8th 2023, 12:28:07 am (UTC+00:00)

    Scanned the following path: @@ -905,7 +905,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1090,7 +1090,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1125,6 +1125,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.7.14/argocd-iac-install.html b/docs/snyk/v2.7.14/argocd-iac-install.html index d516c063c3ba8..9426ec11661c9 100644 --- a/docs/snyk/v2.7.14/argocd-iac-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:24:49 am (UTC+00:00)

    +

    October 8th 2023, 12:26:17 am (UTC+00:00)

    Scanned the following path: @@ -1514,14 +1514,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 17118 + Line number: 17152
  • @@ -1566,14 +1566,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 17152 + Line number: 17118
  • diff --git a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html index 4ce19418dbe92..cac575c912b80 100644 --- a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:25:03 am (UTC+00:00)

    +

    October 8th 2023, 12:26:27 am (UTC+00:00)

    Scanned the following path: @@ -1514,14 +1514,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 778 + Line number: 812
  • @@ -1566,14 +1566,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 812 + Line number: 778
  • diff --git a/docs/snyk/v2.7.14/argocd-test.html b/docs/snyk/v2.7.14/argocd-test.html index 950fd6562d51b..982aad86d898a 100644 --- a/docs/snyk/v2.7.14/argocd-test.html +++ b/docs/snyk/v2.7.14/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:22:14 am (UTC+00:00)

    +

    October 8th 2023, 12:24:22 am (UTC+00:00)

    Scanned the following paths: diff --git a/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html index 4f8d2c4e4b4b7..1e52f40708930 100644 --- a/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:22:25 am (UTC+00:00)

    +

    October 8th 2023, 12:24:28 am (UTC+00:00)

    Scanned the following paths: @@ -852,7 +852,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1015,7 +1015,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1050,6 +1050,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html index 09342f7d6f484..c65a210dd1d1e 100644 --- a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:22:31 am (UTC+00:00)

    +

    October 8th 2023, 12:24:32 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html index 4c1cb8f1d8e16..bb59744cabf07 100644 --- a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html +++ b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:22:58 am (UTC+00:00)

    +

    October 8th 2023, 12:24:51 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    29 known vulnerabilities
    -
    105 vulnerable dependency paths
    +
    33 known vulnerabilities
    +
    125 vulnerable dependency paths
    2065 dependencies
    @@ -634,6 +634,99 @@

    References

    More about this vulnerability

    +
    +
    +

    Out-of-bounds Write

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and glibc/libc-bin@2.35-0ubuntu3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + glibc/libc-bin@2.35-0ubuntu3.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + glibc/libc6@2.35-0ubuntu3.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A buffer overflow was discovered in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment variable. This issue could allow a local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when launching binaries with SUID permission to execute code with elevated privileges.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 glibc to version 2.35-0ubuntu3.4 or higher.

    +

    References

    + + +
    + + +

    Directory Traversal

    @@ -782,7 +875,7 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream xz-utils package and not the xz-utils package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the software maintainers are unable to reproduce this as of 2023-09-12 because the example crafted file is temporarily offline.

    +

    ** DISPUTED ** An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    Remediation

    There is no fixed version for Ubuntu:22.04 xz-utils.

    References

    @@ -794,6 +887,7 @@

    References

  • cve@mitre.org
  • cve@mitre.org
  • cve@mitre.org
  • +
  • cve@mitre.org

  • @@ -922,6 +1016,357 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-43785

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43786

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43787

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + +

    Access of Uninitialized Pointer

    diff --git a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html index bf29e934c06db..048f0935ffe28 100644 --- a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:23:05 am (UTC+00:00)

    +

    October 8th 2023, 12:24:55 am (UTC+00:00)

    Scanned the following path: @@ -905,7 +905,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1090,7 +1090,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1125,6 +1125,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.8.4/argocd-iac-install.html b/docs/snyk/v2.8.4/argocd-iac-install.html index 5f74f2148397b..bb000f12fa479 100644 --- a/docs/snyk/v2.8.4/argocd-iac-install.html +++ b/docs/snyk/v2.8.4/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:21:35 am (UTC+00:00)

    +

    October 8th 2023, 12:23:52 am (UTC+00:00)

    Scanned the following path: @@ -1460,14 +1460,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 19317 + Line number: 19351
  • @@ -1512,14 +1512,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 19351 + Line number: 19317
  • diff --git a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html b/docs/snyk/v2.8.4/argocd-iac-namespace-install.html index cc0982d073c19..9794d757c19bc 100644 --- a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.8.4/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:21:47 am (UTC+00:00)

    +

    October 8th 2023, 12:24:02 am (UTC+00:00)

    Scanned the following path: @@ -1460,14 +1460,14 @@

    Container is running without liveness probe

    spec - containers[dex] + initContainers[copyutil] livenessProbe
  • - Line number: 823 + Line number: 857
  • @@ -1512,14 +1512,14 @@

    Container is running without liveness probe

    spec - initContainers[copyutil] + containers[dex] livenessProbe
  • - Line number: 857 + Line number: 823
  • diff --git a/docs/snyk/v2.8.4/argocd-test.html b/docs/snyk/v2.8.4/argocd-test.html index c231307e65854..7f92a47fa3e28 100644 --- a/docs/snyk/v2.8.4/argocd-test.html +++ b/docs/snyk/v2.8.4/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:18:51 am (UTC+00:00)

    +

    October 8th 2023, 12:21:43 am (UTC+00:00)

    Scanned the following paths: diff --git a/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html index ba807896bd4af..bc933434ce92f 100644 --- a/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:19:00 am (UTC+00:00)

    +

    October 8th 2023, 12:21:50 am (UTC+00:00)

    Scanned the following paths: @@ -852,7 +852,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1015,7 +1015,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1050,6 +1050,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html b/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html index 5d86d078e915f..28bdc3254037b 100644 --- a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:19:05 am (UTC+00:00)

    +

    October 8th 2023, 12:21:55 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html b/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html index d2fabc64806b7..a42469bb1abe7 100644 --- a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html +++ b/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:19:32 am (UTC+00:00)

    +

    October 8th 2023, 12:22:17 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    27 known vulnerabilities
    -
    102 vulnerable dependency paths
    +
    31 known vulnerabilities
    +
    122 vulnerable dependency paths
    2116 dependencies
    @@ -476,6 +476,99 @@

    Snyk test report

    +
    +

    Out-of-bounds Write

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and glibc/libc-bin@2.35-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + glibc/libc-bin@2.35-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + glibc/libc6@2.35-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A buffer overflow was discovered in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment variable. This issue could allow a local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when launching binaries with SUID permission to execute code with elevated privileges.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 glibc to version 2.35-0ubuntu3.4 or higher.

    +

    References

    + + +
    + + + +

    Directory Traversal

    @@ -614,7 +707,7 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream xz-utils package and not the xz-utils package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the software maintainers are unable to reproduce this as of 2023-09-12 because the example crafted file is temporarily offline.

    +

    ** DISPUTED ** An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    Remediation

    There is no fixed version for Ubuntu:22.04 xz-utils.

    References

    @@ -626,6 +719,7 @@

    References

  • cve@mitre.org
  • cve@mitre.org
  • cve@mitre.org
  • +
  • cve@mitre.org

  • @@ -754,6 +848,357 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-43785

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43786

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43787

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + +

    Access of Uninitialized Pointer

    diff --git a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html b/docs/snyk/v2.8.4/redis_7.0.11-alpine.html index e44d0b26fc925..43ea5cbef33d5 100644 --- a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.8.4/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    September 17th 2023, 12:19:39 am (UTC+00:00)

    +

    October 8th 2023, 12:22:21 am (UTC+00:00)

    Scanned the following path: @@ -905,7 +905,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1090,7 +1090,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. See How to fix? for Alpine:3.18 relevant fixed versions and status.

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() @@ -1125,6 +1125,8 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html b/docs/snyk/v2.9.0-rc2/argocd-iac-install.html new file mode 100644 index 0000000000000..2f6b57aae9818 --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/argocd-iac-install.html @@ -0,0 +1,2679 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:21:14 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • /argo-cd/manifests/install.yaml (Kubernetes)
    • +
    +
    + +
    +
    40 total issues
    +
    +
    +
    +
    + +
    + + + + + + +
    Project manifests/install.yaml
    Path /argo-cd/manifests/install.yaml
    Project Type Kubernetes
    +
    +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[0] + + resources + +
    • + +
    • + Line number: 20316 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 11] + + rules[4] + + resources + +
    • + +
    • + Line number: 20393 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 12] + + rules[0] + + resources + +
    • + +
    • + Line number: 20421 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 13] + + rules[3] + + resources + +
    • + +
    • + Line number: 20469 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 13] + + rules[1] + + resources + +
    • + +
    • + Line number: 20451 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 14] + + rules[0] + + resources + +
    • + +
    • + Line number: 20485 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 45] + + spec + + template + + spec + + initContainers[copyutil] + + imagePullPolicy + +
    • + +
    • + Line number: 21618 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 41] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 20969 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21214 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21180 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 43] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21274 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 44] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21361 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21618 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21418 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 21703 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 22019 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container is running with multiple open ports

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-36 +
    • + +
    • Introduced through: + [DocId: 42] + + spec + + template + + spec + + containers[dex] + + ports + +
    • + +
    • + Line number: 21194 +
    • +
    + +
    + +

    Impact

    +

    Increases the attack surface of the application and the container.

    + +

    Remediation

    +

    Reduce `ports` count to 2

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 41] + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + livenessProbe + +
    • + +
    • + Line number: 20969 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 42] + + spec + + template + + spec + + initContainers[copyutil] + + livenessProbe + +
    • + +
    • + Line number: 21214 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 42] + + spec + + template + + spec + + containers[dex] + + livenessProbe + +
    • + +
    • + Line number: 21180 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 44] + + spec + + template + + spec + + containers[redis] + + livenessProbe + +
    • + +
    • + Line number: 21361 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 45] + + spec + + template + + spec + + initContainers[copyutil] + + livenessProbe + +
    • + +
    • + Line number: 21618 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 41] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 20969 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21180 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21214 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 43] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21274 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 44] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21361 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21618 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21418 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 21703 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 22019 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 41] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21104 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21222 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 42] + + input + + spec + + template + + spec + + containers[dex] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21197 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 43] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21295 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 44] + + input + + spec + + template + + spec + + containers[redis] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21371 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21625 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 45] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21591 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 46] + + input + + spec + + template + + spec + + containers[argocd-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 21929 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 47] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 22167 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +
    + +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html b/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html new file mode 100644 index 0000000000000..3f6c7b2a9cbd4 --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html @@ -0,0 +1,2679 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:21:23 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • /argo-cd/manifests/namespace-install.yaml (Kubernetes)
    • +
    +
    + +
    +
    40 total issues
    +
    +
    +
    +
    + +
    + + + + + + +
    Project manifests/namespace-install.yaml
    Path /argo-cd/manifests/namespace-install.yaml
    Project Type Kubernetes
    +
    +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 7] + + rules[0] + + resources + +
    • + +
    • + Line number: 77 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 8] + + rules[4] + + resources + +
    • + +
    • + Line number: 154 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 9] + + rules[0] + + resources + +
    • + +
    • + Line number: 182 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[3] + + resources + +
    • + +
    • + Line number: 230 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 10] + + rules[1] + + resources + +
    • + +
    • + Line number: 212 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Role with dangerous permissions

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-47 +
    • + +
    • Introduced through: + [DocId: 11] + + rules[0] + + resources + +
    • + +
    • + Line number: 246 +
    • +
    + +
    + +

    Impact

    +

    Using this role grants dangerous permissions

    + +

    Remediation

    +

    Consider removing this permissions

    + + +
    +
    + + + +
    +
    +

    Container could be running with outdated image

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-42 +
    • + +
    • Introduced through: + [DocId: 38] + + spec + + template + + spec + + initContainers[copyutil] + + imagePullPolicy + +
    • + +
    • + Line number: 1274 +
    • +
    + +
    + +

    Impact

    +

    The container may run with outdated or unauthorized image

    + +

    Remediation

    +

    Set `imagePullPolicy` attribute to `Always`

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 34] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 625 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 35] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 870 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 35] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 836 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 36] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 930 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1017 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1274 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1074 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1359 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container has no CPU limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-5 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + cpu + +
    • + +
    • + Line number: 1675 +
    • +
    + +
    + +

    Impact

    +

    CPU limits can prevent containers from consuming valuable compute time for no benefit (e.g. inefficient code) that might lead to unnecessary costs. It is advisable to also configure CPU requests to ensure application stability.

    + +

    Remediation

    +

    Add `resources.limits.cpu` field with required CPU limit value

    + + +
    +
    + + + +
    +
    +

    Container is running with multiple open ports

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-36 +
    • + +
    • Introduced through: + [DocId: 35] + + spec + + template + + spec + + containers[dex] + + ports + +
    • + +
    • + Line number: 850 +
    • +
    + +
    + +

    Impact

    +

    Increases the attack surface of the application and the container.

    + +

    Remediation

    +

    Reduce `ports` count to 2

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 34] + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + livenessProbe + +
    • + +
    • + Line number: 625 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 35] + + spec + + template + + spec + + initContainers[copyutil] + + livenessProbe + +
    • + +
    • + Line number: 870 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 35] + + spec + + template + + spec + + containers[dex] + + livenessProbe + +
    • + +
    • + Line number: 836 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 37] + + spec + + template + + spec + + containers[redis] + + livenessProbe + +
    • + +
    • + Line number: 1017 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without liveness probe

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-41 +
    • + +
    • Introduced through: + [DocId: 38] + + spec + + template + + spec + + initContainers[copyutil] + + livenessProbe + +
    • + +
    • + Line number: 1274 +
    • +
    + +
    + +

    Impact

    +

    Kubernetes will not be able to detect if application is able to service requests, and will not restart unhealthy pods

    + +

    Remediation

    +

    Add `livenessProbe` attribute

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 34] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 625 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 35] + + input + + spec + + template + + spec + + containers[dex] + + resources + + limits + + memory + +
    • + +
    • + Line number: 836 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 35] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 870 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 36] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 930 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + containers[redis] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1017 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + initContainers[copyutil] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1274 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1074 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + containers[argocd-server] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1359 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container is running without memory limit

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-4 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + resources + + limits + + memory + +
    • + +
    • + Line number: 1675 +
    • +
    + +
    + +

    Impact

    +

    Containers without memory limits are more likely to be terminated when the node runs out of memory

    + +

    Remediation

    +

    Set `resources.limits.memory` value

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 34] + + input + + spec + + template + + spec + + containers[argocd-applicationset-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 760 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 35] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 878 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 35] + + input + + spec + + template + + spec + + containers[dex] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 853 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 36] + + input + + spec + + template + + spec + + containers[argocd-notifications-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 951 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 37] + + input + + spec + + template + + spec + + containers[redis] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1027 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + initContainers[copyutil] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1281 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 38] + + input + + spec + + template + + spec + + containers[argocd-repo-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1247 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 39] + + input + + spec + + template + + spec + + containers[argocd-server] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1585 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +

    Container's or Pod's UID could clash with host's UID

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Public ID: SNYK-CC-K8S-11 +
    • + +
    • Introduced through: + [DocId: 40] + + input + + spec + + template + + spec + + containers[argocd-application-controller] + + securityContext + + runAsUser + +
    • + +
    • + Line number: 1823 +
    • +
    + +
    + +

    Impact

    +

    UID of the container processes could clash with host's UIDs and lead to unintentional authorization bypass

    + +

    Remediation

    +

    Set `securityContext.runAsUser` value to greater or equal than 10'000. SecurityContext can be set on both `pod` and `container` level. If both are set, then the container level takes precedence

    + + +
    +
    + + + +
    +
    +
    + +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/argocd-test.html b/docs/snyk/v2.9.0-rc2/argocd-test.html new file mode 100644 index 0000000000000..b73a0c715912e --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/argocd-test.html @@ -0,0 +1,972 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:18:53 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2 (gomodules)
    • /argo-cd (yarn)
    • +
    +
    + +
    +
    5 known vulnerabilities
    +
    18 vulnerable dependency paths
    +
    1920 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/r3labs/diff@1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.15.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.15.1 + + github.com/hashicorp/go-version@1.2.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.4 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.91.1 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/subscriptions@#9dcecdc3eebf + + github.com/argoproj/notifications-engine/pkg/services@#9dcecdc3eebf + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.13.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/gosimple/slug@1.13.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html new file mode 100644 index 0000000000000..0c8d8bdcd8f12 --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html @@ -0,0 +1,2521 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:19:01 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex (apk)
    • ghcr.io/dexidp/dex:v2.37.0/hairyhenderson/gomplate/v3 (gomodules)
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex (gomodules)
    • ghcr.io/dexidp/dex:v2.37.0/dexidp/dex (gomodules)
    • +
    +
    + +
    +
    25 known vulnerabilities
    +
    68 vulnerable dependency paths
    +
    786 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Out-of-bounds Write

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and busybox/busybox@1.36.1-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/busybox@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 + + busybox/busybox@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/busybox-binsh@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    There is a stack overflow vulnerability in ash.c:6030 in busybox before 1.35. In the environment of Internet of Vehicles, this vulnerability can be executed from command to arbitrary code execution.

    +

    Remediation

    +

    Upgrade Alpine:3.18 busybox to version 1.36.1-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Authentication

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: The AES-SIV cipher implementation contains a bug that causes + it to ignore empty associated data entries which are unauthenticated as + a consequence.

    +

    Impact summary: Applications that use the AES-SIV algorithm and want to + authenticate empty data entries as associated data can be mislead by removing + adding or reordering such empty entries as these are ignored by the OpenSSL + implementation. We are currently unaware of any such applications.

    +

    The AES-SIV algorithm allows for authentication of multiple associated + data entries along with the encryption. To authenticate empty data the + application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with + NULL pointer as the output buffer and 0 as the input buffer length. + The AES-SIV implementation in OpenSSL just returns success for such a call + instead of performing the associated data authentication operation. + The empty data thus will not be authenticated.

    +

    As this issue does not affect non-empty associated data authentication and + we expect it to be rare for an application to use empty associated data + entries this is qualified as Low severity issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.1-r2 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Inefficient Regular Expression Complexity

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.1-r3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.2-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Cross-site Scripting (XSS)

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/html +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and golang.org/x/net/html@v0.11.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + golang.org/x/net/html@v0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/html is a package that implements an HTML5-compliant tokenizer and parser.

    +

    Affected versions of this package are vulnerable to Cross-site Scripting (XSS) in the render1() function in render.go. Text nodes not in the HTML namespace are incorrectly literally rendered, causing text which should be escaped to not be.

    +

    Details

    +

    A cross-site scripting attack occurs when the attacker tricks a legitimate web-based application or site to accept a request as originating from a trusted source.

    +

    This is done by escaping the context of the web application; the web application then delivers that data to its users along with other trusted dynamic content, without validating it. The browser unknowingly executes malicious script on the client side (through client-side languages; usually JavaScript or HTML) in order to perform actions that are otherwise typically blocked by the browser’s Same Origin Policy.

    +

    Injecting malicious code is the most prevalent manner by which XSS is exploited; for this reason, escaping characters in order to prevent this manipulation is the top method for securing code against this vulnerability.

    +

    Escaping means that the application is coded to mark key characters, and particularly key characters included in user input, to prevent those characters from being interpreted in a dangerous context. For example, in HTML, < can be coded as &lt; and > can be coded as &gt; in order to be interpreted and displayed as themselves in text, while within the code itself, they are used for HTML tags. If malicious content is injected into an application that escapes special characters and that malicious content uses < and > as HTML tags, those characters are nonetheless not interpreted as HTML tags by the browser if they’ve been correctly escaped in the application code and in this way the attempted attack is diverted.

    +

    The most prominent use of XSS is to steal cookies (source: OWASP HttpOnly) and hijack user sessions, but XSS exploits have been used to expose sensitive information, enable access to privileged services and functionality and deliver malware.

    +

    Types of attacks

    +

    There are a few methods by which XSS can be manipulated:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypeOriginDescription
    StoredServerThe malicious code is inserted in the application (usually as a link) by the attacker. The code is activated every time a user clicks the link.
    ReflectedServerThe attacker delivers a malicious link externally from the vulnerable web site application to a user. When clicked, malicious code is sent to the vulnerable web site, which reflects the attack back to the user’s browser.
    DOM-basedClientThe attacker forces the user’s browser to render a malicious page. The data in the page itself delivers the cross-site scripting data.
    MutatedThe attacker injects code that appears safe, but is then rewritten and modified by the browser, while parsing the markup. An example is rebalancing unclosed quotation marks or even adding quotation marks to unquoted parameters.
    +

    Affected environments

    +

    The following environments are susceptible to an XSS attack:

    +
      +
    • Web servers
    • +
    • Application servers
    • +
    • Web application environments
    • +
    +

    How to prevent

    +

    This section describes the top best practices designed to specifically protect your code:

    +
      +
    • Sanitize data input in an HTTP request before reflecting it back, ensuring all data is validated, filtered or escaped before echoing anything back to the user, such as the values of query parameters during searches.
    • +
    • Convert special characters such as ?, &, /, <, > and spaces to their respective HTML or URL encoded equivalents.
    • +
    • Give users the option to disable client-side scripts.
    • +
    • Redirect invalid requests.
    • +
    • Detect simultaneous logins, including those from two separate IP addresses, and invalidate those sessions.
    • +
    • Use and enforce a Content Security Policy (source: Wikipedia) to disable any features that might be manipulated for an XSS attack.
    • +
    • Read the documentation for any of the libraries referenced in your code to understand which elements allow for embedded HTML.
    • +
    +

    Remediation

    +

    Upgrade golang.org/x/net/html to version 0.13.0 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/vault/sdk/helper/certutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/certutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/compressutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/consts@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/jsonutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/pluginutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/helper/strutil@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/logical@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/physical@v0.5.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/sdk/physical/inmem@v0.5.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/vault/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/vault/api@v1.6.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/vault/api@v1.6.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/serf/coordinate +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/serf/coordinate@v0.9.7 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/serf/coordinate@v0.9.7 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl/v2 +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/hashicorp/hcl/v2@v2.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/customdecode@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/ext/tryfunc@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/gohcl@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclparse@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclsyntax@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/hclwrite@v2.13.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/hashicorp/hcl/v2/json@v2.13.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/hcl +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/hcl@v1.0.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/hcl/parser@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/hcl/strconv@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/hcl/token@v1.0.0 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/hcl/json/parser@v1.0.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/golang-lru/simplelru +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/golang-lru/simplelru@v0.5.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/golang-lru/simplelru@v0.5.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-version@v1.5.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-version@v1.5.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-sockaddr +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-sockaddr@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-sockaddr@v1.0.2 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-sockaddr/template@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/strutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-secure-stdlib/strutil@v0.1.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/parseutil +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-secure-stdlib/parseutil@v0.1.5 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-secure-stdlib/mlock +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-secure-stdlib/mlock@v0.1.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-rootcerts +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-rootcerts@v1.0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-rootcerts@v1.0.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-retryablehttp@v0.7.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-retryablehttp@v0.7.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-plugin +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-plugin@v1.4.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-plugin@v1.4.4 + + + +
    • +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-plugin/internal/plugin@v1.4.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-immutable-radix +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-immutable-radix@v1.3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-immutable-radix@v1.3.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/go-cleanhttp@v0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/errwrap +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/errwrap@v1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/errwrap@v1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/consul/api +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/hashicorp/consul/api@v1.13.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/hashicorp/consul/api@v1.13.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and github.com/gosimple/slug@v1.12.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + github.com/gosimple/slug@v1.12.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/go-sql-driver/mysql +
    • + +
    • Introduced through: + + github.com/dexidp/dex@* and github.com/go-sql-driver/mysql@v1.7.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/dexidp/dex@* + + github.com/go-sql-driver/mysql@v1.7.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html b/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html new file mode 100644 index 0000000000000..9639db40d48fe --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html @@ -0,0 +1,492 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:19:04 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • haproxy:2.6.14-alpine (apk)
    • +
    +
    + +
    +
    0 known vulnerabilities
    +
    0 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    +
    + + + + + + + +
    Project docker-image|haproxy
    Path haproxy:2.6.14-alpine
    Package Manager apk
    +
    +
    + No known vulnerabilities detected. +
    +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html b/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html new file mode 100644 index 0000000000000..5af817b2532e1 --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html @@ -0,0 +1,3698 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:19:25 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • quay.io/argoproj/argocd:v2.9.0-rc2/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:v2.9.0-rc2/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc2/kustomize/kustomize/v5 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc2/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc2/git-lfs/git-lfs (gomodules)
    • +
    +
    + +
    +
    31 known vulnerabilities
    +
    122 vulnerable dependency paths
    +
    2270 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    Out-of-bounds Write

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and glibc/libc-bin@2.35-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + glibc/libc-bin@2.35-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + glibc/libc6@2.35-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A buffer overflow was discovered in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment variable. This issue could allow a local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when launching binaries with SUID permission to execute code with elevated privileges.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 glibc to version 2.35-0ubuntu3.4 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Directory Traversal

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + github.com/cyphar/filepath-securejoin +
    • + +
    • Introduced through: + + helm.sh/helm/v3@* and github.com/cyphar/filepath-securejoin@v0.2.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + helm.sh/helm/v3@* + + github.com/cyphar/filepath-securejoin@v0.2.3 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    Affected versions of this package are vulnerable to Directory Traversal via the filepath.FromSlash() function, allwoing attackers to generate paths that were outside of the provided rootfs.

    +

    Note: + This vulnerability is only exploitable on Windows OS.

    +

    Details

    +

    A Directory Traversal attack (also known as path traversal) aims to access files and directories that are stored outside the intended folder. By manipulating files with "dot-dot-slash (../)" sequences and its variations, or by using absolute file paths, it may be possible to access arbitrary files and directories stored on file system, including application source code, configuration, and other critical system files.

    +

    Directory Traversal vulnerabilities can be generally divided into two types:

    +
      +
    • Information Disclosure: Allows the attacker to gain information about the folder structure or read the contents of sensitive files on the system.
    • +
    +

    st is a module for serving static files on web pages, and contains a vulnerability of this type. In our example, we will serve files from the public route.

    +

    If an attacker requests the following URL from our server, it will in turn leak the sensitive private key of the root user.

    +
    curl http://localhost:8080/public/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/root/.ssh/id_rsa
    +        
    +

    Note %2e is the URL encoded version of . (dot).

    +
      +
    • Writing arbitrary files: Allows the attacker to create or replace existing files. This type of vulnerability is also known as Zip-Slip.
    • +
    +

    One way to achieve this is by using a malicious zip archive that holds path traversal filenames. When each filename in the zip archive gets concatenated to the target extraction folder, without validation, the final path ends up outside of the target folder. If an executable or a configuration file is overwritten with a file containing malicious code, the problem can turn into an arbitrary code execution issue quite easily.

    +

    The following is an example of a zip archive with one benign file and one malicious file. Extracting the malicious file will result in traversing out of the target folder, ending up in /root/.ssh/ overwriting the authorized_keys file:

    +
    2018-04-15 22:04:29 .....           19           19  good.txt
    +        2018-04-15 22:04:42 .....           20           20  ../../../../../../root/.ssh/authorized_keys
    +        
    +

    Remediation

    +

    Upgrade github.com/cyphar/filepath-securejoin to version 0.2.4 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2020-22916

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + xz-utils/liblzma5 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and xz-utils/liblzma5@5.2.5-2ubuntu1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + xz-utils/liblzma5@5.2.5-2ubuntu1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream xz-utils package and not the xz-utils package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    ** DISPUTED ** An issue discovered in XZ 5.2.5 allows attackers to cause a denial of service via decompression of a crafted file. NOTE: the vendor disputes the claims of "endless output" and "denial of service" because decompression of the 17,486 bytes always results in 114,881,179 bytes, which is often a reasonable size increase.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 xz-utils.

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + perl/perl-modules-5.34 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + perl@5.34.0-3ubuntu1.2 + + perl/perl-modules-5.34@5.34.0-3ubuntu1.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + perl@5.34.0-3ubuntu1.2 + + perl/libperl5.34@5.34.0-3ubuntu1.2 + + perl/perl-modules-5.34@5.34.0-3ubuntu1.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + perl@5.34.0-3ubuntu1.2 + + perl/libperl5.34@5.34.0-3ubuntu1.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + perl@5.34.0-3ubuntu1.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + perl/perl-base@5.34.0-3ubuntu1.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream perl package and not the perl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    In Perl 5.34.0, function S_find_uninit_var in sv.c has a stack-based crash that can lead to remote code execution or local privilege escalation.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 perl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43785

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43786

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-43787

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libx11/libx11-data +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + libx11/libx11-data@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libxext/libxext6@2:1.3.4-1build1 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libxmu/libxmuu1@2:1.1.3-3 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + xauth@1:1.1-1build2 + + libx11/libx11-6@2:1.7.5-1ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Access of Uninitialized Pointer

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and krb5/libk5crypto3@1.19.2-2ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libk5crypto3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libk5crypto3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + krb5/libk5crypto3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libkrb5support0@1.19.2-2ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    lib/kadm5/kadm_rpc_xdr.c in MIT Kerberos 5 (aka krb5) before 1.20.2 and 1.21.x before 1.21.1 frees an uninitialized pointer. A remote authenticated user can trigger a kadmind crash. This occurs because _xdr_kadm5_principal_ent_rec does not validate the relationship between n_key_data and the key_data array count.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/r3labs/diff@v1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/r3labs/diff@v1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-version@v1.2.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/hashicorp/go-version@v1.2.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-retryablehttp@v0.7.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/hashicorp/go-retryablehttp@v0.7.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-multierror +
    • + +
    • Introduced through: + + helm.sh/helm/v3@* and github.com/hashicorp/go-multierror@v1.1.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + helm.sh/helm/v3@* + + github.com/hashicorp/go-multierror@v1.1.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/hashicorp/go-cleanhttp@v0.5.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/hashicorp/go-cleanhttp@v0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + github.com/gosimple/slug@v1.13.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    CVE-2022-46908

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + sqlite3/libsqlite3-0 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, gnupg2/gpg@2.2.27-3ubuntu2.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + sqlite3/libsqlite3-0@3.37.2-2ubuntu0.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream sqlite3 package and not the sqlite3 package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    SQLite through 3.40.0, when relying on --safe for execution of an untrusted CLI script, does not properly implement the azProhibitedFunctions protection mechanism, and instead allows UDF functions such as WRITEFILE.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 sqlite3.

    +

    References

    + + +
    + + + +
    +
    +

    Arbitrary Code Injection

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + shadow/passwd +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and shadow/passwd@1:4.8.1-2ubuntu2.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + shadow/login@1:4.8.1-2ubuntu2.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream shadow package and not the shadow package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 shadow.

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + procps/libprocps8 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and procps/libprocps8@2:3.3.17-6ubuntu2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + procps/libprocps8@2:3.3.17-6ubuntu2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + procps@2:3.3.17-6ubuntu2 + + procps/libprocps8@2:3.3.17-6ubuntu2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + procps@2:3.3.17-6ubuntu2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream procps package and not the procps package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Under some circumstances, this weakness allows a user who has access to run the “ps” utility on a machine, the ability to write almost unlimited amounts of unfiltered data into the process heap.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 procps.

    +

    References

    + + +
    + + + +
    +
    +

    Uncontrolled Recursion

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + pcre3/libpcre3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + grep@3.7-1build1 + + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream pcre3 package and not the pcre3 package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 pcre3.

    +

    References

    + + +
    + + + +
    +
    +

    Release of Invalid Pointer or Reference

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and patch@2.7.6-7build2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + patch@2.7.6-7build2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    Double Free

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + patch +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and patch@2.7.6-7build2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + patch@2.7.6-7build2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 patch.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Authentication

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: The AES-SIV cipher implementation contains a bug that causes + it to ignore empty associated data entries which are unauthenticated as + a consequence.

    +

    Impact summary: Applications that use the AES-SIV algorithm and want to + authenticate empty data entries as associated data can be mislead by removing + adding or reordering such empty entries as these are ignored by the OpenSSL + implementation. We are currently unaware of any such applications.

    +

    The AES-SIV algorithm allows for authentication of multiple associated + data entries along with the encryption. To authenticate empty data the + application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with + NULL pointer as the output buffer and 0 as the input buffer length. + The AES-SIV implementation in OpenSSL just returns success for such a call + instead of performing the associated data authentication operation. + The empty data thus will not be authenticated.

    +

    As this issue does not affect non-empty associated data authentication and + we expect it to be rare for an application to use empty associated data + entries this is qualified as Low severity issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-28531

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssh/openssh-client +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssh/openssh-client@1:8.9p1-3ubuntu0.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssh.

    +

    References

    + + +
    + + + +
    +
    +

    NULL Pointer Dereference

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openldap/libldap-2.5-0 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openldap/libldap-common@2.5.16+dfsg-0ubuntu0.22.04.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openldap package and not the openldap package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in openldap. This security flaw causes a null pointer dereference in ber_memalloc_x() function.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openldap.

    +

    References

    + + +
    + + + +
    +
    +

    Resource Exhaustion

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + libzstd/libzstd1 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libzstd/libzstd1@1.4.8+dfsg-3build1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libzstd/libzstd1@1.4.8+dfsg-3build1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream libzstd package and not the libzstd package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in zstd v1.4.10, where an attacker can supply empty string as an argument to the command line tool to cause buffer overrun.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 libzstd.

    +

    References

    + + +
    + + + +
    +
    +

    Integer Overflow or Wraparound

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + krb5/libk5crypto3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and krb5/libk5crypto3@1.19.2-2ubuntu0.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libk5crypto3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libk5crypto3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + krb5/libk5crypto3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + krb5/libkrb5support0@1.19.2-2ubuntu0.2 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    An issue was discovered in MIT Kerberos 5 (aka krb5) through 1.16. There is a variable "dbentry->n_key_data" in kadmin/dbutil/dump.c that can store 16-bit data but unknowingly the developer has assigned a "u4" variable to it, which is for 32-bit data. An attacker can use this vulnerability to affect other artifacts of the database as we know that a Kerberos database dump file contains trusted data.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 krb5.

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + gnupg2/gpgv +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpgv@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + apt@2.4.10 + + gnupg2/gpgv@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpgv@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + + gnupg2/gpgconf@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + gnupg2/gpg@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + gnupg2/gpg-agent@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + gnupg2/gpgsm@2.2.27-3ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/gnupg@2.2.27-3ubuntu2.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream gnupg2 package and not the gnupg2 package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    GnuPG can be made to spin on a relatively small input by (for example) crafting a public key with thousands of signatures attached, compressed down to just a few KB.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 gnupg2.

    +

    References

    + + +
    + + + +
    +
    +

    Allocation of Resources Without Limits or Throttling

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and glibc/libc-bin@2.35-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + glibc/libc-bin@2.35-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + glibc/libc6@2.35-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    sha256crypt and sha512crypt through 0.6 allow attackers to cause a denial of service (CPU consumption) because the algorithm's runtime is proportional to the square of the length of the password.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 glibc.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + git/git-man +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + git/git-man@1:2.34.1-1ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git-lfs@3.0.2-1ubuntu0.2 + + git@1:2.34.1-1ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream git package and not the git package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    GIT version 2.15.1 and earlier contains a Input Validation Error vulnerability in Client that can result in problems including messing up terminal configuration to RCE. This attack appear to be exploitable via The user must interact with a malicious git server, (or have their traffic modified in a MITM attack).

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 git.

    +

    References

    + + +
    + + + +
    +
    +

    Uncontrolled Recursion

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + gcc-12/libstdc++6 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + apt@2.4.10 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + apt@2.4.10 + + apt/libapt-pkg6.0@2.4.10 + + gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream gcc-12 package and not the gcc-12 package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    libiberty/rust-demangle.c in GNU GCC 11.2 allows stack consumption in demangle_const, as demonstrated by nm-new.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 gcc-12.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Input Validation

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + coreutils +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and coreutils@8.32-4.1ubuntu1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + coreutils@8.32-4.1ubuntu1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream coreutils package and not the coreutils package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    chroot in GNU coreutils, when used with --userspec, allows local users to escape to the parent session via a crafted TIOCSTI ioctl call, which pushes characters to the terminal's input buffer.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 coreutils.

    +

    References

    + + +
    + + + +
    +
    +

    Out-of-bounds Write

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + bash +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and bash@5.1-6ubuntu1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + bash@5.1-6ubuntu1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream bash package and not the bash package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A flaw was found in the bash package, where a heap-buffer overflow can occur in valid parameter_transform. This issue may lead to memory problems.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 bash.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html b/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html new file mode 100644 index 0000000000000..915b9188485f4 --- /dev/null +++ b/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html @@ -0,0 +1,1144 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 8th 2023, 12:19:35 am (UTC+00:00)

    +
    +
    + Scanned the following path: +
      +
    • redis:7.0.11-alpine (apk)
    • +
    +
    + +
    +
    4 known vulnerabilities
    +
    32 vulnerable dependency paths
    +
    18 dependencies
    +
    +
    +
    +
    +
    + + + + + + + +
    Project docker-image|redis
    Path redis:7.0.11-alpine
    Package Manager apk
    +
    +
    +
    +
    +

    Out-of-bounds Write

    +
    + +
    + critical severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + busybox/busybox +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and busybox/busybox@1.36.1-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/busybox@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 + + busybox/busybox@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/busybox-binsh@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + alpine-baselayout/alpine-baselayout@3.4.3-r1 + + busybox/busybox-binsh@1.36.1-r0 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream busybox package and not the busybox package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    There is a stack overflow vulnerability in ash.c:6030 in busybox before 1.35. In the environment of Internet of Vehicles, this vulnerability can be executed from command to arbitrary code execution.

    +

    Remediation

    +

    Upgrade Alpine:3.18 busybox to version 1.36.1-r1 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Improper Authentication

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine:3.18. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: The AES-SIV cipher implementation contains a bug that causes + it to ignore empty associated data entries which are unauthenticated as + a consequence.

    +

    Impact summary: Applications that use the AES-SIV algorithm and want to + authenticate empty data entries as associated data can be mislead by removing + adding or reordering such empty entries as these are ignored by the OpenSSL + implementation. We are currently unaware of any such applications.

    +

    The AES-SIV algorithm allows for authentication of multiple associated + data entries along with the encryption. To authenticate empty data the + application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with + NULL pointer as the output buffer and 0 as the input buffer length. + The AES-SIV implementation in OpenSSL just returns success for such a call + instead of performing the associated data authentication operation. + The empty data thus will not be authenticated.

    +

    As this issue does not affect non-empty associated data authentication and + we expect it to be rare for an application to use empty associated data + entries this is qualified as Low severity issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.1-r2 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Inefficient Regular Expression Complexity

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.1-r3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.2-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    +
    +
    + + + From af17c8d0ff9c118436f907be175a71cd14538536 Mon Sep 17 00:00:00 2001 From: Alex Souslik Date: Fri, 13 Oct 2023 23:00:47 +0300 Subject: [PATCH 006/269] bump helm 3.13.1, kustomize 5.1.1 (#15703) Signed-off-by: alex-souslik-hs --- .../checksums/helm-v3.13.1-linux-amd64.tar.gz.sha256 | 1 + .../checksums/helm-v3.13.1-linux-arm64.tar.gz.sha256 | 1 + .../checksums/helm-v3.13.1-linux-ppc64le.tar.gz.sha256 | 1 + .../checksums/helm-v3.13.1-linux-s390x.tar.gz.sha256 | 1 + .../checksums/kustomize_5.1.1_darwin_amd64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.1.1_linux_amd64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.1.1_linux_arm64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.1.1_linux_ppc64le.tar.gz.sha256 | 1 + .../checksums/kustomize_5.1.1_linux_s390x.tar.gz.sha256 | 1 + hack/tool-versions.sh | 4 ++-- 10 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 hack/installers/checksums/helm-v3.13.1-linux-amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.13.1-linux-arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.13.1-linux-ppc64le.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.13.1-linux-s390x.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.1.1_darwin_amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.1.1_linux_amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.1.1_linux_arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.1.1_linux_ppc64le.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.1.1_linux_s390x.tar.gz.sha256 diff --git a/hack/installers/checksums/helm-v3.13.1-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.1-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..752a8c186935c --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.1-linux-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +98c363564d00afd0cc3088e8f830f2a0eeb5f28755b3d8c48df89866374a1ed0 helm-v3.13.1-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.13.1-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.1-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..16904cec9ea94 --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.1-linux-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +8c4a0777218b266a7b977394aaf0e9cef30ed2df6e742d683e523d75508d6efe helm-v3.13.1-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.13.1-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.1-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..3f1e79193a05e --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.1-linux-ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +f0d4ae95b4db25d03ced987e30d424564bd4727af6a4a0b7fca41f14203306fb helm-v3.13.1-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.13.1-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.1-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..493db677b1cf2 --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.1-linux-s390x.tar.gz.sha256 @@ -0,0 +1 @@ +b657b72b34f568527093dede148ae72fcbc1f2e67d3fd6f2ffa1095637fbddb6 helm-v3.13.1-linux-s390x.tar.gz diff --git a/hack/installers/checksums/kustomize_5.1.1_darwin_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.1.1_darwin_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..09a5d2486e71c --- /dev/null +++ b/hack/installers/checksums/kustomize_5.1.1_darwin_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +94047e967028b2849f9be1988f0cc084187ee3b77a1a0d88ede3979894da4af4 kustomize_5.1.1_darwin_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.1.1_linux_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.1.1_linux_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..79e38f6c825b7 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.1.1_linux_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +3b30477a7ff4fb6547fa77d8117e66d995c2bdd526de0dafbf8b7bcb9556c85d kustomize_5.1.1_linux_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.1.1_linux_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.1.1_linux_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..5a5da060b3d58 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.1.1_linux_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +a1bfb5d919c84817b8265d661fb99aae8176bcfe0b9df92651de93304cae953d kustomize_5.1.1_linux_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.1.1_linux_ppc64le.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.1.1_linux_ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..de21b4f3fd6d7 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.1.1_linux_ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +d9437fcadb9f3ff321ed83c8b485a7066cb7274971ee2e599be238c08be88493 kustomize_5.1.1_linux_ppc64le.tar.gz diff --git a/hack/installers/checksums/kustomize_5.1.1_linux_s390x.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.1.1_linux_s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..86e92abf259ae --- /dev/null +++ b/hack/installers/checksums/kustomize_5.1.1_linux_s390x.tar.gz.sha256 @@ -0,0 +1 @@ +24712149a2ebf38b854918988314df7d3255f738c8f1875c9823dd2e6aa07a60 kustomize_5.1.1_linux_s390x.tar.gz diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 0a78a89c9f0f4..00dd572966182 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -11,8 +11,8 @@ # Use ./hack/installers/checksums/add-helm-checksums.sh and # add-kustomize-checksums.sh to help download checksums. ############################################################################### -helm3_version=3.12.1 +helm3_version=3.13.1 kubectl_version=1.17.8 kubectx_version=0.6.3 -kustomize5_version=5.1.0 +kustomize5_version=5.1.1 protoc_version=3.17.3 From 0fdd534c896bd24137b82047c6c5aeb8e56063e9 Mon Sep 17 00:00:00 2001 From: Matthijs Date: Sun, 15 Oct 2023 11:24:50 +0200 Subject: [PATCH 007/269] Added timezone example to sync_windows page (#15926) I was looking for this in the docs but I could not find it. Did find that it was possible https://github.com/argoproj/argo-cd/pull/7442/files so I have added to an example to make it clear that this is possible. Signed-off-by: Matthijs --- docs/user-guide/sync_windows.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user-guide/sync_windows.md b/docs/user-guide/sync_windows.md index 031d8e6d67b30..f6bc6b82f8b69 100644 --- a/docs/user-guide/sync_windows.md +++ b/docs/user-guide/sync_windows.md @@ -64,6 +64,7 @@ spec: manualSync: true - kind: deny schedule: '0 22 * * *' + timeZone: "Europe/Amsterdam" duration: 1h namespaces: - default From dbc48f372cf3463e27f0b90f01e6788076c13b2f Mon Sep 17 00:00:00 2001 From: naruse <62323683+naruse666@users.noreply.github.com> Date: Mon, 16 Oct 2023 02:26:48 +0900 Subject: [PATCH 008/269] fix(ci): unstable integration test (#15976) * wait more Signed-off-by: naruse666 * fix: wait Signed-off-by: naruse666 * rerun Signed-off-by: naruse666 * rerun 2 Signed-off-by: naruse666 --------- Signed-off-by: naruse666 --- test/e2e/app_management_ns_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index 15cbd43534025..6312303c71a2c 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -2448,6 +2448,7 @@ func TestNamespacedDisableManifestGeneration(t *testing.T) { }). When(). And(func() { + time.Sleep(3 * time.Second) SetEnableManifestGeneration(map[ApplicationSourceType]bool{ ApplicationSourceTypeKustomize: false, }) From 99a4bf0a2d4a9eface33a03d29bc3554d0faa704 Mon Sep 17 00:00:00 2001 From: Nathan Romriell Date: Mon, 16 Oct 2023 11:10:56 -0700 Subject: [PATCH 009/269] fix: delete event cache deadlock test flakiness (#15964) Signed-off-by: Nathan Romriell --- controller/cache/cache_test.go | 76 +++++++++++++++++----------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index de2d96eb7aa28..c94038a89b881 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -120,7 +120,7 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { } fakeClient := fake.NewSimpleClientset() settingsMgr := argosettings.NewSettingsManager(context.TODO(), fakeClient, "argocd") - externalLockRef := sync.RWMutex{} + liveStateCacheLock := sync.RWMutex{} gitopsEngineClusterCache := &mocks.ClusterCache{} clustersCache := liveStateCache{ clusters: map[string]cache.ClusterCache{ @@ -132,11 +132,14 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { settingsMgr: settingsMgr, // Set the lock here so we can reference it later // nolint We need to overwrite here to have access to the lock - lock: externalLockRef, + lock: liveStateCacheLock, } channel := make(chan string) // Mocked lock held by the gitops-engine cluster cache - mockMutex := sync.RWMutex{} + gitopsEngineClusterCacheLock := sync.Mutex{} + // Ensure completion of both EnsureSynced and Invalidate + ensureSyncedCompleted := sync.Mutex{} + invalidateCompleted := sync.Mutex{} // Locks to force trigger condition during test // Condition order: // EnsuredSynced -> Locks gitops-engine @@ -144,40 +147,39 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { // EnsureSynced via sync, newResource, populateResourceInfoHandler -> attempts to Lock liveStateCache // handleDeleteEvent via cluster.Invalidate -> attempts to Lock gitops-engine handleDeleteWasCalled := sync.Mutex{} - engineHoldsLock := sync.Mutex{} + engineHoldsEngineLock := sync.Mutex{} + ensureSyncedCompleted.Lock() + invalidateCompleted.Lock() handleDeleteWasCalled.Lock() - engineHoldsLock.Lock() + engineHoldsEngineLock.Lock() + gitopsEngineClusterCache.On("EnsureSynced").Run(func(args mock.Arguments) { - // Held by EnsureSync calling into sync and watchEvents - mockMutex.Lock() - defer mockMutex.Unlock() - // Continue Execution of timer func - engineHoldsLock.Unlock() - // Wait for handleDeleteEvent to be called triggering the lock - // on the liveStateCache + gitopsEngineClusterCacheLock.Lock() + t.Log("EnsureSynced: Engine has engine lock") + engineHoldsEngineLock.Unlock() + defer gitopsEngineClusterCacheLock.Unlock() + // Wait until handleDeleteEvent holds the liveStateCache lock handleDeleteWasCalled.Lock() - t.Logf("handleDelete was called, EnsureSynced continuing...") - handleDeleteWasCalled.Unlock() - // Try and obtain the lock on the liveStateCache - alreadyFailed := !externalLockRef.TryLock() - if alreadyFailed { - channel <- "DEADLOCKED -- EnsureSynced could not obtain lock on liveStateCache" - return - } - externalLockRef.Lock() - t.Logf("EnsureSynce was able to lock liveStateCache") - externalLockRef.Unlock() + // Try and obtain the liveStateCache lock + clustersCache.lock.Lock() + t.Log("EnsureSynced: Engine has LiveStateCache lock") + clustersCache.lock.Unlock() + ensureSyncedCompleted.Unlock() }).Return(nil).Once() + gitopsEngineClusterCache.On("Invalidate").Run(func(args mock.Arguments) { - // If deadlock is fixed should be able to acquire lock here - alreadyFailed := !mockMutex.TryLock() - if alreadyFailed { - channel <- "DEADLOCKED -- Invalidate could not obtain lock on gitops-engine" - return - } - mockMutex.Lock() - t.Logf("Invalidate was able to lock gitops-engine cache") - mockMutex.Unlock() + // Allow EnsureSynced to continue now that we're in the deadlock condition + handleDeleteWasCalled.Unlock() + // Wait until gitops engine holds the gitops lock + // This prevents timing issues if we reach this point before EnsureSynced has obtained the lock + engineHoldsEngineLock.Lock() + t.Log("Invalidate: Engine has engine lock") + engineHoldsEngineLock.Unlock() + // Lock engine lock + gitopsEngineClusterCacheLock.Lock() + t.Log("Invalidate: Invalidate has engine lock") + gitopsEngineClusterCacheLock.Unlock() + invalidateCompleted.Unlock() }).Return() go func() { // Start the gitops-engine lock holds @@ -187,14 +189,14 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { assert.Fail(t, err.Error()) } }() - // Wait for EnsureSynced to grab the lock for gitops-engine - engineHoldsLock.Lock() - t.Log("EnsureSynced has obtained lock on gitops-engine") - engineHoldsLock.Unlock() // Run in background go clustersCache.handleDeleteEvent(testCluster.Server) // Allow execution to continue on clusters cache call to trigger lock - handleDeleteWasCalled.Unlock() + ensureSyncedCompleted.Lock() + invalidateCompleted.Lock() + t.Log("Competing functions were able to obtain locks") + invalidateCompleted.Unlock() + ensureSyncedCompleted.Unlock() channel <- "PASSED" }() select { From 94401b9cb2e0c48b407391c57f355fdffbf23a35 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 16:31:59 -0400 Subject: [PATCH 010/269] [Bot] docs: Update Snyk reports (#15977) Signed-off-by: CI Co-authored-by: CI --- docs/snyk/index.md | 18 +- docs/snyk/master/argocd-iac-install.html | 2 +- .../master/argocd-iac-namespace-install.html | 2 +- docs/snyk/master/argocd-test.html | 4 +- .../master/ghcr.io_dexidp_dex_v2.37.0.html | 172 +- docs/snyk/master/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_latest.html | 472 ++- docs/snyk/master/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.6.15/argocd-iac-install.html | 2 +- .../v2.6.15/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.6.15/argocd-test.html | 2581 +++++++++++++++- .../v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html | 172 +- docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.6.15.html | 805 ++++- docs/snyk/v2.6.15/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.7.14/argocd-iac-install.html | 2 +- .../v2.7.14/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.7.14/argocd-test.html | 2693 +++++++++++++++- .../v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html | 172 +- docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.7.14.html | 805 ++++- docs/snyk/v2.7.14/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.8.4/argocd-iac-install.html | 2 +- .../v2.8.4/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.8.4/argocd-test.html | 2659 +++++++++++++++- .../v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html | 172 +- docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.8.4.html | 881 +++++- docs/snyk/v2.8.4/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.9.0-rc2/argocd-iac-install.html | 2 +- .../argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.9.0-rc2/argocd-test.html | 2748 ++++++++++++++++- .../ghcr.io_dexidp_dex_v2.37.0.html | 172 +- .../v2.9.0-rc2/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.9.0-rc2.html | 881 +++++- docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html | 2 +- 36 files changed, 15114 insertions(+), 333 deletions(-) diff --git a/docs/snyk/index.md b/docs/snyk/index.md index f4e0bb57e59b0..fddd77111a7e3 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -17,7 +17,7 @@ recent minor releases. | [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](master/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](master/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 17 | +| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 19 | | [redis:7.0.11-alpine](master/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | @@ -26,11 +26,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.9.0-rc2/argocd-test.html) | 0 | 0 | 5 | 0 | +| [go.mod](v2.9.0-rc2/argocd-test.html) | 0 | 2 | 5 | 0 | | [ui/yarn.lock](v2.9.0-rc2/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.9.0-rc2/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.9.0-rc2](v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html) | 0 | 1 | 6 | 17 | +| [argocd:v2.9.0-rc2](v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html) | 0 | 2 | 6 | 20 | | [redis:7.0.11-alpine](v2.9.0-rc2/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.9.0-rc2/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.9.0-rc2/argocd-iac-namespace-install.html) | - | - | - | - | @@ -39,11 +39,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.8.4/argocd-test.html) | 0 | 0 | 5 | 0 | +| [go.mod](v2.8.4/argocd-test.html) | 0 | 2 | 5 | 0 | | [ui/yarn.lock](v2.8.4/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.8.4/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 1 | 6 | 17 | +| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 2 | 6 | 20 | | [redis:7.0.11-alpine](v2.8.4/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.8.4/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.8.4/argocd-iac-namespace-install.html) | - | - | - | - | @@ -52,11 +52,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.7.14/argocd-test.html) | 0 | 1 | 5 | 0 | +| [go.mod](v2.7.14/argocd-test.html) | 0 | 3 | 5 | 0 | | [ui/yarn.lock](v2.7.14/argocd-test.html) | 0 | 1 | 0 | 0 | | [dex:v2.37.0](v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.7.14/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 1 | 6 | 17 | +| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 2 | 6 | 20 | | [redis:7.0.11-alpine](v2.7.14/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.7.14/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.7.14/argocd-iac-namespace-install.html) | - | - | - | - | @@ -65,11 +65,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.6.15/argocd-test.html) | 0 | 1 | 5 | 0 | +| [go.mod](v2.6.15/argocd-test.html) | 0 | 3 | 5 | 0 | | [ui/yarn.lock](v2.6.15/argocd-test.html) | 0 | 1 | 0 | 0 | | [dex:v2.37.0](v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.6.15/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 1 | 6 | 17 | +| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 2 | 6 | 20 | | [redis:7.0.11-alpine](v2.6.15/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.6.15/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.6.15/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index 327eefb575940..cdbbcd216e583 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:18:32 am (UTC+00:00)

    +

    October 15th 2023, 12:17:18 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index 632fa36c65e03..5ab8913fc9766 100644 --- a/docs/snyk/master/argocd-iac-namespace-install.html +++ b/docs/snyk/master/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:18:42 am (UTC+00:00)

    +

    October 15th 2023, 12:17:30 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index 950841ba92087..de493e0e6e42c 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:16:00 am (UTC+00:00)

    +

    October 15th 2023, 12:14:41 am (UTC+00:00)

    Scanned the following paths: @@ -468,7 +468,7 @@

    Snyk test report

    5 known vulnerabilities
    18 vulnerable dependency paths
    -
    1920 dependencies
    +
    1922 dependencies
    diff --git a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html index 56de2da104ac4..d9d7bb771d57e 100644 --- a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:16:18 am (UTC+00:00)

    +

    October 15th 2023, 12:14:53 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    25 known vulnerabilities
    -
    68 vulnerable dependency paths
    +
    27 known vulnerabilities
    +
    72 vulnerable dependency paths
    786 dependencies
    @@ -583,6 +583,170 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/grpc@v1.46.2 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/grpc@v1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + golang.org/x/net/http2@v0.7.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Improper Authentication

    diff --git a/docs/snyk/master/haproxy_2.6.14-alpine.html b/docs/snyk/master/haproxy_2.6.14-alpine.html index 224d53a9e1a8a..1f696570c59d5 100644 --- a/docs/snyk/master/haproxy_2.6.14-alpine.html +++ b/docs/snyk/master/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:16:26 am (UTC+00:00)

    +

    October 15th 2023, 12:15:00 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index 7df0b350478fe..1009be1e34406 100644 --- a/docs/snyk/master/quay.io_argoproj_argocd_latest.html +++ b/docs/snyk/master/quay.io_argoproj_argocd_latest.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:16:47 am (UTC+00:00)

    +

    October 15th 2023, 12:15:23 am (UTC+00:00)

    Scanned the following paths: @@ -466,9 +466,9 @@

    Snyk test report

    -
    27 known vulnerabilities
    -
    102 vulnerable dependency paths
    -
    2270 dependencies
    +
    29 known vulnerabilities
    +
    120 vulnerable dependency paths
    +
    2278 dependencies
    @@ -477,7 +477,7 @@

    Snyk test report

    -

    Directory Traversal

    +

    Denial of Service (DoS)

    @@ -493,12 +493,12 @@

    Directory Traversal

  • Vulnerable module: - github.com/cyphar/filepath-securejoin + golang.org/x/net/http2
  • Introduced through: - helm.sh/helm/v3@* and github.com/cyphar/filepath-securejoin@v0.2.3 + helm.sh/helm/v3@* and golang.org/x/net/http2@v0.13.0
  • @@ -513,7 +513,7 @@

    Detailed paths

    Introduced through: helm.sh/helm/v3@* - github.com/cyphar/filepath-securejoin@v0.2.3 + golang.org/x/net/http2@v0.13.0 @@ -525,41 +525,27 @@

    Detailed paths


    Overview

    -

    Affected versions of this package are vulnerable to Directory Traversal via the filepath.FromSlash() function, allwoing attackers to generate paths that were outside of the provided rootfs.

    -

    Note: - This vulnerability is only exploitable on Windows OS.

    -

    Details

    -

    A Directory Traversal attack (also known as path traversal) aims to access files and directories that are stored outside the intended folder. By manipulating files with "dot-dot-slash (../)" sequences and its variations, or by using absolute file paths, it may be possible to access arbitrary files and directories stored on file system, including application source code, configuration, and other critical system files.

    -

    Directory Traversal vulnerabilities can be generally divided into two types:

    -
      -
    • Information Disclosure: Allows the attacker to gain information about the folder structure or read the contents of sensitive files on the system.
    • -
    -

    st is a module for serving static files on web pages, and contains a vulnerability of this type. In our example, we will serve files from the public route.

    -

    If an attacker requests the following URL from our server, it will in turn leak the sensitive private key of the root user.

    -
    curl http://localhost:8080/public/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/root/.ssh/id_rsa
    -        
    -

    Note %2e is the URL encoded version of . (dot).

    -
      -
    • Writing arbitrary files: Allows the attacker to create or replace existing files. This type of vulnerability is also known as Zip-Slip.
    • -
    -

    One way to achieve this is by using a malicious zip archive that holds path traversal filenames. When each filename in the zip archive gets concatenated to the target extraction folder, without validation, the final path ends up outside of the target folder. If an executable or a configuration file is overwritten with a file containing malicious code, the problem can turn into an arbitrary code execution issue quite easily.

    -

    The following is an example of a zip archive with one benign file and one malicious file. Extracting the malicious file will result in traversing out of the target folder, ending up in /root/.ssh/ overwriting the authorized_keys file:

    -
    2018-04-15 22:04:29 .....           19           19  good.txt
    -        2018-04-15 22:04:42 .....           20           20  ../../../../../../root/.ssh/authorized_keys
    -        
    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    Remediation

    -

    Upgrade github.com/cyphar/filepath-securejoin to version 0.2.4 or higher.

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    References


    @@ -898,7 +884,7 @@

    Detailed paths

    git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -911,7 +897,7 @@

    Detailed paths

    git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 @@ -1897,7 +1883,7 @@

    Detailed paths

    git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 @@ -1994,6 +1980,408 @@

    References

    More about this vulnerability

    +
    +
    +

    Inefficient Regular Expression Complexity

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + +

    CVE-2023-28531

    @@ -2114,7 +2502,7 @@

    Detailed paths

    git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -2376,7 +2764,7 @@

    Detailed paths

    git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -2389,7 +2777,7 @@

    Detailed paths

    git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 diff --git a/docs/snyk/master/redis_7.0.11-alpine.html b/docs/snyk/master/redis_7.0.11-alpine.html index a47b1c9a5220b..d4cf7fe946b5b 100644 --- a/docs/snyk/master/redis_7.0.11-alpine.html +++ b/docs/snyk/master/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:16:54 am (UTC+00:00)

    +

    October 15th 2023, 12:15:30 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-iac-install.html b/docs/snyk/v2.6.15/argocd-iac-install.html index a292f7164db2f..b38345ee04e69 100644 --- a/docs/snyk/v2.6.15/argocd-iac-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:29:23 am (UTC+00:00)

    +

    October 15th 2023, 12:28:31 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html index 3023cbb54080e..e6cf243f42cc2 100644 --- a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:29:32 am (UTC+00:00)

    +

    October 15th 2023, 12:28:43 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-test.html b/docs/snyk/v2.6.15/argocd-test.html index 493a8e13b30f3..d48c69439bc60 100644 --- a/docs/snyk/v2.6.15/argocd-test.html +++ b/docs/snyk/v2.6.15/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:26:40 am (UTC+00:00)

    +

    October 15th 2023, 12:26:23 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    7 known vulnerabilities
    -
    20 vulnerable dependency paths
    +
    9 known vulnerabilities
    +
    157 vulnerable dependency paths
    1727 dependencies
    @@ -627,6 +627,2579 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and google.golang.org/grpc@1.51.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@#16092bd1d58a + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.31.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig@1.11.1 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.51.0 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.51.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.24.2 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/soheilhy/cmux@0.1.5 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@#16092bd1d58a + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#a4dd357b057e + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.31.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@#16092bd1d58a + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f754726f03da + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#a4dd357b057e + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.51.0 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.51.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.51.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f754726f03da + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f754726f03da + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/resource@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.11.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.24.2 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.24.2 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.11.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/tools/reference@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/resource@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f754726f03da + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/meta/v1@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f754726f03da + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#b4dd8b8c3976 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/manager@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f754726f03da + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b4dd8b8c3976 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b4dd8b8c3976 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Directory Traversal

    diff --git a/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html index 7c5ad90a6c26b..682d6d00feadc 100644 --- a/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:26:49 am (UTC+00:00)

    +

    October 15th 2023, 12:26:31 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    25 known vulnerabilities
    -
    68 vulnerable dependency paths
    +
    27 known vulnerabilities
    +
    72 vulnerable dependency paths
    786 dependencies
    @@ -583,6 +583,170 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/grpc@v1.46.2 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/grpc@v1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + golang.org/x/net/http2@v0.7.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Improper Authentication

    diff --git a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html index a36fe3fd870af..1d1b7ac0b764b 100644 --- a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:26:53 am (UTC+00:00)

    +

    October 15th 2023, 12:26:35 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html index cbc03e2824255..cd0e96a404b08 100644 --- a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html +++ b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:28:02 am (UTC+00:00)

    +

    October 15th 2023, 12:27:03 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    40 known vulnerabilities
    -
    134 vulnerable dependency paths
    +
    46 known vulnerabilities
    +
    157 vulnerable dependency paths
    2063 dependencies
    @@ -643,6 +643,79 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.51.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + google.golang.org/grpc@v1.51.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + +

    Denial of Service (DoS)

    @@ -731,6 +804,88 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.11.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    • + Introduced through: + helm.sh/helm/v3@* + + golang.org/x/net/http2@v0.0.0-20220722155237-a158d28d115b + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Denial of Service

    @@ -962,6 +1117,9 @@

    References

  • secalert@redhat.com
  • secalert@redhat.com
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com

  • @@ -1066,6 +1224,99 @@

    References

    More about this vulnerability

    +
    +
    +

    Heap-based Buffer Overflow

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.6.15, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. + The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. + Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    +

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    +

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    +

    Note:

    +

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. + Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    +

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    +
      +
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: + CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      +
    2. +
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      +
    4. +
    +

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    +
      +
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      +
    2. +
    3. Environment variables as described in the libcurl section.

      +
    4. +
    +

    Changelog:

    +

    2023-10-04: Initial publication

    +

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    CVE-2020-22916

    @@ -1261,7 +1512,7 @@

    References

    -

    CVE-2023-43785

    +

    Out-of-bounds Read

    @@ -1362,12 +1613,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to a boundary condition within the _XkbReadKeySyms() function. This flaw allows a local user to trigger an out-of-bounds read error and read the contents of memory on the system.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -1378,7 +1633,7 @@

    References

    -

    CVE-2023-43786

    +

    Loop with Unreachable Exit Condition ('Infinite Loop')

    @@ -1479,12 +1734,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an infinite loop within the PutSubImage() function. This flaw allows a local user to consume all available system resources and cause a denial of service condition.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -1495,7 +1754,7 @@

    References

    -

    CVE-2023-43787

    +

    Integer Overflow or Wraparound

    @@ -1596,12 +1855,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an integer overflow within the XCreateImage() function. This flaw allows a local user to trigger an integer overflow and execute arbitrary code with elevated privileges.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -3148,7 +3411,7 @@

    References

    -

    CVE-2023-28531

    +

    Inefficient Regular Expression Complexity

    @@ -3164,12 +3427,12 @@

    CVE-2023-28531

  • Vulnerable module: - openssh/openssh-client + openssl/libssl3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.6.15 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.6.15 and openssl/libssl3@3.0.2-0ubuntu1.10
  • @@ -3184,36 +3447,438 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@v2.6.15 - openssh/openssh-client@1:8.9p1-3ubuntu0.3 + openssl/libssl3@3.0.2-0ubuntu1.10 - - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssh.

    -

    References

    - +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + -
    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + - +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssl@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
  • + + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-28531

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssh/openssh-client +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssh.

    +

    References

    + + +
    + +
    @@ -4260,6 +4925,72 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-38546

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.6.15, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    Improper Input Validation

    diff --git a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html index 29faf943e9997..9145ccc25b134 100644 --- a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:28:07 am (UTC+00:00)

    +

    October 15th 2023, 12:27:08 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-iac-install.html b/docs/snyk/v2.7.14/argocd-iac-install.html index 9426ec11661c9..2ec1b5c084982 100644 --- a/docs/snyk/v2.7.14/argocd-iac-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:26:17 am (UTC+00:00)

    +

    October 15th 2023, 12:25:57 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html index cac575c912b80..7eb1bed27e1fe 100644 --- a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:26:27 am (UTC+00:00)

    +

    October 15th 2023, 12:26:08 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-test.html b/docs/snyk/v2.7.14/argocd-test.html index 982aad86d898a..0ac0a0289e1fa 100644 --- a/docs/snyk/v2.7.14/argocd-test.html +++ b/docs/snyk/v2.7.14/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:24:22 am (UTC+00:00)

    +

    October 15th 2023, 12:23:35 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    7 known vulnerabilities
    -
    20 vulnerable dependency paths
    +
    9 known vulnerabilities
    +
    161 vulnerable dependency paths
    1748 dependencies
    @@ -627,6 +627,2691 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and google.golang.org/grpc@1.51.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@#16092bd1d58a + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.31.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig@1.11.1 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.51.0 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.51.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.24.2 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/soheilhy/cmux@0.1.5 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@#16092bd1d58a + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#a4dd357b057e + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.31.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.11.1 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@#16092bd1d58a + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f754726f03da + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#a4dd357b057e + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.51.0 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.51.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.51.0 + + google.golang.org/grpc/health/grpc_health_v1@1.51.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f754726f03da + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f754726f03da + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/resource@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.11.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.24.2 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.24.2 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/manager@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/recorder@0.11.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.11.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/tools/reference@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/resource@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#f754726f03da + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.3.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.3.0 + + google.golang.org/grpc@1.51.0 + + google.golang.org/grpc/internal/transport@1.51.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/meta/v1@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#f754726f03da + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#ad9a694fe4bc + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/common@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/common@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#f754726f03da + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/hook@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/sync/common@#ad9a694fe4bc + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#ad9a694fe4bc + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/objectutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Directory Traversal

    diff --git a/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html index 1e52f40708930..0227ad9f0c750 100644 --- a/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:24:28 am (UTC+00:00)

    +

    October 15th 2023, 12:23:43 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    25 known vulnerabilities
    -
    68 vulnerable dependency paths
    +
    27 known vulnerabilities
    +
    72 vulnerable dependency paths
    786 dependencies
    @@ -583,6 +583,170 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/grpc@v1.46.2 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/grpc@v1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + golang.org/x/net/http2@v0.7.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Improper Authentication

    diff --git a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html index c65a210dd1d1e..abf669350cd1a 100644 --- a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:24:32 am (UTC+00:00)

    +

    October 15th 2023, 12:23:47 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html index bb59744cabf07..2bf2450f0d958 100644 --- a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html +++ b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:24:51 am (UTC+00:00)

    +

    October 15th 2023, 12:24:23 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    33 known vulnerabilities
    -
    125 vulnerable dependency paths
    +
    39 known vulnerabilities
    +
    148 vulnerable dependency paths
    2065 dependencies
    @@ -476,6 +476,79 @@

    Snyk test report

    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.51.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + google.golang.org/grpc@v1.51.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +

    Denial of Service (DoS)

    @@ -554,6 +627,88 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.11.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    • + Introduced through: + helm.sh/helm/v3@* + + golang.org/x/net/http2@v0.5.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Denial of Service (DoS)

    @@ -719,6 +874,9 @@

    References

  • secalert@redhat.com
  • secalert@redhat.com
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com

  • @@ -823,6 +981,99 @@

    References

    More about this vulnerability

    +
    +
    +

    Heap-based Buffer Overflow

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.7.14, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. + The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. + Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    +

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    +

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    +

    Note:

    +

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. + Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    +

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    +
      +
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: + CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      +
    2. +
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      +
    4. +
    +

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    +
      +
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      +
    2. +
    3. Environment variables as described in the libcurl section.

      +
    4. +
    +

    Changelog:

    +

    2023-10-04: Initial publication

    +

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    CVE-2020-22916

    @@ -1018,7 +1269,7 @@

    References

    -

    CVE-2023-43785

    +

    Out-of-bounds Read

    @@ -1119,12 +1370,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to a boundary condition within the _XkbReadKeySyms() function. This flaw allows a local user to trigger an out-of-bounds read error and read the contents of memory on the system.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -1135,7 +1390,7 @@

    References

    -

    CVE-2023-43786

    +

    Loop with Unreachable Exit Condition ('Infinite Loop')

    @@ -1236,12 +1491,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an infinite loop within the PutSubImage() function. This flaw allows a local user to consume all available system resources and cause a denial of service condition.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -1252,7 +1511,7 @@

    References

    -

    CVE-2023-43787

    +

    Integer Overflow or Wraparound

    @@ -1353,12 +1612,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an integer overflow within the XCreateImage() function. This flaw allows a local user to trigger an integer overflow and execute arbitrary code with elevated privileges.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -2617,7 +2880,7 @@

    References

    -

    CVE-2023-28531

    +

    Inefficient Regular Expression Complexity

    @@ -2633,12 +2896,12 @@

    CVE-2023-28531

  • Vulnerable module: - openssh/openssh-client + openssl/libssl3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.7.14 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.7.14 and openssl/libssl3@3.0.2-0ubuntu1.10
  • @@ -2653,36 +2916,438 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@v2.7.14 - openssh/openssh-client@1:8.9p1-3ubuntu0.3 + openssl/libssl3@3.0.2-0ubuntu1.10 - - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssh.

    -

    References

    - +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + -
    +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + - +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssl@3.0.2-0ubuntu1.10 + + + +
  • +
  • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
  • + + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-28531

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssh/openssh-client +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssh.

    +

    References

    + + +
    + +
    @@ -3729,6 +4394,72 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-38546

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.7.14, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    Improper Input Validation

    diff --git a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html index 048f0935ffe28..69df11ccdc4a9 100644 --- a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:24:55 am (UTC+00:00)

    +

    October 15th 2023, 12:24:30 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/argocd-iac-install.html b/docs/snyk/v2.8.4/argocd-iac-install.html index bb000f12fa479..f7ede8ff7e0aa 100644 --- a/docs/snyk/v2.8.4/argocd-iac-install.html +++ b/docs/snyk/v2.8.4/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:23:52 am (UTC+00:00)

    +

    October 15th 2023, 12:22:59 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html b/docs/snyk/v2.8.4/argocd-iac-namespace-install.html index 9794d757c19bc..e4cfddbb16d3b 100644 --- a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.8.4/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:24:02 am (UTC+00:00)

    +

    October 15th 2023, 12:23:11 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/argocd-test.html b/docs/snyk/v2.8.4/argocd-test.html index 7f92a47fa3e28..1de80ab7cac2f 100644 --- a/docs/snyk/v2.8.4/argocd-test.html +++ b/docs/snyk/v2.8.4/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:21:43 am (UTC+00:00)

    +

    October 15th 2023, 12:20:42 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    5 known vulnerabilities
    -
    18 vulnerable dependency paths
    +
    7 known vulnerabilities
    +
    161 vulnerable dependency paths
    1851 dependencies
    @@ -476,6 +476,2657 @@

    Snyk test report

    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and google.golang.org/grpc@1.56.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.1 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.56.1 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.56.1 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig@1.16.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.1 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.56.1 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.1 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.56.1 + + google.golang.org/grpc/health/grpc_health_v1@1.56.1 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.24.2 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/soheilhy/cmux@0.1.5 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.1 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.1 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.56.1 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.1 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.56.1 + + google.golang.org/grpc/health/grpc_health_v1@1.56.1 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/resource@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.11.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.24.2 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.24.2 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.11.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/resource@#425d65e07695 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/tools/reference@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#425d65e07695 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.1 + + google.golang.org/grpc/internal/transport@1.56.1 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/meta/v1@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#425d65e07695 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/manager@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + + +

    MPL-2.0 license

    diff --git a/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html index bc933434ce92f..8317707e30243 100644 --- a/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:21:50 am (UTC+00:00)

    +

    October 15th 2023, 12:20:56 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    25 known vulnerabilities
    -
    68 vulnerable dependency paths
    +
    27 known vulnerabilities
    +
    72 vulnerable dependency paths
    786 dependencies
    @@ -583,6 +583,170 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/grpc@v1.46.2 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/grpc@v1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + golang.org/x/net/http2@v0.7.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Improper Authentication

    diff --git a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html b/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html index 28bdc3254037b..07dbf17451bd3 100644 --- a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:21:55 am (UTC+00:00)

    +

    October 15th 2023, 12:21:02 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html b/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html index a42469bb1abe7..3fa6411766044 100644 --- a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html +++ b/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:22:17 am (UTC+00:00)

    +

    October 15th 2023, 12:21:24 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    31 known vulnerabilities
    -
    122 vulnerable dependency paths
    +
    37 known vulnerabilities
    +
    145 vulnerable dependency paths
    2116 dependencies
    @@ -476,6 +476,161 @@

    Snyk test report

    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.56.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + google.golang.org/grpc@v1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.11.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    • + Introduced through: + helm.sh/helm/v3@* + + golang.org/x/net/http2@v0.8.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + + +

    Out-of-bounds Write

    +
    +
    +

    Heap-based Buffer Overflow

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.8.4, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. + The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. + Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    +

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    +

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    +

    Note:

    +

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. + Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    +

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    +
      +
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: + CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      +
    2. +
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      +
    4. +
    +

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    +
      +
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      +
    2. +
    3. Environment variables as described in the libcurl section.

      +
    4. +
    +

    Changelog:

    +

    2023-10-04: Initial publication

    +

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    CVE-2020-22916

    @@ -850,7 +1101,7 @@

    References

    -

    CVE-2023-43785

    +

    Out-of-bounds Read

    @@ -951,12 +1202,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to a boundary condition within the _XkbReadKeySyms() function. This flaw allows a local user to trigger an out-of-bounds read error and read the contents of memory on the system.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -967,7 +1222,7 @@

    References

    -

    CVE-2023-43786

    +

    Loop with Unreachable Exit Condition ('Infinite Loop')

    @@ -1068,12 +1323,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an infinite loop within the PutSubImage() function. This flaw allows a local user to consume all available system resources and cause a denial of service condition.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -1084,7 +1343,7 @@

    References

    -

    CVE-2023-43787

    +

    Integer Overflow or Wraparound

    @@ -1185,12 +1444,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an integer overflow within the XCreateImage() function. This flaw allows a local user to trigger an integer overflow and execute arbitrary code with elevated privileges.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -2440,7 +2703,7 @@

    References

    -

    CVE-2023-28531

    +

    Inefficient Regular Expression Complexity

    @@ -2456,12 +2719,12 @@

    CVE-2023-28531

  • Vulnerable module: - openssh/openssh-client + openssl/libssl3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.8.4 and openssl/libssl3@3.0.2-0ubuntu1.10
  • @@ -2476,76 +2739,478 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@v2.8.4 - openssh/openssh-client@1:8.9p1-3ubuntu0.3 + openssl/libssl3@3.0.2-0ubuntu1.10 - - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssh.

    -

    References

    - - -
    - - - -
    -
    -

    NULL Pointer Dereference

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openldap/libldap-2.5-0 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.8.4, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
    • Introduced through: docker-image|quay.io/argoproj/argocd@v2.8.4 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-28531

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssh/openssh-client +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssh.

    +

    References

    + + +
    + + + +
    +
    +

    NULL Pointer Dereference

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openldap/libldap-2.5-0 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.8.4, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -3552,6 +4217,72 @@

      References

      More about this vulnerability

    +
    +
    +

    CVE-2023-38546

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.8.4, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    Improper Input Validation

    diff --git a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html b/docs/snyk/v2.8.4/redis_7.0.11-alpine.html index 43ea5cbef33d5..3a5dc5021f2e9 100644 --- a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.8.4/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:22:21 am (UTC+00:00)

    +

    October 15th 2023, 12:21:29 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html b/docs/snyk/v2.9.0-rc2/argocd-iac-install.html index 2f6b57aae9818..34bc0c556c3d0 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html +++ b/docs/snyk/v2.9.0-rc2/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:21:14 am (UTC+00:00)

    +

    October 15th 2023, 12:20:10 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html b/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html index 3f6c7b2a9cbd4..b55f00109791b 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:21:23 am (UTC+00:00)

    +

    October 15th 2023, 12:20:21 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-test.html b/docs/snyk/v2.9.0-rc2/argocd-test.html index b73a0c715912e..7e647f138369b 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-test.html +++ b/docs/snyk/v2.9.0-rc2/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:18:53 am (UTC+00:00)

    +

    October 15th 2023, 12:17:43 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    5 known vulnerabilities
    -
    18 vulnerable dependency paths
    +
    7 known vulnerabilities
    +
    166 vulnerable dependency paths
    1920 dependencies
    @@ -476,6 +476,2746 @@

    Snyk test report

    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and google.golang.org/grpc@1.56.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig@1.16.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.56.2 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.56.2 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 + + github.com/grpc-ecosystem/grpc-gateway/v2/runtime@2.11.3 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.2 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.24.2 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/soheilhy/cmux@0.1.5 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#9dcecdc3eebf + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/rbac/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/reflection@1.56.2 + + google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.2 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + google.golang.org/grpc/health@1.56.2 + + google.golang.org/grpc/health/grpc_health_v1@1.56.2 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#9dcecdc3eebf + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/resource@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/testing@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/scheme@0.11.0 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/resource@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/util/retry@0.24.2 + + k8s.io/apimachinery/pkg/api/errors@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/portforward@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.24.2 + + k8s.io/apimachinery/pkg/api/equality@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/api/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/fake@0.24.2 + + k8s.io/client-go/testing@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/health@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.11.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/auth@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/diff@#b0fffe419a0f + + k8s.io/apimachinery/pkg/util/managedfields@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/resource@#b0fffe419a0f + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/core/v1@0.24.2 + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/record@0.24.2 + + k8s.io/client-go/tools/reference@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#9dcecdc3eebf + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers/apps/v1@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/informers@0.24.2 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#9dcecdc3eebf + + k8s.io/client-go/listers/core/v1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/term@0.24.2 + + k8s.io/client-go/tools/remotecommand@0.24.2 + + k8s.io/client-go/transport/spdy@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + k8s.io/client-go/transport@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 + + github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 + + google.golang.org/grpc@1.56.2 + + google.golang.org/grpc/internal/transport@1.56.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/storage/v1beta1@0.24.2 + + k8s.io/client-go/applyconfigurations/meta/v1@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/hook@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/manager@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 + + k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#9dcecdc3eebf + + k8s.io/client-go/tools/clientcmd@0.24.2 + + k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 + + k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + k8s.io/client-go/kubernetes@0.24.2 + + k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#b0fffe419a0f + + k8s.io/kubernetes/pkg/apis/storage/install@1.24.2 + + k8s.io/kubernetes/pkg/apis/storage/v1alpha1@1.24.2 + + k8s.io/api/storage/v1alpha1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync/ignore@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/hook@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/sync/common@#b0fffe419a0f + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/client-go/rest@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/cache@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/sync@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/gitops-engine/pkg/utils/kube@#b0fffe419a0f + + k8s.io/kubectl/pkg/util/openapi@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 + + k8s.io/client-go/tools/cache@0.24.2 + + k8s.io/client-go/tools/pager@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 + + k8s.io/client-go/restmapper@0.24.2 + + k8s.io/client-go/discovery@0.24.2 + + k8s.io/client-go/kubernetes/scheme@0.24.2 + + k8s.io/api/storage/v1beta1@0.24.2 + + k8s.io/api/core/v1@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + sigs.k8s.io/controller-runtime/pkg/controller@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/event@0.11.0 + + sigs.k8s.io/controller-runtime/pkg/client@0.11.0 + + k8s.io/client-go/dynamic@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 + + k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 + + k8s.io/apimachinery/pkg/watch@0.24.2 + + k8s.io/apimachinery/pkg/util/net@0.24.2 + + golang.org/x/net/http2@0.15.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + + +

    MPL-2.0 license

    diff --git a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html index 0c8d8bdcd8f12..2051e0965c34d 100644 --- a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:19:01 am (UTC+00:00)

    +

    October 15th 2023, 12:17:51 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    25 known vulnerabilities
    -
    68 vulnerable dependency paths
    +
    27 known vulnerabilities
    +
    72 vulnerable dependency paths
    786 dependencies
    @@ -583,6 +583,170 @@

    References

    More about this vulnerability

    +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and google.golang.org/grpc@v1.46.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + google.golang.org/grpc@v1.46.2 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + google.golang.org/grpc@v1.56.1 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/hairyhenderson/gomplate/v3@* and golang.org/x/net/http2@v0.7.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/hairyhenderson/gomplate/v3@* + + golang.org/x/net/http2@v0.7.0 + + + +
    • +
    • + Introduced through: + github.com/dexidp/dex@* + + golang.org/x/net/http2@v0.11.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + +

    Improper Authentication

    diff --git a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html b/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html index 9639db40d48fe..20f19d4becc2e 100644 --- a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:19:04 am (UTC+00:00)

    +

    October 15th 2023, 12:17:55 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html b/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html index 5af817b2532e1..0aab8254e5f9e 100644 --- a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html +++ b/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:19:25 am (UTC+00:00)

    +

    October 15th 2023, 12:18:18 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    31 known vulnerabilities
    -
    122 vulnerable dependency paths
    +
    37 known vulnerabilities
    +
    145 vulnerable dependency paths
    2270 dependencies
    @@ -476,6 +476,161 @@

    Snyk test report

    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + google.golang.org/grpc +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.56.2 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + google.golang.org/grpc@v1.56.2 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    google.golang.org/grpc is a Go implementation of gRPC

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    +

    References

    + + +
    + + + +
    +
    +

    Denial of Service (DoS)

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Vulnerable module: + + golang.org/x/net/http2 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.15.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + golang.org/x/net/http2@v0.15.0 + + + +
    • +
    • + Introduced through: + helm.sh/helm/v3@* + + golang.org/x/net/http2@v0.8.0 + + + +
    • +
    + +
    + +
    + +

    Overview

    +

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    +

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    +

    Remediation

    +

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    +

    References

    + + +
    + + + +

    Out-of-bounds Write

    +
    +
    +

    Heap-based Buffer Overflow

    +
    + +
    + high severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. + The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. + Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    +

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    +

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    +

    Note:

    +

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. + Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    +

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    +
      +
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: + CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      +
    2. +
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      +
    4. +
    +

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    +
      +
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      +
    2. +
    3. Environment variables as described in the libcurl section.

      +
    4. +
    +

    Changelog:

    +

    2023-10-04: Initial publication

    +

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    CVE-2020-22916

    @@ -850,7 +1101,7 @@

    References

    -

    CVE-2023-43785

    +

    Out-of-bounds Read

    @@ -951,12 +1202,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to a boundary condition within the _XkbReadKeySyms() function. This flaw allows a local user to trigger an out-of-bounds read error and read the contents of memory on the system.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -967,7 +1222,7 @@

    References

    -

    CVE-2023-43786

    +

    Loop with Unreachable Exit Condition ('Infinite Loop')

    @@ -1068,12 +1323,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an infinite loop within the PutSubImage() function. This flaw allows a local user to consume all available system resources and cause a denial of service condition.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -1084,7 +1343,7 @@

    References

    -

    CVE-2023-43787

    +

    Integer Overflow or Wraparound

    @@ -1185,12 +1444,16 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A vulnerability was found in libX11 due to an integer overflow within the XCreateImage() function. This flaw allows a local user to trigger an integer overflow and execute arbitrary code with elevated privileges.

    Remediation

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    References


    @@ -2440,7 +2703,7 @@

    References

    -

    CVE-2023-28531

    +

    Inefficient Regular Expression Complexity

    @@ -2456,12 +2719,12 @@

    CVE-2023-28531

  • Vulnerable module: - openssh/openssh-client + openssl/libssl3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssh/openssh-client@1:8.9p1-3ubuntu0.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssl/libssl3@3.0.2-0ubuntu1.10
  • @@ -2476,76 +2739,478 @@

    Detailed paths

    Introduced through: docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - openssh/openssh-client@1:8.9p1-3ubuntu0.4 + openssl/libssl3@3.0.2-0ubuntu1.10 - - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssh.

    -

    References

    - - -
    - - - -
    -
    -

    NULL Pointer Dereference

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openldap/libldap-2.5-0 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
    • Introduced through: docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - gnupg2/dirmngr@2.2.27-3ubuntu2.1 + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. One of those + checks confirms that the modulus ('p' parameter) is not too large. Trying to use + a very large modulus is slow and OpenSSL will not normally use a modulus which + is over 10,000 bits in length.

    +

    However the DH_check() function checks numerous aspects of the key or parameters + that have been supplied. Some of those checks use the supplied modulus value + even if it has already been found to be too large.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulernable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the '-check' option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue. + The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    Excessive Iteration

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    +

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() + or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long + delays. Where the key or parameters that are being checked have been obtained + from an untrusted source this may lead to a Denial of Service.

    +

    The function DH_check() performs various checks on DH parameters. After fixing + CVE-2023-3446 it was discovered that a large q parameter value can also trigger + an overly long computation during some of these checks. A correct q value, + if present, cannot be larger than the modulus p parameter, thus it is + unnecessary to perform these checks if q is larger than p.

    +

    An application that calls DH_check() and supplies a key or parameters obtained + from an untrusted source could be vulnerable to a Denial of Service attack.

    +

    The function DH_check() is itself called by a number of other OpenSSL functions. + An application calling any of those other functions may similarly be affected. + The other functions affected by this are DH_check_ex() and + EVP_PKEY_param_check().

    +

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications + when using the "-check" option.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    References

    + + +
    + + + +
    +
    +

    CVE-2023-28531

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssh/openssh-client +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssh/openssh-client@1:8.9p1-3ubuntu0.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssh package and not the openssh package as distributed by Ubuntu:22.04. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    ssh-add in OpenSSH before 9.3 adds smartcard keys to ssh-agent without the intended per-hop destination constraints. The earliest affected version is 8.9.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 openssh.

    +

    References

    + + +
    + + + +
    +
    +

    NULL Pointer Dereference

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openldap/libldap-2.5-0 +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + gnupg2/dirmngr@2.2.27-3ubuntu2.1 openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -3552,6 +4217,72 @@

      References

      More about this vulnerability

    +
    +
    +

    CVE-2023-38546

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + curl/libcurl3-gnutls +
    • + +
    • Introduced through: + + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    This vulnerability has not been analyzed by NVD yet.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    +

    References

    + + +
    + + +

    Improper Input Validation

    diff --git a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html b/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html index 915b9188485f4..6cb08e277c738 100644 --- a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 8th 2023, 12:19:35 am (UTC+00:00)

    +

    October 15th 2023, 12:18:24 am (UTC+00:00)

    Scanned the following path: From 614a2531b0177b63d8887751fbe1f086dd416581 Mon Sep 17 00:00:00 2001 From: ericblackburn Date: Mon, 16 Oct 2023 16:43:13 -0400 Subject: [PATCH 011/269] fix(appset): performProgressiveSyncs only when the applicationset is using it (#15299) Signed-off-by: Eric Blackburn --- applicationset/controllers/applicationset_controller.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 60bab2564d92c..89357639c6dda 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -163,13 +163,15 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque if r.EnableProgressiveSyncs { if applicationSetInfo.Spec.Strategy == nil && len(applicationSetInfo.Status.ApplicationStatus) > 0 { + // If appset used progressive sync but stopped, clean up the progressive sync application statuses log.Infof("Removing %v unnecessary AppStatus entries from ApplicationSet %v", len(applicationSetInfo.Status.ApplicationStatus), applicationSetInfo.Name) err := r.setAppSetApplicationStatus(ctx, &applicationSetInfo, []argov1alpha1.ApplicationSetApplicationStatus{}) if err != nil { return ctrl.Result{}, fmt.Errorf("failed to clear previous AppSet application statuses for %v: %w", applicationSetInfo.Name, err) } - } else { + } else if applicationSetInfo.Spec.Strategy != nil { + // appset uses progressive sync applications, err := r.getCurrentApplications(ctx, applicationSetInfo) if err != nil { return ctrl.Result{}, fmt.Errorf("failed to get current applications for application set: %w", err) From da57e03ccedee48806115064c7cb78c2611f1d1d Mon Sep 17 00:00:00 2001 From: Kota Kimura <86363983+kkk777-7@users.noreply.github.com> Date: Tue, 17 Oct 2023 05:46:06 +0900 Subject: [PATCH 012/269] fix: helm set parameter to allow passing list parameters (#15978) Signed-off-by: kkk777-7 --- util/helm/cmd.go | 4 ++++ util/helm/helm_test.go | 1 + 2 files changed, 5 insertions(+) diff --git a/util/helm/cmd.go b/util/helm/cmd.go index f8240d555217e..419c7daff5d3c 100644 --- a/util/helm/cmd.go +++ b/util/helm/cmd.go @@ -274,6 +274,10 @@ var ( ) func cleanSetParameters(val string) string { + // `{}` equal helm list parameters format, so don't escape `,`. + if strings.HasPrefix(val, `{`) && strings.HasSuffix(val, `}`) { + return val + } return re.ReplaceAllString(val, `$1\,`) } diff --git a/util/helm/helm_test.go b/util/helm/helm_test.go index ab8e3bc58008c..a91968e45b5b4 100644 --- a/util/helm/helm_test.go +++ b/util/helm/helm_test.go @@ -165,6 +165,7 @@ func TestHelmArgCleaner(t *testing.T) { `bar`: `bar`, `not, clean`: `not\, clean`, `a\,b,c`: `a\,b\,c`, + `{a,b,c}`: `{a,b,c}`, } { cleaned := cleanSetParameters(input) assert.Equal(t, expected, cleaned) From f7788a71e342d44363293f289b96a53a8511b15e Mon Sep 17 00:00:00 2001 From: Yudi A Phanama <11147376+phanama@users.noreply.github.com> Date: Tue, 17 Oct 2023 19:10:39 +0700 Subject: [PATCH 013/269] fix(grpcproxy): add GRPCKeepAliveEnforcementMinimum (#15708) the absence of the setting potentially causes ENHANCE_YOUR_CALM Signed-off-by: phanama Co-authored-by: Dan Garfield --- pkg/apiclient/grpcproxy.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/apiclient/grpcproxy.go b/pkg/apiclient/grpcproxy.go index 9e5b841ae273a..dcbb3b296833e 100644 --- a/pkg/apiclient/grpcproxy.go +++ b/pkg/apiclient/grpcproxy.go @@ -13,9 +13,11 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + "github.com/argoproj/argo-cd/v2/common" argocderrors "github.com/argoproj/argo-cd/v2/util/errors" argoio "github.com/argoproj/argo-cd/v2/util/io" "github.com/argoproj/argo-cd/v2/util/rand" @@ -112,6 +114,11 @@ func (c *client) startGRPCProxy() (*grpc.Server, net.Listener, error) { } proxySrv := grpc.NewServer( grpc.ForceServerCodec(&noopCodec{}), + grpc.KeepaliveEnforcementPolicy( + keepalive.EnforcementPolicy{ + MinTime: common.GRPCKeepAliveEnforcementMinimum, + }, + ), grpc.UnknownServiceHandler(func(srv interface{}, stream grpc.ServerStream) error { fullMethodName, ok := grpc.MethodFromServerStream(stream) if !ok { From df32338a72845698890db34ae77c6eea8541a95a Mon Sep 17 00:00:00 2001 From: Shaurya Gulati Date: Tue, 17 Oct 2023 17:49:54 +0530 Subject: [PATCH 014/269] feat: Add examples to --help output for "delete PROJECT ROLE-NAME" (#15986) * feat: Add examples to --help output for delete PROJECT ROLE-NAME Signed-off-by: Shauryagulati --------- Signed-off-by: Shauryagulati --- cmd/argocd/commands/project_role.go | 6 ++++++ docs/user-guide/commands/argocd_proj_role_delete.md | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index 987e61914d858..ecc7d670ce42e 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -18,6 +18,7 @@ import ( "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/io" "github.com/argoproj/argo-cd/v2/util/jwt" + "github.com/argoproj/argo-cd/v2/util/templates" ) const ( @@ -176,6 +177,11 @@ func NewProjectRoleDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. var command = &cobra.Command{ Use: "delete PROJECT ROLE-NAME", Short: "Delete a project role", + Example: templates.Examples(` + # Delete a project role from the "my-project" project with the name "my-role". + argocd proj role delete my-project my-role + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_proj_role_delete.md b/docs/user-guide/commands/argocd_proj_role_delete.md index 42fc14fd031b8..0d25facb22691 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete.md +++ b/docs/user-guide/commands/argocd_proj_role_delete.md @@ -8,6 +8,13 @@ Delete a project role argocd proj role delete PROJECT ROLE-NAME [flags] ``` +### Examples + +``` + # Delete a project role from the "my-project" project with the name "my-role". + argocd proj role delete my-project my-role +``` + ### Options ``` From 1a43ff6cb3bae5aa07a1e01f459d1aaeb96f39c5 Mon Sep 17 00:00:00 2001 From: Gaurang Kudale Date: Wed, 18 Oct 2023 07:02:35 +0530 Subject: [PATCH 015/269] feat(cli): add the cluster-list-example (#15690) (#15866) --- cmd/argocd/commands/cluster.go | 17 ++++++++++++++ .../commands/argocd_cluster_list.md | 22 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/cmd/argocd/commands/cluster.go b/cmd/argocd/commands/cluster.go index a1d1589540af0..3df4be6632d85 100644 --- a/cmd/argocd/commands/cluster.go +++ b/cmd/argocd/commands/cluster.go @@ -485,6 +485,23 @@ func NewClusterListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comman errors.CheckError(fmt.Errorf("unknown output format: %s", output)) } }, + Example: ` +# List Clusters in Default "Wide" Format +argocd cluster list + +# List Cluster via specifing the server +argocd cluster list --server + +# List Clusters in JSON Format +argocd cluster list -o json --server + +# List Clusters in YAML Format +argocd cluster list -o yaml --server + +# List Clusters that have been added to your Argo CD +argocd cluster list -o server + +`, } command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|server") return command diff --git a/docs/user-guide/commands/argocd_cluster_list.md b/docs/user-guide/commands/argocd_cluster_list.md index aa5e090f4f4bd..9779a4fb8af0b 100644 --- a/docs/user-guide/commands/argocd_cluster_list.md +++ b/docs/user-guide/commands/argocd_cluster_list.md @@ -8,6 +8,28 @@ List configured clusters argocd cluster list [flags] ``` +### Examples + +``` + +# List Clusters in Default "Wide" Format +argocd cluster list + +# List Cluster via specifing the server +argocd cluster list --server + +# List Clusters in JSON Format +argocd cluster list -o json --server + +# List Clusters in YAML Format +argocd cluster list -o yaml --server + +# List Clusters that have been added to your Argo CD +argocd cluster list -o server + + +``` + ### Options ``` From f7a353a8295faf27e18f59cc1369cec2941974d2 Mon Sep 17 00:00:00 2001 From: Gaurang Kudale Date: Wed, 18 Oct 2023 08:15:48 +0530 Subject: [PATCH 016/269] feat(cli): add the repocred-list-example (#15690) (#15869) * update the repocreds-list changes Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale * update the string Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale --------- Signed-off-by: Gaurang Kudale --- cmd/argocd/commands/repocreds.go | 10 ++++++++-- docs/user-guide/commands/argocd_repocreds_list.md | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/cmd/argocd/commands/repocreds.go b/cmd/argocd/commands/repocreds.go index cf764e7d84de9..e43b9713a2927 100644 --- a/cmd/argocd/commands/repocreds.go +++ b/cmd/argocd/commands/repocreds.go @@ -247,11 +247,17 @@ func NewRepoCredsListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm Use: "list", Short: "List configured repository credentials", Example: templates.Examples(` - # List all the configured repository credentials + # List all repo urls argocd repocreds list - # List all the configured repository credentials in json format + # List all repo urls in json format argocd repocreds list -o json + + # List all repo urls in yaml format + argocd repocreds list -o yaml + + # List all repo urls in url format + argocd repocreds list -o url `), Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_repocreds_list.md b/docs/user-guide/commands/argocd_repocreds_list.md index 4db3506d3f580..ae358afab2056 100644 --- a/docs/user-guide/commands/argocd_repocreds_list.md +++ b/docs/user-guide/commands/argocd_repocreds_list.md @@ -11,11 +11,17 @@ argocd repocreds list [flags] ### Examples ``` - # List all the configured repository credentials + # List all repo urls argocd repocreds list - # List all the configured repository credentials in json format + # List all repo urls in json format argocd repocreds list -o json + + # List all repo urls in yaml format + argocd repocreds list -o yaml + + # List all repo urls in url format + argocd repocreds list -o url ``` ### Options From 5b07a126785e194f1701b725915642f6c63ce73f Mon Sep 17 00:00:00 2001 From: Ratan Gulati Date: Wed, 18 Oct 2023 08:17:55 +0530 Subject: [PATCH 017/269] feat: Add examples to --help output for remaining "get APPNAME" (#15862) * feat: Add examples to --help output for get APPNAME Signed-off-by: Ratan Gulati * feat: Add examples to --help output for get APPNAME Signed-off-by: Ratan Gulati * Update app.go Signed-off-by: Ratan Gulati * Update argocd_app_get.md Signed-off-by: Ratan Gulati * Update argocd_app_get.md Signed-off-by: Ratan Gulati * updated app.go Signed-off-by: Ratan Gulati * Update app.go Signed-off-by: Ratan Gulati * Update argocd_app_get.md Signed-off-by: Ratan Gulati * Update app.go Signed-off-by: Ratan Gulati * docs: clarify health inheritance (#15799) * docs: resource health inheritance Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * write more better Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Ratan Gulati * updated file Signed-off-by: Ratan Gulati * Update app.go Signed-off-by: Ratan Gulati * updated get-APPNAME Signed-off-by: Ratan Gulati * updated get-APPNAME Signed-off-by: Ratan Gulati --------- Signed-off-by: Ratan Gulati Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- cmd/argocd/commands/app.go | 29 ++++++++++++++++++++ docs/user-guide/commands/argocd_app_get.md | 31 ++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 55ed2ee8790f3..a8872ffc9774c 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -318,6 +318,35 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com var command = &cobra.Command{ Use: "get APPNAME", Short: "Get application details", + Example: templates.Examples(` + # Get basic details about the application "my-app" in wide format + argocd app get my-app -o wide + + # Get detailed information about the application "my-app" in YAML format + argocd app get my-app -o yaml + + # Get details of the application "my-app" in JSON format + argocd get my-app -o json + + # Get application details and include information about the current operation + argocd app get my-app --show-operation + + # Show application parameters and overrides + argocd app get my-app --show-params + + # Refresh application data when retrieving + argocd app get my-app --refresh + + # Perform a hard refresh, including refreshing application data and target manifests cache + argocd app get my-app --hard-refresh + + # Get application details and display them in a tree format + argocd app get my-app --output tree + + # Get application details and display them in a detailed tree format + argocd app get my-app --output tree=detailed + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() if len(args) == 0 { diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index 33787d8083f22..cf766ed9eb0d7 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -8,6 +8,37 @@ Get application details argocd app get APPNAME [flags] ``` +### Examples + +``` + # Get basic details about the application "my-app" in wide format + argocd app get my-app -o wide + + # Get detailed information about the application "my-app" in YAML format + argocd app get my-app -o yaml + + # Get details of the application "my-app" in JSON format + argocd get my-app -o json + + # Get application details and include information about the current operation + argocd app get my-app --show-operation + + # Show application parameters and overrides + argocd app get my-app --show-params + + # Refresh application data when retrieving + argocd app get my-app --refresh + + # Perform a hard refresh, including refreshing application data and target manifests cache + argocd app get my-app --hard-refresh + + # Get application details and display them in a tree format + argocd app get my-app --output tree + + # Get application details and display them in a detailed tree format + argocd app get my-app --output tree=detailed +``` + ### Options ``` From 9e0e8d5e8a055ccc93b0bfbedcfa2eee91aaf5d3 Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Wed, 18 Oct 2023 17:17:00 +0200 Subject: [PATCH 018/269] chore(deps): upgrade k8s version and client-go (#15852) * chore(deps): upgrade k8s version and client-go Signed-off-by: fengshunli <1171313930@qq.com> * revert bad merge Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix codegen Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix codegen Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix: check for double definition As found in #13965 (and as a follow-up to #13999), we also need to define what happens if _both_ managedNamespaceMetadata _and_ an Application manifest are both defined for the same namespace. The idea here is that if that happens, we emit an `ApplicationConditionRepeatedResourceWarning`, and set the sync status to `Unknown`, since it's unclear what is supposed to happen. The user will then have the option of removing one of the two definitions. Signed-off-by: Blake Pettersson * fix: check for double definition A simpler fix - don't add a managed namespace to the targetObjs list if a namespace already exists in the application source. Signed-off-by: Blake Pettersson * build: extra space in doc Signed-off-by: Blake Pettersson * build: extra space in doc, again Signed-off-by: Blake Pettersson * chore: bump gitops-engine Signed-off-by: Blake Pettersson --------- Signed-off-by: fengshunli <1171313930@qq.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Blake Pettersson Co-authored-by: fengshunli <1171313930@qq.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .../controllers/applicationset_controller.go | 32 +- .../applicationset_controller_test.go | 28 +- applicationset/utils/clusterUtils.go | 2 +- assets/swagger.json | 8 +- cmd/argocd/commands/admin/cluster.go | 2 +- cmd/argocd/commands/app.go | 10 +- cmd/util/app.go | 2 +- cmd/util/project.go | 2 +- controller/appcontroller.go | 15 +- controller/state.go | 13 +- .../notifications/troubleshooting-commands.md | 4 + .../argocd-application-controller.md | 1 + .../server-commands/argocd-dex_gendexcfg.md | 1 + .../server-commands/argocd-dex_rundex.md | 1 + .../server-commands/argocd-server.md | 1 + .../server-commands/argocd-server_version.md | 1 + docs/operator-manual/upgrading/2.8-2.9.md | 12 + docs/operator-manual/upgrading/overview.md | 1 + docs/user-guide/commands/argocd_account.md | 1 + .../argocd_admin_app_get-reconcile-results.md | 1 + .../argocd_admin_cluster_kubeconfig.md | 1 + .../argocd_admin_cluster_namespaces.md | 1 + ...ster_namespaces_disable-namespaced-mode.md | 1 + ...uster_namespaces_enable-namespaced-mode.md | 1 + .../commands/argocd_admin_cluster_shards.md | 1 + .../commands/argocd_admin_cluster_stats.md | 1 + .../commands/argocd_admin_dashboard.md | 1 + .../commands/argocd_admin_export.md | 1 + .../commands/argocd_admin_import.md | 1 + .../commands/argocd_admin_initial-password.md | 1 + .../commands/argocd_admin_notifications.md | 1 + .../argocd_admin_notifications_template.md | 1 + ...argocd_admin_notifications_template_get.md | 1 + ...ocd_admin_notifications_template_notify.md | 1 + .../argocd_admin_notifications_trigger.md | 1 + .../argocd_admin_notifications_trigger_get.md | 1 + .../argocd_admin_notifications_trigger_run.md | 1 + .../argocd_admin_proj_generate-allow-list.md | 1 + .../argocd_admin_proj_update-role-policy.md | 1 + .../commands/argocd_admin_settings.md | 1 + .../commands/argocd_admin_settings_rbac.md | 1 + .../argocd_admin_settings_rbac_can.md | 1 + .../argocd_admin_settings_rbac_validate.md | 1 + ...rgocd_admin_settings_resource-overrides.md | 1 + ...dmin_settings_resource-overrides_health.md | 1 + ...s_resource-overrides_ignore-differences.md | 1 + ...ource-overrides_ignore-resource-updates.md | 1 + ...ettings_resource-overrides_list-actions.md | 1 + ..._settings_resource-overrides_run-action.md | 1 + .../argocd_admin_settings_validate.md | 1 + docs/user-guide/commands/argocd_app.md | 1 + docs/user-guide/commands/argocd_appset.md | 1 + docs/user-guide/commands/argocd_cert.md | 1 + docs/user-guide/commands/argocd_cluster.md | 1 + docs/user-guide/commands/argocd_gpg.md | 1 + docs/user-guide/commands/argocd_proj.md | 1 + docs/user-guide/commands/argocd_repo.md | 1 + docs/user-guide/commands/argocd_repocreds.md | 1 + docs/user-guide/commands/argocd_version.md | 1 + docs/user-guide/sync-options.md | 50 +- go.mod | 117 ++--- go.sum | 437 +++--------------- hack/dev-mounter/main.go | 5 +- .../generators/cluster_generator.go | 2 +- .../v1alpha1/applicationset_types_test.go | 4 +- pkg/apis/application/v1alpha1/types_test.go | 8 +- pkg/client/clientset/versioned/clientset.go | 3 +- .../informers/externalversions/factory.go | 79 +++- server/application/application.go | 11 +- server/application/application_test.go | 10 +- server/application/terminal.go | 2 +- server/cluster/cluster_test.go | 2 +- test/e2e/app_management_ns_test.go | 20 +- test/e2e/app_management_test.go | 14 +- test/e2e/project_management_test.go | 24 +- util/argo/normalizers/corev1_known_types.go | 15 + util/argo/normalizers/diffing_known_types.txt | 5 + util/db/cluster.go | 2 +- util/db/helmrepository.go | 2 +- util/db/secrets.go | 5 +- util/rbac/rbac.go | 5 +- util/settings/settings.go | 26 +- 82 files changed, 446 insertions(+), 579 deletions(-) create mode 100644 docs/operator-manual/upgrading/2.8-2.9.md diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 89357639c6dda..45b6649685e6e 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -544,22 +544,24 @@ func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate { } } -func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProgressiveSyncs bool, maxConcurrentReconciliations int) error { - if err := mgr.GetFieldIndexer().IndexField(context.TODO(), &argov1alpha1.Application{}, ".metadata.controller", func(rawObj client.Object) []string { - // grab the job object, extract the owner... - app := rawObj.(*argov1alpha1.Application) - owner := metav1.GetControllerOf(app) - if owner == nil { - return nil - } - // ...make sure it's a application set... - if owner.APIVersion != argov1alpha1.SchemeGroupVersion.String() || owner.Kind != "ApplicationSet" { - return nil - } +func appControllerIndexer(rawObj client.Object) []string { + // grab the job object, extract the owner... + app := rawObj.(*argov1alpha1.Application) + owner := metav1.GetControllerOf(app) + if owner == nil { + return nil + } + // ...make sure it's a application set... + if owner.APIVersion != argov1alpha1.SchemeGroupVersion.String() || owner.Kind != "ApplicationSet" { + return nil + } - // ...and if so, return it - return []string{owner.Name} - }); err != nil { + // ...and if so, return it + return []string{owner.Name} +} + +func (r *ApplicationSetReconciler) SetupWithManager(mgr ctrl.Manager, enableProgressiveSyncs bool, maxConcurrentReconciliations int) error { + if err := mgr.GetFieldIndexer().IndexField(context.TODO(), &argov1alpha1.Application{}, ".metadata.controller", appControllerIndexer); err != nil { return fmt.Errorf("error setting up with manager: %w", err) } diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index 7c3721e2ee6ed..d734d26ff437e 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -994,7 +994,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { initObjs = append(initObjs, &a) } - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() r := ApplicationSetReconciler{ Client: client, @@ -1088,7 +1088,7 @@ func TestRemoveFinalizerOnInvalidDestination_FinalizerTypes(t *testing.T) { initObjs := []crtclient.Object{&app, &appSet} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "my-secret", @@ -1250,7 +1250,7 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { initObjs := []crtclient.Object{&app, &appSet} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "my-secret", @@ -1482,7 +1482,7 @@ func TestCreateApplications(t *testing.T) { initObjs = append(initObjs, &a) } - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() r := ApplicationSetReconciler{ Client: client, @@ -1626,7 +1626,7 @@ func TestDeleteInCluster(t *testing.T) { initObjs = append(initObjs, &temp) } - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() r := ApplicationSetReconciler{ Client: client, @@ -2000,7 +2000,15 @@ func TestReconcilerValidationProjectErrorBehaviour(t *testing.T) { argoDBMock := dbmocks.ArgoDB{} argoObjs := []runtime.Object{&project} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} + badCluster := v1alpha1.Cluster{Server: "https://bad-cluster", Name: "bad-cluster"} + argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) + argoDBMock.On("GetCluster", mock.Anything, "https://bad-cluster").Return(&badCluster, nil) + argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ + goodCluster, + }}, nil) + r := ApplicationSetReconciler{ Client: client, Scheme: scheme, @@ -2076,7 +2084,7 @@ func TestSetApplicationSetStatusCondition(t *testing.T) { argoDBMock := dbmocks.ArgoDB{} argoObjs := []runtime.Object{} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() r := ApplicationSetReconciler{ Client: client, @@ -2146,7 +2154,7 @@ func applicationsUpdateSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp argoDBMock := dbmocks.ArgoDB{} argoObjs := []runtime.Object{&defaultProject} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ @@ -2316,7 +2324,7 @@ func applicationsDeleteSyncPolicyTest(t *testing.T, applicationsSyncPolicy v1alp argoDBMock := dbmocks.ArgoDB{} argoObjs := []runtime.Object{&defaultProject} - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() goodCluster := v1alpha1.Cluster{Server: "https://good-cluster", Name: "good-cluster"} argoDBMock.On("GetCluster", mock.Anything, "https://good-cluster").Return(&goodCluster, nil) argoDBMock.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ @@ -2627,7 +2635,7 @@ func TestPolicies(t *testing.T) { }, } - client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).Build() + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&appSet).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() r := ApplicationSetReconciler{ Client: client, diff --git a/applicationset/utils/clusterUtils.go b/applicationset/utils/clusterUtils.go index ee9832f533e5e..3b34a5a863dbd 100644 --- a/applicationset/utils/clusterUtils.go +++ b/applicationset/utils/clusterUtils.go @@ -180,7 +180,7 @@ func secretToCluster(s *corev1.Secret) (*appv1.Cluster, error) { if val, err := strconv.Atoi(string(shardStr)); err != nil { log.Warnf("Error while parsing shard in cluster secret '%s': %v", s.Name, err) } else { - shard = pointer.Int64Ptr(int64(val)) + shard = pointer.Int64(int64(val)) } } cluster := appv1.Cluster{ diff --git a/assets/swagger.json b/assets/swagger.json index ae4688966dd0c..b9d4cbf21c563 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -5089,7 +5089,7 @@ } }, "runtimeRawExtension": { - "description": "RawExtension is used to hold extensions in external versions.\n\nTo use this, make a field which has RawExtension as its type in your external, versioned\nstruct, and Object in your internal struct. You also need to register your\nvarious plugin types.\n\n// Internal package:\ntype MyAPIObject struct {\n\truntime.TypeMeta `json:\",inline\"`\n\tMyPlugin runtime.Object `json:\"myPlugin\"`\n}\ntype PluginA struct {\n\tAOption string `json:\"aOption\"`\n}\n\n// External package:\ntype MyAPIObject struct {\n\truntime.TypeMeta `json:\",inline\"`\n\tMyPlugin runtime.RawExtension `json:\"myPlugin\"`\n}\ntype PluginA struct {\n\tAOption string `json:\"aOption\"`\n}\n\n// On the wire, the JSON will look something like this:\n{\n\t\"kind\":\"MyAPIObject\",\n\t\"apiVersion\":\"v1\",\n\t\"myPlugin\": {\n\t\t\"kind\":\"PluginA\",\n\t\t\"aOption\":\"foo\",\n\t},\n}\n\nSo what happens? Decode first uses json or yaml to unmarshal the serialized data into\nyour external MyAPIObject. That causes the raw JSON to be stored, but not unpacked.\nThe next step is to copy (using pkg/conversion) into the internal struct. The runtime\npackage's DefaultScheme has conversion functions installed which will unpack the\nJSON stored in RawExtension, turning it into the correct object type, and storing it\nin the Object. (TODO: In the case where the object is of an unknown type, a\nruntime.Unknown object will be created and stored.)\n\n+k8s:deepcopy-gen=true\n+protobuf=true\n+k8s:openapi-gen=true", + "description": "RawExtension is used to hold extensions in external versions.\n\nTo use this, make a field which has RawExtension as its type in your external, versioned\nstruct, and Object in your internal struct. You also need to register your\nvarious plugin types.\n\n// Internal package:\n\n\ttype MyAPIObject struct {\n\t\truntime.TypeMeta `json:\",inline\"`\n\t\tMyPlugin runtime.Object `json:\"myPlugin\"`\n\t}\n\n\ttype PluginA struct {\n\t\tAOption string `json:\"aOption\"`\n\t}\n\n// External package:\n\n\ttype MyAPIObject struct {\n\t\truntime.TypeMeta `json:\",inline\"`\n\t\tMyPlugin runtime.RawExtension `json:\"myPlugin\"`\n\t}\n\n\ttype PluginA struct {\n\t\tAOption string `json:\"aOption\"`\n\t}\n\n// On the wire, the JSON will look something like this:\n\n\t{\n\t\t\"kind\":\"MyAPIObject\",\n\t\t\"apiVersion\":\"v1\",\n\t\t\"myPlugin\": {\n\t\t\t\"kind\":\"PluginA\",\n\t\t\t\"aOption\":\"foo\",\n\t\t},\n\t}\n\nSo what happens? Decode first uses json or yaml to unmarshal the serialized data into\nyour external MyAPIObject. That causes the raw JSON to be stored, but not unpacked.\nThe next step is to copy (using pkg/conversion) into the internal struct. The runtime\npackage's DefaultScheme has conversion functions installed which will unpack the\nJSON stored in RawExtension, turning it into the correct object type, and storing it\nin the Object. (TODO: In the case where the object is of an unknown type, a\nruntime.Unknown object will be created and stored.)\n\n+k8s:deepcopy-gen=true\n+protobuf=true\n+k8s:openapi-gen=true", "type": "object", "properties": { "raw": { @@ -5496,10 +5496,6 @@ "type": "string" } }, - "clusterName": { - "description": "Deprecated: ClusterName is a legacy field that was always cleared by\nthe system and never used; it will be removed completely in 1.25.\n\nThe name in the go struct is changed to help clients detect\naccidental use.\n\n+optional", - "type": "string" - }, "creationTimestamp": { "$ref": "#/definitions/v1Time" }, @@ -5571,8 +5567,8 @@ } }, "v1ObjectReference": { + "description": "ObjectReference contains enough information to let you inspect or modify the referred object.\n---\nNew uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.\n 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.\n 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular\n restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\".\n Those cannot be well described when embedded.\n 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.\n 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity\n during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple\n and the version of the actual struct is irrelevant.\n 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type\n will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.\n\nInstead of using this type, create a locally provided and used type that is well-focused on your reference.\nFor example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n+structType=atomic", "type": "object", - "title": "ObjectReference contains enough information to let you inspect or modify the referred object.\n---\nNew uses of this type are discouraged because of difficulty describing its usage when embedded in APIs.\n 1. Ignored fields. It includes many fields which are not generally honored. For instance, ResourceVersion and FieldPath are both very rarely valid in actual usage.\n 2. Invalid usage help. It is impossible to add specific help for individual usage. In most embedded usages, there are particular\n restrictions like, \"must refer only to types A and B\" or \"UID not honored\" or \"name must be restricted\".\n Those cannot be well described when embedded.\n 3. Inconsistent validation. Because the usages are different, the validation rules are different by usage, which makes it hard for users to predict what will happen.\n 4. The fields are both imprecise and overly precise. Kind is not a precise mapping to a URL. This can produce ambiguity\n during interpretation and require a REST mapping. In most cases, the dependency is on the group,resource tuple\n and the version of the actual struct is irrelevant.\n 5. We cannot easily change it. Because this type is embedded in many locations, updates to this type\n will affect numerous schemas. Don't make new APIs embed an underspecified API type they do not control.\nInstead of using this type, create a locally provided and used type that is well-focused on your reference.\nFor example, ServiceReferences for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 .\n+k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object\n+structType=atomic", "properties": { "apiVersion": { "type": "string", diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 1bc1417fead4d..a72aaebc201a0 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -124,7 +124,7 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie if replicas > 0 { distributionFunction := sharding.GetDistributionFunction(argoDB, common.DefaultShardingAlgorithm) distributionFunction(&cluster) - cluster.Shard = pointer.Int64Ptr(int64(clusterShard)) + cluster.Shard = pointer.Int64(int64(clusterShard)) log.Infof("Cluster with uid: %s will be processed by shard %d", cluster.ID, clusterShard) } diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index a8872ffc9774c..0a54c517ca696 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -524,8 +524,8 @@ func NewApplicationLogsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } else { return } - } //Done with receive message - } //Done with retry + } // Done with receive message + } // Done with retry }, } @@ -889,7 +889,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n for i, item := range source.Kustomize.Images { if argoappv1.KustomizeImage(kustomizeImage).Match(item) { updated = true - //remove i + // remove i a := source.Kustomize.Images copy(a[i:], a[i+1:]) // Shift a[i+1:] left one index. a[len(a)-1] = "" // Erase last element (write zero value). @@ -1904,7 +1904,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co Backoff: &argoappv1.Backoff{ Duration: retryBackoffDuration.String(), MaxDuration: retryBackoffMaxDuration.String(), - Factor: pointer.Int64Ptr(retryBackoffFactor), + Factor: pointer.Int64(retryBackoffFactor), }, } } @@ -2143,7 +2143,7 @@ func checkResourceStatus(watch watchOpts, healthStatus string, syncStatus string } else if watch.degraded && watch.health { healthCheckPassed = healthStatus == string(health.HealthStatusHealthy) || healthStatus == string(health.HealthStatusDegraded) - //below are good + // below are good } else if watch.suspended && watch.health { healthCheckPassed = healthStatus == string(health.HealthStatusHealthy) || healthStatus == string(health.HealthStatusSuspended) diff --git a/cmd/util/app.go b/cmd/util/app.go index d64c5ed02e6cb..e08ee80305c48 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -295,7 +295,7 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap Backoff: &argoappv1.Backoff{ Duration: appOpts.retryBackoffDuration.String(), MaxDuration: appOpts.retryBackoffMaxDuration.String(), - Factor: pointer.Int64Ptr(appOpts.retryBackoffFactor), + Factor: pointer.Int64(appOpts.retryBackoffFactor), }, } } else if appOpts.retryLimit == 0 { diff --git a/cmd/util/project.go b/cmd/util/project.go index ef157f6873081..fa446ceb3b41c 100644 --- a/cmd/util/project.go +++ b/cmd/util/project.go @@ -115,7 +115,7 @@ func GetOrphanedResourcesSettings(flagSet *pflag.FlagSet, opts ProjectOpts) *v1a if opts.orphanedResourcesEnabled || warnChanged { settings := v1alpha1.OrphanedResourcesMonitorSettings{} if warnChanged { - settings.Warn = pointer.BoolPtr(opts.orphanedResourcesWarn) + settings.Warn = pointer.Bool(opts.orphanedResourcesWarn) } return &settings } diff --git a/controller/appcontroller.go b/controller/appcontroller.go index afa2a2d7b8186..4cae0dc486761 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -181,7 +181,8 @@ func NewApplicationController( appInformer, appLister := ctrl.newApplicationInformerAndLister() indexers := cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc} projInformer := v1alpha1.NewAppProjectInformer(applicationClientset, namespace, appResyncPeriod, indexers) - projInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + var err error + _, err = projInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { if key, err := cache.MetaNamespaceKeyFunc(obj); err == nil { ctrl.projectRefreshQueue.Add(key) @@ -208,6 +209,9 @@ func NewApplicationController( } }, }) + if err != nil { + return nil, err + } factory := informers.NewSharedInformerFactoryWithOptions(ctrl.kubeClientset, defaultDeploymentInformerResyncDuration, informers.WithNamespace(settingsMgr.GetNamespace())) deploymentInformer := factory.Apps().V1().Deployments() @@ -235,7 +239,7 @@ func NewApplicationController( } metricsAddr := fmt.Sprintf("0.0.0.0:%d", metricsPort) - var err error + ctrl.metricsServer, err = metrics.NewMetricsServer(metricsAddr, appLister, ctrl.canProcessApp, readinessHealthCheck, metricsApplicationLabels) if err != nil { return nil, err @@ -1569,7 +1573,7 @@ func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application, } else if hardExpired || softExpired { // The commented line below mysteriously crashes if app.Status.ReconciledAt is nil // reason = fmt.Sprintf("comparison expired. reconciledAt: %v, expiry: %v", app.Status.ReconciledAt, statusRefreshTimeout) - //TODO: find existing Golang bug or create a new one + // TODO: find existing Golang bug or create a new one reconciledAtStr := "never" if app.Status.ReconciledAt != nil { reconciledAtStr = app.Status.ReconciledAt.String() @@ -1979,7 +1983,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar }, ) lister := applisters.NewApplicationLister(informer.GetIndexer()) - informer.AddEventHandler( + _, err := informer.AddEventHandler( cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { if !ctrl.canProcessApp(obj) { @@ -2023,6 +2027,9 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar }, }, ) + if err != nil { + return nil, nil + } return informer, lister } diff --git a/controller/state.go b/controller/state.go index 19757510aa71d..2704545add445 100644 --- a/controller/state.go +++ b/controller/state.go @@ -391,6 +391,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 now := metav1.Now() var manifestInfos []*apiclient.ManifestResponse + targetNsExists := false if len(localManifests) == 0 { // If the length of revisions is not same as the length of sources, @@ -453,6 +454,13 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 LastTransitionTime: &now, }) } + + // If we reach this path, this means that a namespace has been both defined in Git, as well in the + // application's managedNamespaceMetadata. We want to ensure that this manifest is the one being used instead + // of what is present in managedNamespaceMetadata. + if isManagedNamespace(targetObj, app) { + targetNsExists = true + } } ts.AddCheckpoint("dedup_ms") @@ -511,7 +519,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 // entry in source control. In order for the namespace not to risk being pruned, we'll need to generate a // namespace which we can compare the live namespace with. For that, we'll do the same as is done in // gitops-engine, the difference here being that we create a managed namespace which is only used for comparison. - if isManagedNamespace(liveObj, app) { + // + // targetNsExists == true implies that it already exists as a target, so no need to add the namespace to the + // targetObjs array. + if isManagedNamespace(liveObj, app) && !targetNsExists { nsSpec := &v1.Namespace{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: kubeutil.NamespaceKind}, ObjectMeta: metav1.ObjectMeta{Name: liveObj.GetName()}} managedNs, err := kubeutil.ToUnstructured(nsSpec) diff --git a/docs/operator-manual/notifications/troubleshooting-commands.md b/docs/operator-manual/notifications/troubleshooting-commands.md index 633eb47d71690..8674e9677c1eb 100644 --- a/docs/operator-manual/notifications/troubleshooting-commands.md +++ b/docs/operator-manual/notifications/troubleshooting-commands.md @@ -39,6 +39,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml --cluster string The name of the kubeconfig cluster to use --config-map string argocd-notifications-cm.yaml file path --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request @@ -95,6 +96,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook --cluster string The name of the kubeconfig cluster to use --config-map string argocd-notifications-cm.yaml file path --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request @@ -150,6 +152,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml --cluster string The name of the kubeconfig cluster to use --config-map string argocd-notifications-cm.yaml file path --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request @@ -205,6 +208,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml --cluster string The name of the kubeconfig cluster to use --config-map string argocd-notifications-cm.yaml file path --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 21d26b29c572e..5b107253088e8 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -28,6 +28,7 @@ argocd-application-controller [flags] --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use --default-cache-expiration duration Cache expiration default (default 24h0m0s) + --disable-compression If true, opt-out of response compression for all requests to the server --dynamic-cluster-distribution-enabled Enables dynamic cluster distribution. --gloglevel int Set the glog logging level -h, --help help for argocd-application-controller diff --git a/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md b/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md index 1e784e94a2620..a889b64133a93 100644 --- a/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md +++ b/docs/operator-manual/server-commands/argocd-dex_gendexcfg.md @@ -19,6 +19,7 @@ argocd-dex gendexcfg [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --disable-tls Disable TLS on the HTTP endpoint -h, --help help for gendexcfg --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/operator-manual/server-commands/argocd-dex_rundex.md b/docs/operator-manual/server-commands/argocd-dex_rundex.md index 16e2b15abbece..b2d453feba613 100644 --- a/docs/operator-manual/server-commands/argocd-dex_rundex.md +++ b/docs/operator-manual/server-commands/argocd-dex_rundex.md @@ -19,6 +19,7 @@ argocd-dex rundex [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --disable-tls Disable TLS on the HTTP endpoint -h, --help help for rundex --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index d39459ad181d6..980383df7848e 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -34,6 +34,7 @@ argocd-server [flags] --dex-server-plaintext Use a plaintext client (non-TLS) to connect to dex server --dex-server-strict-tls Perform strict validation of TLS certificates when connecting to dex server --disable-auth Disable client authentication + --disable-compression If true, opt-out of response compression for all requests to the server --enable-gzip Enable GZIP compression (default true) --enable-proxy-extension Enable Proxy Extension feature --gloglevel int Set the glog logging level diff --git a/docs/operator-manual/server-commands/argocd-server_version.md b/docs/operator-manual/server-commands/argocd-server_version.md index 2d7d9d1151e8a..2659c99e87219 100644 --- a/docs/operator-manual/server-commands/argocd-server_version.md +++ b/docs/operator-manual/server-commands/argocd-server_version.md @@ -26,6 +26,7 @@ argocd-server version [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request diff --git a/docs/operator-manual/upgrading/2.8-2.9.md b/docs/operator-manual/upgrading/2.8-2.9.md new file mode 100644 index 0000000000000..6a82684019ac4 --- /dev/null +++ b/docs/operator-manual/upgrading/2.8-2.9.md @@ -0,0 +1,12 @@ +# v2.8 to 2.9 + +## `managedNamespaceMetadata` no longer preserves client-side-applied labels or annotations + +Argo CD 2.9 upgraded kubectl from 1.24 to 1.26. This upgrade introduced a change where client-side-applied labels and +annotations are no longer preserved when using a server-side kubectl apply. This change affects the +`managedNamespaceMetadata` field of the `Application` CRD. Previously, labels and annotations applied via a client-side +apply would be preserved when `managedNamespaceMetadata` was enabled. Now, those existing labels and annotation will be +removed. + +To avoid unexpected behavior, follow the [client-side to server-side resource upgrade guide](https://kubernetes.io/docs/reference/using-api/server-side-apply/#upgrading-from-client-side-apply-to-server-side-apply) +before enabling `managedNamespaceMetadata` on an existing namespace. diff --git a/docs/operator-manual/upgrading/overview.md b/docs/operator-manual/upgrading/overview.md index 419fc7bbb1353..67ab78076c648 100644 --- a/docs/operator-manual/upgrading/overview.md +++ b/docs/operator-manual/upgrading/overview.md @@ -37,6 +37,7 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/ +* [v2.8 to v2.9](./2.8-2.9.md) * [v2.7 to v2.8](./2.7-2.8.md) * [v2.6 to v2.7](./2.6-2.7.md) * [v2.5 to v2.6](./2.5-2.6.md) diff --git a/docs/user-guide/commands/argocd_account.md b/docs/user-guide/commands/argocd_account.md index 2d25f8df3225b..88d483ffac68e 100644 --- a/docs/user-guide/commands/argocd_account.md +++ b/docs/user-guide/commands/argocd_account.md @@ -35,6 +35,7 @@ argocd account [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for account --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md index de477064a2ad3..3290098999b7c 100644 --- a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md +++ b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md @@ -19,6 +19,7 @@ argocd admin app get-reconcile-results PATH [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for get-reconcile-results --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 3266b7ad1beb1..8105605e80cd0 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -19,6 +19,7 @@ argocd admin cluster kubeconfig CLUSTER_URL OUTPUT_PATH [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for kubeconfig --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md index e784f9e66bf72..fee5c7679e159 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces.md @@ -19,6 +19,7 @@ argocd admin cluster namespaces [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for namespaces --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md index 33eb9c5fc1f90..fcbebd7612337 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces_disable-namespaced-mode.md @@ -19,6 +19,7 @@ argocd admin cluster namespaces disable-namespaced-mode PATTERN [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --dry-run Print what will be performed (default true) -h, --help help for disable-namespaced-mode --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md b/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md index 20f94415c5000..762a652d7ab12 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md +++ b/docs/user-guide/commands/argocd_admin_cluster_namespaces_enable-namespaced-mode.md @@ -20,6 +20,7 @@ argocd admin cluster namespaces enable-namespaced-mode PATTERN [flags] --cluster string The name of the kubeconfig cluster to use --cluster-resources Indicates if cluster level resources should be managed. --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --dry-run Print what will be performed (default true) -h, --help help for enable-namespaced-mode --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md index 31f3524b3f0e0..6648b91b2199e 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_shards.md +++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md @@ -21,6 +21,7 @@ argocd admin cluster shards [flags] --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use --default-cache-expiration duration Cache expiration default (default 24h0m0s) + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for shards --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index 65ae696744c56..9e916288adf7e 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -21,6 +21,7 @@ argocd admin cluster stats [flags] --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use --default-cache-expiration duration Cache expiration default (default 24h0m0s) + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for stats --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index f3336df30e0d4..5dcfb31cf5a2c 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -20,6 +20,7 @@ argocd admin dashboard [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for dashboard --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_export.md b/docs/user-guide/commands/argocd_admin_export.md index f609439979ad3..d168fe5450a74 100644 --- a/docs/user-guide/commands/argocd_admin_export.md +++ b/docs/user-guide/commands/argocd_admin_export.md @@ -19,6 +19,7 @@ argocd admin export [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for export --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_import.md b/docs/user-guide/commands/argocd_admin_import.md index 834f72396effa..dc8a4b2dbf947 100644 --- a/docs/user-guide/commands/argocd_admin_import.md +++ b/docs/user-guide/commands/argocd_admin_import.md @@ -19,6 +19,7 @@ argocd admin import SOURCE [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --dry-run Print what will be performed -h, --help help for import --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/user-guide/commands/argocd_admin_initial-password.md b/docs/user-guide/commands/argocd_admin_initial-password.md index fc61e7f722213..dbc44561debdc 100644 --- a/docs/user-guide/commands/argocd_admin_initial-password.md +++ b/docs/user-guide/commands/argocd_admin_initial-password.md @@ -19,6 +19,7 @@ argocd admin initial-password [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for initial-password --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_notifications.md b/docs/user-guide/commands/argocd_admin_notifications.md index 779832d0a1b47..87429217f99e9 100644 --- a/docs/user-guide/commands/argocd_admin_notifications.md +++ b/docs/user-guide/commands/argocd_admin_notifications.md @@ -23,6 +23,7 @@ argocd admin notifications [flags] --cluster string The name of the kubeconfig cluster to use --config-map string argocd-notifications-cm.yaml file path --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for notifications --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_notifications_template.md b/docs/user-guide/commands/argocd_admin_notifications_template.md index f3519e631af25..75d5700aaac04 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template.md @@ -35,6 +35,7 @@ argocd admin notifications template [flags] --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_notifications_template_get.md b/docs/user-guide/commands/argocd_admin_notifications_template_get.md index 432e0b6b1c5d7..214a8e5cd442b 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_get.md @@ -47,6 +47,7 @@ argocd admin notifications template get app-sync-succeeded -o=yaml --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md index a26b70dd80d70..4f94a9d960476 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_template_notify.md +++ b/docs/user-guide/commands/argocd_admin_notifications_template_notify.md @@ -48,6 +48,7 @@ argocd admin notifications template notify app-sync-succeeded guestbook --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger.md b/docs/user-guide/commands/argocd_admin_notifications_trigger.md index 6e15faa0dcd92..d6ff9e53ab235 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger.md @@ -35,6 +35,7 @@ argocd admin notifications trigger [flags] --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md index 2a23ea1c1ec01..acd2ab5af9553 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_get.md @@ -47,6 +47,7 @@ argocd admin notifications trigger get on-sync-failed -o=yaml --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md index 4caf2d389b009..f8bebb2937937 100644 --- a/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md +++ b/docs/user-guide/commands/argocd_admin_notifications_trigger_run.md @@ -47,6 +47,7 @@ argocd admin notifications trigger run on-sync-status-unknown ./sample-app.yaml --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md index 81cb5c7cbf1f4..a16d6468cb446 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md @@ -19,6 +19,7 @@ argocd admin proj generate-allow-list CLUSTERROLE_PATH PROJ_NAME [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for generate-allow-list --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md b/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md index cc3a3e6320ef5..c1c4823077e01 100644 --- a/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md +++ b/docs/user-guide/commands/argocd_admin_proj_update-role-policy.md @@ -30,6 +30,7 @@ argocd admin proj update-role-policy PROJECT_GLOB MODIFICATION ACTION [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server --dry-run Dry run (default true) -h, --help help for update-role-policy --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure diff --git a/docs/user-guide/commands/argocd_admin_settings.md b/docs/user-guide/commands/argocd_admin_settings.md index 5687a473f9fa7..3c631cf8f123b 100644 --- a/docs/user-guide/commands/argocd_admin_settings.md +++ b/docs/user-guide/commands/argocd_admin_settings.md @@ -21,6 +21,7 @@ argocd admin settings [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for settings --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac.md b/docs/user-guide/commands/argocd_admin_settings_rbac.md index fabdee7171051..043c39979a98a 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac.md @@ -33,6 +33,7 @@ argocd admin settings rbac [flags] --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md index 2aafc6bd07cf7..f14092785facf 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_can.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_can.md @@ -50,6 +50,7 @@ argocd admin settings rbac can someuser create application 'default/app' --defau --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use --default-role string name of the default role to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for can --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md index 9ad6ec2bc4c37..75bc909882e19 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md @@ -41,6 +41,7 @@ argocd admin settings rbac validate --policy-file=POLICYFILE [flags] --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md index 1191f8cd0be9e..eeec6bcf5f63a 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides.md @@ -33,6 +33,7 @@ argocd admin settings resource-overrides [flags] --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md index d240f57a81294..1e5cc49335cc5 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_health.md @@ -44,6 +44,7 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md index adc9451de05da..752b3a64c59c7 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-differences.md @@ -44,6 +44,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md index f520c56fba20d..69f09208cf42f 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_ignore-resource-updates.md @@ -44,6 +44,7 @@ argocd admin settings resource-overrides ignore-resource-updates ./deploy.yaml - --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md index 342339af2fc9d..57f60f3d726f5 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_list-actions.md @@ -44,6 +44,7 @@ argocd admin settings resource-overrides action list /tmp/deploy.yaml --argocd-c --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md index 7ebc5d0873a78..f7ce62d4559fe 100644 --- a/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md +++ b/docs/user-guide/commands/argocd_admin_settings_resource-overrides_run-action.md @@ -44,6 +44,7 @@ argocd admin settings resource-overrides action run /tmp/deploy.yaml restart --a --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_admin_settings_validate.md b/docs/user-guide/commands/argocd_admin_settings_validate.md index dd66ef2fec386..8e40a403441b5 100644 --- a/docs/user-guide/commands/argocd_admin_settings_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_validate.md @@ -49,6 +49,7 @@ argocd admin settings validate --group accounts --group plugins --load-cluster-s --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server + --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) diff --git a/docs/user-guide/commands/argocd_app.md b/docs/user-guide/commands/argocd_app.md index f4a057ea70c1a..543fcd96035ec 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -32,6 +32,7 @@ argocd app [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for app --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_appset.md b/docs/user-guide/commands/argocd_appset.md index 1965ec0ca6be7..7b543ae318831 100644 --- a/docs/user-guide/commands/argocd_appset.md +++ b/docs/user-guide/commands/argocd_appset.md @@ -35,6 +35,7 @@ argocd appset [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for appset --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_cert.md b/docs/user-guide/commands/argocd_cert.md index 54d913937131b..b126328a4372f 100644 --- a/docs/user-guide/commands/argocd_cert.md +++ b/docs/user-guide/commands/argocd_cert.md @@ -42,6 +42,7 @@ argocd cert [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for cert --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_cluster.md b/docs/user-guide/commands/argocd_cluster.md index 7cd7e142b4c27..a30c357d54d71 100644 --- a/docs/user-guide/commands/argocd_cluster.md +++ b/docs/user-guide/commands/argocd_cluster.md @@ -39,6 +39,7 @@ argocd cluster [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for cluster --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_gpg.md b/docs/user-guide/commands/argocd_gpg.md index 45f4f4134176a..bca15e98b7c87 100644 --- a/docs/user-guide/commands/argocd_gpg.md +++ b/docs/user-guide/commands/argocd_gpg.md @@ -19,6 +19,7 @@ argocd gpg [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for gpg --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_proj.md b/docs/user-guide/commands/argocd_proj.md index ed119f226756d..17aeef0cdfc27 100644 --- a/docs/user-guide/commands/argocd_proj.md +++ b/docs/user-guide/commands/argocd_proj.md @@ -35,6 +35,7 @@ argocd proj [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for proj --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_repo.md b/docs/user-guide/commands/argocd_repo.md index cfc1bd4aba35a..4df85f7b00d3d 100644 --- a/docs/user-guide/commands/argocd_repo.md +++ b/docs/user-guide/commands/argocd_repo.md @@ -37,6 +37,7 @@ argocd repo rm https://github.com/yourusername/your-repo.git --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for repo --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_repocreds.md b/docs/user-guide/commands/argocd_repocreds.md index 5774654d4e3b5..f073b2bbb6161 100644 --- a/docs/user-guide/commands/argocd_repocreds.md +++ b/docs/user-guide/commands/argocd_repocreds.md @@ -32,6 +32,7 @@ argocd repocreds [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for repocreds --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/commands/argocd_version.md b/docs/user-guide/commands/argocd_version.md index a1a1bb223d3fc..6a7fa7baf5ecb 100644 --- a/docs/user-guide/commands/argocd_version.md +++ b/docs/user-guide/commands/argocd_version.md @@ -37,6 +37,7 @@ argocd version [flags] --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server -h, --help help for version --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster diff --git a/docs/user-guide/sync-options.md b/docs/user-guide/sync-options.md index 9afe031ba7469..817fabbe5fb45 100644 --- a/docs/user-guide/sync-options.md +++ b/docs/user-guide/sync-options.md @@ -339,51 +339,11 @@ spec: - CreateNamespace=true ``` -In the case where Argo CD is "adopting" an existing namespace which already has metadata set on it, we rely on using -Server Side Apply in order not to lose metadata which has already been set. The main implication here is that it takes -a few extra steps to get rid of an already preexisting field. - -Imagine we have a pre-existing namespace as below: - -```yaml -apiVersion: v1 -kind: Namespace -metadata: - name: foobar - annotations: - foo: bar - abc: "123" -``` - -If we want to manage the `foobar` namespace with Argo CD and to then also remove the `foo: bar` annotation, in -`managedNamespaceMetadata` we'd need to first rename the `foo` value: - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -spec: - syncPolicy: - managedNamespaceMetadata: - annotations: - abc: 123 # adding this is informational with SSA; this would be sticking around in any case until we set a new value - foo: remove-me - syncOptions: - - CreateNamespace=true -``` - -Once that has been synced, we're ok to remove `foo` - -```yaml -apiVersion: argoproj.io/v1alpha1 -kind: Application -spec: - syncPolicy: - managedNamespaceMetadata: - annotations: - abc: 123 # adding this is informational with SSA; this would be sticking around in any case until we set a new value - syncOptions: - - CreateNamespace=true -``` +In the case where Argo CD is "adopting" an existing namespace which already has metadata set on it, you should first +[upgrade the resource to server-side apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/#upgrading-from-client-side-apply-to-server-side-apply) +before enabling `managedNamespaceMetadata`. Argo CD relies on `kubectl`, which does not support managing +client-side-applied resources with server-side-applies. If you do not upgrade the resource to server-side apply, Argo CD +may remove existing labels/annotations, which may or may not be the desired behavior. Another thing to keep mind of is that if you have a k8s manifest for the same namespace in your Argo CD application, that will take precedence and *overwrite whatever values that have been set in `managedNamespaceMetadata`*. In other words, if diff --git a/go.mod b/go.mod index c1d4232baeec5..d95edd4ef6210 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 - github.com/argoproj/gitops-engine v0.7.1-0.20230929203505-a00ce82f1c17 + github.com/argoproj/gitops-engine v0.7.1-0.20231013183858-f15cf615b814 github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 @@ -19,6 +19,7 @@ require ( github.com/bombsimon/logrusr/v2 v2.0.1 github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 github.com/casbin/casbin/v2 v2.77.2 + github.com/cespare/xxhash/v2 v2.2.0 github.com/coreos/go-oidc/v3 v3.6.0 github.com/cyphar/filepath-securejoin v0.2.4 github.com/dustin/go-humanize v1.0.1 @@ -88,19 +89,19 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.24.2 - k8s.io/apiextensions-apiserver v0.24.2 - k8s.io/apimachinery v0.24.2 - k8s.io/apiserver v0.24.2 - k8s.io/client-go v0.24.2 - k8s.io/code-generator v0.24.2 - k8s.io/klog/v2 v2.70.1 - k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 - k8s.io/kubectl v0.24.2 - k8s.io/utils v0.0.0-20220706174534-f6158b442e7c + k8s.io/api v0.26.4 + k8s.io/apiextensions-apiserver v0.26.4 + k8s.io/apimachinery v0.26.4 + k8s.io/apiserver v0.26.4 + k8s.io/client-go v0.26.4 + k8s.io/code-generator v0.26.4 + k8s.io/klog/v2 v2.100.1 + k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f + k8s.io/kubectl v0.26.4 + k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 oras.land/oras-go/v2 v2.3.0 - sigs.k8s.io/controller-runtime v0.11.0 + sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/structured-merge-diff/v4 v4.3.0 sigs.k8s.io/yaml v1.3.0 ) @@ -147,7 +148,7 @@ require ( github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect - github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/PagerDuty/go-pagerduty v1.7.0 // indirect @@ -157,17 +158,18 @@ require ( github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // 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 - github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect github.com/cloudflare/circl v1.3.3 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/emicklei/go-restful/v3 v3.8.0 // indirect + github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect + github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect @@ -180,8 +182,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.1 // indirect github.com/go-openapi/spec v0.20.8 // indirect github.com/go-openapi/strfmt v0.21.7 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -221,7 +223,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.0 // indirect github.com/moby/spdystream v0.2.0 // indirect - github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect + github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect @@ -238,8 +240,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect - github.com/rs/cors v1.8.0 // indirect - github.com/russross/blackfriday v1.6.0 // indirect + github.com/rs/cors v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect @@ -274,15 +275,15 @@ require ( gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - k8s.io/cli-runtime v0.24.2 // indirect - k8s.io/component-base v0.24.2 // indirect - k8s.io/component-helpers v0.24.2 // indirect - k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 // indirect - k8s.io/kube-aggregator v0.24.2 // indirect - k8s.io/kubernetes v1.24.2 // indirect - sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124 // indirect - sigs.k8s.io/kustomize/api v0.11.5 // indirect - sigs.k8s.io/kustomize/kyaml v0.13.7 // indirect + k8s.io/cli-runtime v0.26.4 // indirect + k8s.io/component-base v0.26.4 // indirect + k8s.io/component-helpers v0.26.4 // indirect + k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect + k8s.io/kube-aggregator v0.26.4 // indirect + k8s.io/kubernetes v1.26.4 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.12.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect ) replace ( @@ -299,30 +300,34 @@ replace ( // Avoid CVE-2022-28948 gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - // https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505627280 - k8s.io/api => k8s.io/api v0.24.2 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.24.2 - k8s.io/apimachinery => k8s.io/apimachinery v0.24.2 - k8s.io/apiserver => k8s.io/apiserver v0.24.2 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.24.2 - k8s.io/client-go => k8s.io/client-go v0.24.2 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.24.2 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.24.2 - k8s.io/code-generator => k8s.io/code-generator v0.24.2 - k8s.io/component-base => k8s.io/component-base v0.24.2 - k8s.io/component-helpers => k8s.io/component-helpers v0.24.2 - k8s.io/controller-manager => k8s.io/controller-manager v0.24.2 - k8s.io/cri-api => k8s.io/cri-api v0.24.2 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.24.2 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.24.2 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.24.2 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.24.2 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.24.2 - k8s.io/kubectl => k8s.io/kubectl v0.24.2 - k8s.io/kubelet => k8s.io/kubelet v0.24.2 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.24.2 - k8s.io/metrics => k8s.io/metrics v0.24.2 - k8s.io/mount-utils => k8s.io/mount-utils v0.24.2 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.24.2 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.24.2 + k8s.io/api => k8s.io/api v0.26.4 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.4 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.4 + k8s.io/apiserver => k8s.io/apiserver v0.26.4 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.4 + k8s.io/client-go => k8s.io/client-go v0.26.4 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.4 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.4 + k8s.io/code-generator => k8s.io/code-generator v0.26.4 + k8s.io/component-base => k8s.io/component-base v0.26.4 + k8s.io/component-helpers => k8s.io/component-helpers v0.26.4 + k8s.io/controller-manager => k8s.io/controller-manager v0.26.4 + k8s.io/cri-api => k8s.io/cri-api v0.26.4 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.4 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.26.4 + k8s.io/kms => k8s.io/kms v0.26.4 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.4 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.4 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.4 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.4 + k8s.io/kubectl => k8s.io/kubectl v0.26.4 + k8s.io/kubelet => k8s.io/kubelet v0.26.4 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.4 + k8s.io/metrics => k8s.io/metrics v0.26.4 + k8s.io/mount-utils => k8s.io/mount-utils v0.26.4 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.4 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.4 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.26.4 + k8s.io/sample-controller => k8s.io/sample-controller v0.26.4 + ) diff --git a/go.sum b/go.sum index d243c179785b4..d9b3a9acf2e2a 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690/go.mod h1:Ulb78X89vxKYgdL24HMTiXYHlyHEvruOj1ZPlqeNEZM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -277,7 +275,6 @@ cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCV cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI= cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs= cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= @@ -606,10 +603,8 @@ code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMV dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20201218220906-28db891af037/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= -github.com/Azure/azure-sdk-for-go v55.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1 h1:tz19qLF65vuu2ibfTqGVJxG/zZAI27NEIIbvAOQwYbw= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 h1:QkAcEIAKbNL4KoFr4SathZPhDhF4mVwpBMFlYjyAqy8= @@ -620,10 +615,8 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A= github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg= github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= @@ -632,8 +625,6 @@ github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSY github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.1.0/go.mod h1:Ha3z/SqBeaalWQvokg3NZAlQTalVMtOIAs1aGK7G6u8= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= @@ -644,15 +635,13 @@ github.com/AzureAD/microsoft-authentication-library-for-go v0.5.2 h1:BGX4OiGP9ht github.com/AzureAD/microsoft-authentication-library-for-go v0.5.2/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/k8s-cloud-provider v1.16.1-0.20210702024009-ea6160c1d0e3/go.mod h1:8XasY4ymP2V/tn2OOV9ZadmiTE1FIB/h3W+yNlPttKw= -github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= github.com/Jeffail/gabs v1.4.0/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU= -github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= @@ -660,14 +649,10 @@ github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0 github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= -github.com/Microsoft/go-winio v0.4.15/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PagerDuty/go-pagerduty v1.7.0 h1:S1NcMKECxT5hJwV4VT+QzeSsSiv4oWl1s2821dUqG/8= github.com/PagerDuty/go-pagerduty v1.7.0/go.mod h1:PuFyJKRz1liIAH4h5KVXVD18Obpp1ZXRdxHvmGXooro= @@ -702,21 +687,19 @@ github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6u github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20230929203505-a00ce82f1c17 h1:PD2CJKPakR4u5hDsi6MG8gJUB4oj4Peltm7bGkn0Rfc= -github.com/argoproj/gitops-engine v0.7.1-0.20230929203505-a00ce82f1c17/go.mod h1:/GMN0JuoJUUpnKlNLp2Wn/mfK8sglFsdPn+eoxSddmg= +github.com/argoproj/gitops-engine v0.7.1-0.20231013183858-f15cf615b814 h1:oTaLRbCwjnGtScIX2ZRdIEDsiDxonwh9/BbUxdXrjYc= +github.com/argoproj/gitops-engine v0.7.1-0.20231013183858-f15cf615b814/go.mod h1:1TchqKw9XmYYZluyEHa1dTJQoZgbV6PhabB/e8Wf3KY= github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf h1:4wliaBwd6iKvT/5huDTJntaYtTSdwPLs00SOQwDSK6A= github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf/go.mod h1:TuK0BNKo34DIUOyCCGOB9ij+smGCxeCgt9ZB+0fMWno= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -726,11 +709,8 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/auth0/go-jwt-middleware v1.0.1/go.mod h1:YSeUX3z6+TF2H+7padiEqNJ73Zy9vXW72U//IgN0BIM= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.35.24/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= -github.com/aws/aws-sdk-go v1.38.49/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go v1.44.317 h1:+8XWrLmGMwPPXSRSLPzhgcGnzJ2mYkgkrcB9C/GnSOU= github.com/aws/aws-sdk-go v1.44.317/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= @@ -762,20 +742,16 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.18.0/go.mod h1:+lGbb3+1ugwKrNTWcf2RT github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc= github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= -github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= @@ -799,28 +775,20 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/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/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1 h1:HD4PLRzjuCVW79mQ0/pdsalOLHJ+FaEoqJLxfltpb2U= -github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +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= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I= github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/clusterhq/flocker-go v0.0.0-20160920122132-2b8b7259d313/go.mod h1:P1wt9Z3DP8O6W3rvwCt0REIlshg1InHImaLW0t3ObY0= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -836,72 +804,35 @@ github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= 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/container-storage-interface/spec v1.5.0/go.mod h1:8K96oQNkJ7pFcC2R9Z1ynGGBB1I93kcS6PGg3SsOk8s= -github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.12/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/coredns/caddy v1.1.0/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= -github.com/coredns/corefile-migration v1.0.14/go.mod h1:XnhgULOEouimnzgn0t4WPuFDN2/PJQcTxdWKC5eXNGE= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o= github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I= github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= -github.com/docker/distribution v2.8.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v20.10.12+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -913,10 +844,9 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= +github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -936,12 +866,12 @@ github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= -github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= github.com/expr-lang/expr v0.0.0-20230912141041-709c5dd55aa7 h1:Sg2XxaymeyqqaLG34aB2mvlX+nii916/Gv1ovWc4jMc= @@ -956,15 +886,11 @@ github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -972,19 +898,15 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e h1:C3DkNr9pxqXqCrmRHO7s3XgZS3zpi9GEA01GuWZODfo= github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e/go.mod h1:LB3osS9X2JMYmTzcCArHHLrndBAfcVLQAvUddfs+ONs= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do= github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= @@ -1024,8 +946,7 @@ github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-logr/zapr v1.2.0 h1:n4JnPI1T3Qq1SFEi/F8rwLrZERp2bso19PJZDB9dayk= -github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -1035,13 +956,14 @@ github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpX github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= @@ -1064,14 +986,11 @@ github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/ github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-ozzo/ozzo-validation v3.5.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM= github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= @@ -1120,17 +1039,12 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355 h1:HTVNOdTWO/gHYeFnr/HwpYwY6tgMcYd+Rgf1XrHnORY= github.com/gogits/go-gogs-client v0.0.0-20200905025246-8bb8a50cb355/go.mod h1:cY2AIrMgHm6oOHmR7jY+9TtjzSjQ3iG7tURJG3Y6XH0= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= @@ -1168,15 +1082,11 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cadvisor v0.44.1/go.mod h1:GQ9KQfz0iNHQk3D6ftzJWK4TXabfIgM10Oy3FkR+Gzg= -github.com/google/cel-go v0.10.1/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= -github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= @@ -1265,21 +1175,16 @@ github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38 github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4/go.mod h1:lEO7XoHJ/xNRBCxrn4h/CEB67h0kW1B0t4ooP2yrjUA= -github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -1295,10 +1200,8 @@ github.com/gregdel/pushover v1.2.1/go.mod h1:EcaO66Nn1StkpEm1iKtBTV3d2A16SoMsVER github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= @@ -1308,9 +1211,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -1336,13 +1237,10 @@ github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/heketi/heketi v10.3.0+incompatible/go.mod h1:bB9ly3RchcQqsQ9CpyaQwvva7RS5ytVoSoholZQON6o= -github.com/heketi/tests v0.0.0-20151005000721-f3775cbcefd6/go.mod h1:xGMAM8JLi7UkZt1i4FQeQy0R2T8GLUwQhOP5M1gBhy4= github.com/howeyc/gopass v0.0.0-20170109162249-bf9dde6d0d2c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4= @@ -1351,7 +1249,7 @@ github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmK github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= @@ -1361,7 +1259,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/ishidawataru/sctp v0.0.0-20190723014705-7c296d48a2b5/go.mod h1:DM4VvS+hD/kDi1U1QsX2fnZowwBhqD0Dk3bRPKF/Oc8= github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= @@ -1389,7 +1286,6 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -1403,13 +1299,11 @@ github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q github.com/k0kubun/pp v3.0.1+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= @@ -1441,29 +1335,21 @@ github.com/ktrysmt/go-bitbucket v0.9.67 h1:pFQs95TTgrwd3I9gKnas8zTYMVUOId0ZI4N0y github.com/ktrysmt/go-bitbucket v0.9.67/go.mod h1:g4i0XvhrK5dQ+RIZAJmF0XfBvhBEn3Ibt/6YbEyXkXw= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= -github.com/lpabon/godbc v0.1.1/go.mod h1:Jo9QV0cf3U6jZABgiJ2skINAXb9j8m51r07g4KI92ZA= github.com/lusis/go-slackbot v0.0.0-20180109053408-401027ccfef5/go.mod h1:c2mYKRyMb1BPkO5St0c/ps62L4S0W2NAkaTXj9qEI+0= github.com/lusis/slack-test v0.0.0-20190426140909-c40012f20018/go.mod h1:sFlOUpQL1YcjhFVXhg1CG8ZASEs/Mf1oVb6H75JL/zg= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailgun/mailgun-go v2.0.0+incompatible/go.mod h1:NWTyU+O4aczg/nsGhQnvHL6v2n5Gy6Sv5tNDVvC6FbU= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= @@ -1478,14 +1364,12 @@ github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= @@ -1493,24 +1377,20 @@ github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4 github.com/mattn/go-zglob v0.0.4 h1:LQi2iOm0/fGgu80AioIJ/1j9w9Oh+9DZ39J4VAGzHQM= github.com/mattn/go-zglob v0.0.4/go.mod h1:MxxjyoXXnMxfIpxTK2GAkw1w8glPsQILx3N5wrKakiY= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 h1:YH424zrwLTlyHSH/GzLMJeu5zhYVZSx5RQxGKm1h96s= github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/mindprince/gonvml v0.0.0-20190828220739-9ebdce4bb989/go.mod h1:2eu9pRWp8mo84xCg6KswZ+USQHjwgRhNp06sozOdsTY= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= github.com/minio/minio-go/v7 v7.0.58/go.mod h1:NUDy4A4oXPq1l2yK6LTSvCEzAMeIcoz9lcj5dbzSrRE= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= @@ -1524,13 +1404,10 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/moby/ipvs v1.0.1/go.mod h1:2pngiyseZbIKXNv7hsKj3O9UEz30c53MT9005gt2hxQ= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/mountinfo v0.6.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1538,18 +1415,14 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mvdan/xurls v1.1.0/go.mod h1:tQlNn3BED8bE/15hnSL2HLkDeLWpNPAwtw7wkEq44oU= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -1573,16 +1446,13 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/oliveagle/jsonpath v0.0.0-20180606110733-2e52cf6e6852/go.mod h1:eqOVx5Vwu4gd2mmMZvVZsgIqNSaW3xxRThUJ0k/TPk4= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -1595,7 +1465,6 @@ github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkA github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.7.0 h1:/XxtEV3I3Eif/HobnVx9YmJgk8ENdRsuUmM+fLCFNow= github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= @@ -1606,6 +1475,7 @@ github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9 github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo= github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM= +github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= @@ -1613,15 +1483,8 @@ github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdM github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runc v1.1.1/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -1637,9 +1500,7 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= @@ -1665,15 +1526,11 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -1684,38 +1541,27 @@ github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/quobyte/api v0.1.8/go.mod h1:jL7lIHrmqQ7yh05OJ+eEEdHr0u/kmT1Ff9iHd+4H6VI= github.com/r3labs/diff v1.1.0 h1:V53xhrbTHrWFWq3gI4b94AjgEJOerO1+1l0xyHOBi8M= github.com/r3labs/diff v1.1.0/go.mod h1:7WjXasNzi0vJetRcB/RqNl5dlIsmXcTTLmF5IoH6Xig= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.0.0-rc.4/go.mod h1:Vo3EsyWnicKnSKCA7HhgnvnyA74wOA69Cd2Meli5mmA= github.com/redis/go-redis/v9 v9.0.5 h1:CuQcn5HIEeK7BgElubPP8CGtE0KakrnbBSTLjathl5o= github.com/redis/go-redis/v9 v9.0.5/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk= -github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= @@ -1732,13 +1578,9 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.8.0 h1:P2KMzcFwrPoSjkF1WLRPsp3UMLyql8L4v9hQpVeK5so= -github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww= -github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -1747,7 +1589,6 @@ github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= @@ -1770,7 +1611,6 @@ github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:s github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= github.com/slack-go/slack v0.12.2/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1780,41 +1620,27 @@ github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJ github.com/sony/sonyflake v1.0.0 h1:MpU6Ro7tfXwgn2l5eluf9xQvQJDROTBImNCfRXn/YeM= github.com/sony/sonyflake v1.0.0/go.mod h1:Jv3cfhf/UFtolOTTRd3q4Nl6ENqM+KfyZ5PseKfZGF4= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 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.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= -github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/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= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/storageos/go-api v2.2.0+incompatible/go.mod h1:ZrLn+e0ZuF3Y65PNF6dIwbJPZqfmtCXxFm9ckv0agOY= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -1829,8 +1655,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -1839,31 +1663,22 @@ github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhV github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmihailenco/go-tinylfu v0.2.2 h1:H1eiG6HM36iniK6+21n9LLpzx1G9R3DJa2UjUjbynsI= github.com/vmihailenco/go-tinylfu v0.2.2/go.mod h1:CutYi2Q9puTxfcolkliPq4npPuofg9N9t8JVrjzwa3Q= github.com/vmihailenco/msgpack/v5 v5.3.4 h1:qMKAwOV+meBw2Y8k9cVwAy7qErtYCwBzZ2ellBfvnqc= github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= github.com/xanzy/go-gitlab v0.91.1 h1:gnV57IPGYywWer32oXKBcdmc8dVxeKl3AauV8Bu17rw= @@ -1879,10 +1694,8 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1895,20 +1708,8 @@ github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/client/v3 v3.5.1/go.mod h1:OnjH4M8OnAotwaB2l9bVgZzRFKru7/ZMoS46OtKyd3Q= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= @@ -1924,38 +1725,26 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd h1:Uo/x0Ir5vQJ+683GXB9Ug+4fcjsbp7z7Ul8UaZbhsRM= go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1972,14 +1761,11 @@ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9i go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1991,13 +1777,11 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= @@ -2015,9 +1799,7 @@ golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= @@ -2027,7 +1809,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20210220032938-85be41e4509f/go.mod h1:I6l2HNBLBZEcrOoCpyKLdY2lHoRZ8lI4x60KMCQDft4= golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= @@ -2058,15 +1839,12 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -2092,7 +1870,6 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190607181551-461777fb6f67/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -2131,10 +1908,8 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -2175,8 +1950,6 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -2223,12 +1996,10 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2240,19 +2011,13 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2260,11 +2025,9 @@ golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2279,8 +2042,6 @@ golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2294,16 +2055,12 @@ golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2314,17 +2071,13 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2397,7 +2150,6 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb 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= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2407,7 +2159,6 @@ golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -2433,7 +2184,6 @@ golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -2442,7 +2192,6 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -2480,7 +2229,6 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= @@ -2505,13 +2253,10 @@ gomodules.xyz/notify v0.1.1 h1:1tTuoyswmPvzqPCTEDQK8SZ3ukCxLsonAAwst2+y1a0= gomodules.xyz/notify v0.1.1/go.mod h1:QgQyU4xEA/plJcDeT66J2Go2V7U4c0pD9wjo7HfFil4= gomodules.xyz/version v0.1.0/go.mod h1:Y8xuV02mL/45psyPKG3NCVOwvAOy6T5Kx0l3rCjKSjU= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= -gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0= gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA= gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY= gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo= @@ -2537,8 +2282,6 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= @@ -2602,7 +2345,6 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -2623,7 +2365,6 @@ 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-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -2637,7 +2378,6 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -2801,7 +2541,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= @@ -2822,26 +2561,18 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.0/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE= gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.1/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -2850,7 +2581,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2860,73 +2590,52 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.24.2 h1:g518dPU/L7VRLxWfcadQn2OnsiGWVOadTLpdnqgY2OI= -k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg= -k8s.io/apiextensions-apiserver v0.24.2 h1:/4NEQHKlEz1MlaK/wHT5KMKC9UKYz6NZz6JE6ov4G6k= -k8s.io/apiextensions-apiserver v0.24.2/go.mod h1:e5t2GMFVngUEHUd0wuCJzw8YDwZoqZfJiGOW6mm2hLQ= -k8s.io/apimachinery v0.24.2 h1:5QlH9SL2C8KMcrNJPor+LbXVTaZRReml7svPEh4OKDM= -k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apiserver v0.24.2 h1:orxipm5elPJSkkFNlwH9ClqaKEDJJA3yR2cAAlCnyj4= -k8s.io/apiserver v0.24.2/go.mod h1:pSuKzr3zV+L+MWqsEo0kHHYwCo77AT5qXbFXP2jbvFI= -k8s.io/cli-runtime v0.24.2 h1:KxY6tSgPGsahA6c1/dmR3uF5jOxXPx2QQY6C5ZrLmtE= -k8s.io/cli-runtime v0.24.2/go.mod h1:1LIhKL2RblkhfG4v5lZEt7FtgFG5mVb8wqv5lE9m5qY= -k8s.io/client-go v0.24.2 h1:CoXFSf8if+bLEbinDqN9ePIDGzcLtqhfd6jpfnwGOFA= -k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30= -k8s.io/cloud-provider v0.24.2/go.mod h1:a7jyWjizk+IKbcIf8+mX2cj3NvpRv9ZyGdXDyb8UEkI= -k8s.io/cluster-bootstrap v0.24.2/go.mod h1:eIHV338K03vBm3u/ROZiNXxWJ4AJRoTR9PEUhcTvYkg= -k8s.io/code-generator v0.24.2 h1:EGeRWzJrpwi6T6CvoNl0spM6fnAnOdCr0rz7H4NU1rk= -k8s.io/code-generator v0.24.2/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w= -k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU= -k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM= -k8s.io/component-helpers v0.24.2 h1:gtXmI/TjVINtkAdZn7m5p8+Vd0Mk4d1q8kwJMMLBdwY= -k8s.io/component-helpers v0.24.2/go.mod h1:TRQPBQKfmqkmV6c0HAmUs8cXVNYYYLsXy4zu8eODi9g= -k8s.io/controller-manager v0.24.2/go.mod h1:hpwCof4KxP4vrw/M5QiVxU6Zmmggmr1keGXtjGHF+vc= -k8s.io/cri-api v0.24.2/go.mod h1:t3tImFtGeStN+ES69bQUX9sFg67ek38BM9YIJhMmuig= -k8s.io/csi-translation-lib v0.24.2/go.mod h1:pdHc2CYLViQYYsOqOp79hjKYi8J4NZ7vpiVzn1SqBrg= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/api v0.26.4 h1:qSG2PmtcD23BkYiWfoYAcak870eF/hE7NNYBYavTT94= +k8s.io/api v0.26.4/go.mod h1:WwKEXU3R1rgCZ77AYa7DFksd9/BAIKyOmRlbVxgvjCk= +k8s.io/apiextensions-apiserver v0.26.4 h1:9D2RTxYGxrG5uYg6D7QZRcykXvavBvcA59j5kTaedQI= +k8s.io/apiextensions-apiserver v0.26.4/go.mod h1:cd4uGFGIgzEqUghWpRsr9KE8j2KNTjY8Ji8pnMMazyw= +k8s.io/apimachinery v0.26.4 h1:rZccKdBLg9vP6J09JD+z8Yr99Ce8gk3Lbi9TCx05Jzs= +k8s.io/apimachinery v0.26.4/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/apiserver v0.26.4 h1:3Oq4mnJv0mzVX7BR/Nod+8KjlELf/3Ljvu9ZWDyLUoA= +k8s.io/apiserver v0.26.4/go.mod h1:yAY3O1vBM4/0OIGAGeWcdfzQvgdwJ188VirLcuSAVnw= +k8s.io/cli-runtime v0.26.4 h1:MgSU871KDzBDX7V9GtuqS6Ai9lhQCHgRzkurnXOWtZ0= +k8s.io/cli-runtime v0.26.4/go.mod h1:MjJ2DXMChw2zcG0/agzm17xwKpfVxOfuoCdfY9iOCOE= +k8s.io/client-go v0.26.4 h1:/7P/IbGBuT73A+G97trf44NTPSNqvuBREpOfdLbHvD4= +k8s.io/client-go v0.26.4/go.mod h1:6qOItWm3EwxJdl/8p5t7FWtWUOwyMdA8N9ekbW4idpI= +k8s.io/code-generator v0.26.4 h1:zgDD0qX13p/jtrAoYRRiYeQ5ibnriwmo2cMkMZAtJxc= +k8s.io/code-generator v0.26.4/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= +k8s.io/component-base v0.26.4 h1:Bg2xzyXNKL3eAuiTEu3XE198d6z22ENgFgGQv2GGOUk= +k8s.io/component-base v0.26.4/go.mod h1:lTuWL1Xz/a4e80gmIC3YZG2JCO4xNwtKWHJWeJmsq20= +k8s.io/component-helpers v0.26.4 h1:qbZrh8QmfL+Yn7lWEI/BPrvITGgkBy33djP5Tzsu2hA= +k8s.io/component-helpers v0.26.4/go.mod h1:2Siz5eWmaKu0khASXMTCfJuASZAbCPX9mtjlCe5IWRs= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185 h1:TT1WdmqqXareKxZ/oNXEUSwKlLiHzPMyB0t8BaFeBYI= -k8s.io/gengo v0.0.0-20211129171323-c02415ce4185/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= -k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-aggregator v0.24.2 h1:vaKw45vFA5fIT0wdSehPIL7idjVxgLqz6iedOHedLG4= -k8s.io/kube-aggregator v0.24.2/go.mod h1:Ju2jNDixn+vqeeKEBfjfpc204bO1pbdXX0N9knCxeMQ= -k8s.io/kube-controller-manager v0.24.2/go.mod h1:KDE0yqiEvxYiO0WRpPA4rVx8AcK1vsWydUF37AJ9lTI= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661/go.mod h1:daOouuuwd9JXpv1L7Y34iV3yf6nxzipkKMWWlqlvK9M= -k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8 h1:yEQKdMCjzAOvGeiTwG4hO/hNVNtDOuUFvMUZ0OlaIzs= -k8s.io/kube-openapi v0.0.0-20220627174259-011e075b9cb8/go.mod h1:mbJ+NSUoAhuR14N0S63bPkh8MGVSo3VYSGZtH/mfMe0= -k8s.io/kube-proxy v0.24.2/go.mod h1:bozS2ufl/Ns6s40Ue34eV7rqyLVygi5usSmCgW7rFU8= -k8s.io/kube-scheduler v0.24.2/go.mod h1:DRa+aeXKSYUUOHHIc/9EcaO9+FW5FydaOfPSvaSW5Ko= -k8s.io/kubectl v0.24.2 h1:+RfQVhth8akUmIc2Ge8krMl/pt66V7210ka3RE/p0J4= -k8s.io/kubectl v0.24.2/go.mod h1:+HIFJc0bA6Tzu5O/YcuUt45APAxnNL8LeMuXwoiGsPg= -k8s.io/kubelet v0.24.2/go.mod h1:Xm9DkWQjwOs+uGOUIIGIPMvvmenvj0lDVOErvIKOOt0= -k8s.io/kubernetes v1.24.2 h1:AyjtHzSysliKR04Km91njmk2yaKmOa3ZISQZCIGUnVI= -k8s.io/kubernetes v1.24.2/go.mod h1:8e8maMiZzBR2/8Po5Uulx+MXZUYJuN3vtKwD4Ct1Xi0= -k8s.io/legacy-cloud-providers v0.24.2/go.mod h1:sgkasgIP2ZOew8fzoOq0mQLVXJ4AmB57IUbFUjzPWEo= -k8s.io/metrics v0.24.2/go.mod h1:5NWURxZ6Lz5gj8TFU83+vdWIVASx7W8lwPpHYCqopMo= -k8s.io/mount-utils v0.24.2/go.mod h1:XrSqB3a2e8sq+aU+rlbcBtQ3EgcuDk5RP9ZsGxjoDrI= -k8s.io/pod-security-admission v0.24.2/go.mod h1:znnuDHWWWvh/tpbYYPwTsd4y//qHi3cOX+wGxET/mMI= -k8s.io/sample-apiserver v0.24.2/go.mod h1:mf8qgDdu450wqpCJOkSAmoTgU4PIMAcfa5uTBwmJekE= -k8s.io/system-validators v1.7.0/go.mod h1:gP1Ky+R9wtrSiFbrpEPwWMeYz9yqyy1S/KOh0Vci7WI= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-aggregator v0.26.4 h1:iGljhq5exQkbuc3bnkwUx95RPCBDExg7DkX9XaYhg6w= +k8s.io/kube-aggregator v0.26.4/go.mod h1:eWfg4tU0+l57ebWiS5THOANIJUrKRxudSVDJ+63bqvQ= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +k8s.io/kubectl v0.26.4 h1:A0Oa0u/po4KxXnXsNCOwLojAe9cQR3TJNJabEIf7U1w= +k8s.io/kubectl v0.26.4/go.mod h1:cWtp/+I4p+h5En3s2zO1zCry9v3/6h37EQ2tF3jNRnM= +k8s.io/kubernetes v1.26.4 h1:/c00/JjOltBwhNOBs+hO433Q3fRyeWWtyYF6z2xtmag= +k8s.io/kubernetes v1.26.4/go.mod h1:NxzR7U7mS+OGa3J/qweI86Pek//mlfHqDgt6NNGdz8g= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220706174534-f6158b442e7c h1:hFZO68mv/0xe8+V0gRT9BAq3/31cKjjeVv4nScriuBk= -k8s.io/utils v0.0.0-20220706174534-f6158b442e7c/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 h1:RZkKxMR3jbQxdCEcglq3j7wY3PRJIopAwBlx1RE71X0= layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427/go.mod h1:ivKkcY8Zxw5ba0jldhZCYYQfGdb2K6u9tbYK1AwMIBc= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= -modernc.org/cc v1.0.0/go.mod h1:1Sk4//wdnYJiUIxnW8ddKpaOJCF37yAdqYnkxUpaYxw= modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI= @@ -2937,7 +2646,6 @@ modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWs modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws= modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo= modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ= -modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk= modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A= @@ -2946,7 +2654,6 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU= modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA= modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0= modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s= -modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= @@ -2956,12 +2663,10 @@ modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4= -modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw= modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw= modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw= modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8= nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= @@ -2972,22 +2677,16 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30/go.mod h1:fEO7lRTdivWO2qYVCVG7dEADOMo/MLDCVr8So2g88Uw= -sigs.k8s.io/controller-runtime v0.11.0 h1:DqO+c8mywcZLFJWILq4iktoECTyn30Bkj0CwgqMpZWQ= -sigs.k8s.io/controller-runtime v0.11.0/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124 h1:2sgAQQcY0dEW2SsQwTXhQV4vO6+rSslYx8K3XmM5hqQ= -sigs.k8s.io/json v0.0.0-20220525155127-227cbc7cc124/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/kustomize/api v0.11.4/go.mod h1:k+8RsqYbgpkIrJ4p9jcdPqe8DprLxFUUO0yNOq8C+xI= -sigs.k8s.io/kustomize/api v0.11.5 h1:vLDp++YAX7iy2y2CVPJNy9pk9CY8XaUKgHkjbVtnWag= -sigs.k8s.io/kustomize/api v0.11.5/go.mod h1:2UDpxS6AonWXow2ZbySd4AjUxmdXLeTlvGBC46uSiq8= -sigs.k8s.io/kustomize/cmd/config v0.10.6/go.mod h1:/S4A4nUANUa4bZJ/Edt7ZQTyKOY9WCER0uBS1SW2Rco= -sigs.k8s.io/kustomize/kustomize/v4 v4.5.4/go.mod h1:Zo/Xc5FKD6sHl0lilbrieeGeZHVYCA4BzxeAaLI05Bg= -sigs.k8s.io/kustomize/kyaml v0.13.6/go.mod h1:yHP031rn1QX1lr/Xd934Ri/xdVNG8BE2ECa78Ht/kEg= -sigs.k8s.io/kustomize/kyaml v0.13.7 h1:/EZ/nPaLUzeJKF/BuJ4QCuMVJWiEVoI8iftOHY3g3tk= -sigs.k8s.io/kustomize/kyaml v0.13.7/go.mod h1:6K+IUOuir3Y7nucPRAjw9yth04KSWBnP5pqUTGwj/qU= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= +sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= +sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= +sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= diff --git a/hack/dev-mounter/main.go b/hack/dev-mounter/main.go index bd01ae939e5b9..61988b2daa275 100644 --- a/hack/dev-mounter/main.go +++ b/hack/dev-mounter/main.go @@ -97,12 +97,15 @@ func newCommand() *cobra.Command { kubeClient := kubernetes.NewForConfigOrDie(config) factory := informers.NewSharedInformerFactoryWithOptions(kubeClient, 1*time.Minute, informers.WithNamespace(ns)) informer := factory.Core().V1().ConfigMaps().Informer() - informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ + _, err = informer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: handledConfigMap, UpdateFunc: func(oldObj, newObj interface{}) { handledConfigMap(newObj) }, }) + if err != nil { + log.Error(err) + } informer.Run(context.Background().Done()) }, } diff --git a/hack/gen-resources/generators/cluster_generator.go b/hack/gen-resources/generators/cluster_generator.go index eec1cdfe3cc2e..6f125723c35ef 100644 --- a/hack/gen-resources/generators/cluster_generator.go +++ b/hack/gen-resources/generators/cluster_generator.go @@ -99,7 +99,7 @@ func (cg *ClusterGenerator) getClusterCredentials(namespace string, releaseSuffi return nil, nil, nil, err } - err = exec.Stream(remotecommand.StreamOptions{ + err = exec.StreamWithContext(context.Background(), remotecommand.StreamOptions{ Stdin: &stdin, Stdout: &stdout, Stderr: &stderr, diff --git a/pkg/apis/application/v1alpha1/applicationset_types_test.go b/pkg/apis/application/v1alpha1/applicationset_types_test.go index 1f9dc64b1fdb3..282cc1ca9a423 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types_test.go +++ b/pkg/apis/application/v1alpha1/applicationset_types_test.go @@ -173,9 +173,9 @@ func TestSCMProviderGeneratorGitlab_WillIncludeSharedProjects(t *testing.T) { settings := SCMProviderGeneratorGitlab{} assert.True(t, settings.WillIncludeSharedProjects()) - settings.IncludeSharedProjects = pointer.BoolPtr(false) + settings.IncludeSharedProjects = pointer.Bool(false) assert.False(t, settings.WillIncludeSharedProjects()) - settings.IncludeSharedProjects = pointer.BoolPtr(true) + settings.IncludeSharedProjects = pointer.Bool(true) assert.True(t, settings.WillIncludeSharedProjects()) } diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index 35b49f8e91c70..668cf97b07e5a 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -646,7 +646,7 @@ func TestAppProject_ValidateDestinations(t *testing.T) { err = p.ValidateProject() assert.NoError(t, err) - //no duplicates allowed + // no duplicates allowed p.Spec.Destinations = []ApplicationDestination{validDestination, validDestination} err = p.ValidateProject() assert.Error(t, err) @@ -2966,7 +2966,7 @@ func TestRetryStrategy_NextRetryAtCustomBackoff(t *testing.T) { retry := RetryStrategy{ Backoff: &Backoff{ Duration: "2s", - Factor: pointer.Int64Ptr(3), + Factor: pointer.Int64(3), MaxDuration: "1m", }, } @@ -3075,10 +3075,10 @@ func TestOrphanedResourcesMonitorSettings_IsWarn(t *testing.T) { settings := OrphanedResourcesMonitorSettings{} assert.False(t, settings.IsWarn()) - settings.Warn = pointer.BoolPtr(false) + settings.Warn = pointer.Bool(false) assert.False(t, settings.IsWarn()) - settings.Warn = pointer.BoolPtr(true) + settings.Warn = pointer.Bool(true) assert.True(t, settings.IsWarn()) } diff --git a/pkg/client/clientset/versioned/clientset.go b/pkg/client/clientset/versioned/clientset.go index 0c0911e0387c5..869b10d0f82d6 100644 --- a/pkg/client/clientset/versioned/clientset.go +++ b/pkg/client/clientset/versioned/clientset.go @@ -17,8 +17,7 @@ type Interface interface { ArgoprojV1alpha1() argoprojv1alpha1.ArgoprojV1alpha1Interface } -// Clientset contains the clients for groups. Each group has exactly one -// version included in a Clientset. +// Clientset contains the clients for groups. type Clientset struct { *discovery.DiscoveryClient argoprojV1alpha1 *argoprojv1alpha1.ArgoprojV1alpha1Client diff --git a/pkg/client/informers/externalversions/factory.go b/pkg/client/informers/externalversions/factory.go index 57bd66c672490..7d04eeb35ed52 100644 --- a/pkg/client/informers/externalversions/factory.go +++ b/pkg/client/informers/externalversions/factory.go @@ -31,6 +31,11 @@ type sharedInformerFactory struct { // startedInformers is used for tracking which informers have been started. // This allows Start() to be called multiple times safely. startedInformers map[reflect.Type]bool + // wg tracks how many goroutines were started. + wg sync.WaitGroup + // shuttingDown is true when Shutdown has been called. It may still be running + // because it needs to wait for goroutines. + shuttingDown bool } // WithCustomResyncConfig sets a custom resync period for the specified informer types. @@ -91,20 +96,39 @@ func NewSharedInformerFactoryWithOptions(client versioned.Interface, defaultResy return factory } -// Start initializes all requested informers. func (f *sharedInformerFactory) Start(stopCh <-chan struct{}) { f.lock.Lock() defer f.lock.Unlock() + if f.shuttingDown { + return + } + for informerType, informer := range f.informers { if !f.startedInformers[informerType] { - go informer.Run(stopCh) + f.wg.Add(1) + // We need a new variable in each loop iteration, + // otherwise the goroutine would use the loop variable + // and that keeps changing. + informer := informer + go func() { + defer f.wg.Done() + informer.Run(stopCh) + }() f.startedInformers[informerType] = true } } } -// WaitForCacheSync waits for all started informers' cache were synced. +func (f *sharedInformerFactory) Shutdown() { + f.lock.Lock() + f.shuttingDown = true + f.lock.Unlock() + + // Will return immediately if there is nothing to wait for. + f.wg.Wait() +} + func (f *sharedInformerFactory) WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool { informers := func() map[reflect.Type]cache.SharedIndexInformer { f.lock.Lock() @@ -151,11 +175,58 @@ func (f *sharedInformerFactory) InformerFor(obj runtime.Object, newFunc internal // SharedInformerFactory provides shared informers for resources in all known // API group versions. +// +// It is typically used like this: +// +// ctx, cancel := context.Background() +// defer cancel() +// factory := NewSharedInformerFactory(client, resyncPeriod) +// defer factory.WaitForStop() // Returns immediately if nothing was started. +// genericInformer := factory.ForResource(resource) +// typedInformer := factory.SomeAPIGroup().V1().SomeType() +// factory.Start(ctx.Done()) // Start processing these informers. +// synced := factory.WaitForCacheSync(ctx.Done()) +// for v, ok := range synced { +// if !ok { +// fmt.Fprintf(os.Stderr, "caches failed to sync: %v", v) +// return +// } +// } +// +// // Creating informers can also be created after Start, but then +// // Start must be called again: +// anotherGenericInformer := factory.ForResource(resource) +// factory.Start(ctx.Done()) type SharedInformerFactory interface { internalinterfaces.SharedInformerFactory - ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // Start initializes all requested informers. They are handled in goroutines + // which run until the stop channel gets closed. + Start(stopCh <-chan struct{}) + + // Shutdown marks a factory as shutting down. At that point no new + // informers can be started anymore and Start will return without + // doing anything. + // + // In addition, Shutdown blocks until all goroutines have terminated. For that + // to happen, the close channel(s) that they were started with must be closed, + // either before Shutdown gets called or while it is waiting. + // + // Shutdown may be called multiple times, even concurrently. All such calls will + // block until all goroutines have terminated. + Shutdown() + + // WaitForCacheSync blocks until all started informers' caches were synced + // or the stop channel gets closed. WaitForCacheSync(stopCh <-chan struct{}) map[reflect.Type]bool + // ForResource gives generic access to a shared informer of the matching type. + ForResource(resource schema.GroupVersionResource) (GenericInformer, error) + + // InternalInformerFor returns the SharedIndexInformer for obj using an internal + // client. + InformerFor(obj runtime.Object, newFunc internalinterfaces.NewInformerFunc) cache.SharedIndexInformer + Argoproj() application.Interface } diff --git a/server/application/application.go b/server/application/application.go index 12484685e52b3..ec600d29b3c6b 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -116,7 +116,10 @@ func NewServer( if appBroadcaster == nil { appBroadcaster = &broadcasterHandler{} } - appInformer.AddEventHandler(appBroadcaster) + _, err := appInformer.AddEventHandler(appBroadcaster) + if err != nil { + log.Error(err) + } s := &Server{ ns: namespace, appclientset: appclientset, @@ -1216,9 +1219,9 @@ func (s *Server) getCachedAppState(ctx context.Context, a *appv1.Application, ge return errors.New(argoutil.FormatAppConditions(conditions)) } _, err = s.Get(ctx, &application.ApplicationQuery{ - Name: pointer.StringPtr(a.GetName()), - AppNamespace: pointer.StringPtr(a.GetNamespace()), - Refresh: pointer.StringPtr(string(appv1.RefreshTypeNormal)), + Name: pointer.String(a.GetName()), + AppNamespace: pointer.String(a.GetNamespace()), + Refresh: pointer.String(string(appv1.RefreshTypeNormal)), }) if err != nil { return fmt.Errorf("error getting application by query: %w", err) diff --git a/server/application/application_test.go b/server/application/application_test.go index 56be539e48ac0..c0f7d000b1506 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -209,7 +209,7 @@ func newTestAppServerWithEnforcerConfigure(f func(*rbac.Enforcer), t *testing.T, // populate the app informer with the fake objects appInformer := factory.Argoproj().V1alpha1().Applications().Informer() // TODO(jessesuen): probably should return cancel function so tests can stop background informer - //ctx, cancel := context.WithCancel(context.Background()) + // ctx, cancel := context.WithCancel(context.Background()) go appInformer.Run(ctx.Done()) if !k8scache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced) { panic("Timed out waiting for caches to sync") @@ -1136,7 +1136,7 @@ func testListAppsWithLabels(t *testing.T, appQuery application.ApplicationQuery, label: "!key2", expectedResult: []string{"App2", "App3"}}, } - //test valid scenarios + // test valid scenarios for _, validTest := range validTests { t.Run(validTest.testName, func(t *testing.T) { appQuery.Selector = &validTest.label @@ -1162,7 +1162,7 @@ func testListAppsWithLabels(t *testing.T, appQuery application.ApplicationQuery, label: "key1 Date: Thu, 19 Oct 2023 00:38:04 +0530 Subject: [PATCH 019/269] feat: use rate limited queue (#15480) * feat: use rate limited queue Signed-off-by: Soumya Ghosh Dastidar --- .../commands/argocd_application_controller.go | 12 ++ controller/appcontroller.go | 30 +++-- controller/appcontroller_test.go | 11 +- docs/operator-manual/high_availability.md | 53 ++++++++ .../argocd-application-controller.md | 6 + go.mod | 2 +- pkg/ratelimiter/ratelimiter.go | 123 ++++++++++++++++++ util/env/env.go | 27 ++++ 8 files changed, 247 insertions(+), 17 deletions(-) create mode 100644 pkg/ratelimiter/ratelimiter.go diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index a43174633b02a..39d8e017b7f26 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -6,6 +6,7 @@ import ( "math" "time" + "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" "github.com/argoproj/pkg/stats" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" @@ -45,6 +46,7 @@ const ( func NewCommand() *cobra.Command { var ( + workqueueRateLimit ratelimiter.AppControllerRateLimiterConfig clientConfig clientcmd.ClientConfig appResyncPeriod int64 appHardResyncPeriod int64 @@ -160,6 +162,7 @@ func NewCommand() *cobra.Command { persistResourceHealth, clusterFilter, applicationNamespaces, + &workqueueRateLimit, ) errors.CheckError(err) cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer()) @@ -205,6 +208,15 @@ func NewCommand() *cobra.Command { command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that applications are allowed to be reconciled from") command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", true), "Enables storing the managed resources health in the Application CRD") command.Flags().StringVar(&shardingAlgorithm, "sharding-method", env.StringFromEnv(common.EnvControllerShardingAlgorithm, common.DefaultShardingAlgorithm), "Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin] ") + // global queue rate limit config + command.Flags().Int64Var(&workqueueRateLimit.BucketSize, "wq-bucket-size", env.ParseInt64FromEnv("WORKQUEUE_BUCKET_SIZE", 500, 1, math.MaxInt64), "Set Workqueue Rate Limiter Bucket Size, default 500") + command.Flags().Int64Var(&workqueueRateLimit.BucketQPS, "wq-bucket-qps", env.ParseInt64FromEnv("WORKQUEUE_BUCKET_QPS", 50, 1, math.MaxInt64), "Set Workqueue Rate Limiter Bucket QPS, default 50") + // individual item rate limit config + // when WORKQUEUE_FAILURE_COOLDOWN is 0 per item rate limiting is disabled(default) + command.Flags().DurationVar(&workqueueRateLimit.FailureCoolDown, "wq-cooldown-ns", time.Duration(env.ParseInt64FromEnv("WORKQUEUE_FAILURE_COOLDOWN_NS", 0, 0, (24*time.Hour).Nanoseconds())), "Set Workqueue Per Item Rate Limiter Cooldown duration in ns, default 0(per item rate limiter disabled)") + command.Flags().DurationVar(&workqueueRateLimit.BaseDelay, "wq-basedelay-ns", time.Duration(env.ParseInt64FromEnv("WORKQUEUE_BASE_DELAY_NS", time.Millisecond.Nanoseconds(), time.Nanosecond.Nanoseconds(), (24*time.Hour).Nanoseconds())), "Set Workqueue Per Item Rate Limiter Base Delay duration in nanoseconds, default 1000000 (1ms)") + command.Flags().DurationVar(&workqueueRateLimit.MaxDelay, "wq-maxdelay-ns", time.Duration(env.ParseInt64FromEnv("WORKQUEUE_MAX_DELAY_NS", time.Second.Nanoseconds(), 1*time.Millisecond.Nanoseconds(), (24*time.Hour).Nanoseconds())), "Set Workqueue Per Item Rate Limiter Max Delay duration in nanoseconds, default 1000000000 (1s)") + command.Flags().Float64Var(&workqueueRateLimit.BackoffFactor, "wq-backoff-factor", env.ParseFloat64FromEnv("WORKQUEUE_BACKOFF_FACTOR", 1.5, 0, math.MaxFloat64), "Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5") command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.") cacheSource = appstatecache.AddCacheFlagsToCmd(&command, func(client *redis.Client) { redisClient = client diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 4cae0dc486761..46e3ede0f3a3e 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -14,6 +14,7 @@ import ( "sync" "time" + "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" clustercache "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/health" @@ -148,9 +149,14 @@ func NewApplicationController( persistResourceHealth bool, clusterFilter func(cluster *appv1.Cluster) bool, applicationNamespaces []string, + rateLimiterConfig *ratelimiter.AppControllerRateLimiterConfig, ) (*ApplicationController, error) { log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v", appResyncPeriod, appHardResyncPeriod) db := db.NewDB(namespace, settingsMgr, kubeClientset) + if rateLimiterConfig == nil { + rateLimiterConfig = ratelimiter.GetDefaultAppRateLimiterConfig() + log.Info("Using default workqueue rate limiter config") + } ctrl := ApplicationController{ cache: argoCache, namespace: namespace, @@ -158,10 +164,10 @@ func NewApplicationController( kubectl: kubectl, applicationClientset: applicationClientset, repoClientset: repoClientset, - appRefreshQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "app_reconciliation_queue"), - appOperationQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "app_operation_processing_queue"), - projectRefreshQueue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "project_reconciliation_queue"), - appComparisonTypeRefreshQueue: workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter()), + appRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_reconciliation_queue"), + appOperationQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_operation_processing_queue"), + projectRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "project_reconciliation_queue"), + appComparisonTypeRefreshQueue: workqueue.NewRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig)), db: db, statusRefreshTimeout: appResyncPeriod, statusHardRefreshTimeout: appHardResyncPeriod, @@ -185,7 +191,7 @@ func NewApplicationController( _, err = projInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { if key, err := cache.MetaNamespaceKeyFunc(obj); err == nil { - ctrl.projectRefreshQueue.Add(key) + ctrl.projectRefreshQueue.AddRateLimited(key) if projMeta, ok := obj.(metav1.Object); ok { ctrl.InvalidateProjectsCache(projMeta.GetName()) } @@ -194,7 +200,7 @@ func NewApplicationController( }, UpdateFunc: func(old, new interface{}) { if key, err := cache.MetaNamespaceKeyFunc(new); err == nil { - ctrl.projectRefreshQueue.Add(key) + ctrl.projectRefreshQueue.AddRateLimited(key) if projMeta, ok := new.(metav1.Object); ok { ctrl.InvalidateProjectsCache(projMeta.GetName()) } @@ -202,6 +208,7 @@ func NewApplicationController( }, DeleteFunc: func(obj interface{}) { if key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj); err == nil { + // immediately push to queue for deletes ctrl.projectRefreshQueue.Add(key) if projMeta, ok := obj.(metav1.Object); ok { ctrl.InvalidateProjectsCache(projMeta.GetName()) @@ -815,8 +822,8 @@ func (ctrl *ApplicationController) requestAppRefresh(appName string, compareWith ctrl.appRefreshQueue.AddAfter(key, *after) ctrl.appOperationQueue.AddAfter(key, *after) } else { - ctrl.appRefreshQueue.Add(key) - ctrl.appOperationQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) + ctrl.appOperationQueue.AddRateLimited(key) } } } @@ -1991,8 +1998,8 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar } key, err := cache.MetaNamespaceKeyFunc(obj) if err == nil { - ctrl.appRefreshQueue.Add(key) - ctrl.appOperationQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) + ctrl.appOperationQueue.AddRateLimited(key) } }, UpdateFunc: func(old, new interface{}) { @@ -2012,7 +2019,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar compareWith = CompareWithLatest.Pointer() } ctrl.requestAppRefresh(newApp.QualifiedName(), compareWith, nil) - ctrl.appOperationQueue.Add(key) + ctrl.appOperationQueue.AddRateLimited(key) }, DeleteFunc: func(obj interface{}) { if !ctrl.canProcessApp(obj) { @@ -2022,6 +2029,7 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar // key function. key, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) if err == nil { + // for deletes, we immediately add to the refresh queue ctrl.appRefreshQueue.Add(key) } }, diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index cfb2141664348..2129c88885fff 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -123,6 +123,7 @@ func newFakeController(data *fakeData) *ApplicationController { true, nil, data.applicationNamespaces, + nil, ) if err != nil { panic(err) @@ -793,7 +794,7 @@ func TestNormalizeApplication(t *testing.T) { // Verify we normalize the app because project is missing ctrl := newFakeController(&data) key, _ := cache.MetaNamespaceKeyFunc(app) - ctrl.appRefreshQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil normalized := false @@ -815,7 +816,7 @@ func TestNormalizeApplication(t *testing.T) { data.apps[0] = app ctrl := newFakeController(&data) key, _ := cache.MetaNamespaceKeyFunc(app) - ctrl.appRefreshQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil normalized := false @@ -1278,7 +1279,7 @@ func TestUpdateReconciledAt(t *testing.T) { t.Run("UpdatedOnFullReconciliation", func(t *testing.T) { receivedPatch = map[string]interface{}{} ctrl.requestAppRefresh(app.Name, CompareWithLatest.Pointer(), nil) - ctrl.appRefreshQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) ctrl.processAppRefreshQueueItem() @@ -1293,7 +1294,7 @@ func TestUpdateReconciledAt(t *testing.T) { t.Run("NotUpdatedOnPartialReconciliation", func(t *testing.T) { receivedPatch = map[string]interface{}{} - ctrl.appRefreshQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), nil) ctrl.processAppRefreshQueueItem() @@ -1323,7 +1324,7 @@ func TestProjectErrorToCondition(t *testing.T) { managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), }) key, _ := cache.MetaNamespaceKeyFunc(app) - ctrl.appRefreshQueue.Add(key) + ctrl.appRefreshQueue.AddRateLimited(key) ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), nil) ctrl.processAppRefreshQueueItem() diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index ac59c333ba7cb..db4cb0a6e077e 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -243,3 +243,56 @@ spec: path: my-application # ... ``` + +## Rate Limiting Application Reconciliations + +To prevent high controller resource usage or sync loops caused either due to misbehaving apps or other environment specific factors, +we can configure rate limits on the workqueues used by the application controller. There are two types of rate limits that can be configured: + + * Global rate limits + * Per item rate limits + +The final rate limiter uses a combination of both and calculates the final backoff as `max(globalBackoff, perItemBackoff)`. + +### Global rate limits + + This is enabled by default, it is a simple bucket based rate limiter that limits the number of items that can be queued per second. +This is useful to prevent a large number of apps from being queued at the same time. + +To configure the bucket limiter you can set the following environment variables: + + * `WORKQUEUE_BUCKET_SIZE` - The number of items that can be queued in a single burst. Defaults to 500. + * `WORKQUEUE_BUCKET_QPS` - The number of items that can be queued per second. Defaults to 50. + +### Per item rate limits + + This by default returns a fixed base delay/backoff value but can be configured to return exponential values, read further to understand it's working. +Per item rate limiter limits the number of times a particular item can be queued. This is based on exponential backoff where the backoff time for an item keeps increasing exponentially +if it is queued multiple times in a short period, but the backoff is reset automatically if a configured `cool down` period has elapsed since the last time the item was queued. + +To configure the per item limiter you can set the following environment variables: + + * `WORKQUEUE_FAILURE_COOLDOWN_NS` : The cool down period in nanoseconds, once period has elapsed for an item the backoff is reset. Exponential backoff is disabled if set to 0(default), eg. values : 10 * 10^9 (=10s) + * `WORKQUEUE_BASE_DELAY_NS` : The base delay in nanoseconds, this is the initial backoff used in the exponential backoff formula. Defaults to 1000 (=1μs) + * `WORKQUEUE_MAX_DELAY_NS` : The max delay in nanoseconds, this is the max backoff limit. Defaults to 3 * 10^9 (=3s) + * `WORKQUEUE_BACKOFF_FACTOR` : The backoff factor, this is the factor by which the backoff is increased for each retry. Defaults to 1.5 + +The formula used to calculate the backoff time for an item, where `numRequeue` is the number of times the item has been queued +and `lastRequeueTime` is the time at which the item was last queued: + +- When `WORKQUEUE_FAILURE_COOLDOWN_NS` != 0 : + +``` +backoff = time.Since(lastRequeueTime) >= WORKQUEUE_FAILURE_COOLDOWN_NS ? + WORKQUEUE_BASE_DELAY_NS : + min( + WORKQUEUE_MAX_DELAY_NS, + WORKQUEUE_BASE_DELAY_NS * WORKQUEUE_BACKOFF_FACTOR ^ (numRequeue) + ) +``` + +- When `WORKQUEUE_FAILURE_COOLDOWN_NS` = 0 : + +``` +backoff = WORKQUEUE_BASE_DELAY_NS +``` \ No newline at end of file diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 5b107253088e8..99e4c42df28db 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -70,5 +70,11 @@ argocd-application-controller [flags] --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use --username string Username for basic authentication to the API server + --wq-backoff-factor float Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5 (default 1.5) + --wq-basedelay-ns duration Set Workqueue Per Item Rate Limiter Base Delay duration in nanoseconds, default 1000000 (1ms) (default 1ms) + --wq-bucket-qps int Set Workqueue Rate Limiter Bucket QPS, default 50 (default 50) + --wq-bucket-size int Set Workqueue Rate Limiter Bucket Size, default 500 (default 500) + --wq-cooldown-ns duration Set Workqueue Per Item Rate Limiter Cooldown duration in ns, default 0(per item rate limiter disabled) + --wq-maxdelay-ns duration Set Workqueue Per Item Rate Limiter Max Delay duration in nanoseconds, default 1000000000 (1s) (default 1s) ``` diff --git a/go.mod b/go.mod index d95edd4ef6210..fe2500918c40f 100644 --- a/go.mod +++ b/go.mod @@ -265,7 +265,7 @@ require ( golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.3.0 golang.org/x/tools v0.7.0 // indirect gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect diff --git a/pkg/ratelimiter/ratelimiter.go b/pkg/ratelimiter/ratelimiter.go new file mode 100644 index 0000000000000..32507d883e8ae --- /dev/null +++ b/pkg/ratelimiter/ratelimiter.go @@ -0,0 +1,123 @@ +package ratelimiter + +import ( + "math" + "sync" + "time" + + "golang.org/x/time/rate" + "k8s.io/client-go/util/workqueue" +) + +type AppControllerRateLimiterConfig struct { + BucketSize int64 + BucketQPS int64 + FailureCoolDown time.Duration + BaseDelay time.Duration + MaxDelay time.Duration + BackoffFactor float64 +} + +func GetDefaultAppRateLimiterConfig() *AppControllerRateLimiterConfig { + return &AppControllerRateLimiterConfig{ + // global queue rate limit config + 500, + 50, + // individual item rate limit config + // when WORKQUEUE_FAILURE_COOLDOWN is 0 per item rate limiting is disabled(default) + 0, + time.Millisecond, + time.Second, + 1.5, + } +} + +// NewCustomAppControllerRateLimiter is a constructor for the rate limiter for a workqueue used by app controller. It has +// both overall and per-item rate limiting. The overall is a token bucket and the per-item is exponential(with auto resets) +func NewCustomAppControllerRateLimiter(cfg *AppControllerRateLimiterConfig) workqueue.RateLimiter { + return workqueue.NewMaxOfRateLimiter( + NewItemExponentialRateLimiterWithAutoReset(cfg.BaseDelay, cfg.MaxDelay, cfg.FailureCoolDown, cfg.BackoffFactor), + &workqueue.BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(cfg.BucketQPS), int(cfg.BucketSize))}, + ) +} + +type failureData struct { + failures int + lastFailure time.Time +} + +// ItemExponentialRateLimiterWithAutoReset does a simple baseDelay*2^ limit +// dealing with max failures and expiration/resets are up dependent on the cooldown period +type ItemExponentialRateLimiterWithAutoReset struct { + failuresLock sync.Mutex + failures map[interface{}]failureData + + baseDelay time.Duration + maxDelay time.Duration + coolDown time.Duration + backoffFactor float64 +} + +var _ workqueue.RateLimiter = &ItemExponentialRateLimiterWithAutoReset{} + +func NewItemExponentialRateLimiterWithAutoReset(baseDelay, maxDelay, failureCoolDown time.Duration, backoffFactor float64) workqueue.RateLimiter { + return &ItemExponentialRateLimiterWithAutoReset{ + failures: map[interface{}]failureData{}, + baseDelay: baseDelay, + maxDelay: maxDelay, + coolDown: failureCoolDown, + backoffFactor: backoffFactor, + } +} + +func (r *ItemExponentialRateLimiterWithAutoReset) When(item interface{}) time.Duration { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + if _, ok := r.failures[item]; !ok { + r.failures[item] = failureData{ + failures: 0, + lastFailure: time.Now(), + } + } + + exp := r.failures[item] + + // if coolDown period is reached reset failures for item + if time.Since(exp.lastFailure) >= r.coolDown { + delete(r.failures, item) + return r.baseDelay + } + + r.failures[item] = failureData{ + failures: exp.failures + 1, + lastFailure: time.Now(), + } + + // The backoff is capped such that 'calculated' value never overflows. + backoff := float64(r.baseDelay.Nanoseconds()) * math.Pow(r.backoffFactor, float64(exp.failures)) + if backoff > math.MaxInt64 { + return r.maxDelay + } + + calculated := time.Duration(backoff) + if calculated > r.maxDelay { + return r.maxDelay + } + + return calculated +} + +func (r *ItemExponentialRateLimiterWithAutoReset) NumRequeues(item interface{}) int { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + return r.failures[item].failures +} + +func (r *ItemExponentialRateLimiterWithAutoReset) Forget(item interface{}) { + r.failuresLock.Lock() + defer r.failuresLock.Unlock() + + delete(r.failures, item) +} diff --git a/util/env/env.go b/util/env/env.go index 1b49a0c322065..221db7b0efaab 100644 --- a/util/env/env.go +++ b/util/env/env.go @@ -96,6 +96,33 @@ func ParseFloatFromEnv(env string, defaultValue, min, max float32) float32 { return float32(num) } +// Helper function to parse a float64 from an environment variable. Returns a +// default if env is not set, is not parseable to a number, exceeds max (if +// max is greater than 0) or is less than min (and min is greater than 0). +// +// nolint:unparam +func ParseFloat64FromEnv(env string, defaultValue, min, max float64) float64 { + str := os.Getenv(env) + if str == "" { + return defaultValue + } + + num, err := strconv.ParseFloat(str, 64) + if err != nil { + log.Warnf("Could not parse '%s' as a float32 from environment %s", str, env) + return defaultValue + } + if num < min { + log.Warnf("Value in %s is %f, which is less than minimum %f allowed", env, num, min) + return defaultValue + } + if num > max { + log.Warnf("Value in %s is %f, which is greater than maximum %f allowed", env, num, max) + return defaultValue + } + return num +} + // Helper function to parse a time duration from an environment variable. Returns a // default if env is not set, is not parseable to a duration, exceeds max (if // max is greater than 0) or is less than min. From d7cd236f21166d45673c6bcdb61f8afa2e7dfd51 Mon Sep 17 00:00:00 2001 From: BhavikaSharma Date: Wed, 18 Oct 2023 13:57:21 -0700 Subject: [PATCH 020/269] fix: Add ENV variable to configure GRPC Keep Alive Time (#15656) (#15806) * Add ENV variables to configure GRPC Keep Alive Time Signed-off-by: Bhavika Sharma * Retrigger CI pipeline Signed-off-by: Bhavika Sharma * Resolve conflict with master Signed-off-by: Bhavika Sharma * Update docs/user-guide/environment-variables.md Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Signed-off-by: BhavikaSharma --------- Signed-off-by: Bhavika Sharma Signed-off-by: BhavikaSharma Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- cmpserver/server.go | 2 +- common/common.go | 23 ++++++++++-- common/common_test.go | 46 ++++++++++++++++++++++++ docs/user-guide/environment-variables.md | 1 + pkg/apiclient/grpcproxy.go | 2 +- reposerver/server.go | 2 +- server/server.go | 2 +- util/grpc/grpc.go | 2 +- 8 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 common/common_test.go diff --git a/cmpserver/server.go b/cmpserver/server.go index bbb493f6b1d66..1d07e531394d3 100644 --- a/cmpserver/server.go +++ b/cmpserver/server.go @@ -65,7 +65,7 @@ func NewServer(initConstants plugin.CMPServerInitConstants) (*ArgoCDCMPServer, e grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize), grpc.KeepaliveEnforcementPolicy( keepalive.EnforcementPolicy{ - MinTime: common.GRPCKeepAliveEnforcementMinimum, + MinTime: common.GetGRPCKeepAliveEnforcementMinimum(), }, ), } diff --git a/common/common.go b/common/common.go index d7c2d24738b58..5faedc2e344c4 100644 --- a/common/common.go +++ b/common/common.go @@ -258,6 +258,8 @@ const ( EnvRedisName = "ARGOCD_REDIS_NAME" // EnvRedisHaProxyName is the name of the Argo CD Redis HA proxy component, as specified by the value under the LabelKeyAppName label key. EnvRedisHaProxyName = "ARGOCD_REDIS_HAPROXY_NAME" + // EnvGRPCKeepAliveMin defines the GRPCKeepAliveEnforcementMinimum, used in the grpc.KeepaliveEnforcementPolicy. Expects a "Duration" format (e.g. 10s). + EnvGRPCKeepAliveMin = "ARGOCD_GRPC_KEEP_ALIVE_MIN" ) // Config Management Plugin related constants @@ -351,11 +353,26 @@ const ( // gRPC settings const ( - GRPCKeepAliveEnforcementMinimum = 10 * time.Second - // GRPCKeepAliveTime is 2x enforcement minimum to ensure network jitter does not introduce ENHANCE_YOUR_CALM errors - GRPCKeepAliveTime = 2 * GRPCKeepAliveEnforcementMinimum + defaultGRPCKeepAliveEnforcementMinimum = 10 * time.Second ) +func GetGRPCKeepAliveEnforcementMinimum() time.Duration { + if GRPCKeepAliveMinStr := os.Getenv(EnvGRPCKeepAliveMin); GRPCKeepAliveMinStr != "" { + GRPCKeepAliveMin, err := time.ParseDuration(GRPCKeepAliveMinStr) + if err != nil { + logrus.Warnf("invalid env var value for %s: cannot parse: %s. Default value %s will be used.", EnvGRPCKeepAliveMin, err, defaultGRPCKeepAliveEnforcementMinimum) + return defaultGRPCKeepAliveEnforcementMinimum + } + return GRPCKeepAliveMin + } + return defaultGRPCKeepAliveEnforcementMinimum +} + +func GetGRPCKeepAliveTime() time.Duration { + // GRPCKeepAliveTime is 2x enforcement minimum to ensure network jitter does not introduce ENHANCE_YOUR_CALM errors + return 2 * GetGRPCKeepAliveEnforcementMinimum() +} + // Security severity logging const ( SecurityField = "security" diff --git a/common/common_test.go b/common/common_test.go new file mode 100644 index 0000000000000..5632c1e7a78cc --- /dev/null +++ b/common/common_test.go @@ -0,0 +1,46 @@ +package common + +import ( + "fmt" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +// Test env var not set for EnvGRPCKeepAliveMin +func Test_GRPCKeepAliveMinNotSet(t *testing.T) { + grpcKeepAliveMin := GetGRPCKeepAliveEnforcementMinimum() + grpcKeepAliveExpectedMin := defaultGRPCKeepAliveEnforcementMinimum + assert.Equal(t, grpcKeepAliveExpectedMin, grpcKeepAliveMin) + + grpcKeepAliveTime := GetGRPCKeepAliveTime() + assert.Equal(t, 2*grpcKeepAliveExpectedMin, grpcKeepAliveTime) +} + +// Test valid env var set for EnvGRPCKeepAliveMin +func Test_GRPCKeepAliveMinIsSet(t *testing.T) { + numSeconds := 15 + os.Setenv(EnvGRPCKeepAliveMin, fmt.Sprintf("%ds", numSeconds)) + + grpcKeepAliveMin := GetGRPCKeepAliveEnforcementMinimum() + grpcKeepAliveExpectedMin := time.Duration(numSeconds) * time.Second + assert.Equal(t, grpcKeepAliveExpectedMin, grpcKeepAliveMin) + + grpcKeepAliveTime := GetGRPCKeepAliveTime() + assert.Equal(t, 2*grpcKeepAliveExpectedMin, grpcKeepAliveTime) +} + +// Test invalid env var set for EnvGRPCKeepAliveMin +func Test_GRPCKeepAliveMinIncorrectlySet(t *testing.T) { + numSeconds := 15 + os.Setenv(EnvGRPCKeepAliveMin, fmt.Sprintf("%d", numSeconds)) + + grpcKeepAliveMin := GetGRPCKeepAliveEnforcementMinimum() + grpcKeepAliveExpectedMin := defaultGRPCKeepAliveEnforcementMinimum + assert.Equal(t, grpcKeepAliveExpectedMin, grpcKeepAliveMin) + + grpcKeepAliveTime := GetGRPCKeepAliveTime() + assert.Equal(t, 2*grpcKeepAliveExpectedMin, grpcKeepAliveTime) +} diff --git a/docs/user-guide/environment-variables.md b/docs/user-guide/environment-variables.md index 238db85b5c718..c990073363f04 100644 --- a/docs/user-guide/environment-variables.md +++ b/docs/user-guide/environment-variables.md @@ -12,3 +12,4 @@ The following environment variables can be used with `argocd` CLI: | `ARGOCD_APPLICATION_CONTROLLER_NAME` | the Argo CD Application Controller name (default "argocd-application-controller") | | `ARGOCD_REDIS_NAME` | the Argo CD Redis name (default "argocd-redis") | | `ARGOCD_REDIS_HAPROXY_NAME` | the Argo CD Redis HA Proxy name (default "argocd-redis-ha-haproxy") | +| `ARGOCD_GRPC_KEEP_ALIVE_MIN` | defines the GRPCKeepAliveEnforcementMinimum, used in the grpc.KeepaliveEnforcementPolicy. Expects a "Duration" format (default `10s`). | diff --git a/pkg/apiclient/grpcproxy.go b/pkg/apiclient/grpcproxy.go index dcbb3b296833e..28af7b62783df 100644 --- a/pkg/apiclient/grpcproxy.go +++ b/pkg/apiclient/grpcproxy.go @@ -116,7 +116,7 @@ func (c *client) startGRPCProxy() (*grpc.Server, net.Listener, error) { grpc.ForceServerCodec(&noopCodec{}), grpc.KeepaliveEnforcementPolicy( keepalive.EnforcementPolicy{ - MinTime: common.GRPCKeepAliveEnforcementMinimum, + MinTime: common.GetGRPCKeepAliveEnforcementMinimum(), }, ), grpc.UnknownServiceHandler(func(srv interface{}, stream grpc.ServerStream) error { diff --git a/reposerver/server.go b/reposerver/server.go index 9576604751dfc..007b7136e41ed 100644 --- a/reposerver/server.go +++ b/reposerver/server.go @@ -90,7 +90,7 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach grpc.MaxSendMsgSize(apiclient.MaxGRPCMessageSize), grpc.KeepaliveEnforcementPolicy( keepalive.EnforcementPolicy{ - MinTime: common.GRPCKeepAliveEnforcementMinimum, + MinTime: common.GetGRPCKeepAliveEnforcementMinimum(), }, ), } diff --git a/server/server.go b/server/server.go index a0fc5327e985c..b4225dfdc51b8 100644 --- a/server/server.go +++ b/server/server.go @@ -731,7 +731,7 @@ func (a *ArgoCDServer) newGRPCServer() (*grpc.Server, application.AppResourceTre grpc.ConnectionTimeout(300 * time.Second), grpc.KeepaliveEnforcementPolicy( keepalive.EnforcementPolicy{ - MinTime: common.GRPCKeepAliveEnforcementMinimum, + MinTime: common.GetGRPCKeepAliveEnforcementMinimum(), }, ), } diff --git a/util/grpc/grpc.go b/util/grpc/grpc.go index 323d78398a8ce..1741727a5d604 100644 --- a/util/grpc/grpc.go +++ b/util/grpc/grpc.go @@ -88,7 +88,7 @@ func BlockingDial(ctx context.Context, network, address string, creds credential grpc.FailOnNonTempDialError(true), grpc.WithContextDialer(dialer), grpc.WithTransportCredentials(insecure.NewCredentials()), // we are handling TLS, so tell grpc not to - grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: common.GRPCKeepAliveTime}), + grpc.WithKeepaliveParams(keepalive.ClientParameters{Time: common.GetGRPCKeepAliveTime()}), ) conn, err := grpc.DialContext(ctx, address, opts...) var res interface{} From ab1cc50a8379f93530d33d3118eccaf53e324d70 Mon Sep 17 00:00:00 2001 From: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> Date: Thu, 19 Oct 2023 18:49:26 +0530 Subject: [PATCH 021/269] add example to --help command in argocd_admin_dashboard.md file (#16034) Signed-off-by: Harshvir Potpose --- cmd/argocd/commands/admin/dashboard.go | 9 +++++++++ docs/user-guide/commands/argocd_admin_dashboard.md | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/cmd/argocd/commands/admin/dashboard.go b/cmd/argocd/commands/admin/dashboard.go index c75476ea8eb2d..33d2866e1f1c0 100644 --- a/cmd/argocd/commands/admin/dashboard.go +++ b/cmd/argocd/commands/admin/dashboard.go @@ -32,6 +32,15 @@ func NewDashboardCommand() *cobra.Command { println(fmt.Sprintf("Argo CD UI is available at http://%s:%d", address, port)) <-ctx.Done() }, + Example: `# Start the Argo CD Web UI locally on the default port and address +$ argocd admin dashboard + +# Start the Argo CD Web UI locally on a custom port and address +$ argocd admin dashboard --port 8080 --address 127.0.0.1 + +# Start the Argo CD Web UI with GZip compression +$ argocd admin dashboard --redis-compress gzip + `, } initialize.InitCommand(cmd) cmd.Flags().IntVar(&port, "port", common.DefaultPortAPIServer, "Listen on given port") diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index 5dcfb31cf5a2c..be4d5c18468ab 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -8,6 +8,20 @@ Starts Argo CD Web UI locally argocd admin dashboard [flags] ``` +### Examples + +``` +# Start the Argo CD Web UI locally on the default port and address +$ argocd admin dashboard + +# Start the Argo CD Web UI locally on a custom port and address +$ argocd admin dashboard --port 8080 --address 127.0.0.1 + +# Start the Argo CD Web UI with GZip compression +$ argocd admin dashboard --redis-compress gzip + +``` + ### Options ``` From 3e643843ddb7bd3ae9c46da31e6b8f987fcdcdf1 Mon Sep 17 00:00:00 2001 From: "Yuan (Terry) Tang" Date: Thu, 19 Oct 2023 11:17:11 -0400 Subject: [PATCH 022/269] chore: Revert "fix: Replace antonmedv/expr with expr-lang/expr" (#16027) Signed-off-by: Yuan Tang --- go.mod | 1 - go.sum | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fe2500918c40f..2dc71e929b0e9 100644 --- a/go.mod +++ b/go.mod @@ -287,7 +287,6 @@ require ( ) replace ( - github.com/antonmedv/expr => github.com/expr-lang/expr v0.0.0-20230912141041-709c5dd55aa7 // https://github.com/golang/go/issues/33546#issuecomment-519656923 github.com/go-check/check => github.com/go-check/check v0.0.0-20180628173108-788fd7840127 diff --git a/go.sum b/go.sum index d9b3a9acf2e2a..fcf4a561a7511 100644 --- a/go.sum +++ b/go.sum @@ -687,6 +687,8 @@ github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6u github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antonmedv/expr v1.15.2 h1:afFXpDWIC2n3bF+kTZE1JvFo+c34uaM3sTqh8z0xfdU= +github.com/antonmedv/expr v1.15.2/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= @@ -874,8 +876,6 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= -github.com/expr-lang/expr v0.0.0-20230912141041-709c5dd55aa7 h1:Sg2XxaymeyqqaLG34aB2mvlX+nii916/Gv1ovWc4jMc= -github.com/expr-lang/expr v0.0.0-20230912141041-709c5dd55aa7/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= From bf80422a9dc8cdc41bd682c5a0ded89789389aef Mon Sep 17 00:00:00 2001 From: Christian Hernandez Date: Thu, 19 Oct 2023 09:35:31 -0700 Subject: [PATCH 023/269] added example of using build env vars in your Kustomized Argo CD Application (#16025) Signed-off-by: Christian Hernandez --- docs/user-guide/kustomize.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index ee137cab27149..9c7f7c9889b1c 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -143,6 +143,34 @@ argocd app set --kustomize-version v3.5.4 Kustomize apps have access to the [standard build environment](build-environment.md) which can be used in combination with a [config managment plugin](../operator-manual/config-management-plugins.md) to alter the rendered manifests. +You can use these build environment variables in your Argo CD Application manifests. You can enable this by setting `.spec.source.kustomize.commonAnnotationsEnvsubst` to `true` in your Application manifest. + +For example, the following Application manifest will set the `app-source` annotation to the name of the Application: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook-app + namespace: argocd +spec: + project: default + destination: + namespace: demo + server: https://kubernetes.default.svc + source: + path: kustomize-guestbook + repoURL: https://github.com/argoproj/argocd-example-apps + targetRevision: HEAD + kustomize: + commonAnnotationsEnvsubst: true + commonAnnotations: + app-source: ${ARGOCD_APP_NAME} + syncPolicy: + syncOptions: + - CreateNamespace=true +``` + ## Kustomizing Helm charts It's possible to [render Helm charts with Kustomize](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/chart.md). From 1fe6c8993ab4fa0e8430629af74d7bc6a6333a0b Mon Sep 17 00:00:00 2001 From: Nick K <83962080+nkkowa@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:42:45 -0400 Subject: [PATCH 024/269] fix: list manually provided external urls before generated ones (#13296) Signed-off-by: Nick --- controller/cache/info.go | 42 +++++++++++++++++++++++++---------- controller/cache/info_test.go | 2 +- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/controller/cache/info.go b/controller/cache/info.go index cf0d12318a447..53512de6b713a 100644 --- a/controller/cache/info.go +++ b/controller/cache/info.go @@ -37,6 +37,16 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa } } } + + for k, v := range un.GetAnnotations() { + if strings.HasPrefix(k, common.AnnotationKeyLinkPrefix) { + if res.NetworkingInfo == nil { + res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{} + } + res.NetworkingInfo.ExternalURLs = append(res.NetworkingInfo.ExternalURLs, v) + } + } + switch gvk.Group { case "": switch gvk.Kind { @@ -58,15 +68,6 @@ func populateNodeInfo(un *unstructured.Unstructured, res *ResourceInfo, customLa populateIstioVirtualServiceInfo(un, res) } } - - for k, v := range un.GetAnnotations() { - if strings.HasPrefix(k, common.AnnotationKeyLinkPrefix) { - if res.NetworkingInfo == nil { - res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{} - } - res.NetworkingInfo.ExternalURLs = append(res.NetworkingInfo.ExternalURLs, v) - } - } } func getIngress(un *unstructured.Unstructured) []v1.LoadBalancerIngress { @@ -93,7 +94,13 @@ func populateServiceInfo(un *unstructured.Unstructured, res *ResourceInfo) { if serviceType, ok, err := unstructured.NestedString(un.Object, "spec", "type"); ok && err == nil && serviceType == string(v1.ServiceTypeLoadBalancer) { ingress = getIngress(un) } - res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress} + + var urls []string + if res.NetworkingInfo != nil { + urls = res.NetworkingInfo.ExternalURLs + } + + res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetLabels: targetLabels, Ingress: ingress, ExternalURLs: urls} } func getServiceName(backend map[string]interface{}, gvk schema.GroupVersionKind) (string, error) { @@ -263,7 +270,12 @@ func populateIstioVirtualServiceInfo(un *unstructured.Unstructured, res *Resourc targets = append(targets, target) } - res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets} + var urls []string + if res.NetworkingInfo != nil { + urls = res.NetworkingInfo.ExternalURLs + } + + res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{TargetRefs: targets, ExternalURLs: urls} } func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { @@ -374,7 +386,13 @@ func populatePodInfo(un *unstructured.Unstructured, res *ResourceInfo) { if restarts > 0 { res.Info = append(res.Info, v1alpha1.InfoItem{Name: "Restart Count", Value: fmt.Sprintf("%d", restarts)}) } - res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{Labels: un.GetLabels()} + + var urls []string + if res.NetworkingInfo != nil { + urls = res.NetworkingInfo.ExternalURLs + } + + res.NetworkingInfo = &v1alpha1.ResourceNetworkingInfo{Labels: un.GetLabels(), ExternalURLs: urls} } func populateHostNodeInfo(un *unstructured.Unstructured, res *ResourceInfo) { diff --git a/controller/cache/info_test.go b/controller/cache/info_test.go index 8a06d3745e13b..ad5202532589b 100644 --- a/controller/cache/info_test.go +++ b/controller/cache/info_test.go @@ -406,7 +406,7 @@ func TestGetLinkAnnotatedIngressInfo(t *testing.T) { Kind: kube.ServiceKind, Name: "helm-guestbook", }}, - ExternalURLs: []string{"https://helm-guestbook.com/", "http://my-grafana.com/ingress-link"}, + ExternalURLs: []string{"http://my-grafana.com/ingress-link", "https://helm-guestbook.com/"}, }, info.NetworkingInfo) } From 973565e194c094d163d2fd0873364d0e36951806 Mon Sep 17 00:00:00 2001 From: bagnaram <11695670+bagnaram@users.noreply.github.com> Date: Thu, 19 Oct 2023 14:24:58 -0600 Subject: [PATCH 025/269] feat(ui): Recursive Helm Values files detection (#15935) (#15936) Signed-off-by: bagnaram <11695670+bagnaram@users.noreply.github.com> --- reposerver/repository/repository.go | 32 +++++++++---------- reposerver/repository/repository_test.go | 21 +++++++++--- .../testdata/values-files/dir/values.yaml | 1 + 3 files changed, 33 insertions(+), 21 deletions(-) create mode 100644 reposerver/repository/testdata/values-files/dir/values.yaml diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 1498dd81d4f6e..f66bc71ac4621 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -1997,12 +1997,13 @@ func (s *Service) createGetAppDetailsCacheHandler(res *apiclient.RepoAppDetailsR func populateHelmAppDetails(res *apiclient.RepoAppDetailsResponse, appPath string, repoRoot string, q *apiclient.RepoServerAppDetailsQuery, gitRepoPaths io.TempPaths) error { var selectedValueFiles []string + var availableValueFiles []string if q.Source.Helm != nil { selectedValueFiles = q.Source.Helm.ValueFiles } - availableValueFiles, err := findHelmValueFilesInPath(appPath) + err := filepath.Walk(appPath, walkHelmValueFilesInPath(appPath, &availableValueFiles)) if err != nil { return err } @@ -2079,26 +2080,25 @@ func loadFileIntoIfExists(path pathutil.ResolvedFilePath, destination *string) e return nil } -func findHelmValueFilesInPath(path string) ([]string, error) { - var result []string +func walkHelmValueFilesInPath(root string, valueFiles *[]string) filepath.WalkFunc { + return func(path string, info os.FileInfo, err error) error { - files, err := os.ReadDir(path) - if err != nil { - return result, fmt.Errorf("error reading helm values file from %s: %w", path, err) - } - - for _, f := range files { - if f.IsDir() { - continue + if err != nil { + return fmt.Errorf("error reading helm values file from %s: %w", path, err) } - filename := f.Name() - fileNameExt := strings.ToLower(filepath.Ext(filename)) + + filename := info.Name() + fileNameExt := strings.ToLower(filepath.Ext(path)) if strings.Contains(filename, "values") && (fileNameExt == ".yaml" || fileNameExt == ".yml") { - result = append(result, filename) + relPath, err := filepath.Rel(root, path) + if err != nil { + return fmt.Errorf("error traversing path from %s to %s: %w", root, path, err) + } + *valueFiles = append(*valueFiles, relPath) } - } - return result, nil + return nil + } } func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apiclient.RepoServerAppDetailsQuery, appPath string, reversion string, credsStore git.CredsStore) error { diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index c2ac086d85346..a24eb5008c47b 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -2663,16 +2663,27 @@ func runGit(t *testing.T, workDir string, args ...string) string { return stringOut } -func Test_findHelmValueFilesInPath(t *testing.T) { +func Test_walkHelmValueFilesInPath(t *testing.T) { t.Run("does not exist", func(t *testing.T) { - files, err := findHelmValueFilesInPath("/obviously/does/not/exist") + var files []string + root := "/obviously/does/not/exist" + err := filepath.Walk(root, walkHelmValueFilesInPath(root, &files)) assert.Error(t, err) assert.Empty(t, files) }) t.Run("values files", func(t *testing.T) { - files, err := findHelmValueFilesInPath("./testdata/values-files") + var files []string + root := "./testdata/values-files" + err := filepath.Walk(root, walkHelmValueFilesInPath(root, &files)) assert.NoError(t, err) - assert.Len(t, files, 4) + assert.Len(t, files, 5) + }) + t.Run("unrelated root", func(t *testing.T) { + var files []string + root := "./testdata/values-files" + unrelated_root := "/different/root/path" + err := filepath.Walk(root, walkHelmValueFilesInPath(unrelated_root, &files)) + assert.Error(t, err) }) } @@ -2690,7 +2701,7 @@ func Test_populateHelmAppDetails(t *testing.T) { err = populateHelmAppDetails(&res, appPath, appPath, &q, emptyTempPaths) require.NoError(t, err) assert.Len(t, res.Helm.Parameters, 3) - assert.Len(t, res.Helm.ValueFiles, 4) + assert.Len(t, res.Helm.ValueFiles, 5) } func Test_populateHelmAppDetails_values_symlinks(t *testing.T) { diff --git a/reposerver/repository/testdata/values-files/dir/values.yaml b/reposerver/repository/testdata/values-files/dir/values.yaml new file mode 100644 index 0000000000000..55262d50ff71c --- /dev/null +++ b/reposerver/repository/testdata/values-files/dir/values.yaml @@ -0,0 +1 @@ +values: yaml From 35a9e0cc6dfbd52ba4f97472bd57c3f18efa3c7d Mon Sep 17 00:00:00 2001 From: Victor Sollerhed Date: Mon, 23 Oct 2023 15:30:28 +0200 Subject: [PATCH 026/269] chore(deps): bump kustomize to v5.2.1 (#16054) * kustomize v5.2.1 checksums Signed-off-by: Victor Sollerhed * kustomize v5.2.1 tool-versions Signed-off-by: Victor Sollerhed --------- Signed-off-by: Victor Sollerhed --- .../checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 | 1 + .../checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 | 1 + hack/tool-versions.sh | 2 +- 7 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 create mode 100644 hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 diff --git a/hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..655910d278d31 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_darwin_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +b7aba749da75d33e6fea49a5098747d379abc45583ff5cd16e2356127a396549 kustomize_5.2.1_darwin_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..55f753b7cb4a5 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_darwin_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +f6a5f3cffd45bac585a0c80b5ed855c2b72d932a1d6e8e7c87aae3be4eba5750 kustomize_5.2.1_darwin_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..a9cb3b79c77e8 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_amd64.tar.gz.sha256 @@ -0,0 +1 @@ +88346543206b889f9287c0b92c70708040ecd5aad54dd33019c4d6579cd24de8 kustomize_5.2.1_linux_amd64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..ff4078ddd85f3 --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_arm64.tar.gz.sha256 @@ -0,0 +1 @@ +5566f7badece5a72d42075d8dffa6296a228966dd6ac2390de7afbb9675c3aaa kustomize_5.2.1_linux_arm64.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..b5b6c7e9f077c --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +82d732cf624b6fa67dfabe751e9a1510e2d08605996b1b130b4c0f5b835b130e kustomize_5.2.1_linux_ppc64le.tar.gz diff --git a/hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 b/hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..565fb1df10d8e --- /dev/null +++ b/hack/installers/checksums/kustomize_5.2.1_linux_s390x.tar.gz.sha256 @@ -0,0 +1 @@ +d94cb97a2776b4685ab41233dfd5f0b426f399d2fce87d2b69e1ce4907f3aad2 kustomize_5.2.1_linux_s390x.tar.gz diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 00dd572966182..842af77c8a2ac 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -14,5 +14,5 @@ helm3_version=3.13.1 kubectl_version=1.17.8 kubectx_version=0.6.3 -kustomize5_version=5.1.1 +kustomize5_version=5.2.1 protoc_version=3.17.3 From 9a922de9b290109b38c6fb171915f7de1293a965 Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Mon, 23 Oct 2023 06:32:35 -0700 Subject: [PATCH 027/269] fix: ensure appset don't attempt to remove application kind in patch requests (#16056) Signed-off-by: Alexander Matyushentsev --- applicationset/utils/createOrUpdate.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/applicationset/utils/createOrUpdate.go b/applicationset/utils/createOrUpdate.go index 096be5a9a97d3..274070c2ef5be 100644 --- a/applicationset/utils/createOrUpdate.go +++ b/applicationset/utils/createOrUpdate.go @@ -10,6 +10,7 @@ import ( "k8s.io/apimachinery/pkg/conversion" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" @@ -78,6 +79,12 @@ func CreateOrUpdate(ctx context.Context, c client.Client, obj client.Object, f c return a.Namespace == b.Namespace && a.Name == b.Name && a.Server == b.Server }, ) + // make sure updated object has the same apiVersion & kind as original object + if objKind, ok := obj.(schema.ObjectKind); ok { + if existingKind, ok := existing.(schema.ObjectKind); ok { + existingKind.SetGroupVersionKind(objKind.GroupVersionKind()) + } + } if equality.DeepEqual(existing, obj) { return controllerutil.OperationResultNone, nil From c72a38861879ac3298279c5b429e68425d8d95b4 Mon Sep 17 00:00:00 2001 From: Ratan Gulati Date: Mon, 23 Oct 2023 19:11:36 +0530 Subject: [PATCH 028/269] feat(cli): Add examples to --help output for "gpg add" (#16020) * feat: Add examples to --help output for gpg add Signed-off-by: Ratan Gulati * Update gpg.go Signed-off-by: Ratan Gulati * feat: Add examples to --help output for gpg add Signed-off-by: Ratan Gulati * updated file Signed-off-by: Ratan Gulati --------- Signed-off-by: Ratan Gulati --- cmd/argocd/commands/gpg.go | 6 ++++++ docs/user-guide/commands/argocd_gpg_add.md | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go index 7a48a915bebec..3c0496d2f012a 100644 --- a/cmd/argocd/commands/gpg.go +++ b/cmd/argocd/commands/gpg.go @@ -14,6 +14,7 @@ import ( appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/util/errors" argoio "github.com/argoproj/argo-cd/v2/util/io" + "github.com/argoproj/argo-cd/v2/util/templates" ) // NewGPGCommand returns a new instance of an `argocd repo` command @@ -109,6 +110,11 @@ func NewGPGAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "add", Short: "Adds a GPG public key to the server's keyring", + Example: templates.Examples(` + # Add a GPG public key to the server's keyring from a file. + argocd gpg add --from /path/to/keyfile + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_gpg_add.md b/docs/user-guide/commands/argocd_gpg_add.md index c3fb32369d86d..3ef5d4e6c72d5 100644 --- a/docs/user-guide/commands/argocd_gpg_add.md +++ b/docs/user-guide/commands/argocd_gpg_add.md @@ -8,6 +8,13 @@ Adds a GPG public key to the server's keyring argocd gpg add [flags] ``` +### Examples + +``` + # Add a GPG public key to the server's keyring from a file. + argocd gpg add --from /path/to/keyfile +``` + ### Options ``` From 20618b44eddd94977d19d8f6c4b773eb9ce1169f Mon Sep 17 00:00:00 2001 From: Shaurya Gulati Date: Mon, 23 Oct 2023 19:13:18 +0530 Subject: [PATCH 029/269] feat(cli): Add examples to --help output for "list PROJECT" (#16033) Signed-off-by: Shauryagulati --- cmd/argocd/commands/project_role.go | 9 +++++++++ docs/user-guide/commands/argocd_proj_role_list.md | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index ecc7d670ce42e..166d8f3979be2 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -395,6 +395,15 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co var command = &cobra.Command{ Use: "list PROJECT", Short: "List all the roles in a project", + Example: templates.Examples(` + # This command will list all the roles in argocd-project in a default table format. + argocd list argocd-project + + # List the roles in the project in formats like json, yaml, wide, or name. + argocd list argocd-project --output json + + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index b535cf724add9..ea6e0099d4611 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -8,6 +8,16 @@ List all the roles in a project argocd proj role list PROJECT [flags] ``` +### Examples + +``` + # This command will list all the roles in argocd-project in a default table format. + argocd list argocd-project + + # List the roles in the project in formats like json, yaml, wide, or name. + argocd list argocd-project --output json +``` + ### Options ``` From 752004c8705578b450e04129a13f319a874b940b Mon Sep 17 00:00:00 2001 From: Mathias Petermann Date: Mon, 23 Oct 2023 15:59:56 +0200 Subject: [PATCH 030/269] feat(cmp): Print stderr output from command even on success (#15921) (#15973) * feat(cmp): Print stderr output from command even on success Signed-off-by: Mathias Petermann * docs(cmp): Document logging from cmp sidecard for development purposes Signed-off-by: Mathias Petermann --------- Signed-off-by: Mathias Petermann --- cmpserver/plugin/plugin.go | 13 +++++++++---- docs/operator-manual/config-management-plugins.md | 2 ++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cmpserver/plugin/plugin.go b/cmpserver/plugin/plugin.go index f03b73f24dcf6..ca1e7592218ea 100644 --- a/cmpserver/plugin/plugin.go +++ b/cmpserver/plugin/plugin.go @@ -120,11 +120,16 @@ func runCommand(ctx context.Context, command Command, path string, env []string) logCtx.Error(err.Error()) return strings.TrimSuffix(output, "\n"), err } + + logCtx = logCtx.WithFields(log.Fields{ + "stderr": stderr.String(), + "command": command, + }) if len(output) == 0 { - log.WithFields(log.Fields{ - "stderr": stderr.String(), - "command": command, - }).Warn("Plugin command returned zero output") + logCtx.Warn("Plugin command returned zero output") + } else { + // Log stderr even on successfull commands to help develop plugins + logCtx.Info("Plugin command successfull") } return strings.TrimSuffix(output, "\n"), nil diff --git a/docs/operator-manual/config-management-plugins.md b/docs/operator-manual/config-management-plugins.md index ee805b71cd604..b77a4bdd7ba21 100644 --- a/docs/operator-manual/config-management-plugins.md +++ b/docs/operator-manual/config-management-plugins.md @@ -44,6 +44,7 @@ spec: args: [-c, 'echo "Initializing..."'] # The generate command runs in the Application source directory each time manifests are generated. Standard output # must be ONLY valid Kubernetes Objects in either YAML or JSON. A non-zero exit code will fail manifest generation. + # To write log messages from the command, write them to stderr, it will always be displayed. # Error output will be sent to the UI, so avoid printing sensitive information (such as secrets). generate: command: [sh, -c] @@ -333,6 +334,7 @@ If you are actively developing a sidecar-installed CMP, keep a few things in min 3. CMP errors are cached by the repo-server in Redis. Restarting the repo-server Pod will not clear the cache. Always do a "Hard Refresh" when actively developing a CMP so you have the latest output. 4. Verify your sidecar has started properly by viewing the Pod and seeing that two containers are running `kubectl get pod -l app.kubernetes.io/component=repo-server -n argocd` +5. Write log message to stderr and set the `--loglevel=info` flag in the sidecar. This will print everything written to stderr, even on successfull command execution. ### Other Common Errors From 56a7bb79a4d66e5f0a7932d62aaef3f18d38ea08 Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Mon, 23 Oct 2023 08:40:13 -0700 Subject: [PATCH 031/269] fix: auto-sync fails with 'another operation is already in progress' error (#15638) Signed-off-by: Alexander Matyushentsev --- controller/appcontroller.go | 8 ++++++++ util/argo/argo.go | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 46e3ede0f3a3e..537f8d5a411e4 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + goerrors "errors" "fmt" "math" "net/http" @@ -1801,6 +1802,13 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * _, err := argo.SetAppOperation(appIf, app.Name, &op) setOpTime := time.Since(start) if err != nil { + if goerrors.Is(err, argo.ErrAnotherOperationInProgress) { + // skipping auto-sync because another operation is in progress and was not noticed due to stale data in informer + // it is safe to skip auto-sync because it is already running + logCtx.Warnf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) + return nil, 0 + } + logCtx.Errorf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: err.Error()}, setOpTime } diff --git a/util/argo/argo.go b/util/argo/argo.go index 9b08d3aeeb847..9187726ab17dc 100644 --- a/util/argo/argo.go +++ b/util/argo/argo.go @@ -35,6 +35,10 @@ const ( errDestinationMissing = "Destination server missing from app spec" ) +var ( + ErrAnotherOperationInProgress = status.Errorf(codes.FailedPrecondition, "another operation is already in progress") +) + // AugmentSyncMsg enrich the K8s message with user-relevant information func AugmentSyncMsg(res common.ResourceSyncResult, apiResourceInfoGetter func() ([]kube.APIResourceInfo, error)) (string, error) { switch res.Message { @@ -800,7 +804,7 @@ func SetAppOperation(appIf v1alpha1.ApplicationInterface, appName string, op *ar return nil, fmt.Errorf("error getting application %q: %w", appName, err) } if a.Operation != nil { - return nil, status.Errorf(codes.FailedPrecondition, "another operation is already in progress") + return nil, ErrAnotherOperationInProgress } a.Operation = op a.Status.OperationState = nil From f4e0d354548c101096b234363b5fcd7dce07017f Mon Sep 17 00:00:00 2001 From: May Zhang Date: Mon, 23 Oct 2023 14:44:49 -0700 Subject: [PATCH 032/269] fix: argocd notification controller app cluster permission issue (#16057) * if applicationNamespaces is not provided as input parameter, then use namespaced appClient Signed-off-by: May Zhang * fix go lint error Signed-off-by: May Zhang --------- Signed-off-by: May Zhang --- notification_controller/controller/controller.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 1ad2ab361ab93..a08c0cc1f9714 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -61,7 +61,13 @@ func NewController( secretName string, configMapName string, ) *notificationController { - appClient := client.Resource(applications) + var appClient dynamic.ResourceInterface + namespaceableAppClient := client.Resource(applications) + appClient = namespaceableAppClient + if len(applicationNamespaces) == 0 { + appClient = namespaceableAppClient.Namespace(namespace) + } + appInformer := newInformer(appClient, namespace, applicationNamespaces, appLabelSelector) appProjInformer := newInformer(newAppProjClient(client, namespace), namespace, []string{namespace}, "") secretInformer := k8s.NewSecretInformer(k8sClient, namespace, secretName) @@ -74,7 +80,7 @@ func NewController( appInformer: appInformer, appProjInformer: appProjInformer, apiFactory: apiFactory} - res.ctrl = controller.NewController(appClient, appInformer, apiFactory, + res.ctrl = controller.NewController(namespaceableAppClient, appInformer, apiFactory, controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { app, ok := (obj).(*unstructured.Unstructured) if !ok { From a43b799609a75f2376cfe14268d69b8ee6f2e8dd Mon Sep 17 00:00:00 2001 From: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Date: Tue, 24 Oct 2023 06:45:53 +0530 Subject: [PATCH 033/269] feat: add write back to application informer (#15987) Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> --- controller/appcontroller.go | 34 +++++++++++++++++++++++++------- controller/appcontroller_test.go | 32 +++++++++++++++--------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 537f8d5a411e4..3b54c13d4eb43 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -1331,8 +1331,7 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta } kube.RetryUntilSucceed(context.Background(), updateOperationStateTimeout, "Update application operation state", logutils.NewLogrusLogger(logutils.NewWithCurrentConfig()), func() error { - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err = appClient.Patch(context.Background(), app.Name, types.MergePatchType, patchJSON, metav1.PatchOptions{}) + _, err := ctrl.PatchAppWithWriteBack(context.Background(), app.Name, app.Namespace, types.MergePatchType, patchJSON, metav1.PatchOptions{}) if err != nil { // Stop retrying updating deleted application if apierr.IsNotFound(err) { @@ -1370,6 +1369,27 @@ func (ctrl *ApplicationController) setOperationState(app *appv1.Application, sta } } +// writeBackToInformer writes a just recently updated App back into the informer cache. +// This prevents the situation where the controller operates on a stale app and repeats work +func (ctrl *ApplicationController) writeBackToInformer(app *appv1.Application) { + logCtx := log.WithFields(log.Fields{"application": app.Name, "appNamespace": app.Namespace, "project": app.Spec.Project, "informer-writeBack": true}) + err := ctrl.appInformer.GetStore().Update(app) + if err != nil { + logCtx.Errorf("failed to update informer store: %v", err) + return + } +} + +// PatchAppWithWriteBack patches an application and writes it back to the informer cache +func (ctrl *ApplicationController) PatchAppWithWriteBack(ctx context.Context, name, ns string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *appv1.Application, err error) { + patchedApp, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(ns).Patch(ctx, name, pt, data, opts, subresources...) + if err != nil { + return patchedApp, err + } + ctrl.writeBackToInformer(patchedApp) + return patchedApp, err +} + func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext bool) { patchMs := time.Duration(0) // time spent in doing patch/update calls setOpMs := time.Duration(0) // time spent in doing Operation patch calls in autosync @@ -1643,8 +1663,7 @@ func (ctrl *ApplicationController) normalizeApplication(orig, app *appv1.Applica if err != nil { logCtx.Errorf("error constructing app spec patch: %v", err) } else if modified { - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) - _, err = appClient.Patch(context.Background(), app.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + _, err := ctrl.PatchAppWithWriteBack(context.Background(), app.Name, app.Namespace, types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { logCtx.Errorf("Error persisting normalized application spec: %v", err) } else { @@ -1688,8 +1707,7 @@ func (ctrl *ApplicationController) persistAppStatus(orig *appv1.Application, new defer func() { patchMs = time.Since(start) }() - appClient := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(orig.Namespace) - _, err = appClient.Patch(context.Background(), orig.Name, types.MergePatchType, patch, metav1.PatchOptions{}) + _, err = ctrl.PatchAppWithWriteBack(context.Background(), orig.Name, orig.Namespace, types.MergePatchType, patch, metav1.PatchOptions{}) if err != nil { logCtx.Warnf("Error updating application: %v", err) } else { @@ -1799,7 +1817,7 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * appIf := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace) start := time.Now() - _, err := argo.SetAppOperation(appIf, app.Name, &op) + updatedApp, err := argo.SetAppOperation(appIf, app.Name, &op) setOpTime := time.Since(start) if err != nil { if goerrors.Is(err, argo.ErrAnotherOperationInProgress) { @@ -1811,6 +1829,8 @@ func (ctrl *ApplicationController) autoSync(app *appv1.Application, syncStatus * logCtx.Errorf("Failed to initiate auto-sync to %s: %v", desiredCommitSHA, err) return &appv1.ApplicationCondition{Type: appv1.ApplicationConditionSyncError, Message: err.Error()}, setOpTime + } else { + ctrl.writeBackToInformer(updatedApp) } message := fmt.Sprintf("Initiated automated sync to '%s'", desiredCommitSHA) ctrl.auditLogger.LogAppEvent(app, argo.EventInfo{Reason: argo.EventReasonOperationStarted, Type: v1.EventTypeNormal}, message, "") diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 2129c88885fff..a47114f5c2527 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -625,7 +625,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }) fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil @@ -675,7 +675,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }) fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) objs, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil @@ -709,7 +709,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }) fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil @@ -804,7 +804,7 @@ func TestNormalizeApplication(t *testing.T) { normalized = true } } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processAppRefreshQueueItem() assert.True(t, normalized) @@ -826,7 +826,7 @@ func TestNormalizeApplication(t *testing.T) { normalized = true } } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processAppRefreshQueueItem() assert.False(t, normalized) @@ -923,7 +923,7 @@ func TestSetOperationStateOnDeletedApp(t *testing.T) { patched := false fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, apierr.NewNotFound(schema.GroupResource{}, "my-app") + return true, &v1alpha1.Application{}, apierr.NewNotFound(schema.GroupResource{}, "my-app") }) ctrl.setOperationState(newFakeApp(), &v1alpha1.OperationState{Phase: synccommon.OperationSucceeded}) assert.True(t, patched) @@ -955,9 +955,9 @@ func TestSetOperationStateLogRetries(t *testing.T) { fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { if !patched { patched = true - return true, nil, errors.New("fake error") + return true, &v1alpha1.Application{}, errors.New("fake error") } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.setOperationState(newFakeApp(), &v1alpha1.OperationState{Phase: synccommon.OperationSucceeded}) assert.True(t, patched) @@ -1273,7 +1273,7 @@ func TestUpdateReconciledAt(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) t.Run("UpdatedOnFullReconciliation", func(t *testing.T) { @@ -1347,7 +1347,7 @@ func TestFinalizeProjectDeletion_HasApplications(t *testing.T) { patched := false fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { patched = true - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) err := ctrl.finalizeProjectDeletion(proj) @@ -1365,7 +1365,7 @@ func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.AppProject{}, nil }) err := ctrl.finalizeProjectDeletion(proj) @@ -1390,7 +1390,7 @@ func TestProcessRequestedAppOperation_FailedNoRetries(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) @@ -1418,7 +1418,7 @@ func TestProcessRequestedAppOperation_InvalidDestination(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) }() @@ -1444,7 +1444,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) @@ -1487,7 +1487,7 @@ func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) @@ -1520,7 +1520,7 @@ func TestProcessRequestedAppOperation_HasRetriesTerminated(t *testing.T) { if patchAction, ok := action.(kubetesting.PatchAction); ok { assert.NoError(t, json.Unmarshal(patchAction.GetPatch(), &receivedPatch)) } - return true, nil, nil + return true, &v1alpha1.Application{}, nil }) ctrl.processRequestedAppOperation(app) From f8cd449e36b9a9f977340b73ede92e7510e6ed4e Mon Sep 17 00:00:00 2001 From: Edith Puclla <58795858+edithturn@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:22:21 +0100 Subject: [PATCH 034/269] docs: add percona to list of Argo users (#16079) * Add Percona user Signed-off-by: Edith Puclla * Add Percona user Signed-off-by: Edith Puclla Add Percona in USERS --------- Signed-off-by: Edith Puclla --- USERS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/USERS.md b/USERS.md index 652a68c6e679f..6c4bc8e5e3eac 100644 --- a/USERS.md +++ b/USERS.md @@ -25,7 +25,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [AppDirect](https://www.appdirect.com) 1. [Arctiq Inc.](https://www.arctiq.ca) 1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/) -2. [Autodesk](https://www.autodesk.com) +1. [Autodesk](https://www.autodesk.com) 1. [Axual B.V.](https://axual.com) 1. [Back Market](https://www.backmarket.com) 1. [Baloise](https://www.baloise.com) @@ -210,6 +210,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Patreon](https://www.patreon.com/) 1. [PayPay](https://paypay.ne.jp/) 1. [Peloton Interactive](https://www.onepeloton.com/) +1. [Percona](https://percona.com/) 1. [PGS](https://www.pgs.com) 1. [Pigment](https://www.gopigment.com/) 1. [Pipefy](https://www.pipefy.com/) From 91875c01b8d11e6670bcc516920ceff57b52bc06 Mon Sep 17 00:00:00 2001 From: Rafal Date: Tue, 24 Oct 2023 17:58:05 +0200 Subject: [PATCH 035/269] fix(ui): Dark theme improvements (#15891) Signed-off-by: Rafal Pelczar --- ui/src/app/app.tsx | 4 +++- .../application-details.scss | 12 ++++++++++-- .../application-resource-tree.scss | 18 +++++++++++++++++- .../application-status-panel.scss | 4 +++- .../applications-list/applications-list.scss | 2 +- ui/src/app/applications/components/utils.scss | 7 ++++++- 6 files changed, 40 insertions(+), 7 deletions(-) diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index e38e28d91a9db..2cc63effeed2f 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -217,7 +217,9 @@ export class App extends React.Component< - {this.state.popupProps && } + services.viewPreferences.getPreferences()}> + {pref =>
    {this.state.popupProps && }
    } +
    diff --git a/ui/src/app/applications/components/application-details/application-details.scss b/ui/src/app/applications/components/application-details/application-details.scss index a653063fdc102..af1ca3e9d07dc 100644 --- a/ui/src/app/applications/components/application-details/application-details.scss +++ b/ui/src/app/applications/components/application-details/application-details.scss @@ -1,5 +1,6 @@ @import 'node_modules/argo-ui/src/styles/config'; @import 'node_modules/foundation-sites/scss/util/util'; +@import 'node_modules/argo-ui/src/styles/theme'; @import '../../../shared/config.scss'; $header: 120px; @@ -211,9 +212,14 @@ $header: 120px; z-index: 1; padding: 5px; display: inline-block; - background-color: $argo-color-gray-1; box-shadow: 1px 1px 3px $argo-color-gray-5; position: absolute; + + @include themify($themes) { + background: themed('background-2'); + } + + a { padding: 5px; margin: 2px; @@ -255,7 +261,9 @@ $header: 120px; } .separator { - border-right: 1px solid $argo-color-gray-4; + @include themify($themes) { + border-right: 1px solid themed('border'); + } padding-top: 6px; padding-bottom: 6px; } diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss index f4c6ba0d0df9f..0cc459b0dc52b 100644 --- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss +++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.scss @@ -79,6 +79,10 @@ border: 1px solid transparent; cursor: pointer; + .theme-dark & { + box-shadow: 1px 1px 1px $argo-color-gray-7; + } + .icon { font-size: 2em; } @@ -120,6 +124,10 @@ } margin-top: 9px; margin-left: 215px; + + .theme-dark & { + box-shadow: 1px 1px 1px $argo-color-gray-7; + } } &--podgroup--expansion { @@ -131,6 +139,10 @@ box-shadow: 1px 1px 1px $argo-color-gray-4; background-color: white; margin-left: 215px; + + .theme-dark & { + box-shadow: 1px 1px 1px $argo-color-gray-7; + } } &--pod { @@ -348,8 +360,12 @@ border-radius: 33px; left: -20px; top: -8px; - border: 4px solid white; text-align: center; + + @include themify($themes) { + border: 4px solid themed('background-2'); + } + i { color: $white-color; line-height: 56px; diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss index 9898db27d2ba6..e96c29624d5d1 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.scss +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.scss @@ -101,7 +101,9 @@ } &:not(:first-child) { - border-left: 1px solid $argo-color-gray-3; + @include themify($themes) { + border-left: 1px solid themed('border'); + } } & { diff --git a/ui/src/app/applications/components/applications-list/applications-list.scss b/ui/src/app/applications/components/applications-list/applications-list.scss index fbe03245e94e6..6d359e59723e3 100644 --- a/ui/src/app/applications/components/applications-list/applications-list.scss +++ b/ui/src/app/applications/components/applications-list/applications-list.scss @@ -118,9 +118,9 @@ } &__search { - border: 1px solid $argo-color-gray-4; @include themify($themes) { background-color: themed('light-argo-gray-2'); + border: 1px solid themed('border'); } border-radius: 7px; position: relative; diff --git a/ui/src/app/applications/components/utils.scss b/ui/src/app/applications/components/utils.scss index 24d9c275bff62..245573df95d92 100644 --- a/ui/src/app/applications/components/utils.scss +++ b/ui/src/app/applications/components/utils.scss @@ -1,3 +1,5 @@ +@import 'node_modules/argo-ui/src/styles/theme'; + .propagation-policy-list { display: flex; justify-content: left; @@ -9,9 +11,12 @@ padding-right: 2em; label { - color: #6D7F8B; font-size: 15px; cursor: pointer; + + @include themify($themes) { + color: themed('light-argo-gray-6'); + } } input { From eab38b53ace0fb479462d9ae776f9c31567de4ee Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:43:11 -0400 Subject: [PATCH 036/269] docs(bounty): proposal for feature to hide annotations on secrets in UI (#15699) * docs(bounty): proposal for feature to hide annotations on secrets in the UI Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix file location Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .../feature-bounties/hide-annotations.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docs/proposals/feature-bounties/hide-annotations.md diff --git a/docs/proposals/feature-bounties/hide-annotations.md b/docs/proposals/feature-bounties/hide-annotations.md new file mode 100644 index 0000000000000..47c9b943b8f71 --- /dev/null +++ b/docs/proposals/feature-bounties/hide-annotations.md @@ -0,0 +1,23 @@ +# Proposal: Allow Hiding Certain Annotations in the Argo CD Web UI + +Based on this issue: https://github.com/argoproj/argo-cd/issues/15693 + +Award amount: $100 + +## Solution + +!!! note + This is the proposed solution. The accepted PR may differ from this proposal. + +Add a new config item in argocd-cm: + +```yaml +hide.secret.annotations: | +- openshift.io/token-secret.value +``` + +This will hide the `openshift.io/token-secret.value` annotation from the UI. Behind the scenes, it would likely work the +same way as the `last-applied-configuration` annotation hiding works: https://github.com/argoproj/gitops-engine/blob/b0fffe419a0f0a40f9f2c0b6346b752ed6537385/pkg/diff/diff.go#L897 + +I considered whether we'd want to support hiding things besides annotations and in resources besides secrets, but +having reviewed existing issues, I think this narrow feature is sufficient. From 5d3bdb5bd01cd3836db4ae3172bbd2630c7a51c3 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 24 Oct 2023 14:14:43 -0400 Subject: [PATCH 037/269] fix(docs): proj role list example (#16074) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- cmd/argocd/commands/project_role.go | 4 ++-- docs/user-guide/commands/argocd_proj_role_list.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index 166d8f3979be2..8dca406a9dc30 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -397,10 +397,10 @@ func NewProjectRoleListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co Short: "List all the roles in a project", Example: templates.Examples(` # This command will list all the roles in argocd-project in a default table format. - argocd list argocd-project + argocd proj role list PROJECT # List the roles in the project in formats like json, yaml, wide, or name. - argocd list argocd-project --output json + argocd proj role list PROJECT --output json `), diff --git a/docs/user-guide/commands/argocd_proj_role_list.md b/docs/user-guide/commands/argocd_proj_role_list.md index ea6e0099d4611..3cfd630ddc988 100644 --- a/docs/user-guide/commands/argocd_proj_role_list.md +++ b/docs/user-guide/commands/argocd_proj_role_list.md @@ -12,10 +12,10 @@ argocd proj role list PROJECT [flags] ``` # This command will list all the roles in argocd-project in a default table format. - argocd list argocd-project + argocd proj role list PROJECT # List the roles in the project in formats like json, yaml, wide, or name. - argocd list argocd-project --output json + argocd proj role list PROJECT --output json ``` ### Options From f37d24f6d8494f5905bc0485d079ea5070e25a2b Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Tue, 24 Oct 2023 13:41:22 -0700 Subject: [PATCH 038/269] feat: make git requests configurable (#15646) * feat: make git requests configurable Signed-off-by: Alexander Matyushentsev * docs: mention new settings in 'argocd-cmd-params-cm' configmap Signed-off-by: Alexander Matyushentsev * add comment about ignored error Signed-off-by: Alexander Matyushentsev --------- Signed-off-by: Alexander Matyushentsev --- .../operator-manual/argocd-cmd-params-cm.yaml | 4 ++++ .../argocd-repo-server-deployment.yaml | 12 ++++++++++ manifests/core-install.yaml | 12 ++++++++++ manifests/ha/install.yaml | 12 ++++++++++ manifests/ha/namespace-install.yaml | 12 ++++++++++ manifests/install.yaml | 12 ++++++++++ manifests/namespace-install.yaml | 12 ++++++++++ reposerver/metrics/githandlers.go | 24 +++++++++++++++++++ util/git/client.go | 8 +++++-- 9 files changed, 106 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index 7d38506d0b7ec..f9f8b3fc14d52 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -154,6 +154,10 @@ data: reposerver.streamed.manifest.max.extracted.size: "1G" # Enable git submodule support reposerver.enable.git.submodule: "true" + # Number of concurrent git ls-remote requests. Any value less than 1 means no limit. + reposerver.git.lsremote.parallelism.limit: "0" + # Git requests timeout. + reposerver.git.request.timeout: "15s" # Disable TLS on the HTTP endpoint dexserver.disable.tls: "false" diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index eb230e0f9b856..728c80c14bc2a 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -168,6 +168,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 8456f5c3ef430..86e636e12ef59 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21042,6 +21042,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index a2e1e5b91b668..043083de6be84 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -22528,6 +22528,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index ea123ef2e50ef..524ec8ace3e6c 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2184,6 +2184,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/install.yaml b/manifests/install.yaml index 6783484ed0150..a08c3a5cd1302 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21574,6 +21574,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 0490434f4046c..cfdf7756ff134 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1230,6 +1230,18 @@ spec: key: reposerver.enable.git.submodule name: argocd-cmd-params-cm optional: true + - name: ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + key: reposerver.git.lsremote.parallelism.limit + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_REQUEST_TIMEOUT + valueFrom: + configMapKeyRef: + key: reposerver.git.request.timeout + name: argocd-cmd-params-cm + optional: true - name: HELM_CACHE_HOME value: /helm-working-dir - name: HELM_CONFIG_HOME diff --git a/reposerver/metrics/githandlers.go b/reposerver/metrics/githandlers.go index cce632cf56813..09a0591002c52 100644 --- a/reposerver/metrics/githandlers.go +++ b/reposerver/metrics/githandlers.go @@ -1,11 +1,27 @@ package metrics import ( + "context" + "math" "time" + "golang.org/x/sync/semaphore" + + "github.com/argoproj/argo-cd/v2/util/env" "github.com/argoproj/argo-cd/v2/util/git" ) +var ( + lsRemoteParallelismLimit = env.ParseInt64FromEnv("ARGOCD_GIT_LS_REMOTE_PARALLELISM_LIMIT", 0, 0, math.MaxInt64) + lsRemoteParallelismLimitSemaphore *semaphore.Weighted +) + +func init() { + if lsRemoteParallelismLimit > 0 { + lsRemoteParallelismLimitSemaphore = semaphore.NewWeighted(lsRemoteParallelismLimit) + } +} + // NewGitClientEventHandlers creates event handlers that update Git related metrics func NewGitClientEventHandlers(metricsServer *MetricsServer) git.EventHandlers { return git.EventHandlers{ @@ -19,7 +35,15 @@ func NewGitClientEventHandlers(metricsServer *MetricsServer) git.EventHandlers { OnLsRemote: func(repo string) func() { startTime := time.Now() metricsServer.IncGitRequest(repo, GitRequestTypeLsRemote) + if lsRemoteParallelismLimitSemaphore != nil { + // The `Acquire` method returns either `nil` or error of the provided context. The + // context.Background() is never canceled, so it is safe to ignore the error. + _ = lsRemoteParallelismLimitSemaphore.Acquire(context.Background(), 1) + } return func() { + if lsRemoteParallelismLimitSemaphore != nil { + lsRemoteParallelismLimitSemaphore.Release(1) + } metricsServer.ObserveGitRequestDuration(repo, GitRequestTypeLsRemote, time.Since(startTime)) } }, diff --git a/util/git/client.go b/util/git/client.go index 6b8587c0b3660..6a8828d13f432 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -174,6 +174,10 @@ func NewClientExt(rawRepoURL string, root string, creds Creds, insecure bool, en return client, nil } +var ( + gitClientTimeout = env.ParseDurationFromEnv("ARGOCD_GIT_REQUEST_TIMEOUT", 15*time.Second, 0, math.MaxInt64) +) + // Returns a HTTP client object suitable for go-git to use using the following // pattern: // - If insecure is true, always returns a client with certificate verification @@ -185,8 +189,8 @@ func NewClientExt(rawRepoURL string, root string, creds Creds, insecure bool, en func GetRepoHTTPClient(repoURL string, insecure bool, creds Creds, proxyURL string) *http.Client { // Default HTTP client var customHTTPClient = &http.Client{ - // 15 second timeout - Timeout: 15 * time.Second, + // 15 second timeout by default + Timeout: gitClientTimeout, // don't follow redirect CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse From f1d3d66da3ea3af673d441f2092a0c9a94909004 Mon Sep 17 00:00:00 2001 From: Jordan Moore <1930631+OneCricketeer@users.noreply.github.com> Date: Wed, 25 Oct 2023 09:58:00 -0500 Subject: [PATCH 039/269] fix(banzai/KafkaCluster): Update health.lua (#15962) fix(banzai/KafkaCluster): Update health.lua (#15962) Uses ipairs() to correctly iterates over indexed elements Signed-off-by: Jordan Moore <1930631+OneCricketeer@users.noreply.github.com> --- .../KafkaCluster/health.lua | 23 ++++++++----------- .../KafkaCluster/health_test.yaml | 2 +- .../KafkaCluster/testdata/healthy.yaml | 6 ++--- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health.lua b/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health.lua index d24afea652c2a..7422fd4104727 100644 --- a/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health.lua +++ b/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health.lua @@ -1,22 +1,17 @@ local health_status = {} if obj.status ~= nil then if obj.status.brokersState ~= nil then - local counter = 0 - local brokerReady = 0 - for i, broker in pairs(obj.status.brokersState) do - if (brokerReady <= tonumber(i)) then - brokerReady = tonumber(i)+1 - else - brokerReady = brokerReady - end - if broker.configurationState == "ConfigInSync" and broker.gracefulActionState.cruiseControlState == "GracefulUpscaleSucceeded" then - counter = counter + 1 - end - if broker.configurationState == "ConfigInSync" and broker.gracefulActionState.cruiseControlState == "GracefulDownscaleSucceeded" then - counter = counter + 1 + local numberBrokers = 0 + local healthyBrokers = 0 + for _, broker in pairs(obj.status.brokersState) do + numberBrokers = numberBrokers + 1 + if broker.configurationState == "ConfigInSync" then + if broker.gracefulActionState.cruiseControlState == "GracefulUpscaleSucceeded" or broker.gracefulActionState.cruiseControlState == "GracefulDownscaleSucceeded" then + healthyBrokers = healthyBrokers + 1 end + end end - if counter == brokerReady then + if numberBrokers == healthyBrokers then if obj.status.cruiseControlTopicStatus == "CruiseControlTopicReady" and obj.status.state == "ClusterRunning" then health_status.message = "Kafka Brokers, CruiseControl and cluster are in Healthy State." health_status.status = "Healthy" diff --git a/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health_test.yaml b/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health_test.yaml index 9446d882d941a..776cc02739326 100644 --- a/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health_test.yaml +++ b/resource_customizations/kafka.banzaicloud.io/KafkaCluster/health_test.yaml @@ -14,4 +14,4 @@ tests: - healthStatus: status: Healthy message: "Kafka Brokers, CruiseControl and cluster are in Healthy State." - inputPath: testdata/healthy.yaml + inputPath: testdata/healthy.yaml \ No newline at end of file diff --git a/resource_customizations/kafka.banzaicloud.io/KafkaCluster/testdata/healthy.yaml b/resource_customizations/kafka.banzaicloud.io/KafkaCluster/testdata/healthy.yaml index 9dd791b9c39fe..44666fd6a83a5 100644 --- a/resource_customizations/kafka.banzaicloud.io/KafkaCluster/testdata/healthy.yaml +++ b/resource_customizations/kafka.banzaicloud.io/KafkaCluster/testdata/healthy.yaml @@ -20,21 +20,21 @@ spec: {} status: alertCount: 0 brokersState: - "0": + "101": configurationState: ConfigInSync gracefulActionState: cruiseControlState: GracefulUpscaleSucceeded errorMessage: CruiseControl not yet ready rackAwarenessState: | broker.rack=us-east-1,us-east-1c - "1": + "102": configurationState: ConfigInSync gracefulActionState: cruiseControlState: GracefulUpscaleSucceeded errorMessage: CruiseControl not yet ready rackAwarenessState: | broker.rack=us-east-1,us-east-1b - "2": + "103": configurationState: ConfigInSync gracefulActionState: cruiseControlState: GracefulUpscaleSucceeded From bc5fb811d660d8f1b4d47b81035147d5e9409882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Etien=20Ro=C5=BEnik?= <12816736+eroznik@users.noreply.github.com> Date: Wed, 25 Oct 2023 17:13:21 +0200 Subject: [PATCH 040/269] feat: expose notification secrets for request payload templating (#16055) Signed-off-by: Etien Roznik <12816736+eroznik@users.noreply.github.com> --- .../notifications/templates.md | 34 +++++++ util/notification/settings/settings.go | 1 + util/notification/settings/settings_test.go | 92 +++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 util/notification/settings/settings_test.go diff --git a/docs/operator-manual/notifications/templates.md b/docs/operator-manual/notifications/templates.md index f865229e12835..1d80f20953b24 100644 --- a/docs/operator-manual/notifications/templates.md +++ b/docs/operator-manual/notifications/templates.md @@ -20,6 +20,7 @@ Each template has access to the following fields: - `app` holds the application object. - `context` is a user-defined string map and might include any string keys and values. +- `secrets` provides access to sensitive data stored in `argocd-notifications-secret` - `serviceType` holds the notification service type name (such as "slack" or "email). The field can be used to conditionally render service-specific fields. - `recipient` holds the recipient name. @@ -43,6 +44,39 @@ data: message: "Something happened in {{ .context.environmentName }} in the {{ .context.region }} data center!" ``` +## Defining and using secrets within notification templates + +Some notification service use cases will require the use of secrets within templates. This can be achieved with the use of +the `secrets` data variable available within the templates. + +Given that we have the following `argocd-notifications-secret`: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: argocd-notifications-secret +stringData: + sampleWebhookToken: secret-token +type: Opaque +``` + +We can use the defined `sampleWebhookToken` in a template as such: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-notifications-cm +data: + template.trigger-webhook: | + webhook: + sample-webhook: + method: POST + path: 'webhook/endpoint/with/auth' + body: 'token={{ .secrets.sampleWebhookToken }}&variables[APP_SOURCE_PATH]={{ .app.spec.source.path }} +``` + ## Notification Service Specific Fields The `message` field of the template definition allows creating a basic notification for any notification service. You can leverage notification service-specific diff --git a/util/notification/settings/settings.go b/util/notification/settings/settings.go index 865a627747d31..ed6a44b60f365 100644 --- a/util/notification/settings/settings.go +++ b/util/notification/settings/settings.go @@ -37,6 +37,7 @@ func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.C return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ "app": obj, "context": injectLegacyVar(context, dest.Service), + "secrets": secret.Data, }) }, nil } diff --git a/util/notification/settings/settings_test.go b/util/notification/settings/settings_test.go new file mode 100644 index 0000000000000..21c2eaf416d37 --- /dev/null +++ b/util/notification/settings/settings_test.go @@ -0,0 +1,92 @@ +package settings + +import ( + "fmt" + "testing" + + "github.com/argoproj/argo-cd/v2/reposerver/apiclient/mocks" + service "github.com/argoproj/argo-cd/v2/util/notification/argocd" + "github.com/argoproj/notifications-engine/pkg/api" + "github.com/argoproj/notifications-engine/pkg/services" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" +) + +const testNamespace = "default" +const testContextKey = "test-context-key" +const testContextKeyValue = "test-context-key-value" + +func TestInitGetVars(t *testing.T) { + notificationsCm := corev1.ConfigMap{ + ObjectMeta: v1.ObjectMeta{ + Namespace: testNamespace, + Name: "argocd-notifications-cm", + }, + Data: map[string]string{ + "context": fmt.Sprintf("%s: %s", testContextKey, testContextKeyValue), + "service.webhook.test": "url: https://test.com", + "template.app-created": "email:\n subject: Application {{.app.metadata.name}} has been created.\nmessage: Application {{.app.metadata.name}} has been created.\nteams:\n title: Application {{.app.metadata.name}} has been created.\n", + "trigger.on-created": "- description: Application is created.\n oncePer: app.metadata.name\n send:\n - app-created\n when: \"true\"\n", + }, + } + notificationsSecret := corev1.Secret{ + ObjectMeta: v1.ObjectMeta{ + Name: "argocd-notifications-secret", + Namespace: testNamespace, + }, + Data: map[string][]byte{ + "notification-secret": []byte("secret-value"), + }, + } + kubeclientset := fake.NewSimpleClientset(&corev1.ConfigMap{ + ObjectMeta: v1.ObjectMeta{ + Namespace: testNamespace, + Name: "argocd-notifications-cm", + }, + Data: notificationsCm.Data, + }, + &corev1.Secret{ + ObjectMeta: v1.ObjectMeta{ + Name: "argocd-notifications-secret", + Namespace: testNamespace, + }, + Data: notificationsSecret.Data, + }) + mockRepoClient := &mocks.Clientset{RepoServerServiceClient: &mocks.RepoServerServiceClient{}} + argocdService, err := service.NewArgoCDService(kubeclientset, testNamespace, mockRepoClient) + require.NoError(t, err) + defer argocdService.Close() + config := api.Config{} + testDestination := services.Destination{ + Service: "webhook", + } + emptyAppData := map[string]interface{}{} + + varsProvider, _ := initGetVars(argocdService, &config, ¬ificationsCm, ¬ificationsSecret) + + t.Run("Vars provider serves Application data on app key", func(t *testing.T) { + appData := map[string]interface{}{ + "name": "app-name", + } + result := varsProvider(appData, testDestination) + assert.NotNil(t, t, result["app"]) + assert.Equal(t, result["app"], appData) + }) + t.Run("Vars provider serves notification context data on context key", func(t *testing.T) { + expectedContext := map[string]string{ + testContextKey: testContextKeyValue, + "notificationType": testDestination.Service, + } + result := varsProvider(emptyAppData, testDestination) + assert.NotNil(t, result["context"]) + assert.Equal(t, result["context"], expectedContext) + }) + t.Run("Vars provider serves notification secrets on secrets key", func(t *testing.T) { + result := varsProvider(emptyAppData, testDestination) + assert.NotNil(t, result["secrets"]) + assert.Equal(t, result["secrets"], notificationsSecret.Data) + }) +} From 30e06d6d4a8647a2a1401968755e0c89ec2687f8 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Wed, 25 Oct 2023 13:57:39 -0400 Subject: [PATCH 041/269] fix(ui): log button behaviors (#15848) (#16098) * Fixed log button behaviors Signed-off-by: Yi Cai * Fixed lint-ui issues Signed-off-by: Yi Cai --------- Signed-off-by: Yi Cai --- .../pod-logs-viewer/pod-logs-viewer.tsx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx index 30b101eecc4f8..1ef2d83815821 100644 --- a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx +++ b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx @@ -1,7 +1,7 @@ import {DataLoader} from 'argo-ui'; import * as classNames from 'classnames'; import * as React from 'react'; -import {useEffect, useState} from 'react'; +import {useEffect, useState, useRef} from 'react'; import {bufferTime, delay, retryWhen} from 'rxjs/operators'; import {LogEntry} from '../../../shared/models'; @@ -83,6 +83,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => { const [highlight, setHighlight] = useState(matchNothing); const [scrollToBottom, setScrollToBottom] = useState(true); const [logs, setLogs] = useState([]); + const logsContainerRef = useRef(null); useEffect(() => { if (viewPodNames) { @@ -102,6 +103,15 @@ export const PodsLogsViewer = (props: PodLogsProps) => { useEffect(() => setScrollToBottom(true), [follow]); + useEffect(() => { + if (scrollToBottom) { + const element = logsContainerRef.current; + if (element) { + element.scrollTop = element.scrollHeight; + } + } + }, [logs, scrollToBottom]); + useEffect(() => { setLogs([]); const logsSource = services.applications @@ -125,6 +135,10 @@ export const PodsLogsViewer = (props: PodLogsProps) => { return () => logsSource.unsubscribe(); }, [applicationName, applicationNamespace, namespace, podName, group, kind, name, containerName, tail, follow, sinceSeconds, filter, previous]); + const handleScroll = (event: React.WheelEvent) => { + if (event.deltaY < 0) setScrollToBottom(false); + }; + const renderLog = (log: LogEntry, lineNum: number) => // show the pod name if there are multiple pods, pad with spaces to align (viewPodNames ? (lineNum === 0 || logs[lineNum - 1].podName !== log.podName ? podColor(podName) + log.podName + reset : ' '.repeat(log.podName.length)) + ' ' : '') + @@ -133,7 +147,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => { // show the log content, highlight the filter text log.content?.replace(highlight, (substring: string) => whiteOnYellow + substring + reset); const logsContent = (width: number, height: number, isWrapped: boolean) => ( -
    +
    {logs.map((log, lineNum) => (
                         {renderLog(log, lineNum)}
    @@ -177,11 +191,7 @@ export const PodsLogsViewer = (props: PodLogsProps) => {
                                     
                                 
                             
    -
    { - if (e.deltaY < 0) setScrollToBottom(false); - }}> +
    {({width, height}: {width: number; height: number}) => logsContent(width, height, prefs.appDetails.wrapLines)}
    From fe3bb118033bee0c7fca9b2d39a3dcabc67d6e8e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:00:09 -0400 Subject: [PATCH 042/269] [Bot] docs: Update Snyk reports (#16061) Signed-off-by: CI Co-authored-by: CI --- docs/snyk/index.md | 16 +- docs/snyk/master/argocd-iac-install.html | 2 +- .../master/argocd-iac-namespace-install.html | 2 +- docs/snyk/master/argocd-test.html | 69 +++++- .../master/ghcr.io_dexidp_dex_v2.37.0.html | 4 +- docs/snyk/master/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_latest.html | 151 ++++++++++++- docs/snyk/master/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.6.15/argocd-iac-install.html | 2 +- .../v2.6.15/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.6.15/argocd-test.html | 4 +- .../v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html | 4 +- docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.6.15.html | 154 ++++++++++--- docs/snyk/v2.6.15/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.7.14/argocd-iac-install.html | 2 +- .../v2.7.14/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.7.14/argocd-test.html | 4 +- .../v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html | 4 +- docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.7.14.html | 154 ++++++++++--- docs/snyk/v2.7.14/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.8.4/argocd-iac-install.html | 2 +- .../v2.8.4/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.8.4/argocd-test.html | 69 +++++- .../v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html | 4 +- docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.8.4.html | 211 +++++++++++++++--- docs/snyk/v2.8.4/redis_7.0.11-alpine.html | 2 +- docs/snyk/v2.9.0-rc2/argocd-iac-install.html | 2 +- .../argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.9.0-rc2/argocd-test.html | 69 +++++- .../ghcr.io_dexidp_dex_v2.37.0.html | 4 +- .../v2.9.0-rc2/haproxy_2.6.14-alpine.html | 2 +- .../quay.io_argoproj_argocd_v2.9.0-rc2.html | 211 +++++++++++++++--- docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html | 2 +- 36 files changed, 995 insertions(+), 177 deletions(-) diff --git a/docs/snyk/index.md b/docs/snyk/index.md index fddd77111a7e3..a8e97a7018013 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -13,11 +13,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](master/argocd-test.html) | 0 | 0 | 5 | 0 | +| [go.mod](master/argocd-test.html) | 0 | 0 | 6 | 0 | | [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](master/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](master/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 3 | 19 | +| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 19 | | [redis:7.0.11-alpine](master/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | @@ -26,11 +26,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.9.0-rc2/argocd-test.html) | 0 | 2 | 5 | 0 | +| [go.mod](v2.9.0-rc2/argocd-test.html) | 0 | 2 | 6 | 0 | | [ui/yarn.lock](v2.9.0-rc2/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.9.0-rc2/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.9.0-rc2](v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html) | 0 | 2 | 6 | 20 | +| [argocd:v2.9.0-rc2](v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html) | 0 | 2 | 7 | 20 | | [redis:7.0.11-alpine](v2.9.0-rc2/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.9.0-rc2/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.9.0-rc2/argocd-iac-namespace-install.html) | - | - | - | - | @@ -39,11 +39,11 @@ recent minor releases. | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.8.4/argocd-test.html) | 0 | 2 | 5 | 0 | +| [go.mod](v2.8.4/argocd-test.html) | 0 | 2 | 6 | 0 | | [ui/yarn.lock](v2.8.4/argocd-test.html) | 0 | 0 | 0 | 0 | | [dex:v2.37.0](v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.8.4/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 2 | 6 | 20 | +| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 2 | 7 | 20 | | [redis:7.0.11-alpine](v2.8.4/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.8.4/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.8.4/argocd-iac-namespace-install.html) | - | - | - | - | @@ -56,7 +56,7 @@ recent minor releases. | [ui/yarn.lock](v2.7.14/argocd-test.html) | 0 | 1 | 0 | 0 | | [dex:v2.37.0](v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.7.14/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 2 | 6 | 20 | +| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 2 | 7 | 20 | | [redis:7.0.11-alpine](v2.7.14/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.7.14/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.7.14/argocd-iac-namespace-install.html) | - | - | - | - | @@ -69,7 +69,7 @@ recent minor releases. | [ui/yarn.lock](v2.6.15/argocd-test.html) | 0 | 1 | 0 | 0 | | [dex:v2.37.0](v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | | [haproxy:2.6.14-alpine](v2.6.15/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 2 | 6 | 20 | +| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 2 | 7 | 20 | | [redis:7.0.11-alpine](v2.6.15/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | | [install.yaml](v2.6.15/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.6.15/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index cdbbcd216e583..418bfdecc40fa 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:17:18 am (UTC+00:00)

    +

    October 22nd 2023, 12:17:18 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index 5ab8913fc9766..d5402379c9056 100644 --- a/docs/snyk/master/argocd-iac-namespace-install.html +++ b/docs/snyk/master/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:17:30 am (UTC+00:00)

    +

    October 22nd 2023, 12:17:28 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index de493e0e6e42c..baf98e4e8af70 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:14:41 am (UTC+00:00)

    +

    October 22nd 2023, 12:14:48 am (UTC+00:00)

    Scanned the following paths: @@ -466,9 +466,9 @@

    Snyk test report

    -
    5 known vulnerabilities
    -
    18 vulnerable dependency paths
    -
    1922 dependencies
    +
    6 known vulnerabilities
    +
    19 vulnerable dependency paths
    +
    1965 dependencies
    @@ -476,6 +476,65 @@

    Snyk test report

    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +

    MPL-2.0 license

    diff --git a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html index d9d7bb771d57e..d5818b81cb2f5 100644 --- a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:14:53 am (UTC+00:00)

    +

    October 22nd 2023, 12:15:00 am (UTC+00:00)

    Scanned the following paths: @@ -651,6 +651,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -733,6 +734,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/master/haproxy_2.6.14-alpine.html b/docs/snyk/master/haproxy_2.6.14-alpine.html index 1f696570c59d5..b0b4060ee0d33 100644 --- a/docs/snyk/master/haproxy_2.6.14-alpine.html +++ b/docs/snyk/master/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:15:00 am (UTC+00:00)

    +

    October 22nd 2023, 12:15:08 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index 1009be1e34406..4241230700e76 100644 --- a/docs/snyk/master/quay.io_argoproj_argocd_latest.html +++ b/docs/snyk/master/quay.io_argoproj_argocd_latest.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:15:23 am (UTC+00:00)

    +

    October 22nd 2023, 12:15:33 am (UTC+00:00)

    Scanned the following paths: @@ -466,9 +466,9 @@

    Snyk test report

    -
    29 known vulnerabilities
    -
    120 vulnerable dependency paths
    -
    2278 dependencies
    +
    31 known vulnerabilities
    +
    123 vulnerable dependency paths
    +
    2320 dependencies
    @@ -534,6 +534,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -962,6 +963,146 @@

    References

    More about this vulnerability

    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + gopkg.in/retry.v1@v1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    Memory Leak

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@latest and glibc/libc-bin@2.35-0ubuntu3.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + glibc/libc-bin@2.35-0ubuntu3.4 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@latest + + glibc/libc6@2.35-0ubuntu3.4 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A flaw was found in the GNU C Library. A recent fix for CVE-2023-4806 introduced the potential for a memory leak, which may result in an application crash.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 glibc.

    +

    References

    + + +
    + + +

    MPL-2.0 license

    diff --git a/docs/snyk/master/redis_7.0.11-alpine.html b/docs/snyk/master/redis_7.0.11-alpine.html index d4cf7fe946b5b..a63c98a15030a 100644 --- a/docs/snyk/master/redis_7.0.11-alpine.html +++ b/docs/snyk/master/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:15:30 am (UTC+00:00)

    +

    October 22nd 2023, 12:15:40 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-iac-install.html b/docs/snyk/v2.6.15/argocd-iac-install.html index b38345ee04e69..90c875983c384 100644 --- a/docs/snyk/v2.6.15/argocd-iac-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:28:31 am (UTC+00:00)

    +

    October 22nd 2023, 12:27:56 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html index e6cf243f42cc2..1bd89d9664d2d 100644 --- a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:28:43 am (UTC+00:00)

    +

    October 22nd 2023, 12:28:06 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-test.html b/docs/snyk/v2.6.15/argocd-test.html index d48c69439bc60..2672f4aef0e82 100644 --- a/docs/snyk/v2.6.15/argocd-test.html +++ b/docs/snyk/v2.6.15/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:26:23 am (UTC+00:00)

    +

    October 22nd 2023, 12:25:59 am (UTC+00:00)

    Scanned the following paths: @@ -936,6 +936,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -3186,6 +3187,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html index 682d6d00feadc..cf45377b1b6b5 100644 --- a/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:26:31 am (UTC+00:00)

    +

    October 22nd 2023, 12:26:08 am (UTC+00:00)

    Scanned the following paths: @@ -651,6 +651,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -733,6 +734,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html index 1d1b7ac0b764b..e107d327e33f3 100644 --- a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:26:35 am (UTC+00:00)

    +

    October 22nd 2023, 12:26:13 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html index cd0e96a404b08..4afe990dd0ffb 100644 --- a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html +++ b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:27:03 am (UTC+00:00)

    +

    October 22nd 2023, 12:26:35 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    46 known vulnerabilities
    -
    157 vulnerable dependency paths
    +
    47 known vulnerabilities
    +
    159 vulnerable dependency paths
    2063 dependencies
    @@ -702,6 +702,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -872,6 +873,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -1120,6 +1122,8 @@

    References

  • secalert@redhat.com
  • secalert@redhat.com
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com

  • @@ -1278,37 +1282,25 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. - The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. - Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    -

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    -

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    -

    Note:

    -

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. - Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    -

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    -
      -
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: - CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      -
    2. -
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      -
    4. -
    -

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    -
      -
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      -
    2. -
    3. Environment variables as described in the libcurl section.

      -
    4. -
    -

    Changelog:

    -

    2023-10-04: Initial publication

    -

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    This flaw makes curl overflow a heap based buffer in the SOCKS5 proxy + handshake.

    +

    When curl is asked to pass along the host name to the SOCKS5 proxy to allow + that to resolve the address instead of it getting done by curl itself, the + maximum length that host name can be is 255 bytes.

    +

    If the host name is detected to be longer, curl switches to local name + resolving and instead passes on the resolved address only. Due to this bug, + the local variable that means "let the host resolve the name" could get the + wrong value during a slow SOCKS5 handshake, and contrary to the intention, + copy the too long host name to the target buffer instead of copying just the + resolved address there.

    +

    The target buffer being a heap based buffer, and the host name coming from the + URL that curl has been told to operate with.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    @@ -2382,6 +2374,89 @@

    References

    More about this vulnerability

    +
    +
    +

    Memory Leak

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and glibc/libc-bin@2.35-0ubuntu3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + glibc/libc-bin@2.35-0ubuntu3.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + glibc/libc6@2.35-0ubuntu3.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A flaw was found in the GNU C Library. A recent fix for CVE-2023-4806 introduced the potential for a memory leak, which may result in an application crash.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 glibc.

    +

    References

    + + +
    + + +

    MPL-2.0 license

    @@ -4977,12 +5052,29 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    This flaw allows an attacker to insert cookies at will into a running program + using libcurl, if the specific series of conditions are met.

    +

    libcurl performs transfers. In its API, an application creates "easy handles" + that are the individual handles for single transfers.

    +

    libcurl provides a function call that duplicates en easy handle called + curl_easy_duphandle.

    +

    If a transfer has cookies enabled when the handle is duplicated, the + cookie-enable state is also cloned - but without cloning the actual + cookies. If the source handle did not read any cookies from a specific file on + disk, the cloned version of the handle would instead store the file name as + none (using the four ASCII letters, no quotes).

    +

    Subsequent use of the cloned handle that does not explicitly set a source to + load cookies from would then inadvertently load cookies from a file named + none - if such a file exists and is readable in the current directory of the + program using libcurl. And if using the correct file format of course.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    diff --git a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html index 9145ccc25b134..4517b6875556d 100644 --- a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:27:08 am (UTC+00:00)

    +

    October 22nd 2023, 12:26:40 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-iac-install.html b/docs/snyk/v2.7.14/argocd-iac-install.html index 2ec1b5c084982..ab8ddd883ddd9 100644 --- a/docs/snyk/v2.7.14/argocd-iac-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:25:57 am (UTC+00:00)

    +

    October 22nd 2023, 12:25:32 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html index 7eb1bed27e1fe..d185574255ccc 100644 --- a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:26:08 am (UTC+00:00)

    +

    October 22nd 2023, 12:25:44 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-test.html b/docs/snyk/v2.7.14/argocd-test.html index 0ac0a0289e1fa..f004e6e9bd197 100644 --- a/docs/snyk/v2.7.14/argocd-test.html +++ b/docs/snyk/v2.7.14/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:23:35 am (UTC+00:00)

    +

    October 22nd 2023, 12:23:29 am (UTC+00:00)

    Scanned the following paths: @@ -936,6 +936,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -3298,6 +3299,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html index 0227ad9f0c750..1b9f8a4109329 100644 --- a/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:23:43 am (UTC+00:00)

    +

    October 22nd 2023, 12:23:36 am (UTC+00:00)

    Scanned the following paths: @@ -651,6 +651,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -733,6 +734,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html index abf669350cd1a..007cb149e346e 100644 --- a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:23:47 am (UTC+00:00)

    +

    October 22nd 2023, 12:23:41 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html index 2bf2450f0d958..03bd4c6c6ccf8 100644 --- a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html +++ b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:24:23 am (UTC+00:00)

    +

    October 22nd 2023, 12:24:02 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    39 known vulnerabilities
    -
    148 vulnerable dependency paths
    +
    40 known vulnerabilities
    +
    150 vulnerable dependency paths
    2065 dependencies
    @@ -534,6 +534,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -695,6 +696,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -877,6 +879,8 @@

    References

  • secalert@redhat.com
  • secalert@redhat.com
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com

  • @@ -1035,37 +1039,25 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. - The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. - Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    -

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    -

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    -

    Note:

    -

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. - Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    -

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    -
      -
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: - CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      -
    2. -
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      -
    4. -
    -

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    -
      -
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      -
    2. -
    3. Environment variables as described in the libcurl section.

      -
    4. -
    -

    Changelog:

    -

    2023-10-04: Initial publication

    -

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    This flaw makes curl overflow a heap based buffer in the SOCKS5 proxy + handshake.

    +

    When curl is asked to pass along the host name to the SOCKS5 proxy to allow + that to resolve the address instead of it getting done by curl itself, the + maximum length that host name can be is 255 bytes.

    +

    If the host name is detected to be longer, curl switches to local name + resolving and instead passes on the resolved address only. Due to this bug, + the local variable that means "let the host resolve the name" could get the + wrong value during a slow SOCKS5 handshake, and contrary to the intention, + copy the too long host name to the target buffer instead of copying just the + resolved address there.

    +

    The target buffer being a heap based buffer, and the host name coming from the + URL that curl has been told to operate with.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    @@ -1851,6 +1843,89 @@

    References

    More about this vulnerability

    +
    +
    +

    Memory Leak

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and glibc/libc-bin@2.35-0ubuntu3.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + glibc/libc-bin@2.35-0ubuntu3.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + glibc/libc6@2.35-0ubuntu3.1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A flaw was found in the GNU C Library. A recent fix for CVE-2023-4806 introduced the potential for a memory leak, which may result in an application crash.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 glibc.

    +

    References

    + + +
    + + +

    MPL-2.0 license

    @@ -4446,12 +4521,29 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    This flaw allows an attacker to insert cookies at will into a running program + using libcurl, if the specific series of conditions are met.

    +

    libcurl performs transfers. In its API, an application creates "easy handles" + that are the individual handles for single transfers.

    +

    libcurl provides a function call that duplicates en easy handle called + curl_easy_duphandle.

    +

    If a transfer has cookies enabled when the handle is duplicated, the + cookie-enable state is also cloned - but without cloning the actual + cookies. If the source handle did not read any cookies from a specific file on + disk, the cloned version of the handle would instead store the file name as + none (using the four ASCII letters, no quotes).

    +

    Subsequent use of the cloned handle that does not explicitly set a source to + load cookies from would then inadvertently load cookies from a file named + none - if such a file exists and is readable in the current directory of the + program using libcurl. And if using the correct file format of course.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    diff --git a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html index 69df11ccdc4a9..abb0d46e599d1 100644 --- a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:24:30 am (UTC+00:00)

    +

    October 22nd 2023, 12:24:07 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/argocd-iac-install.html b/docs/snyk/v2.8.4/argocd-iac-install.html index f7ede8ff7e0aa..74bfd26bd5685 100644 --- a/docs/snyk/v2.8.4/argocd-iac-install.html +++ b/docs/snyk/v2.8.4/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:22:59 am (UTC+00:00)

    +

    October 22nd 2023, 12:22:54 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html b/docs/snyk/v2.8.4/argocd-iac-namespace-install.html index e4cfddbb16d3b..ad9dd5a08070e 100644 --- a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.8.4/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:23:11 am (UTC+00:00)

    +

    October 22nd 2023, 12:23:05 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/argocd-test.html b/docs/snyk/v2.8.4/argocd-test.html index 1de80ab7cac2f..a1275415abd1f 100644 --- a/docs/snyk/v2.8.4/argocd-test.html +++ b/docs/snyk/v2.8.4/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:20:42 am (UTC+00:00)

    +

    October 22nd 2023, 12:20:43 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    7 known vulnerabilities
    -
    161 vulnerable dependency paths
    +
    8 known vulnerabilities
    +
    162 vulnerable dependency paths
    1851 dependencies
    @@ -797,6 +797,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -3112,6 +3113,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -3126,6 +3128,65 @@

    References

    More about this vulnerability

    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + +

    MPL-2.0 license

    diff --git a/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html index 8317707e30243..23d448e47235c 100644 --- a/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:20:56 am (UTC+00:00)

    +

    October 22nd 2023, 12:20:50 am (UTC+00:00)

    Scanned the following paths: @@ -651,6 +651,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -733,6 +734,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html b/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html index 07dbf17451bd3..d69638239b8f3 100644 --- a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:21:02 am (UTC+00:00)

    +

    October 22nd 2023, 12:20:56 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html b/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html index 3fa6411766044..41972f87bb6f3 100644 --- a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html +++ b/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:21:24 am (UTC+00:00)

    +

    October 22nd 2023, 12:21:18 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    37 known vulnerabilities
    -
    145 vulnerable dependency paths
    +
    39 known vulnerabilities
    +
    148 vulnerable dependency paths
    2116 dependencies
    @@ -534,6 +534,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -616,6 +617,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -718,6 +720,8 @@

    References

  • secalert@redhat.com
  • secalert@redhat.com
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com

  • @@ -867,37 +871,25 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. - The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. - Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    -

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    -

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    -

    Note:

    -

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. - Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    -

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    -
      -
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: - CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      -
    2. -
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      -
    4. -
    -

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    -
      -
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      -
    2. -
    3. Environment variables as described in the libcurl section.

      -
    4. -
    -

    Changelog:

    -

    2023-10-04: Initial publication

    -

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    This flaw makes curl overflow a heap based buffer in the SOCKS5 proxy + handshake.

    +

    When curl is asked to pass along the host name to the SOCKS5 proxy to allow + that to resolve the address instead of it getting done by curl itself, the + maximum length that host name can be is 255 bytes.

    +

    If the host name is detected to be longer, curl switches to local name + resolving and instead passes on the resolved address only. Due to this bug, + the local variable that means "let the host resolve the name" could get the + wrong value during a slow SOCKS5 handshake, and contrary to the intention, + copy the too long host name to the target buffer instead of copying just the + resolved address there.

    +

    The target buffer being a heap based buffer, and the host name coming from the + URL that curl has been told to operate with.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    @@ -1683,6 +1675,146 @@

    References

    More about this vulnerability

    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + gopkg.in/retry.v1@v1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    Memory Leak

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.8.4 and glibc/libc-bin@2.35-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + glibc/libc-bin@2.35-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.4 + + glibc/libc6@2.35-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A flaw was found in the GNU C Library. A recent fix for CVE-2023-4806 introduced the potential for a memory leak, which may result in an application crash.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 glibc.

    +

    References

    + + +
    + + +

    MPL-2.0 license

    @@ -4269,12 +4401,29 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    This flaw allows an attacker to insert cookies at will into a running program + using libcurl, if the specific series of conditions are met.

    +

    libcurl performs transfers. In its API, an application creates "easy handles" + that are the individual handles for single transfers.

    +

    libcurl provides a function call that duplicates en easy handle called + curl_easy_duphandle.

    +

    If a transfer has cookies enabled when the handle is duplicated, the + cookie-enable state is also cloned - but without cloning the actual + cookies. If the source handle did not read any cookies from a specific file on + disk, the cloned version of the handle would instead store the file name as + none (using the four ASCII letters, no quotes).

    +

    Subsequent use of the cloned handle that does not explicitly set a source to + load cookies from would then inadvertently load cookies from a file named + none - if such a file exists and is readable in the current directory of the + program using libcurl. And if using the correct file format of course.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    diff --git a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html b/docs/snyk/v2.8.4/redis_7.0.11-alpine.html index 3a5dc5021f2e9..fe91f261fcc18 100644 --- a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.8.4/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:21:29 am (UTC+00:00)

    +

    October 22nd 2023, 12:21:23 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html b/docs/snyk/v2.9.0-rc2/argocd-iac-install.html index 34bc0c556c3d0..3d521f9f74881 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html +++ b/docs/snyk/v2.9.0-rc2/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:20:10 am (UTC+00:00)

    +

    October 22nd 2023, 12:20:12 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html b/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html index b55f00109791b..8280d0891ebd1 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:20:21 am (UTC+00:00)

    +

    October 22nd 2023, 12:20:23 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-test.html b/docs/snyk/v2.9.0-rc2/argocd-test.html index 7e647f138369b..edf48da06d740 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-test.html +++ b/docs/snyk/v2.9.0-rc2/argocd-test.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:17:43 am (UTC+00:00)

    +

    October 22nd 2023, 12:17:48 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    7 known vulnerabilities
    -
    166 vulnerable dependency paths
    +
    8 known vulnerabilities
    +
    167 vulnerable dependency paths
    1920 dependencies
    @@ -814,6 +814,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -3201,6 +3202,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -3215,6 +3217,65 @@

    References

    More about this vulnerability

    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + +

    MPL-2.0 license

    diff --git a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html index 2051e0965c34d..395c6ba1691e8 100644 --- a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:17:51 am (UTC+00:00)

    +

    October 22nd 2023, 12:17:57 am (UTC+00:00)

    Scanned the following paths: @@ -651,6 +651,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -733,6 +734,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • diff --git a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html b/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html index 20f19d4becc2e..87d2e9a0fef4b 100644 --- a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:17:55 am (UTC+00:00)

    +

    October 22nd 2023, 12:18:01 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html b/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html index 0aab8254e5f9e..1bf83c3e87170 100644 --- a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html +++ b/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:18:18 am (UTC+00:00)

    +

    October 22nd 2023, 12:18:24 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    37 known vulnerabilities
    -
    145 vulnerable dependency paths
    +
    39 known vulnerabilities
    +
    148 vulnerable dependency paths
    2270 dependencies
    @@ -534,6 +534,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -616,6 +617,7 @@

    References

  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • +
  • GitHub Commit
  • GitHub Commit
  • GitHub Commit
  • Snyk Blog
  • @@ -718,6 +720,8 @@

    References

  • secalert@redhat.com
  • secalert@redhat.com
  • secalert@redhat.com
  • +
  • secalert@redhat.com
  • +
  • secalert@redhat.com

  • @@ -867,37 +871,25 @@

    Detailed paths

    NVD Description

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    in the SOCKS5 proxy handshake process when the hostname is longer than the target buffer. - The local variable socks5_resolve_local could get the wrong value during a slow SOCKS5 handshake. - Since the code wrongly thinks it should pass on the hostname, even though the hostname is too long to fit, the memory copy can overflow the allocated target buffer.

    -

    This is only exploitable if the SOCKS5 handshake is slow enough to trigger a local variable bug and the client uses a hostname longer than the download buffer.

    -

    Exploiting this vulnerability could allow an attacker to execute arbitrary code on the target system under certain conditions.

    -

    Note:

    -

    An overflow is only possible in applications that don't set CURLOPT_BUFFERSIZE or set it smaller than 65541. - Since the curl tool sets CURLOPT_BUFFERSIZE to 100kB by default, it is not vulnerable unless the user sets the rate limiting to a rate smaller than 65541 bytes/second.

    -

    The options that cause SOCKS5 with remote hostname to be used in libcurl:

    -
      -
    1. CURLOPT_PROXYTYPE set to type CURLPROXY_SOCKS5_HOSTNAME, or: - CURLOPT_PROXY or CURLOPT_PRE_PROXY set to use the scheme socks5h://

      -
    2. -
    3. One of the proxy environment variables can be set to use the socks5h:// scheme. For example, http_proxy, HTTPS_PROXY or ALL_PROXY.

      -
    4. -
    -

    The options that cause SOCKS5 with remote hostname to be used in the curl tool:

    -
      -
    1. --socks5-hostname, --proxy or --preproxy set to use the scheme socks5h://

      -
    2. -
    3. Environment variables as described in the libcurl section.

      -
    4. -
    -

    Changelog:

    -

    2023-10-04: Initial publication

    -

    2023-10-11: Published updated information, including CWE, CVSS, official references and affected versions range.

    +

    This flaw makes curl overflow a heap based buffer in the SOCKS5 proxy + handshake.

    +

    When curl is asked to pass along the host name to the SOCKS5 proxy to allow + that to resolve the address instead of it getting done by curl itself, the + maximum length that host name can be is 255 bytes.

    +

    If the host name is detected to be longer, curl switches to local name + resolving and instead passes on the resolved address only. Due to this bug, + the local variable that means "let the host resolve the name" could get the + wrong value during a slow SOCKS5 handshake, and contrary to the intention, + copy the too long host name to the target buffer instead of copying just the + resolved address there.

    +

    The target buffer being a heap based buffer, and the host name coming from the + URL that curl has been told to operate with.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    @@ -1683,6 +1675,146 @@

    References

    More about this vulnerability

    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@* and gopkg.in/retry.v1@v1.0.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@* + + gopkg.in/retry.v1@v1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    Memory Leak

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + glibc/libc-bin +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and glibc/libc-bin@2.35-0ubuntu3.3 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + glibc/libc-bin@2.35-0ubuntu3.3 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + + glibc/libc6@2.35-0ubuntu3.3 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    A flaw was found in the GNU C Library. A recent fix for CVE-2023-4806 introduced the potential for a memory leak, which may result in an application crash.

    +

    Remediation

    +

    There is no fixed version for Ubuntu:22.04 glibc.

    +

    References

    + + +
    + + +

    MPL-2.0 license

    @@ -4269,12 +4401,29 @@

    Detailed paths


    NVD Description

    -

    This vulnerability has not been analyzed by NVD yet.

    +

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    This flaw allows an attacker to insert cookies at will into a running program + using libcurl, if the specific series of conditions are met.

    +

    libcurl performs transfers. In its API, an application creates "easy handles" + that are the individual handles for single transfers.

    +

    libcurl provides a function call that duplicates en easy handle called + curl_easy_duphandle.

    +

    If a transfer has cookies enabled when the handle is duplicated, the + cookie-enable state is also cloned - but without cloning the actual + cookies. If the source handle did not read any cookies from a specific file on + disk, the cloned version of the handle would instead store the file name as + none (using the four ASCII letters, no quotes).

    +

    Subsequent use of the cloned handle that does not explicitly set a source to + load cookies from would then inadvertently load cookies from a file named + none - if such a file exists and is readable in the current directory of the + program using libcurl. And if using the correct file format of course.

    Remediation

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    References


    diff --git a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html b/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html index 6cb08e277c738..329d39f6c5098 100644 --- a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 15th 2023, 12:18:24 am (UTC+00:00)

    +

    October 22nd 2023, 12:18:30 am (UTC+00:00)

    Scanned the following path: From a723a6c38c7af9c091274ad00f40792c01c68bbd Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:55:37 -0400 Subject: [PATCH 043/269] feat(cli): add project flag to avoid permission denied errors on 404 (#16040) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- cmd/argocd/commands/app_resources.go | 12 ++++++++++-- .../commands/argocd_app_delete-resource.md | 1 + .../user-guide/commands/argocd_app_patch-resource.md | 1 + docs/user-guide/commands/argocd_app_resources.md | 7 ++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cmd/argocd/commands/app_resources.go b/cmd/argocd/commands/app_resources.go index e48465c7e4693..4cffb706ff1bc 100644 --- a/cmd/argocd/commands/app_resources.go +++ b/cmd/argocd/commands/app_resources.go @@ -3,6 +3,7 @@ package commands import ( "fmt" "os" + "text/tabwriter" "github.com/argoproj/argo-cd/v2/cmd/util" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -18,8 +19,6 @@ import ( "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/errors" argoio "github.com/argoproj/argo-cd/v2/util/io" - - "text/tabwriter" ) func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { @@ -30,6 +29,7 @@ func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions) var kind string var group string var all bool + var project string command := &cobra.Command{ Use: "patch-resource APPNAME", Short: "Patch resource in an application", @@ -46,6 +46,7 @@ func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions) command.Flags().StringVar(&group, "group", "", "Group") command.Flags().StringVar(&namespace, "namespace", "", "Namespace") command.Flags().BoolVar(&all, "all", false, "Indicates whether to patch multiple matching of resources") + command.Flags().StringVar(&project, "project", "", `The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist`) command.Run = func(c *cobra.Command, args []string) { ctx := c.Context() @@ -77,6 +78,7 @@ func NewApplicationPatchResourceCommand(clientOpts *argocdclient.ClientOptions) Kind: pointer.String(gvk.Kind), Patch: pointer.String(patch), PatchType: pointer.String(patchType), + Project: pointer.String(project), }) errors.CheckError(err) log.Infof("Resource '%s' patched", obj.GetName()) @@ -94,6 +96,7 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) var force bool var orphan bool var all bool + var project string command := &cobra.Command{ Use: "delete-resource APPNAME", Short: "Delete resource in an application", @@ -108,6 +111,7 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) command.Flags().BoolVar(&force, "force", false, "Indicates whether to orphan the dependents of the deleted resource") command.Flags().BoolVar(&orphan, "orphan", false, "Indicates whether to force delete the resource") command.Flags().BoolVar(&all, "all", false, "Indicates whether to patch multiple matching of resources") + command.Flags().StringVar(&project, "project", "", `The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist`) command.Run = func(c *cobra.Command, args []string) { ctx := c.Context() @@ -139,6 +143,7 @@ func NewApplicationDeleteResourceCommand(clientOpts *argocdclient.ClientOptions) Kind: pointer.String(gvk.Kind), Force: &force, Orphan: &orphan, + Project: pointer.String(project), }) errors.CheckError(err) log.Infof("Resource '%s' deleted", obj.GetName()) @@ -250,6 +255,7 @@ func printResources(listAll bool, orphaned bool, appResourceTree *v1alpha1.Appli func NewApplicationListResourcesCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var orphaned bool var output string + var project string var command = &cobra.Command{ Use: "resources APPNAME", Short: "List resource of application", @@ -266,6 +272,7 @@ func NewApplicationListResourcesCommand(clientOpts *argocdclient.ClientOptions) appResourceTree, err := appIf.ResourceTree(ctx, &applicationpkg.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, + Project: &project, }) errors.CheckError(err) printResources(listAll, orphaned, appResourceTree, output) @@ -273,5 +280,6 @@ func NewApplicationListResourcesCommand(clientOpts *argocdclient.ClientOptions) } command.Flags().BoolVar(&orphaned, "orphaned", false, "Lists only orphaned resources") command.Flags().StringVar(&output, "output", "", "Provides the tree view of the resources") + command.Flags().StringVar(&project, "project", "", `The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist`) return command } diff --git a/docs/user-guide/commands/argocd_app_delete-resource.md b/docs/user-guide/commands/argocd_app_delete-resource.md index f65873227473a..4a305eb4b4489 100644 --- a/docs/user-guide/commands/argocd_app_delete-resource.md +++ b/docs/user-guide/commands/argocd_app_delete-resource.md @@ -18,6 +18,7 @@ argocd app delete-resource APPNAME [flags] --kind string Kind --namespace string Namespace --orphan Indicates whether to force delete the resource + --project string The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist --resource-name string Name of resource ``` diff --git a/docs/user-guide/commands/argocd_app_patch-resource.md b/docs/user-guide/commands/argocd_app_patch-resource.md index 9211f410ea5b1..c849395cb3ea8 100644 --- a/docs/user-guide/commands/argocd_app_patch-resource.md +++ b/docs/user-guide/commands/argocd_app_patch-resource.md @@ -18,6 +18,7 @@ argocd app patch-resource APPNAME [flags] --namespace string Namespace --patch string Patch --patch-type string Which Patching strategy to use: 'application/json-patch+json', 'application/merge-patch+json', or 'application/strategic-merge-patch+json'. Defaults to 'application/merge-patch+json' (default "application/merge-patch+json") + --project string The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist --resource-name string Name of resource ``` diff --git a/docs/user-guide/commands/argocd_app_resources.md b/docs/user-guide/commands/argocd_app_resources.md index b704ad1c41770..22027f74ba3d7 100644 --- a/docs/user-guide/commands/argocd_app_resources.md +++ b/docs/user-guide/commands/argocd_app_resources.md @@ -11,9 +11,10 @@ argocd app resources APPNAME [flags] ### Options ``` - -h, --help help for resources - --orphaned Lists only orphaned resources - --output string Provides the tree view of the resources + -h, --help help for resources + --orphaned Lists only orphaned resources + --output string Provides the tree view of the resources + --project string The name of the application's project - specifying this allows the command to report "not found" instead of "permission denied" if the app does not exist ``` ### Options inherited from parent commands From 591a94ba733171dad37903d023c7c8ed2bd0d25a Mon Sep 17 00:00:00 2001 From: Joseph Perez Date: Wed, 25 Oct 2023 16:03:04 -0400 Subject: [PATCH 044/269] fix: Add timezone to projectwindows list (#15929) * list timezone in default list windows Signed-off-by: Joseph Perez * add list example Signed-off-by: Joseph Perez * clidocsgen Signed-off-by: Joseph Perez --------- Signed-off-by: Joseph Perez --- cmd/argocd/commands/projectwindows.go | 11 +++++++++-- docs/user-guide/commands/argocd_proj_windows_list.md | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go index 76679b5dc3eae..a46f9ece64c36 100644 --- a/cmd/argocd/commands/projectwindows.go +++ b/cmd/argocd/commands/projectwindows.go @@ -274,6 +274,12 @@ func NewProjectWindowsListCommand(clientOpts *argocdclient.ClientOptions) *cobra var command = &cobra.Command{ Use: "list PROJECT", Short: "List project sync windows", + Example: `# List project windows +argocd proj windows list PROJECT + +# List project windows in yaml format +argocd proj windows list PROJECT -o yaml +`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -306,8 +312,8 @@ func NewProjectWindowsListCommand(clientOpts *argocdclient.ClientOptions) *cobra func printSyncWindows(proj *v1alpha1.AppProject) { w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) var fmtStr string - headers := []interface{}{"ID", "STATUS", "KIND", "SCHEDULE", "DURATION", "APPLICATIONS", "NAMESPACES", "CLUSTERS", "MANUALSYNC"} - fmtStr = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n" + headers := []interface{}{"ID", "STATUS", "KIND", "SCHEDULE", "DURATION", "APPLICATIONS", "NAMESPACES", "CLUSTERS", "MANUALSYNC", "TIMEZONE"} + fmtStr = strings.Repeat("%s\t", len(headers)) + "\n" fmt.Fprintf(w, fmtStr, headers...) if proj.Spec.SyncWindows.HasWindows() { for i, window := range proj.Spec.SyncWindows { @@ -321,6 +327,7 @@ func printSyncWindows(proj *v1alpha1.AppProject) { formatListOutput(window.Namespaces), formatListOutput(window.Clusters), formatManualOutput(window.ManualSync), + window.TimeZone, } fmt.Fprintf(w, fmtStr, vals...) } diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index e0267a2517252..94073db4775b8 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -8,6 +8,17 @@ List project sync windows argocd proj windows list PROJECT [flags] ``` +### Examples + +``` +# List project windows +argocd proj windows list PROJECT + +# List project windows in yaml format +argocd proj windows list PROJECT -o yaml + +``` + ### Options ``` From 6e2f2c9d1e2339b3361f3a057747fcfe30e36f44 Mon Sep 17 00:00:00 2001 From: Gaurang Kudale Date: Thu, 26 Oct 2023 01:33:54 +0530 Subject: [PATCH 045/269] feat(cli): add admin-app-example (#15690) (#15861) * update the admin-app-example Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale * update the admin-app-example Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale * update the admin-app-example Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale * updating the admin-app-example Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale * updating the admin-app-example Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale * Update cmd/argocd/commands/admin/app.go Co-authored-by: Blake Pettersson Signed-off-by: Gaurang Kudale * update the string Signed-off-by: Author Name gaurang.kudale02@gmail.com Signed-off-by: Gaurang Kudale --------- Signed-off-by: Gaurang Kudale Signed-off-by: Gaurang Kudale Co-authored-by: Blake Pettersson --- cmd/argocd/commands/admin/app.go | 10 ++++++++++ docs/user-guide/commands/argocd_admin_app.md | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index fbceb436f8609..a4f4557858a22 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -45,6 +45,16 @@ func NewAppCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "app", Short: "Manage applications configuration", + Example: ` +# Compare results of two reconciliations and print diff +argocd admin app diff-reconcile-results APPNAME [flags] + +# Generate declarative config for an application +argocd admin app generate-spec APPNAME + +# Reconcile all applications and store reconciliation summary in the specified file +argocd admin app get-reconcile-results APPNAME +`, Run: func(c *cobra.Command, args []string) { c.HelpFunc()(c, args) }, diff --git a/docs/user-guide/commands/argocd_admin_app.md b/docs/user-guide/commands/argocd_admin_app.md index 5b2200bf1116f..58e0f50f25846 100644 --- a/docs/user-guide/commands/argocd_admin_app.md +++ b/docs/user-guide/commands/argocd_admin_app.md @@ -8,6 +8,21 @@ Manage applications configuration argocd admin app [flags] ``` +### Examples + +``` + +# Compare results of two reconciliations and print diff +argocd admin app diff-reconcile-results APPNAME [flags] + +# Generate declarative config for an application +argocd admin app generate-spec APPNAME + +# Reconcile all applications and store reconciliation summary in the specified file +argocd admin app get-reconcile-results APPNAME + +``` + ### Options ``` From b71277c6beb949d0199d647a582bc25822b88838 Mon Sep 17 00:00:00 2001 From: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:14:17 +0200 Subject: [PATCH 046/269] docs: added identity-center.md doc for AWS SSO (#15689) * docs: added identity center doc (AWS SSO) Signed-off-by: zeusal * Apply suggestions from code review Co-authored-by: Carlos Santana Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> * Update identity-center.md Added note for attribute mapping Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> * Update identity-center.md Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> * Update docs/operator-manual/user-management/identity-center.md Co-authored-by: Justin Marquis <76892343+34fathombelow@users.noreply.github.com> Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> * Update identity-center.md Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> Fixed image order and style doc Update identity-center.md Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> Update identity-center.md Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> * Update identity-center.md Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> --------- Signed-off-by: zeusal Signed-off-by: Zeus Arias Lucero <33123154+zeusal@users.noreply.github.com> Co-authored-by: Zeus Arias Co-authored-by: Carlos Santana Co-authored-by: Justin Marquis <76892343+34fathombelow@users.noreply.github.com> --- docs/assets/identity-center-1.png | Bin 0 -> 108361 bytes docs/assets/identity-center-2.png | Bin 0 -> 179317 bytes docs/assets/identity-center-3.png | Bin 0 -> 70839 bytes docs/assets/identity-center-4.png | Bin 0 -> 20636 bytes docs/assets/identity-center-5.png | Bin 0 -> 52918 bytes docs/assets/identity-center-6.png | Bin 0 -> 56086 bytes .../user-management/identity-center.md | 79 ++++++++++++++++++ mkdocs.yml | 1 + 8 files changed, 80 insertions(+) create mode 100644 docs/assets/identity-center-1.png create mode 100644 docs/assets/identity-center-2.png create mode 100644 docs/assets/identity-center-3.png create mode 100644 docs/assets/identity-center-4.png create mode 100644 docs/assets/identity-center-5.png create mode 100644 docs/assets/identity-center-6.png create mode 100644 docs/operator-manual/user-management/identity-center.md diff --git a/docs/assets/identity-center-1.png b/docs/assets/identity-center-1.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd49528d90f7159b7f89a9166e68c3d2416dfbc GIT binary patch literal 108361 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

    NeB7StDm=j`hbNv49l2KzH&5+zKG`K!1OIR<)2M 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 jrT;Wa{?~GQ6uONw-cqijauIoj~6Lypd>T8G*a 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

    m=&!TwuaY0 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 v7pZM_n9~+MUql?mi z+dnz8??-TOaF9e|620Z1W2XyBOG~RWc>p&^E_jB{ZDP@ls(G(-^dTD zKEbVfVZmTnmu)@aoamp6>}^fJR&6u>)z$TLbo)K!XFVh$Ra!RM$#$*VqPgUs4u=BBBDe!rLKKfP`pIA{m`ma2c|yXz&B|4$7<;{R>C)&KsX zG7~z082LSy!|l4u&$!pTUdjCShKzBEpq;&hdO1Eax3Uz!9@mg~|1W;GPVHcbndL3v z^Ptr$vS8PpxNHwKPe3~*VuV%&3%c%LoE!;mC#tN)4th7IsMQ*o?M&NtjWTSz&A8f6 zXh_}J4HUvaj8C+PDVQq_EY{Bwz@CTAx=pn^<1_;lx8gu#%JBACx=)Q)PZt2!em(Be z@^~qaT)rN2gPVG;{cfgvl(U$ZJr!fs-Ii6)#q(1LQ0H}fvaJr@j7MYtq-z5xY98{h zJKcM}+3-v%+;piT;anDkbZb*Q1CaNooY~TBE>@7<l+{caQHQmHqFl)J-Q?_3{dfCnFyW{jmXxPSY8k8AIJxzm|rk)EWn zJj3kI2uvMix#opX+>^qTzJs+zY@#U5r0Aef58r9CcaI zuIv_^?c)am<6i51#@XoVH6Qffnuk45pB`H6^K;)=6rhsY3Lr?TA$r!;%7XZzK1krJfa_3MZ39~qvAaJ6?lfdTk?VPo2b=B>(n*P=`F@Q74_(`D-=c< zV{LiglYy5`9Ed4-&!C0}=G_hpc(x&nEVmF=C;P+C|!2R10uw{7EDBZ@M5DSAFM zxdD?WBgtpUZBkB#NW7we(hYza*6TIV!<_hLEwd%5Nlg9r4fP@{74apsXafo!o|kMq4ukRCYImh>E{+6sM8} zV>+p!&ikXdedv|G=y<8U;k;`dA)SMOJ&rA91YeN{?Ecw~4ry^8Tk<73&yDb}Q-_t==BabC{-ndTqpU4J*4|*VVk1#V?0G(mPxc@7=kg zbQ~=!+nX|6pq10!^hCvjK+=)T=#$N@fw^)7Ib-lb;8J)9p-yl--F#QEV}$DS#AyQ>0q zz~wr;qJ|CDFYn0CF0${z;J8{ZM(mft#({!W#hhk6Z~4 zx%-tee8Z`2a3PiHYy|T3+9dXAMR?Of>;teq@uvg*E)W-lFYs~9&-{XPVP7&+R7_cNVI}8((Yghu#voBb%%jJxbO9P=YqI*vU+_t zr4!Z4j=NS5!>-|OelWt0%QE+l0YW(>_3lV3UD2ccYM}wP%6-p!>gXns@X&mmy#;7G z+}&>^4GUy*y3I~LS1h{o*Bgb}%?u-Jlk#ne0!F4<2$T<#%-vqWY-WMhKDtcdu*Yk4 z_bDmdzkfzwi_2f0r_O8aw&M1(UrK*fa|uz+ zaX{&L*9V0f_hn-&icVtCSRB4lyzY+;kNLGkw+-LcBD<|IR`tNvr?KKULy$WeMrs`8 zM;!Zn+t9-U001aY2izdh><}z_&xyu5vVy&pfRK>mb{;hEMfprTgW)|IuW%5FX?p_6 zc*!@|x^e@2C$n-msaFgMR#Axvj==0Xlbr5J$JFLL@Y_?<^L$-eL~MvUwT-7%mrQX6 z%NMt)_SC9Bw`3bz+{f9#=p)HP@9ed0cAC%EsE;;3$2_Axd)3i#|4NZVhAad( zM;oSZvj-15cnRH5UkVw%giAN-laJ@@8&;Pk3II`Y*@@N$E}iNuP;?H1**GTXn!`>%Dj*Sy*6y~3O-*9?21C&t=_hCwyEe-Iaxlh)Eu^qp8%_j&4ze`Wx_>Q$3~&S2mn>YUQ9VH z2KRI&;z&>ZXuRA-EVGGQsB(9Yf>r)C4LAWiqGM!P{%D0;dw0`eC11+1ZW5-M_K;~& zk@ha@U2K*qAlnwNgzOo%w;3JIGY6If_}qd&vodRiwP%T;nrDjn!Qn|_E?86Kitt{n z-?o&)L|mVT&K`SvOftryoMTMB-nc3Lz+HrjG+BQDi`sqG9`lsCwPKg8n$^_IiCdks zj{V`((@x)-`PH@lpCb!RWTg{coRw5hS1SDfALS3eQ6-+y}uYg+CE7mKPcC)YAq z=XDubz8p`CUJ2l~mFo$T*>A)%K&`c0+M7f#@%(kivsmwbA~mERI=x^^C@#@r;;Bzc!`3)-=n%p+~1IzuIxRT2Zd%ot(cus_X!l2DN zV@YL~i9$?&VgMVQjjfY4hK{rtM%Qkkeu|m|l`NIzP(8JW9caQUhaP#jtkr}9wl^N; z_z!fDGaZ?=*eHxEhc_zrjO*5}TaA|(+li)dN>E#SZ%+fvbST|bv;XE)If@HhBPhcz z-Hrwq*zbA{u>IC@fH<+gTZ;^_J8U2r>W`FO3b*D+-1TDZkklW(R2#TPoW@kM4Ey%H zoszjr&_;n`5-?e4K$aU~D1|d1->cc`QOQ9i+><}03eN;2UXXDPuy`$H|^O_EF zRJ;M@i0(TKeIZl;@;=CM%-Sdy2iH_Q{METh3UJt>BS<>#Lu)~JJv_AZNs0PHk39dNEgU|*dPE2YZr zSfpCE2%fkFosGW4S|59c;fdoKQ^Evq-R~{I&8<~0?EQI8tL_9epMhm4U?jqO%`(9=`k3@OgmE%v4@^W-T7rd<&X$MSE z_a9&+XSsY9nWI0nw|K>V2pSX&C?XE>dNBDD=}f14GoT2iUg(X8Ay0Pfb22jSNUv2N zcl;4mySp=UJEeB#+_A=GM^!HsOb_cUpyO$96P8~91eG*v~PR7p5p$z zru1rrr^!i1FZ%jBC)0vT;|-Mtm)A0^iCksGEA>qzM@GZ3GBJ|sCR6QYJ;eQx+2`mj6Iye`pM!18#4gJu zc1KaAdyO)HNxKCW>l$_5@!}uNQuyiJ2&hPohW)xRB8glFnPE39NPgq+bTze;hy@e1 z4o!&bkIoK+j#+nRmr@5%9+-F_l_y`lQ+fe4)NWlWi&~uy$_DXbMq6IkdV)qic9$5* zLLk=y9jU}VuihNPY~&NR^Y{5Z??4hB#RQQ>nh%^gT0mGQn|ovLBm}kowWzzU=g6Hd zVOV%+kx`{1x0E3j{!1U_w!N+=R2AchB<xiEgN-=1ZS5)647;`Hv$h(@8N< z1KN!Ym1m1A3~~RCikKn=y1y~z?c4ty=HGuTMxV#{%iK%{4@S(k6`Zsz+z-BLm|@<< zUwoz5>Cc<$$xTYK8_eUR@#_4XiT>ZuB!+z0^}=c*iSAoHrNybL)p&x+EP^eeWBY0BDrq&eHbwC?Y_JMuvi!uRQtiCjAc z?z+w=EXBLj7N$cHYKlhAck^s5#*OR&_X@z3824HeW|zXE5AGac*reBkXsgcQNgV7D zO;n2XJxl?npv;1uLESZ2N4wRqJdQZ;P9Wq>?dfKtIetGfCH!R2Z%0?+jvvVxUA0-G zCU!L`wmNj37iqOw9usj#-}1WE)?`GG^LRP?;zk*J>@do7Qt)=Kw8dk;!XX$UShlS5 zk~KaOWw~fSSoO@yg+5x0KP)*_!C#TMF&(IYv77y(XUt+sLr$N~o?125i?yz0_oR-) z!=82dW3@Nxro@o9xuV`kSo^2|^vvzd=PsJCdk2MDbp4~00f-Qh8C@Iji~1?psJkjq zB>v;0%;0-{?JASYYiuucr3T#fzN6PH@#kL*-AmOM)8y70r$mK4Fo5G6iSMR$wF@=Q zUrmrTR6;!>*C}4Qor|ohtlzg9D2d>BgtnB}L+>S7!+AYc_mig>N)Lo4LzDI0t{kak>_5)CNwz`*uB2JStHm~ihYfoG`;mzAbJQIByeN48r; z;8Td7izCq;fdJyebya1CkAem7 zh?Wf^a&(nE2WN2ULGs zUDuoM)33&n1R7DQ)Yaba>sEwfET* z%tv*G>JkcrY*e?n^VjVKtvqx7qf%=ybVo_Q?}{HV{UK-T!%Q;cRV@M1L7vroZw(Lm!j8zxQszcR3EVk)BgJ`mW9j=jG7Lceq7 zpFW1;#&dc43SVVDfq2rHt7CrVb8D>5h3+Hx{%}saQp=-jbNqXEcL~a=6khVBmF?fJ zmmnnXU6&^tYDoymI~xh42hhafQ$X<$ zHP33e9cB}Eg1zR-=+{I~X5sIbA$lCpE~nijF=5=pZz*Z=ypB6Zc*A_ZV`>eFaPO-> z0TLO%Ssvy1eFDrmGKw?{d@aRjIn970>Ru4k$A28(4?7l9MfKiI+49X1Ha7nt?IMW? zs^@Rx(Lk9O&FDu_Mtz&rYdTAw0YilMq$hgrxa=uCkkT^V(&>>Vfm`4G4|ZcbH$t=r~#W1&2D5q->;F8Y~`hG)pD$+$cOYW zQHh`eh?)*%Aj1Zer9V;EaGYw5rL-7j1d9Ybk*^?0Y4ezlVz5xz!9huxQbc(=>;*3Q zJeQLq7>#A_0%-vf@;U-`2Jhk>6~B9pjvj_ZezZDC<^S}|4XQfkG(&KoX`#e3Z1 zOfnLDZ7lcIbW?CDS?Hch+4q9y6#vweRzV<-?O_DML#WLvZl5~!-I?fZwpriPogRW3 zZ641LYi(snU-4&3i<8uXGe5Hzl;QztzJt`rmrRG=@ndboBZ(ZX$lk&ik~b}5LCdH2 znJbn}Pi+QPT4Z&Ej-@YdG1U89(uzOG3caNX${-D$L0TFv4R_cQRi@2RU_Yf7wa30q z6-#i(acF^181_&w9fW(b&Bg@$ObcKsx#4nrJ=!HnG%viRL}`Pvh`A^03b9?27jsE- z)(j#=?7a>wB3ets`ZhxZn(+=kf5_;k+wchkDcUX^j*+eMIQrTCo7X=lW2f|oPC=~% zA(sA5eF%VOwP11v(J7gQ6U70$*op?x_V%2|Jse%kvrIC6&!9EJ*0a+dXrgl|LIA}$ zo?mawNB?#qPGIytb7B|0PXw-AU`VxB zyZUfhF}YIthY<&f{Ys1MdK`w4cg+@dqte{}`GFwM8u8J1+O>w~xlIFMrB-5f#+C7k zM2gro%LjW$I&b9DrBF$y>(7Mu_3rB)m<#5&Xbn3xiMo`;?^UhzU&U({V06f0sy)HJ zO>7xf03zN_Y)N6?4^EgQ?}0g850}H_-POAu-w}31Y-Q`f&l#vZ?w$-c^M^$~B=BG# z6!>bave&g?(ZyzL8A0B`giKs6oZGv;pftL_k|k4Y9=PzV|02f4^O61@-1yTk%aT6w3~h{TefuCzB=LnciZ!*VR~@SgU>X_McQ z0q*Dv%cD;jn_2?v1cJEV4w~VZDEjBo8Bs88R@H_g8ec>TcYO9nS|#z12R*gf^{{ay zT4ZdJ5>*kZS)uIah{|1@^#T3{Z?{dpnG@q?4bS4mB3MT=FGgouzxm94gGeF4Ej2zV z+6|S!Z%41Wz&nmf2R){eIl5l%Bk+;jcdfBnd;`k7LhqrLPSKL zEA#J&@&;Na;9KW)uTK?<>}76p*uyS@&RuhJnC`4(_AMSW2tot{Z!1CTh0;*&Zt{010+Mhh70&YI9&UbmT~_4)A60(PnE* zZwBrKNb4ujGb+-z3{h2fI|Fa^y^iMdF-e?alO)}UZ1E3YmM^LJ7}w&!Y-)vxuat--N@lndRIHhR@-`*jYhGPGk=aTR-&w~?0vB$l_ zw#-6uaq7{rPO#%rtDln@Gtdo)%JDTM-lV?sL z#k0B*Ixjj7L~rrGT{?1L28Ogqaeca0Y4N-#z}FAK(>S0w28s#^kQ0v|uhUmJ76rq; z@MlK3+mf+G(lKV!Ef!^D{QBgcxAfUZEET*8_6@={aJnkC( zwsd)Oy4S<%(CW;#*c6baf$u-Uc+~QIhvb3JZ;J76U@a!cS9$p~FYF6p-#_gn0xQ$! z(t8mf*+~|}!1QTj`<2*@yp05NK=Du$PdZZZ)R585TzB~eP?o-7&#qXNXxP1G5Q$qj zNJ0>G_>x%R3r5FWc$P|VD$7PBgiBSj{E4RjY)=Le*NYR~Zyh|s zvrEP1(`*Lv2ACuU>}i!c`OeUMy_#}SZc?+Vl}Fkb4%v=9M3X2IZ?&)S2s1*n=)=#n z5}yOe!Mdd$<({*k{;vlbCk{P7e=up{K(7lI*1yb|76ArUNH%>52403gbm9>+BeP-osAe}boi4f(Ba00c8D&>%o4GdQ{n zL>^+d4Loq*t+CYz{7#!Xw_#tX@GWD1pgnmpjN*zlXsT+-REfj5uf2KJJ>PSjK9e!N z|Dmhx$~y`o>~AZ^e zySuvt2=3lU2o{2CH}3A*xHS$9G}d@u-ur&<_xtY5)UBzhnX0LK&%e7*pMCaPd#`n# zB~O8#!XKye(|K;f@UfFzUj~2e<+ad2U)m$Sc)PH*nN{0FO^)XdxqDmIXzJaAN8Kh* zUw)9bU+l#71h`HsGI<=BJ0f!Opi{eGJYB8?8Tk_F+e@)}s@4ogd zV|?$sZmlFte)l1xAm4UQqAev+;_f&mw!#RaYdE!Ca|_A$@l6VBtox&q>vI%xsdETp za-_EWDH|tFAh!cwZ-{ZRB9(vtm8J+sbnIIHA)$QZoLvx0_D&Q?FDk6umQbdX97VDL zIB4=$D*Vvy5F}!oGgAS@ZrjwZfSXzEL{m7sBf3TVoHScYn5chvqVOXQ!xJ6A$9Dr{;6*3-Hd%b<=B=; zv2qAtXF7p}ffTLI4jU|j{@6IiEf(?WVQE`1mfieQ+^krzTbWM;#l3g7I+1^K)RVg3 zFbsb!mI9$2!9z4B)v4iys z8R+TliQUY}f}TyXS(1L0W+d-Su>v6NzKNZP;i9mL6BvEm9CuuCnaVz?oH2&8tOsx; zI16(lA3kRa{8mkSvJMWj*5oWmtcfjfo=tEaGtsj?Mj4QMd7-${()x%Du)dBsHcEKS z84`fRWxE-gU47CTEG`OE3OE?Luh#S0!LM=9Mbw)s-vV+R9f?(3@@NWNNbAQ~p$O%Z5rf zE7091Slc9JPJ@PEpQ@jMIrf4>_)Xp9v~E=)>n~{*6Yo)-5Z|>KKU$=1hNO)=EWh&dYOR#!D+d6RSR8gOL6Ct@%yDXV#CFZ6+w>L{{;a z-mFJHKYLB5zLlv0KK4rBWrp5hAph(;Ad6B;Ul-`abU~MQ#{vctEkWEFyE*3EhOWZd zKo`hXt{?WGdV+Jd906>8%l-CPwBq%S{Zm1(QoqYFDlu zlpWgRIht#8)OyNRFxaf2DrKS35wP{eEZSqbMxN%u#f`0XQ5nk{exqt+Q0w zPeS|Nk<2Zv7>A*ucx3GF1t-xi4i|S-JT!q;&@Zw(v5>L>otXpfS%A$YL(w*XdFkoV zLTD-VPSxQz^2T}xW-mwHjOSlmsmW)LhHhJJ-Y~-iG`D=7S|nAJX~sD3_V@6ra)7@a zb$`XnKsj@~q~Lf_a-N)VrLrT#V$DA7%eQCgwqF+nC{MAejyTK4kY4=KZ4*+zC$e)| zmt{l==zX%lKVSfzM8{PCe(m9o`}tXxMHl!1x|Y!Le*doOY>H~pOOa9_VmUPgV)5bq z%r`#!X7GJVo9|N#6N8=5908Mh-@sZEs-2{H_|3Z{@xF9!x@Q48#iYAf;S-WYS^gxy zLOK^M16^NOBVV}rko;=2od^02dgt~H5aZ>%Tc;;kVh^cXM}^HAwyDj*x0Hh#nSW*5 z;!Y#lYGZ|57{5FFlNx&uss|jFHv4|P^EF`fZ(Xg6OHO|_b8iVTevQu~+?U{)9F=p( ze%HPZx8rjh+>p9g%f+P_C#ay2t+!73wciy_n0@91I6!*@+nRb(xfdb2hg~CmvSTd0 z)EhX{+7q{JULAZVoc;z)f;@3m5%@TI%?kK;GL7V~1mHxfE;c+%^d1>EU#|5VhYx zn0bmyn=ByX8?)4N%r6JxB5()H8d62maSGC`n`&;sRYtaGnn@v*xAWE&#ecZVAV?&Hf~D>*}~6X?z6C-^M1FNM_ML zb8IW_H2rjf(-3JVOv>SD!?RL%U##Er42@L!$!4aU;Q%mk4w!=Bx^Qw876+igrtq8P z2xza7OM{m)sQh^B%w^m713pzm&9$$tw9jJ|b{oQOXov0!j#kxg9-sl*7fy|*TIAR} zs(!#c-CW0D$-H67(P(c`1cZuFNm2ex({zC+pD{Fp#JSrt2Y(mL6#GYFrEZoz3$j$% zV{oenFs%TMhIlsv30l(cuWhpR%mYs`|L|c$(;0*b&)eT0WfFC4nyanpEstIPN@&)W zVCKEW&zc>DW^rPB%)pCuzXK!rtpqEM#PtP|`@~R4Kho{HQw~S2V@UnFsxNfz67)Ge ztYNX3{9cToY)6g*pmJ^jSWXE(!#=&wE~psJ>n-_i`R&lSZP1@EK0iIubFXMNrT}Ph&v-(~ZtA-+52i^=n|BQx7knrE=KH z6YmTLdS8&7`+B{8b2+Ozn&So&y=qRZ(sx; z^_E}MurryoZHwEJh^XmNEywS_&x)&`)@+Tr(G5C0K6Vll;V`2;ic~)xSrm8Lt;P7b z1;hsbg?tIlAq_)7nL)6-Evf?Tn685~W5?n2ns{*~?Z^HG8Rrx-O+hq*fJ@3e9M7e% zOrxHUz>umCuE|vuhR@joVEC5&-M2rVnoyKDUdMgVRkKgU&8c(N!TNG&ouuLjNUP)s zNhDE1^}^pq5kHK2&vuuQ=JafDx*Qdn(!{m<#yb{|QMU=7O=Gs(mF2qQhZp55y;B>r zzYOO=`d>7G%FDu@f71lAqS~__*g9DK6_TRpauD+Y%Z7{HstcWqs;n$YLyBoE)iZzo zM!$RvUkxxB`Uw50%Z|K=t&B^?NPaiJQt55cMNw#5I^?Y4{iUrml78dRiN!<{_Zyc{ z)8bkUzovyx7(X?e)NAH~l!qyA`Iy$^REA*X`$19$2=G_=SFTx3(+?uB6$&{>iO(~d z$3yDWzLI;L|G)D~eYpaqkXt+!xzqH`3mj0sec%|+AFC{(3i_-mpm<1nrqL+;o!e~D zq7ExGgbDq{HG>KL>4E-ul3 zorX@L6Jh_VM}J(G2E!NblE1Te|C++z*Z+Zq_=dp{=qz?P%d(|tLk1O@}75_ok z@%g@LnU<#g_kYEA!@}<5?mb`EX-w_Sdi?Xd|L>}79&%c|V@v)FBE=uL1gSy>KE@dE zeMnfMmjFmgNt(ZRp>_E%A%9q6sbwf`pO+G&$!B__z%ca6woyaKb4V^NBZkRGCI3w_ zS7r0s?=?vZT)~&!aEn_6*3Ym24?qFp3@#8WeONQPkW+W5HI4!pYOLE5I#;+>i_U{Ltn0K7YGe!=QzpTCrp@U$>E9! zjD3jC4~n#QF=1N|{~^V>-*P{b4e!SqJ8hpcHOapB)Y_eEiF-q&?)Y=^I>!D+KUBOb zj#zudlx2VBH}}gkLw@wmB_qC05o|iRDuHae)4!8fHhwo=6L>`DI_bvs0#m!8R z!TZALM&-v1U8v8C!DCDB?y|p&+Nq~ITRPd%%yEBgamWOWO|e@COXH3yk`Ik5vI=Hh z^5s$aX4m!kwVM5-+B$4SH+VlsN2%yNrNvOP7943!v80VKH)g<}(-ZDl^s^*(^8&%& zC~ld67enp_7&?#M<_klTxquW>il&hwZi03C1tEye_UW9AH`H_6Z(ZJ^LNAJHBV3!C z@!1N##8M!P#-&9ubHIm!vZQv0-<4ra)+d{1%^ZWUx=yT$3`_`3? znC9|xTUSS2CT4!ZWy9C4g=cL;cO3DxDgj$seSUNl#KcMOr*hy)A@z}jeW^W_Uv*Gf zk8rvVVj|#VGMmSu*kBUq=YI)zQ>ej`FxQ+*WloVXks8}%F{#I9g<9@|w@Lvay&utL zEPVdm?D@I*Bkt!Ol2g8srxJ+nX?l{=m^~aXH<{2=Dm%1oVhr%hy0hH0_*UE=OEKS= z1mZVy$Zrp9Fcp4_8Eay}AUFTHXI>Ni+*;c3#_!aIue5;V0~P~Ec~f}4x>=1$Mf6lm zmx!nhfajU%q`1_EJ5Sbyb|&1rJ?HyOvgc%HLb@foh~R-w6ClCU&ggBMmkS9|lYstQ zXa#@urZZM9Hc|R{(`QZb3b!4kuz1!MQl572KnJI4&D9gKIfKvzSJkpKf?x? z!`?3^x5^d%<(Z7Bd z6fk*zcYB~yiotghX0UV>h`yvXq|tE80VrZO>%+#1sW~G{Lq*4hwlJ-0fLJzRWj_S< z44{2Aqf6_g9hJcvM|DXv?haGRD=SH(a6MaHBa(Ejq~&ArEl_m$|<7mB!1fa8Kq; zPVP@Ut9RHWuJn0_ma2YJ?kMaxQ$pGbQWMW{W6|%;7{fbTC3HaGZFR)MU94?C{G(ty zPH1+~6{E3t!h%_gji1)MtzV0FX2hi=IZkjBjJWr3l*(ZPSC!ZnKkFuRoZ{EO$)69k zuqo_&uwkXk?bNI>n|mqUF$2tEOe^v4zF1{4f4!Rb7D04iqf+^Wf*v?i&40b#8|k6V zddGe;g925C3Q1;zmwf!v6$71vh(`Eq2laQnLvW)lahfPJH&M5IlRaw1qriNmT$QlYQ|sz zzKC6|QXRgpe5-r-^Q7s6$S)!f%S)COpEo3skK~$(TIlY5T;^^f67)|!uIyR7y-~Q0 z?J88VW?S|$n}t&b#*}vAV^mL1q8BF`ROA%t*|%q6Ck2(i+>`hnm@`p;xikCuNE+|o z1Z<2cgDpU9k>dDbYkmIWpIQ8u0;2P`v<2n`Q@~B-^e8(&$Jb?-uJ)QwK@IZHT;p1q zvZ#YL(mB0J>_@0%fJhrd&p||8Y;ui6RHk4^hu+#GT_9pbue~~a9sHzFO`@Aleq*Ms zWe~`XIk~+U&GMkm_vDe6f^+A4*PU6rq~7(S3;l&fG&G3eiN;BEnE8HG+v)5<&6OOf zjCNy0E#XN-dOvgQkB!N>#13xK>O)xDX&5z+BRs!v4P7r&G!mhgE~5{5JRh^2;LxYd z#%Y4)wCkWCNWk7-t1|RB6K~@WV-@Y?c4DmQW1SV+Tpl+%DXf`_I+5}u4>ak_1E2n( zOVcR^(hz8!JR*@NwAJ48gJP>;X6jD(1~^JFy*1oY$7P z30bdJ4q}_If0DT`&k*M2=d(CkJN24yb+FRQn=!~Ml*kUMY8Udxw;_tIB6%j|P!uag zS%Hh4o!I4O)~@hkBMxDxvdZYOI8**+T_FN(-DBCRbCX2Ugn?ht%=D{_<|Je<1}}I; zGsVRA+*)a28K;MiE})o2?58XdQDGsyeDr}vkrM598dSLL)GJ8jDTp35RIF=QI_Qn_ zi!p_lW53DlYxwRZ3%DBceKO?Mjz2nL$Wzkn`pF5&db2BL)bDb|fz`-ZkS9+li8{ZDBBLE zWBBYybnI+p--n5VvRKzmI8Apfl`rv83k!GpviC;c3$4P!wE+M&P#q0VC0#U*EwTQ& zj}{SqO*s8~nndS$S9`0@g8H)i7~J}T`KQgtC?Ad;dN-Fc`d6{moDMm#F8JvFMB3Sdu65Btj!cR@=iZSQ{ZJ>3F>>+Lh?t=JX{-c z9CeSdwE370NX{-x{GpqhZKpB;*m!r;i!rHRu8#CQu9mAe_bt7#qZ7o7z$y@c8vUzi z?Wx<`r}ZN~k(PUOU`g?hCIA6Hg>tDZq5R7#Wwe7M)#e(ZXf!@7dUJq+qTo*zPu~!{ zj3vurPYkmGLq4SQi-Weof;4(C53j(r3T!OH)d$#_K&LGuY}RG55fy0&tsOuvxJVR7 ze`xxSHdMrI<$7IJgGT|vTwl8SWA#rVZ37Fx-`n#;!vwLBg8PqCWYj)>tg8b_A@a98 z=`=0uewNBWJvgq|4JX#p!~4ut)542PR&d5z8^$UcNL{7<1w>l`yds!@5sRspxhCvD zdD|%%Chn%yvoyvf==3%#Pj5ZSUd8uoY}38ta^|SHe$se@Gq3e)d)F<#M240krQ8bb z8TN`3g%e1lVkE=*cW?OdCP>g@7!!qLQhd2tnl zgpVY04pMSD&iAiaWET!DaSpFi&Qf7w@uEqex-UAL^)2HRRII$-DlUD}PPVh{(AX}; z`3;CGT76`@BDg!Iub0``Lc%zz)0^l&RK69=Fn71jZ~3ADUvN;de+9f0v}OyBd&$IXK6zhI-QQ7 zGjvZY?syVfi_QGYiYa|_UUubUp;~*o89tM5E6`>DNZ0$c-=Hxt*828!WLX|ocswwS zJl)?POCKZBJe@ZzttX5CI0;s}i}%SLctjK`o_u7JcCsbj&I0dh7V)NX5ajt=j}0$C$;dJD`@phG!t*(dT6Y`T55?YgIZi=BCxx%hCDB>5NNv zP_W7#EzIrt%U8kL1yyTD)SoRPyKHWGiZXua7ve05%$D{^-)!MWaE6s1$S*;&F=G?k_GhuXHtDD?FB|!eH~n3pNyE z@`imAXU;#t`G;-M+7tpf)z?P$d_Cf-I0N(8q&9au;tj;xIX^4&gQ-7Lq`d-KIL%6| z!|#3KO`+#AJWZULOiZ*D-CxCWG6$|K$QJQ3f1Z594)L5fIT|T}R$gMf!8P&$RhcqG$Y!_F>TU*@@9nLGs( z`}%?{v5LRW;Ks}ung1{J9|N8Ccb#N=P$i&HX0Cz<``f9MDw73Twc4lV!=;9`B_Gq* z3Iib2yA#{`ECT?#a%bByF;gQBxsIbvypynBW(J{pj`%YNplq?{GV^cC6T13kGvO`JMo?X zkNj5X^M5dq25ig!;4bI!`20_^ipK^O-;4gEiR1tMp`CB5DAPSP+&d>1{8(f6E&KPN zCoiwYe_J6jEs)ycX7a#qtGWMZd079mwL%R7EkSH8_1jj#FROZ>>?sESuv*dn{LKW}Bf>6(JgQdv5?sX1m zDQIifEckl0<9x+^a%=V`M(JO!zocY&9nk6%WBZ>v>aRM=P80Br1VXhkUHu&|t!47| zfgNP~z@Dy5OjFik3dwMWD)rJf%^R7u zK zBd;%~V>kJ%JBHs-dUWR9=(t4h*kR6{dU~0XSU=p-Nc-PmpOt~Qe)cUlQ@JrKpp4$N zSL3&>hg2xSms!mkmuv&MFMKcl{a*WH3UzPKTUWl;UYxJ(R#BJ@XL=ubd?KtZE5brt z#57h9YBxITALLveiZd`_F!mev|Dy46ZerIiaxq_(VfO?2rroCa54mrroFiP{-mhV| zqE(W{C83pzzlh6JQCpt4$DnYql|>2?kF)(e>FcLe(zhr>}t3|VraYQJTIMm@X;*+xgzHJZX_N7fEw@o)n3^!zPw>`s;hi$qtov%X(jxDD!rh3)Ats zcE-}6uX|Hc*_=ybvH?iD61n@Ek3j3TAy8iv%>EOj&2|DEq75V<+l@eI3a{Qj%@pi7 zW&gbQe7g&I=C?PZX#qy>Pwz?bUv3lviL-ddeII>Mh8aen@p(!x?)9bsb8VabznUWect3x6MXgS`UYDbD-2`DBFQtnIQ5qicS@<5e zEG_h16XjxY zQ7_Bw=kCsYWa|moyYTJ!uW8EupKZeI5yM-yaqH@z>CFdpwpq#jS(w@*X%GU&nM z@vC-}`w@@sS19jo@XylO_q%fLb51Xn`vE05A=dVf@m6x=A_}?>(@s(;+92<{S?9Fb zdgfa3_Xo>$K@$^U?$~H%*W+4qp5%VriBY}Nz2-LFUb1%X40?eJKOXDMBc)mq%@Ynx zOssIWhUJ&8$h-Avgu0ZTs*cjn+VB%`|K?9Qc-b*FrO1>xwlML=#lr!6{(>@Mx<+f; z4=t+iVL-r#W~cgg=LU!^QP7hJIn~i=SB{)^8y9$V-xYYB|W_Q)-Gx^GC2+t-?h8K!a-Et~Cbb zP9B!zG_p5t{rvka=G33okMTFELreBy@VV0Kq=%@I{^%OD)6$}f6G)$CjZiv$i&3~E zmevmf#Mr&{~fGb*bl_%Mbz>`iNdEpeP~jx<_PsaVWH&EAG9UTF z;&c1#S0a(Awwmt^x8bb7#xLWi_;_zVf8i;&Jo;Q>R~R983-paar}KNi5aVP-?$#3mcXEokFwD6o#W zTHl)rjBABzWUCIr<$82wFM;=P+?VbW)Y&UM<)y3*0ir*mYY4+|@VdK7(B4eMo^3F^ zSkyYxJpV~eSy-5jginCN;5deZZUJvoo}JP7>=Tm2z?6Q*Qez*$Ok+{PvIb5)V~Jd2 zsoy9Sp?)%9@eKtZz47q6CU_~BNeaqdwXzx0>YK)DT0eN4M|M{_=P}bSpU|3N9E0um zliDnENwSuno{KwjX(#VN)vc`z5#VCxf!`L!*RDB@2J|$Tz0YS_xLZ3o^a}^MZ|gE4c!`001)3^p}~ZoBhGc`MW)+I%L5pthBZ5Xk;M{`Qhw|grF`n?z$Oe} z)72lGey+7VaoMSaIDO$?rx$tJ$9(P+p}rkOQ*MvD-a&a1>67{C1#~`RI5PH}K?IDJ zt>Rw_#Vp*uRi^hqf=G_hZPqa5xW0ekj2d2IhWI@NGoV2CGjk`&t!}nT`%-kD}xV!Vw z?WflSyoVRgkR7X0eQS}evp1XZ>BBF{mE^~c(68JJcjh3P^=q1;=aFwjYH3=Rsm<3{ z&YWlJ&sYhKhHe(Q1wz*=3XEuSO!JzijHTXPmO{eeHgYAWFj!rTdVAxUD^)li6Hu-S zs`1!0n-~s%b*$36dfd|PJcCz`webHJMNdb(F}LB zY8ue5_XK2-IdAD}(XvsN!@O+hwd=aI|NCy*>{W5uPjaNoA;Q3r(z;3Q9W!i?i|-A1 zLvx^0IC~mHYwY8#M6>p=*DJip6>Yp~M&6`HW#dr~GjI0k=fIUNHe5VSA{ejF;XDQ^ z=hfCubKrJWA|3iQINBj6R5b&Y_g}1%QnD*b4)PUxtE!EpR-}!i6;}{sXI#&^uJ+?p@tN<7LA-f!$#1O$1!JK#ZAEj~)UxpfTyNP(`tWTIWR^>fTMS8wr5kJG&=QMhz zU%0x@gW*l{q4(nTT+4BeU2~0Xtm8@C45Q2RxMG*p;f=t+oNK?8529s8;0o@NXT7M{ zo0L@jCFZ{6@ee&4<2S(ICOJ?Pug@JOIe^PH^d1Z7XoIAJt|54-+f0^{x5_v+?uA}< ziI-k=n%T%apH!lL>E&+n{@_nm1pW78|})gJwyz zO06Yj?HmZ77CP!bK2{|sWv0&Mcf~ptvHh@Cyp_+z$QzpDAJz3<^)N%+oE(e8{$Z|| zt>jlB2Ys(lU|8hrei^n&DGN~*E1q*tEs$wd+umIq6zRQ@Ut6Wx$N8g^Xw;x{{KC-% z(7b1{_4wp+XM>7OhEWw0X8jS>2Wc&xVfNG(-6Bl`SMP*Z1ujj0ancP!o_g?1^b5N$ z3zNam++TSKRjdZFGx!iI+v1h9S;)H&$w9b6b_W9zM<&odD^ieEQz! zA;s~?3R0U%w(j>KV;*jD^LHGdxuZ$FQ=_|-yEvkb5o9?w^Trgz^{+x!&B=xJ_RT%6 zqIvn|K1Y`&3T4IS@(jFOCrZ3Re=fc#DviIAyj)nMKTB_QtelI98`eDWWm2O`t2j0TqjR)lHQF1@uofQl& zRXF;+40Sx5Qs|8tw&}WQ8R@?@3xRu>>*w_irK`I=oN|6~^tEm!O&-CDZDoHcTs;&+ zTuyEM*gb-416kGA@0>KUjDfg)wGx}6Uqkcw9N17BI~#AQWd+&&;tz6_`s7zqmc>;E zJyfC6Akrwx`iR?Mx?c5y2FKSBD-&~iGJsSt`4KFKN6b;@Mojg__ZR2VBIM<1>r5r` zaf=CAQK=u4ELppWu69`v@j|ZtY-ISJWlZGRUNvy4UBNYI+M9lG`l%K=vW!_#+__Z2 zJ%S&_Z*krHx1SMz@Q(Ff4k{_pL3ftUKNB%-UBu*f-^=l~S~R;%beEVi6#vtlO+aG$ z_BQ>KG++iNaHw94&#}tD4mWz(ETbun6F3HO^?uKhz2)EZ37@9Wm4v+h@VgYr;}DZb z!hnP|6Nx)M>Y}#+rpWC>@~5*Ogc_daTk7E~%Lfuj2}2$5dUaSdGoQ+W?{i1nchvTZ zKMamfcS86W?$$L>o%yRA`78P3XVR%~(?r4<{rQ&`F*%KH7(X}>Y2Fmy>l{+vMjJ|+ zJQrKB)5x^4Dk9JNMYFpJlPV#xyE>10-CYpYd?#e{)4hJpYj&`My@t`nDyB&PxfrXJ zpk5JpsG*N=b!a#SpWhIJ@h0lo;>bDKIC-RKGH5?0<9=IKPzH{^t8r(6KRu z-xM~Vwk5GN_tnMrAhgK;CHx+>N7BZ68(~udEUVe z4itVP+U3BHmIi-z(#u%=RYUjgfuP&PHrD)LTSE(rU}_mCrN-=;tai3SHI6}@dfMnC z!qMdMd~*I7w?XYmM-c`w$sC(*PGUMen^{I>EC$iGL+MTli_bKk9cD@yVY}Z0aa7Kihz0#eignM~U+>?+KChA}hlQ58uZH#3iwf_(_sOCa$w{lf) z5kdDFH)q?__Yew2QLRv)Y0#g#dm_?=pl@!$vSZDF9#JcdJ*m{PRd;{*V+AJVwIY%a zlb(;?cE29~Qxy_0{(33v34^_l$jF>6pUwNrzVJgQ>h2^039vBG@jxUj?Fn?J|>C$FhZ9hbV*qG7fzgp>2U0I%?jNO@_p`aUT` zjf*cHC8pSWgSxZ&FxwJ-m6v=GWM~V}y`xYiMD98E@2+Q3fBT<)YHj0^yBAZx9i6or zf?(d{YrSFD_9wy8LfkjO&tHnhc*^p&l&vTZ{&A%MyzCB$)JsU}pM)vwo~_a8B~0I` z=`j7OY{$b8)Nt&pIsMMCyyVEgShcNxH1r`tMw25Z?dT0UraO&@7rl1m!KIut#F8cJ zg~Y^dEWr|I1h{CZ-V@?-ce=qx#JlUKGsRcKOKKxaU0wExC;G`lga1QkBLN|2B5~@rMg}UzY~-Q}-~hz%GlabCRgSn> zLl+u=@AULQP1^Lb)KvuWg<5Et=!1a)AfLmOXp%7bnT@i$JCUt=8!Kw#sBY9xQn_w5};UVwx3nE|Z22$0@ z-;Kx%3tTBrC5{p4OsVvR>r1ujGKWPyN3=9pFcjXjE;0oOE(1W;i4u&6gXZ7(_=2%SD^h8IKzhm0?pxg$pj%^k` zZ8uh36^eH4Uhh4+5X0b+-0v?pl1DQXZs+QmUX1xwxp1Mel{tXkuYi(;Zsqa%PTQA9 zU`y{nlicd*l2)5BTYL_%TO6ih;W^cZfh#8(l^~Qz;gmnH;*eWP*4)>~pj6lS){&0T z5H&m35@<7&CF6#+1Q=^%yTHb!%+F7qzEQX~l+aVdR|@?`{g|MJ|{O zQ};#j*qfEEev(?is~24*AB&JI7K{>$uN1Z@h>ROw|YtX*w7T&aoF&1von3n)}~R5*Aww&m<@ zFPm8ZQM0z?w0W*4L)uz~QP0Rn({DLJ>U!2n&qRIu^P?bRn4g@^gN4!yTQHMbXp4oS zmmKX;7}`dPA3SURCCM%ehwyP6cjPQ$(Ere=_k$P~w^QZzwgD?9$J8`#fixmM9;oD| z*t6fQd}*&W+$$=mQKo6*d+n-5iZvy^K;Cbzq%8EqDN?|Vpd0f|mU_}itGqttiW6K`@NZqo$@LOM7CZN@VrcMN<#WwooFA6vN`GMT2-s>Cz zl%B_(2b(LYEjxezj>+4(l4Ra;p_y)ENcd+VG&QCvtgMF0ygPGjFab|-<(zyjI|@-$ zV_^Qo@qUn7Z<}MoNVH!=B=M8*P`ScjX9J7yzJgAhL3>mQhK+Z^ycbW-;e9cSH+%YF zjZWdVT5)D z*TY(aObcGHea+#8%Mz0Co1QmYy6`Uw>e}?#RSeaEd9M1_Y^YQv0*H#4==RvDJltxq zSxWsrlhKviqB&PCA^b;W`7d8BX`wO;W7w>cG`_|AvBPRKv(T}i;unp$k6#@};5yi2 zx4-r>Yl7x0=$sirPqih)un@F0I~MZ@l2rOHaXspqkK)`mZtA`|4R4K&OQ>#e?9YgG z)#tKKs1`s_UCAvMy#iLHt!tRk&(Bg+mtD$5F~7E^l$&Dd#tr*zT4z2l+Rl5yYF4@; zttTO-DXd=o=4_wsU(pC1?`LcTT5yu!_4_j|;zK6WygQTg4g5;miB^#*p6zNDfI>a+hCcI{1o z7`bMK9~lT&|IpPpa~#HV$mAVTsgmp?R56`^?!lNf6UpV5+Am4_=I1_?)W{Bp9ZNWL z8#i0WZqI}uD-O#}6=7t^S@Nh#8zZY62cb`5y}y2~G*|CdNX|6AKHqR#@QOB+(igVJ zf10b3qYn^M1LZ!AIVM~?39HEyPtP4Y%sZb$s4Wg{(Kdy zFLd;_8UZteJRCZgR2&`hhdEda^#vU>l-qv#X4YBM+R@qSmJ%KPu8EHt_}BsnQzdA` z6z1bX_|=?k61yK|D;C9k#r1oWUZ_XqT3p~&H=8;Z`T{t>CS$6$isx~4wZ0Dh zVcs2iDCS&j?P$49!$7d=L-}3!$8#|wwk8%^HjM^zJeb1tJOz$$D8U9Q&*>wm@!=A# zb`GxaIhy98hRw2YT^<_x2R>@Q#N9Paooqc}I0?)sQ^a_`eCtDh?6Fu$zbDYxX{tXiP}il;pQF263e>{i!N_H^?9n7ErV58GQo zS^X`>odd4=e37#@SquJxgicQ|}sG{MuKI^y7R?|j#b`re$@2w~@M zr4X$N;Pol)s+6+AyYWA9YAH|@m$3`J<%Y6vJLD;n=?NRZNZUJldxynlzrXKT`o z9D{6M^rNn5BD)7p=-}=alxD4o=42tUgk=sRtSPa z%KE@qY5frzy1)IlO|RR#$d+2`16iWP;#sFhta-fA&bjRm?Bt?%baac_v0XgnjVcj- zLpX~97tw`*%d#5U!(?WaF>}8;0%%_~L6`ET#jcz7ch<*6{={l_tPG11DVaL$;6Jqwe- zc+6iZ4HX{ySp{PyCg;V+jQ@H&twyH$-hT%?!@dl~`zd z)ST0Y+-7?_SclShZQtSJQ}>{C75Y9djpkS^aH+y~ zkb2yX1DssD0yj2x{*?Ts8-dWm+yWWrj_<=|qlOD?j?*N}x})CzEIoX$}sj8aR;;t-+cgFnsWf zxI6@T{!c8iO@LqF?YX=e&LXzyDNUdausUtz)>zg;U(nQKgJ0s|Wlouqf|7rzSF*4A z)!sWXp%*f7>X^vlg8_;LT2{^Bj9ME-zWO!DK#o+5R5H$8e|(vor?)YtG!8|Yc0G;J ziA<O01_4cjJlRD(+NfB%wcU5U zNYQlU0>#O;24*X^9=^z!oPXnef@`@Yft0bsXAF@PniF*lyI9jxWT^E5^+7GGUrcdcZTz;k8-|LjJO{;8q)){5vmZY zPwNcR1N#F<1AWNrQNc7K*#r1kGilG=Gn+8iYu5>V9qI;@6EPs#L+>21cYCOhSNfMe zYG!uhBdocM|2~W)CG)F+v;;RaNJYh+dOMYqmO9>G-u0e*+|YV_p|(>Zj@1`kKlNEn zj&29evsVC!1l$z=wCL4<@Fk$v&zSHpe0K@XoOnXal~@ z9X#CpDpH@jbO7LaG}2QGCzqpbS7NAq;E4;igoA;8wD%)>!+KfrvE^_{F}V7I&k5?3 z8`jC;FxE*^Py2M*sqNGg))Mxqb9CgzQfFb-tz#{IH~O4gkz>1HSU5s2GgMX?|3>=kh?uRnT z`cD`Hkiv3kdA*p0--r~5hCQqHBc9Ip1;<6+64ifX@vaFahd?Vj$iD^_z!1NzjkZQU z@d6QLGWkbjXrev+r$iOHUsF6Cvfk05>z!NeZV%F>Zu(v)=H5n5v_n^v>Su+%oQ`&F zFUXql0i;HJ^?#jHtnrBq(2BT$+M!zX>blo;Gcx7AY~PF;FbUF@Pa9TD%TTK!Xk6eb z3%_d-@6peX*TZoLf?3Wlk&q}lOhuM3imBq7nd?|BnBV6RE1zmj-3B@|+wmGY0p3<8 zk~7p)Gv>4G9k@tieK=;3ljOUpV}RL(JZ9Oneo5Sda72QZx4K_csuR^8kg zTenhI>dF|(1sK^{n{(Bjsdcgv7ayeVPA0nXsXyH%4hi_Vi}-tv>o0EnlO|N22sHY% z3r`~El5-LiFco3uc!E_VM`0r;C}AR>yknu&d7UFRAktvNC;j;+VpFfyQs;x2u9BKl z&Fl z?(GjyNquQ#4fY{j(j7WadExuq=)@SE+2PD?>8&5H1Sxpn&aI~w74?ccUkI~V3!D+jXFv8xXnVFg0ZrDM17>$NvXA*A=K*O_CRnqw^#s{ z&AP|8KQH{dS~At8%RbuOrzVjS19qjmGYhV-%)Iq*#qMMlkIuLMBdedjFo6i?l=pgl z611t3mF6c0QY4A7xemC%Qv70Z8}nUwYR>=9ulL+RjW^EQXObyCZZAv9f;WP6Vh)$b z;FChxzlw?O;)ddN$U{6C7|Wf>h*09&x_F(@0Etd}C%5CT^h=@BoS_|*U-V<-gWw~u&~@#fl_xO461ea^>N^Ql2!eFj4>uKXrzY^K8pf@`o_g)=_sbzqm) zbF1qYu>#MBZ6333Dd+(pLEsWKcg{ZF zxZ~dL+kMX0UytrT^=FMyYmGJMT5G=VeBS3JNs35wXvz|{8S+jxxE8H@p^T~5_(Odo zct9^*VI%rLG(E0&!)?+06cO)?@;1aTFy@xS3v1(aW45y%DsrB0BgA4a-O#v9t^fJ9 z=&u>n!#j)L%ygnS8hifAO9QW^;4%?d!{|3xxS9nN1oM4cC!5f3GQW$jx*W~guPL}m z6`!KBN2bJP!2xzf@C~ap1p$brbbI&kFQHf+O&HTB~^#Bj$@w0)p-3h3UFhrr2p6<&C2u4LYb*sDq4`+vK& zf6s0{GLuBHeN>KoNK-zuqq9WY!x5Nabk|*^&Y77Shj^hoLqjGRnrMo4*8ukC_)NnSIY%^kJAqa; zuO<62zN^~L6e4q?PGN$!Ht1~$bH+R30uC#!CHN?_JyK1S9ogGqgkHDz32P2MRE z7~@rh(g1h(dJzZFl%Y%B@8@`)>pxJT*ak#THpL!GuYW@hD@=MX#Pm?Ltg&p}7m(@i zS|6I6-?+`*ve^Dv>Y*sti@$Nv{CMI_k+6zjEyRFVbz1pDK0}r}@WO+SI~BaNn&-A_ zS?3jH*UR6O!d&O)e7TrAxHSxFeqVsli&^U5CU}gSs;J&JqGbicrv6^@F*#O!z4teM zgAEM*n+>u!{6BjLn%{hmN3+L}`9Eyy$ueD({BG}| zHlBJ1|GvSPiweOIY}!T>D7y({{=_eE1Icgb;NvZlY3^xG3@7U-Y1|ll|6^ z3Hi+^vOEFd!aJ{>&h${nX*1oU6R5-R2-bPLZt^Y?O3BEo$xHaXKRLR(HzHkv&wbDK z4<||1(uzEW)zYgTHuSsLT94e6IX6WdZkK`IUpz56ed$^iX=dqm?1HxpvdsHxr53F3 zPpM0*QgBHizoWtJWPteSF!?h5^dt~RPjZ_d{4o6){S?~ktTN6kaV)*fxkbOSl(WWsHN)F{3MIJdY|f$nyPDi z;GUH-C-kxT-u%Ege1*mOaeKA1Xc7EFSa)gM^bm_+rZ*0@N}5u8D`k7f^Luz2k<0+wLGc|e@!myss! z@435q$=q0H?9RFc4d=1E!5(9^<<)Dq&u9TdFBzYRJ|rw52#}K*3d>mgnlJzw@yAp+ zCVO0WD=slXI0HE5Zhh7S3`8B~D{G2Y%Y2gdVJWOhu!)QK&qICEWL>N?TDn4}A3uj9 zcn|y?xaQR@@G1|U&W|}I9lp9LufP4Bk{@(G%v@4U*BS58xijNhTiqU4t+O|Wy6guG zs)Z}FfZ@^xa*E|I$k)<=h`v;Z&eMoT7_!GFI;!G_v7}C{J0kiz0LQI$te4S089JrBJOLLV8KP0Hsr8p5XpWCX~gOrAn*@5V!;ei)TxG)QYW zU2DTuz})A5NCdx^>Hk<-ZbdTPB%?l+5OI@?YKRw8$4I8ebUlKkA)~2p0FnD2QFLZg z^P(oKW*5YOYz?ll%Gk0aD*DfOVj^n9mD?1b-%adhma4jdQ?WO0z$B5MFu08~GuIVkwzixFkyn~v&r4(4w*GA4^6ISLjQ z7#tHh6)E#rBUI-2V{Rz}jVYy+a1*nx@Wv5Mu0+i9Ult z*6vqT2!G1L&W*UW1 zdk&sCuRbpGT#{J;gXS>g&7*?XTR$?>f+nU<9b(FMzf2(Eo&^qvux*8@>a=hU4zo;J zl&4Hb*0D2lmxF^_f-RL55{VBWH=V^p5dvV-*HVzS11o8t-dfIn9ivW^3ty10CL(Zf z`pd%)V436(q|_MV1>{LdpT;0ao^49wzCF6Xg+I~*q2UAhP zw`U0f`e>oK$J|v^22IDMM8ntoCWGfeMxp`{6j@#oA2aQ!ITQ;qjEyU`a)ixaHxGo4 zFr&ivGJ;OM9Y2akFhXzQxIbYzeocpt))~5UP*VGNP@FJ4F<4Vn*)SyA9>IIs+J*4-Yn-ml95w zG!t~{nG$_I_yC3&YF3C!5G>h4ubX^Zy`1#o{kcy6^tRNda7@qheGV_3`}}Z?=kdJ{_7pS@C;hda8Lu1`g~Bv6!QR)`bbXRL%@x~ z4a&Mj<3Yj%K4?D&0~7{ul9+L!0SPba;4vRu1@}WzVQB9s_QO_?NZI$yyb@!YGFF%g zP#uievz7gGW#D6Ov28$&dAfO$ppE(O1N0?S5xXKmMA7>Q>-}eWTYO%R+s*H!4hV^e z+-jX451-Mk#%~G@!*VkDUR92!@ z2(*>UYCRuLFWwPco;fe!N|yQB+Sf4O^3rr$pYW3K0jz!SK;BxnENK+(A7Z6`0d^9< z>zN?KTPe0e*iD?+5E{|&sVTH@=)|yfO-b&eVPz2zLNumG6qC|33f$i`KA5({V`lO{ zM7VaWzEzi4z;Hy**zH8LtL!`SKzASU$gizWt>7~ak?TUW#gJy?fog+@6WsPZdG79A zQa7=4%~j8&8N>=(;UDrDWkwB2(sw*e%JRzD_=7(h#lG0u`Q&M3*G|Glv;+vND%iOO z#O7w+bOb!pyLWO9X+k^P3i70kVwnemQLfBE&X@4d_1 zLMfUG$q*We&&4(ihbM&0%?6C|)buZ-n=Du*QomElREd0|=SJ*-Wz^F{TAR&SX@;ay zhSR>J8`Y-V8bD%$O-N@R7xMVr+%vAP?yhig;wthF*@mk!7sNHbEO56Y-13W3cGr`p zPt=pVx4joc#ixy29=rVj*E*pX+N(lBA*edt?RVcvbn^Hex%5s%UF1}I>D^($@76ws zXSx0qUuUh&3ih<;Ro_Axy(H&LD-RhPH7L_T$Gw~aB=mHly9xQ(q4HJ3v%#5=hU&PK! zN2rVVVG!`RT>1=w`1o_GU}wI>!sn0l1y7R2#XB|RgAV6Wxu8EZi>eDGeBV(lgjv?% z2)X3cg{AG;okg42MdsLe-kt-LtY2%qMWu4kSWqma{32|OF@%kvfl%=0>1q$bI-{&a z{>S%#ZX#aa+4-wV0-+j3u;C=}@QTmwiM5fW35%WQ*81KzUzhSOf!DqPo((JTk#y-Y zBag7rO%x57#b>*5r-2Fet+$|VGFNK+1ES{tCf_`=Au+o zIe&QDzk!HeDz>Q01(j2`D-=KU`P*EGH!J? z;mjmc{G)}zSE<1h*fmS9w`V@7(a+C3D7?5BUuPY5G1e?gyE~VgcaLya;RS}hVKR?d z9i>%P|JLf^;Av@eb#}MXKI_AT@{h-sAIXL|1Sg$uPG{5+h5!%}6ts`A%)G44>)SEbl3zs7F zp>PF5`+JWTaE_1CtpLeZ;dzsuPmg5;P-#leqG)P|OuDU$9uoO(gSi7qCydBC4w3Y+zs7- z9qvXwK}F3$99L0hDE#!o9um~_Fj@SW`kv;wFQj@wqqMNHopq;zO#Po*AW+=xB>|*t)o0)v)sXe;Jp<=@R_+$0|xa{bNNLqyteFc zCFe_N)0aDgtM2syinkg!MV}cxBarVB?pEKG`nGKK2E%!HH;ffkmM2<_*H&LQcc$hm znFx{#()JIq%q7cKSMA6c3*{-cEY{{WcU5qnN81c;4zri=TQx-tU3tJ@a&*%(W#Z8X z&v8bUTH=lAvbGQ2xn|6|3o%#?Nds7Nzc>E)^Mesl)W-UpbCKz0zOq+CU#a_9ID9S@ z-y~~`R4P&)bt{?V7!#P58^D@N={pCNc$O?@zRu~8mYr>1J3okcv_c|C*mC{k{^Ca? z*i+2bZWKWqtmaWCx+w&;fsO;amD0_06!TVyn&XHLC9mgeem4otFW*9(oW&LP;Y_N=UKs+d03A=;oz!Bbq^-m0J0p)x9%tJEM`S6;3m0J13c{W_lvHqP}EkWFXNG zQHaw^i5l#L`ucOUZIru8i--QG2o2xzWsjZH$7+>=vo5CX$wE?twbj9Tgvzkd_ml=*wN;an|>1y6f3u=V4 zdFCSEsi@uR??uyn8lG=1B)hTI_CqtoKTEg)^VGW^W4C-!QRj`SAAi%Nz1t7!_&jJz zku6YQha>5QK0HKp2(HSzX4H*W)m9!x$A;K7N4BNO-ecfT(2ECbY6RTg7+#c18_X;< zp?t*il-aIbmfMuUPCg3Nx2eW`JYqY@WCEo>qnNf>Bkjys@`)qj=~W30`>sB99S#VrUS7NVICe znXZ^Y&Wc_--*2lh!4oVO=eOE;Ieu9a#|Y82TPw}<1!S%UT(#vXq|DUOs|W4f2i6&GQIk}P~QG^Yc~T-N&A#kx)UbPwUXZ5o0QtVW0cTj zcR_2iMC);OL9tR$BLMRYG?Op%=1R?bnOEk7_=Zbjgh^jYGsfLY0SGMK91Tq^ld=nD zqGG=eO+(t7HKIu`lcwLxsI}tZ9>6aQzJC?HkT3W})?C_Kzm{CMfwxJ_-PCMs`v0jI z=)vDS<~VWx(@NV!pN5|H@(> z9}AWv?ca&Ry>UiV|4KqfW9O>@RSWDiss^uuKy2thy0y3G?{+f_#e^!G?=%`w;VdyV z-&oOF5)B-Rneg}o?cle&f=Q0eRW=Kl<)^vnox{9C&0;%>(d*))Psat$$)M1ZXc3sm zKFG_v`_Z3Yxv4>n3gCCEMa<^5IKJgSnGSj;Uj4s7kNEcYcJO~Cx8v^Wo)38hT~{oF zx5iTRpR*nF+e21+izJg>^9G&O*%I$FBGOG_V7M$h!OBvhC2dA}hvAAw35#NCt4Ft; z1d}o!_e2#)!J-M%*FTl@_ei3SD~HQGAIY*6uRhH=rdv8`!SgkK#8I8xuUlOKAh6Yf z6k4degOQKvDX;Hlu??BK=fbEfnG&jiQRb6p48B41712k1qVzsKxMDILGsTcL)>urX zQFt=$n$23T5ezKc)F=EHSRHl4*wEP9D=A`)xgzl!cW}G4{(^Jj>QRPivq;h>j0bWJ zL|yZHJ3~b9KS`|!oiG`y+$U9&vydp3-PMGWU3*~%l1JkTC2 zxJiZ1wWN2|4h@|yX#Q0>ADz;t8hcMFHmTk9c@p{s<6JJ6`SGX@FGCjYd>l{EK&9ctd8ZTZOA{x+;W<%NeCK>2J|bYFB} ztfTtr*ekXx6BZxEF|C#^sumoyn5JG5J2zKSl0s{2#ZXNHW6~xY+fjich`&rZu5)^d zM(e1~e>fmiSZuk~Zw-mBMU z2nx7<7kZszPv(A&JJtv+()vBagEe1J_o~A$F`|x&ksR-Qi|XdnW_+Dn^F;K}wP1fs zr4R|xn8t8l+ZUjlP~uWBF{$vEXx}4V)S!kk#w>>gxQw;` zf7B*!#vW;WPZH#*N&W-m#eDtrP|n~rSYTNnb5bcZz>TV-u={EmxCfOwCtcm|e1mHBjM z%jn?XCt)XCyFALxm!v*t^iXd@SQJpQ!vLLZq^jTJWXF>mv82g#%SZgvY2GImm9XxG z6XtC@HPG3PsfTj}`%!4i=!QQvt5;t}(8cRr_?bl z_AcSnVAGQNXoPf=+{bGkqw1&+%*)X3N*;f4`@3JM84YY zqO%%7h}qEX!jP5S#?r3(|eUhoq{_RcMUS>`k#SPj9-Y&mi zCM|p-%Yx4fUjOz4YTfP;`OXQa>dl_v;WA%V8UChuyJev##&=G%)`(0(`()L(UVF!f zr`xAGCw;k?o^W`ogteGk8#X6QdZWYn0R7@JkLn?5$H&MPNKU?>KGDiu(Q+~S!tdc& zOP*H_BDaKKmK zy9`|+Ik_tHzHeUiTB#o3v?J;#0(!Yadem%F2l~E$DbFq$qocdmRKZ0wvo)1o*+BML z`Q;z#T3%0M+1ON6RTHVF%G5GmU@P8Toy!$2e&>|R2GUg_DC{mTn^mo?KI+_z3?s?B zxKV>Gb3elaGll@TwMQ{XKu?1n?@RH;|H$;@V#~x-OZgkO=!b`Y2yVz>wUNa+GNb?z z?7b)$a}rfmRUNJ+5(2D@jt6Z2toTMCeS-q821l{^On*>lD$4*k+?QOG{~P_`nNlrd zIsw0Yki=R?n<|h_M)}cyjFq4|CzVkkx6et4dj$>5FiqD5q%gA%dph#Y3h_LuC}!sr zdzMLOYlYaQen9#L-1p33axR?SQ+jNjPmE-S^asGm)n*c_J}8i+(VR-+EdHT~hIj^@ zh0@yLPR)x3(UeyG=e@wEFv|y|v!dHQW`hGtUT=MVM0Y$Rk=f*oIUFh!J|`2t&$6=qiIiOYgCnT_ zWkI-V?aeHi>zpXYPFP%N@PwZ_iEriG2+)PYW_9rq@c0EI?E+thSkit-_)$xJ(b+#{ z#MAh9TBQ=^!E z9CT!wb!YcH(D43pwG&Xm{%KlF;)K-+CvHo9*E4Y6gm?9?cf`i*wkLbr zqq!MMuUqdwuvv1j2T`Md??^u=ywdO;@=EWCffATh#l6zSut7~IF@5cBbs-l&21l_N zt1P~QyIn3kCQOV+ZnfsNhDL9A=zJJHd*W}}?@)FuM@GDGcLJ2K<$m#5=2OJzr<~lV zIdH6(7m{ApSW91Sl8;8sJ(f1>@bHq^)&lHwnzql}U7{OgDp|h!elDq?WGr6Q!yNEl z=RQGf;9RQeMC33a4c^rsJ+wnODrQ?@B=zO_n_PUwg`wMjqe3u0!OR8mWk*A1J9Y+$ zWrc&68xyBAXIqKR2d(zg_aNP#^{|Ct4z8Yc!&&keg1EOor?DtvNm!TYHVi-ETlon0 z8f+4v%fbTvcgc@j9kCT7Hyv3716hx!qGyCc=pPLhL|sfW21!4Zb2xev4|-?04P?~> zrnV;gUaM<%J3RhtQXVNg`j_0hipB_~Nio3b!B6RpG47CMKml@V438e~gS&i{MhVq3 zSrV{mufXJhd(iquJTma^%0yph^bv9Kf&%|(cMg}nR0e{*FUGY6feXrxlCjyb4+5+- zg{bI2Vk}}cN0?IiD}qLf3C#RbZtMGgQ%vzKW8wW;J5(iws$`9Zr9)g`;*)u70={Vx z#L0%3vfAN~t^p#p-NT{GMixxCpu+FNMynd!QgwMyKEK8k-Fl*kJE3qGw18m{q*5Mu z=FfIyeNa$%?95}}mDq#6N&SXoCn?r{hDUdyIBR&gge%S-6dE;$?8XUmcciIBVH0ib zyt#-_*XUe#>p=DsG8~=-U4;9VpoZV@EZ-~Mn9&lNrdYt zREnmWD$|>3y4oIhjLo{ON?p@DaQ1T=@^m}QM(?RSL9gV@-i@sj_My7>)>!6q>t;&T^eCJ;I%_8WT-nu{Vq zLdPiuHx=!H%X#*6xs>sD1qLQ+(|#GS$TdW7-X(ZEmc9%5CXpW7leSA0AbltO2Uc2 zz}M+8W_|W%GKy-9ZNjbg_e++^@lNgb`+!N-`wvPFQtq76{rr7}A@hv3^>QBq-yO8P zgXO))_-!68cYo}@Ejy(0m6Sx#}%EqFrZnx22~ zLeADvc<5?(?ag^dAL8rHIVWnjA(p3meL+wp^0dQbx{qe(`Y$eOYDhKup111;Ew;4K zXAH3`yyvHDzr2C9tNVu&kELQd+j|jmfv&A%Ei?{-F=e-d$va5| zmW2gAk0lXJ#=lR0JuqFDl)uoSH2o^TX4@X)s;Ra{tzo#a%7fOA`GQK6l(JyWd!LLD zDyjow2`?%S^qxOovPFU~R%mGD=L_FjKZP_>dUd25%Z>y({7+>=b8r70vZ4Ph0!a#+ z(Uq-#Q%Y@I$|pcF?Ez_Y*$LHZeem-3x}xElz5cw1PeGZK6`eZ6UQh{!gz_K&K^pTy zj;MwNI6o%cQL-yDRA?x#?#z`8>^kDZn#bL^qVH0()|iN*9}7ir;%tC+rmzOV zHWhDQW{&)ZX}|uRT+5U8Pe2=bg=KxjW=V zcO}2e*M!r^K{qHAte2W&gfH4U2~VVb4^^ZAP=2o2%4kfylIR9xQ&${h=^{w&U5!%= zK6ZUZSwXBmebp;Nxl*2lkOjp!@;H1j+wDdjs)6GoQuJBjL&>u%0wSDFu14^tdp7$s?`Nc` zw}8SLX+0@FPKHZZGmep(z{jmFiP>gCdDiQZ)D=Xsyi z)a$iMIvAeAP+@M(SB*awnh__TM=|O6;f5z(>TZ8G5M*=9-kgD#U9uPZ_|@W-DUFpr zO`x4CHjdSNUqj3Y^M>OV+@ervR;h259|`vfLiX!?y_7q<~*No!S{bvkvFmPJMqp^ytAsQfK)o zjgpeyP{)R;`4w~B9s^mb_Q*wBp1X(x4V7ng`45Id_cP(@*^VuenbeZ%gezI>GpW64 zlVS7#z3W#QkRUs2s6Rc?$+qUPS7U3EcjM8P{bDbn38b%RZ?QSvJ<6r+Io+JmVBU;3 zw8DH$!PQ&fKGa)TGkF8Dg=IC9{I$LOmMfsSa;+V-^F9eBJVe;KN;Zhph>!kSAGWZ| zzEW``oUYe+urp-vj{E%kgKAaaQO{U@t<)Leo6$GZqEd-_SW$w;uicH2Tg1fIOU7zv zsU4Fys6@A$`Ox+O*-g$L{hB4wG>BvAl?9^3#3scu^P5}c=V;#7YMaV$J)w<^*V~;f zr8rBy{YpyO{q2wFzmn@6b^iHfaU?+nvOP~(o%)5y%)w@6{nbW{kgoy;u|<V;};T0v49&xtfdX6_HVU;F>M;irNR>@wXCPh38}R{z>RYcU$Eg6 zyA9y~^>hpX)(dGHjb702rnn zImH2YgqL-m3sk^5RLw$TzeA@>7gRECHI+@PYsDtYww5ZfIG?sQRf(+J$L#Z@bj`l= z+>w6s{3iImfBnO)gNO#@8U7Bba7AJ`d!x66OrQgDTZOP7S>i>Po zP9w#;$HsFzgKI$%#*lA}k_!umq3NCD&E(PsRgtnFMo(p?hGYf76{v6PxvPkm_)Tc- z@G;@XA9I=|fxkUFPV1hIT3!=Ng1q4^eAc9b*p<9tEvQ$QcgI&6|C;M#mzcR;lA#ch zGS)|Cy)^fSh{AxcKfB~;(g=G%>z2cS^3QFXQ`a}|i(s0qjM%y-G1+qQwsy}maCi|h z*&8*hFNp%NTp#zeeU?a%W02h5h-{dN6uxmxkRppNH>BlXkiCZoR{)==RFhBbCu|gt zX^M0DeLrVlt~DWb04CUY7i}ZgyKLAjhp%dLZOpBBremZ{b;2-`Oc7ZJ`u8;RK8iV; zx5VA;L7b%oGW=hL+{TcmDr&wrRe zqWSyj=rv2D6AWs^pHzT~V0FQl!`tZ(Z+CpBL@egi$Qiuz203b?HXXQX!dDh3nCyc& z8_CUoq;l~rc7N|hV73JxQqD#k-rpUPN^YC45_!$ziDW4X2~W#^NZs2J-L|%`(xrV! zrPFf4xY5kGBgug4Si0J_UxX2?*qZFD{vsQ{SvOoTk1X87BY2dJGSpvmD$3Z>>2Lbs zXT-|OVB64Ju*3QzRPJMQ!8LzY z=aIwRDg*q`xcZZ3C;$!(xpv(|QRH!C#fP2PLR;z2RTd3BFBW-zD4%JxG#sd~siU&C*qX#?{RU$O*Z2<+3N99Cf+{YDA3U&>lwS z*gYKPkH2+GtT63ZT&LowY$Lm3>!N0QLOi*4X)3-vKR2x_XZn-5njvqW(Rq9tt+-9< zO(@ALYi8c1$flQbFA1|_$}!g-ot8VOGuqgA$5Py9yEbfEeAhu?;G&T0)5@A^%cuQb zu&+3-EB3>w5=odD0W;5}e|VRmR%ONBY&KVFe|gqo=P54sK&^IbHG5K#B4$fDqp$ot zrdPV(%u;PUgNbhvYBqW4O)H@lz%3FSzMoI~1p61=5;wS`p%2;|@ha5H=R)z_(ZPp; zPQvLiOS=@X*`&FE<8c{WuY0eB-2^TiA`N%BmnWJQn8g5sTzZL`bm-qxP5Z{-T8NS{ znS&Q-TDpZ^7KQ?2N^3c?HdV74W`?$nC0srAio0@VKJN=T3XBbycBeN)74;gJNKFNs z&B2so^*7UGpE=_K{B`(NY|cv$C(Wym#;Yl={d(N$G_QwM>2%FXN4sDFfCv8a`{<7ha!MMjnCDfPlmn3WufC7UBbf zYG%*rQ#11Jy+1HEVM#J&XDUYud_Dyg0jzOIvdUHx#x4Gk^;esGG0vS#(CW=8xaIQ5y%`E50mE- zz3VrM_SvJ<%g zqKTRgn0+o^9{Drht845k|D(3Msk0&0yC?COZ$aFZu@odpLXPQV>nw=F@6vXR&Ua?* z@H}HQA0Upbs~xQj0tKw{hhT+4mJ#bJtL@LXgw})!76l{RHs^tQN8d9f=WxQ~b3~_g0uU%KJw*(4Swm($1#*s1PG{#bfTo`mm-7{t>tbE821}xR}p3 zlb$WoGToc$xV|kBk?My$o+}Y(XHDX8crl3{=@W6B<-(=j9pGTC zM(Fh%C1_+ulrF8o_W`OmW@v2OBnI&1yQ0|3s`ezhj>g-1+lPue*_?S>`afZBxD8nM zq+&!i2v@7K9Zt4<7??K>+V*V4ZhHKc!%r2|jKUK=Wa6_yAv;ouhy&VAUh!}V&cL;q zgV#aeeIo^D(G^((lY}ec^MRN1Fn!~d=`+&-k1t=~S5!4DI4vIw5*hwl^K@9fb>0~# z<7OA%x3@=r0Hhu4gIQ%-xDqNByfGDpdgtIFvDkqCPkMHcOdIVq$WWI*k4gY0k%#>F7TbEZ2Yi!J(kqg^YRcy98#78Zr#XH8 zB<8sc$=pu&{Y0ac1*se5ak7KF_@HkabxRLnWfeA#qJ%o^(RJWq7Y_i4`&{MEG@3=} zKZ-z2e^$+7_OmLB=jKZ+CA^x-Dx5A9X%C~!UQBe#+A=A}4#-JS7Tw4iqzSrOV_od| z9CHKeI|Z_*A`pAmrI|!ysJme9@kBJ!9ywusS9521uaU;JBb^1~uX8?1 z7tAp|0H?|GnmP_!=H)B$@yFh@g->%DNck$&gZ@O9UU1ufE<*e{V84DREMDores7Os zx_Sf=Xa3{h=rRY<-=(4W>Hq(s|Ha+VrU0E+eAs)Oj^1jxjQj_BBv;&upLkEI?Q)ZW z^}6aLtXV7_dHW8-Po76fgGU@$l*p~67f)(y6%;p!)4?A|vlizJ_Nk)04!H=!^%OQ{ zGV%f=7jUTr9LR8Km|)M7Qh5Q@eqU(0~ykLFmW(z2?g2Ahkc%NHj+P2B3z7c_JQYGDs zJRu6B?HXD!6g@ZL$uGV&-2dFX*}|Uuj$@Ni%AN2o79yp@t(3Wh(_2SRSEH{lLe7mc zq+}a?ARwc{vQKJQ=XaP~&Gy4n)CRp!?9#FODRj8oJlZ}gR6!=r-fPNI|7z1~@%oet z;^JC-u>5<-i|bO@h&rM)a$mImGr||R(E`9}6pR04=Qni+dOVt8+hUq#rQJC?7Y$Kta6a7Z@$;UGojD+Vw)Am>6lAlq?^g50bsl?&8?i$VHNeJs zj^ACxAlV;lajWs9D{Sjx%pcHe}A6r3e6q1M{&|H}*59Qs~BENt6d=eqSI-*KilW{?$G;geIZfi82 zTY5ibbf|Nva>fC2dIht_L#=CQ9&EzOx;ut0QlY08Ud2!sx<%zjdN`42f zlZm>~_SY%kflu)lQ!W9_)aDf~?s%b~f`^ECnnvR7`{_ksn@JUN)dS_Ru=myEuOTw2 zlhW^3Yv9Z`?XJ5+`+IH{owE4625oMS9c0MW>9mC&8*jtvNXc(@O^j7-+|73I$W?db zTcgcXE+l1ms$&s4*o*r($3t_miNcwJ^h#D*L<#p@Bm^(^^@RkU4XfW6k8}$rQn~>1 zcPhOYpuP2JR2LXe)OZU^Ft0%hTSS4qfI0nvFA+48B+#JUZic-7ntDa@!oF zu=VnSE4|&rPS`EA9XWG)H@43kCsJqj+V^ui=eDY5i;tiVuVt=mt7Nfn%$d@2klB z)F9^ww4uw&HL5_bqc}_7n4oOLGmqs+H*T_jwK8KfKvZ%|Lh96j2`^kf|g-N#={=HB0j$I&7o7-`f$4488N5(SfRj(D&0Pn2fm@8gbh!lBnT=vW*bXb%$@lPQKp}A?NGs{z1EL z#>BZGxpftK9*eko@*b_5lDutgKoxaqcq)`_#Zz_3>}C-`Vr5o{q|uw4m)I zaOOLJTGaM zr9_TM|8%1ns2FtCYW!=1`KxM8R}Mna#6)R88uIBiZ|U7TrA};fL%Gv1IXOK?2Gw)> z>%~Vw3FJ+Knbsdf%DE@{L9v>%5oQeR9oTN~nj1oHQ<Ziq}v4ld^l2a*q^AUr()R8hN69?X&7&`o_$5h$riaB z)|imG=lbMst**CKiE>)pkBLH(j%1hHRu9SwHW3Ka&FWf@2<1alzpJIv?GFH|jK+5L z4AJ%p!D{PN<7VaphhyCHAgu5s%ov(-0#s863lKB4)eMSqW}+T?X9{GqQWA-K(8;3= z1T*r-OFlxGYf32^vMUdza>2rBV5fi?@(h=EBk{-V*5yD(Ski}SPrN&RD~AbViK&_? zAwA+05gC8ovlm*9yEvI3LgJ5L1TJ9bSCfme(mlC zKeA_nO)d3&cm4G0ShNLg-t7#G3-eQpRU~WtnSAJh=GXR;i52U=QLxYWxJx?sTU$A= zZF`{%+n2F1>kpkp7byu#K559f$)6}Bsv4~!xl(_09xXJH3v+@Bt|FE>4OYxOK9WZ) zh*ho#PVUL51)YizST77Uqfx$ZLKOygzn~VLY}iSJbS0}!hMLe``Y+#gUG$=TsnM#j!7En{&8-o-uQVs$m!~_$D|vR>*QQx%aeHI6^@wm z7GtPH4N1e&gJ#taJ4x*nH#1MsuQ|2y3N<6)%+fP2^AlBS6PIf`db86+BfFA4_g#!x zeN6Dm5GYamHA=-;60MtF?N#VI=2BZSQ8M6(nnar_&5D*G4|u}jYSQY7f604=J3uHxg;_<7%bq9)in{yF+0VQT-gA9CN?JAV;gZ zE{%Y6HfeJTt#d_0jk4YG_Dsl^oqnXT({140IIkIp?RVc_XSCrZwuF$yc9%`-V#NIl z<3BA|U+LeEBELiB?eXY19taDB%}lGp=P4czjrq9z(ErT+me5YQ^Gtrg*X6GAli*`? zcJnxoeA1WCPm6*-=v}o80Igouuyrk()2Bc-waGMM&c9)vY)n!@QwBwwxwhs5k}Bk%a5U8Vl6YCa{@>15)8Zsox4^=rZB(FrYehb=RdA<_JS3|J~cu%xwIO> zYbJH*Of;Ja=rVl6;isSVcejbIDS@5My=dU%=xW4JBg4vwrQC(Wq=E%t`Qi_womZ1MZM5)$&&{lW9!i#WOL0riJ} zN0nyjet#>UIF3pGsh?<49^>ByEq#)kDGMJtPiH%O(a5n+#Qj*(4_lEMit~FL|7e2R z!@XRsL!_Pjkks%1h_Z84|HnDk$Q|aeGB4t}6ZO`BWsWA4^rTPE-M2*=aOLNOqYt%T zt6W}>ii~OreWUk*7D7BK<}{!7g%=}*=(;E8Qx=G$=X9gHukqiEUK~Pgq19ipu+S}4#|G7f#GGs~f@C&goN zNx{56?wiQ?yHVkFZB11~4PH_lrxIfg*Q|Cq#U@=f=HERkJFc*+m!aEvqS+OWFCL$! zCj$EhZ9mVOcG03N2`PIUr^@KB5IcgoCa;Cs6yKy{Rp) zpKMUssAC1r^FK$cc+$opYFOsV5!~-EI;4O3Jwiws8!$yPKQmybSqpiIoE}2z9=&fr z%GvudnKZ&ZC{lXM_l*o|6wT@E**DPpd+#tebZz6w#(iDNIA0R;fp6TUT=Oes*g&&;L?KsCdRy zZXxBhQ~7NUNy+teG+aNx_2y$hAs7-ok^K|M0;?$oIrrOR`zD3D7|Hxx)FC-&RxaCs z@JW`^FDL>{4^3VN1P2n+PKJ#XyyiygbFa+mBpGSXm_tZjDF3pvY5vb|t+$Qsjt0S4+tg4Gw^2wJ1+EdrhmCi4H_pJ8$=`qsQ7aoZC)$Hi*{*|HM zkGdHm84gm-y6id65R8103a3cwk1@l8$dm@hMzcuP*Jy`(T}wZElkE<&%^)dAR+9zZ z#yYE4jtgjt8TYf(OW=z+o?0n}7i$ckSglTNT*!etprs^3+7>9^bp#X2G&;3?@cnk) zaNefCb7h#x?y#4~{Py&^Txsxh7v_{-+CMcfD(ENDgP-N_LXuVz*)GlPlmSleh5pUXM*h1&JhtJuWdwjyDQydwVlM;8_^&zJM z#R?sl?cg0`qt%c&p@+$r2t@1H$;s(`L%%Wo7H38SjpKpRU1nrjT*PYpuv?Fhqy=9@ zL38Tp#F7OiEIO3rVjWb?RIC?BBsgebHX-zv51-J|;sk+kqD=?0tRe1I70@Jx4&I$; zJA&gBTc68>u6GjE{V4*XaCGa@>p5SED4{jm+0P8`DrsnsSoIuXcc|ObQUx!(%CNmO{4vI#I0WZnOk`JZDGu z=L|p0-p|o~DV4Lhe(InT#X~?q-x{bzODh*$v05`3;+|j;Nn61wH(RCvO|nv@ebpL6 zme$;|v0t@Z6Y$ASy9>82|yI#JAPlAmwikv98vGS7S0I~%Q)3!xad zNTTrWF=aTlDz4ZMJ`Qn*3MFS;oj;mVX})j?Wtl!NV0<}vZO>NAR_t3jW0J8WM6%J*o_m4z+HG> zq|w)!^R2H~$S!%eDpVB{Wpor6ReG($@2m)?_C(SRcX`+aB2Rdo??=_mimjPMo6tZ} z-ce;DJN#t1I+2l!8j&whE_}^+A#}!iz{n_8I%CT>D%I%Mm!CR#%4_)Sy%#Pn+^IX7 zx^A0=wrn8L%Rt#|zM4Q>XnZTtpK;CY*ybC$BjdaJKw-1l`?6|g5Ijl z6d^dkI*hDmn-1QzQi?Qcjf%3sdHQf%m($UP-j8A?(~Xe2rt%+n;Ah`=>YF$+G_|{T?N$5Oh!V6P$b*E3!CCuE4*IvTmzfP4nvpdUh#3Xa4xQ;P3;r=%b_sk~)%d&1VPxpwTIX6kV=IP+mCD4LQ( zaX`SKm?~>Z_3f=jN!9DHmp( z&tU%-W@r0rfJ-9r8h>J#$NWzryv`JdqFN z+iLiN3$s{2k9da1gstp#1s;)9?YCf%-TIsnq#tt_V;PiL#<4f}_Gl~tx~o4jJ(WeVc;XU2;%Qw45XLu7!xtEjomDL&}uW#Ga%PcynTMAZcjI{OsDFhVMg!l0YFtaQb5fNN{tJo7oWF3-eV`S*JkYdu~w-laD+4y z&%vd55{K7_>k47^trm3A+IvS|)aVeWw()CvF`Ow|M(c@oX_)s18bAAJzGDm~LeTTdk|?YUl9%6k2(zKp|Y;j7CAL*AVJKer9=<*V#h8&SxQ z3sFT(pDyQ#Jx2X!aI7W~`%cAN@H0Os=5U)$YJGj0nHa z6u;ue!DJrq)Q-=gUa=Ic`rAL%+Y9lz)U=*}0c66Q0fCx@{3Wb>RgpHZi1&7z@{5 zTKGD+FkV2Mbm*dpxwoOt_gqIcz;(VqD75C0;IBJbCG7XNw?e$%E(NU~Ts`PG*mf$| zQJ6TOHUdJX=-q$i{!A{74zTSl_Pp#R6STjl=&1ALQs%{J{Dw^tk4R$TH3QTXyMAi^ znyY!~88-NIS%Su5_w!zlQIH5JTfG%YduW-ozYRVR<0jjw+6t!_5w#e>?D1}7_{ZlSK-C&0BZvub>%a`sgTyPhy`aXMt$QT;@dW7QH!dk6?&C% zs5~SImO=LToPsNX*h=RaZlA`(N0kNMZ2HkgBTj$SRMds=QwKftsl0ga1bw~5v!piB zk8aYY3FP2mIX>3`NXPfWAM>ov(;wVVT`b>MA|aO^p@k?dDC*UGXUs6%&}x4ZA8A&Y ziwM@%6!>`DPC~+Ib%!`tzkGVY!?V$e&31&6R#GhSp@v9YxeZALm)!lmt&e@GAoTXt zGvMUzBd4Pe7j-daJ=G`K#*lV55a{@adx?kEuets_SEmz~O=UBIB|R!0_jl(tZJ*Zj zoS%?3OG*uu-5Tg^f!^!wCBZhe`(n3##oIHIc+O;Vq7kYMHM6#yaBkcaRMe z!%1U}ie(keq0tGa-)d{oe&MV3c)AU~1Vm0Ysk38PI&pnDMrc81yN5gU<;4L( z!}s%SQKGRBKEEa&tZoS)6S4a!(Ml9cd~R(Kob?nQ)qr_Kl2MI7lDLN#r^#&)@vY0-$) zU~SIg3OnPjc5~xKSBH--Sxr)98})xVhw8scC3%gR@NK)^lG(9_f?dd-Z6B3V)?bf}?sjb<~lm=WDiZA8l0Y2qGeEi8n2@$b^5y3rzEC z%ruyADOg03FgxK_;`-iPx#4JC`lVB+U*Mo~6!)tq4=~-ek*aP;Gnf|zhRGpZg@%wfR3c4>Zk7XwmO-{YXX1qih zm7EzOq*dGWIs@~3X0bos?ujpesxyMjHg#H!VROvTPxfkm(nDz&5IHbd8MW-U;zl_&D$5#RwCDbE}XZJh@ zW1UzM2YzMGY3ztCb;fksyAJq*FyN1_BFK-e^=NKH3a6r{z#c#}KIPpvw!{bhKd-|P za@*Xy`(YrMjS@EARDol2n>?i&s+fQ~2+Vt6YpdJ(Z87cmhYi^D+k}JalwLGue6j=g z!m$UdMWWv${+aiI&-NMIOS^t>I%Ul0d6YPg`W+i>?;|D{58Vyrb7%fSuQqh|iQp<8 z6OqmPx?VodWIe5wjK0)g3}cDV_c=5dHL3Y|kfBe;ZRM5z6SvQ5$h*$Je#n*{Sc&U( z815(e73x-DrphmGdqZBgLX-@93=VHJA3>%%Bv&r$5Y97^G&h4+=L@}r)6gw?l%rd; z(iJu9m#No|l9~%*vD5&6S%0i+_x4@@sZ6ktjIZhWMfqeR~R0?k0QDO;CzTEb5$eZ~rKtFExL%r#r|`J6XZ9YaH9>UIbm zCS(~Z&Gv7S-w<-++$~aGU@pbUv79nq!L;Ca)8qWk(%9Au zx3#2d9>s@OhlE}YC3zMJAKK4VO+vkoNVs0#1dh4MX1r(1@uSHq{gS|gct5Work6Mw zv%)CR#SkN`#81@ZR)Gp40xqVGL;i*pDY3z8h3`!z|Ga`aePiE zk{AjBf<$Mw!``FkXR~skJusTHG`)f1I{k=D?N_!jXtH`wBF=K^9_plS-CC$C)+;&E?FN+{B~Ldmd7^-VCP+5%EYGkE?i&^6r{?k!i65RtAw> zv-zCLL5-`+pC=>^1!0^Ai*3PE$mK`2Q?l(%-6Ov9dPW7n&vRVBN>iGJ12$)i$LeZd8=s@o-V9I?vP=r`%(i3|{;2X0h-F$@x0yfPla68tkO9H&3%-UP{a zd(ZqVMY$`f>4jEM(lI~Qrjg+)ucE>gO}$e#mb#FPPu{In!8@zGLb)!E#J4G9x}{L(`DX5pUf)TKY5n?$O7#cAGivRDin8O2(@1k^ zqjx9XVfDc++`yfqM7R%3_WeCSgOXZH<>L^`uEZ=oy zFGzjl<(*o0m-*`vR6}Z~UIaI=Yfw+D+=L>*h!Li7iGSb$S*JN!o_nrRZ5(REV78j_ zSo!Su@QC@x&Vy`f+z+_ap(DkpmrUMXG(%C~Zny0TZO>0vgc)Z~5$z;mL<0=sLDbR` z9#=n4CL+QI3p&1N%L`O0@g|O$d6@0gAz5;&I*(l(pw#-& z_qJ?)bt*^;!EW97z;LZkXXa`Iq&&0xdaTxtc65$lNHO;4+-dM*D;ZeSW_6{Po=@~V zMZk{^v{Pd>)ygA~Dw=K|F`uT0ba-2VX%T;nHx%Uc5{tS*( z`f&6t`ZPfUw4a0!J#94B&*cAQ4*!z%#}_Ydw8<`D7~ZMV`jeBD;C7YOxa1^idtj+8 zpf@G_oNnUxbZsP+-PUk^60#){)_=16kvGbkZ69bQ0+5kAyzu-rozdQVu!plY3QU+U zeED^ZVYWUtW{TZ$BZv{0I9t7SD(Fks)N$1%iFME3qyQO?iPAmG337GRX-lC{WT>T%hn z3FouC&m#5uQ9lx?9g-NWXuGmqMUaH}) zr3LU*x8q%(3Ji@a{(EE>fLir;4*kQ5s~~b!RiC)f;)j;Cs9+h3i~6J(>h61)rgxI9 zZ~wPslt9*t&;@XJ64GtQA|I{u{N8x7s=Ss7s*Z05X#cjGAewjmXUvQXoalT;)pM&? zmB(6x6*X90gh-*T=ufKf*_QS@#gi-&`ia_T4Wb;n(6yQII}zo$?!k9wPIL22dt6fF zbQn?Rxg8N`K5cRpftRXEH5&!){PM+gE%r~3G;ps|xaXC2-PH-yj!-*U)Fo|ywy))K z%l8(&q0T8$3MvL?Fei{&`6$HAY;HLbj00FS2sf@+NRh|M{Dd|CM6U|u7O5A11m`m< zE#pf^3k@dsOdoTW`2$uF>rk}fOSb2H0-nB;l0^h}*={Ytou02Vne7+1?DK=!{U&u5 zjF{eRueF4E?2#7v3xCyi$4Ae0b`w3d`1DNmD^;K-F^>jX6mnwwX@1go8ZVIV<|KG- z1~nQ+P2XrR8Sy6kydnkH9$!)Xp8bo!LTz_(X@JzFIKG}H$N>7*g-*&XgxXY~4zwOJ zA}JX{2E5PdX)p);TAgq2J(x-Db}!yyP(=D!a|D@fU=(2d14VBsNOq0sCpW zaa@FqT}oN$)$9Z4lSrGd_wdsj?|z0BOFLS=NVq=Y!`LXBI!Y}W2!~6kdt~>2VruPX zEGyEql&YYcSY+xZ9{TMg`Y45X^?k}yM^Mng@59s+{2FPR-vd=GDVMM7&5UMDQ~6y+ z-eQ(78QsT#!%tb74Ns7=!c+raV2syVEnx*}!A;L*#ST}M7xd~QWAok+#dyVG_rTpi zW(MSlh}>93(bqy#BH+fL%+b=H-h8T5e+NaO7e;w)Hs;67qNjz|2GImI-^UrnlS%oswfIICuT#7Q{6)mYX&|Sem>gztDuKy{U z1$urXfrLGQs4tZ_70jpke8mg(y8k2V@^5kT-31jNvNosI`HXf$6GYI*=H_p|G;}|? z{jMqK@AZ#n6E30KWg^d?1hXq=M1@)I^!Bcp^E(E$4q_*BtVrd1wp{ASYfwSIc5K^L zESW!K1rTYxrOZ3{`D=_PAfqGzU1mfYqlB3QYF&wb{;<$>l>MdYhw)V%7;g`8XsJyf z^Nn4S$?|Ok-OP@vxLd38(L=D+RDp2KUP*wBCj(M@fv6AUSYp}!aXMDpCF`|kAn_`f z=$Qu2yx>&+-9mH0M4pJ@_Bk#l#1p>0`$dHHQ)>=UHX8F|j8hWD_a5klHVp!R{3PAN zTpxSpdH{WYrRC@*rRJ*Xc}{L+}k?_Ty*J@ z+VD$5rIa^+(}&5} zeZuT-YSY9v)FVv-j8!hk;2Q64l1uIhBGiypfV;%4l1p>`c-`$kDab{Ppx^Dn8N``} z5PFE_4=wxI3$EKs719}YO;uK-D+fyJ|He#ZB)57dss=#T#Eb8J#2Q7CqAyUgT(eXM zA2_JV-P5JE_xo~RGbOnm>u}aOB|d9JnuHjunBPd`_Szoaib)0jAS-JY`WCVmn^+%~ ze3huK{F!aw@n5VrMZ@0zk#9=4JRncC9z!>*)1o~biCAo-ZBh7n)!tNV63M`l_9NN`=I32j~M9!XcX&(0ROaEg4>{mVR;(cOUG zxQL%UfaNMgemQv{Qd+Ks0JN;xDV)A7KT_37Sy8pHcBxs>iIVBbdPAT9ZvanUYVF&- z));!wdNPE+9HZAO{<+K9g&EzerPyWO-gO(osKUP6>GXUOZc|2CaOB9rvIp;O4j5cP3aYr#YBwUzgg#pyB{C)ZOz= zMn!J0X6Rob<*z&WHaynZy~DD7_4LYZ(@t87o+Us|$SYYI6%EepbtHj&aTv7Y_;=ytU24!ipv3E{dGMEoO9*TbUFIyTdD zmNkfY09#^*r=Pm9b#k`yySG0k-&B`g8L#CF{nSrb-t*N94l^;^*J(-R`j!0RKAnv`G$%&Uv~*+#5i%3 zcSkf&?$K@Ec68`mLgy45o$6&nQo7S9agY?Zhi37c?li=0O^5!T^MB)`n`KvCD!qs63BDv9*0e8{3oMXmId1VZF!{Mz*MNv_I;p#+O($hX zCVO^=nJj}*=l86CkVbH*!|#ti>TdnUbUdd!=HNc)eMr)TjMn4q#MghLJ#nLrT|80A zm_a7<-g+xr@l}-%*!)c+BtYcdpM~+tan_?lH?>wWyu86rZ7}=LKg*9EyLZX|a=m`{ zzhOcDquma$b%yk5)D*kQT6ZQ{`nB&&z|0NFmsHf-cKkHuw`YXwe8`0{*aKI0&&i3~XrdXzI?NWa->vG)Jik{NH<<(K9#P2W> zk-@fOyKt5_EWts#v$p~kw&_Oh&M5w_nB4!#*&%E% z>rdeR`RQTYhnK1nZBFc`G9s9Qz9)iVC*c~RK2NB46}5H6EF_T0ODr zd&O>F_O|m);*B0rmoN(ByaUfIS``r2$n$b>4e^N|CSoM2kRv?r4p2o&6jyA2b`0dF zdl9uwH$FN{VBh9`)I!y;mm@Ibi9`OLy*6}GsyokD_rhySu=|-Nz!c>rxo+t3&~T-e z>*k~j^!a;07f-&J&l$s-1S;2iyHT0EDdF3V2LJL6OlHb{2d5vGMV_vqdr!-Zx9Z>R zWUZk@D@b~jJ3dW%fk8UH5BD^KkPPO4$wTy7oLii>wkH)2Q=wb5olNEvf+g8!E$d9n z`Q8^ZqD5@pnWbHLoCKcc=&}ny>1%C&i)C_#b&(r$MA;g@k#HhYb;b$C1^0kUCe01K z4s??VY*`jI`->5$Dgh1Ik2&b}T&0gN(@%b8KX+r5>)ykMZG9#P2Ku@5L{fx|4SD6U zV4GMr_;f>H$Z4$ zXi!?|Mmh29_sp0Z|CbJLzt5DK9!DeImO2f$YOLY?L6eCUyXV1Flg_f^W$p8jD;1ZA zv0mw-*mD{R$LI~b{4WBwXPhLNKfEoIMA}!M!FyR<4H>y`HHl9;s~Bp>j$a23FV~U6 z5reF+5Q# z!rXTsKm7tW%g^#*6JTnqxJw^m!&anO|DnC3<h?}4a2qS$Qp1XLzL_0^gQkY1?*+!+XFp`8@a zDSRm;(q<4`dUX$rBTi;4kAFXxw2lpt2KI1#h zB##p=WkVYlFM%K&T&ZZ@-(?(!;~am#GoQMNj(Fle@;8`kpRU2x_@u;$({%8gLI@wS z|BY?2GxNxMMlMd9$)?ar5ZS@n>|(+3htEZy87%&icl5?wg2Qd8YmI53z(L=U=Wf4`~0KLBR>Kk5EDy`@62d z>;wKpA`A|-kD&Tj&W&a2_5Ux@Y=0B4|6|Iw`0__W0wtg-{0^6viI`tHaD8xor}gi+ z_87~aI@Vf>$7YEb+9RR^!AS)Cbthw0xU zlSKL9w|RSSZ{f7FHe=9QhEzWfHqXW{x4A3|LE~cf*^nO^b9tjVx`eKC zkoKY+k*2>}sk&aB$Gx=Pv#iI_yp&Ci%55 z%x0@;mG!;%mqkV)CKG3Y<^U!(`!0Wl3yn9^ko)xETo$}`vv(g}$9j%P$o#qvD1iV> zFVQ4ge#xGRM}O*IdNOw>$zJ26DG z$-_Oj+arfkNu3`T ziQiv*i#mD}SYXrFNl}xATp!#>vQX3>QVX4g4-U7|vWSBv3n!)$O&%nd7Ah`J-9z$tM|_hB=xsxD)8h zY~W<<=EonJp(4C?9?W_|WC*|OdvtP=gECh&UvmSvEP*2XF`s0LrpU|&pgEma>vs5V z_HR2HU!4fs%V%26i5eM9xi`PpvBRC>8||r|gkJli5_E?^t;vK-oHXvKYXrZ%}H;uAHy-bdc+Z_rP|ug(L@q5ySbBwA(omAQJazpYmCw# zDMfKzc!Rhr{%mU+M(pRQvQk01O)n@NStSqnm}and#@w#ooh2Q~TGae(*eeCCrYln%~xnn&-xeq)DHT(8RFTAmUWwIf_krIs87%e0$gSTfkkJpVC7xtYsQW%3Ei+@rhzD-G0UQqJ=^Ruzw0c#pBYcxt8VAp@IcCut<=pB z8`d-tAZx*A0iX1*I71+M{gcM``F$`Cw^@r$+o;EY!Fy@i_|9XxM~Hx1s=kne%Aaw# z!o+3>Dbk~g-(540 zpqCDZpSYo}VlzC&ew`xfrorVA%>E~luWr7z69adllwE^OlOI#g7dPP~x^3Q_Cl&V$)*!|%3a2jK3xw#bIwzRpWfJl0I+zEPaVAg+i zu6j461JqA$3M_p;M9X)PQXY}nO7|8hQhr$<={d)pAtI+Gt|BydFc6VLgFSP^73Q(7 z{5-m-HoxJ=&dW=A(C6i+Jl!=!FE`R$a4p;eZ<9dTw#D19Z={~?T$ykXxcfney#P3n zw3({u_vWLKZAPq*YlKf!N>B@fau};U%m-TAbW)i?r!8XI-rhKL}hH+$^FT!SJ!Xwn1vZNJT_c16V)^W2Q*BGXF2(yA}de z@V(A-=6W&hP8jar+5&G&M+PpKN9I&+E*?4k~M7Pf4Q3~gv*r7ge z;u!}>nUSXjTPa_OZ<13|SVDVXD{a3c%5r!tN|iFhQT%QjH~#Az!Ssz^X9mD~fPoO? zRVEb-0Efd1mh=vv>FQsI*h&$pl#(Cp$fSw2+tr0gj<)mVtH;O0Th$|yu(oV-S$4AB z`fV`EOfOhi!MfW|N|iqoN$GG2ZBWMaz-)7V*Lev3a$KrH9xNI9p5d$7n#lHy^@|2N zW@CqeFHXXY5vym3E#Koniq1u>R{~RoN{(Ia{h#-YpeZ-OjM(~L^sjYd#Ga(LKr6(P z6pMBl@Bu!)HpYa?hQ4T=P$0~0=P6`WoXSxC^c$Of-t^U?CSzu^=C9hrob+c|K7cJX ze&Fxk8A|`fTXl~M45=5LqxXehupJTCS+QOgn5`DubmV^HrB!W|9s~W5XmfMKb2zqp+Y$D)xxu3j>Fo7qIoOb8-|HO& z@T@jSI-)@)a7{xt$&v4tjJ)C*Q zV`Za8+fRwl*qdsq@%>PvtYDF!u2KMA+44e}c6)>PWAZ!8npeyDz24Q1x5w8W=IFN6 z(q<0o_QY#0#=7j&OViav9WAO_%wJ0dftX(Zr7_3i+yM{3^$Wi3YwdQtK>nG-#p}44 zEV~NC$k&d-=>F<{Z{)V&g;rVa&d+pZBM)u94mJAP6=sE=$EeEPTSsMv&_U(4k{1py zE@KDnU!L)w`Cy1arEEbZYf*I#4B-vJ@d@OntPYx%TKv7C7_CCB;z6lFC@G0IScQp= z4OIlhZcP-bzxEVCZPkkfvWbB4dN=Q-QGZ~%h+6?h_b(Nnc^D&vVIB)e(kIB3$w(6c zIf?@gn0=k~LJGLfDX*DB%`9J_05I|yCd9m)DuVk{BhVE=h~aaK_r&oeQAiy>7H>-O zO87HYI|tjhC?QoZl6mUHOg{{DTLAap-IvGst4|8leq}Y0tobZ8l5D_)`i|3I1o=H# z)e%=%RQ^1x*ln!@oF}j{y6o$3TnSC(Agkm;JlfQKTRl_o9+OnV=r7qEDboG?({_x! zg4hWwdeP^NDf_guIKN@4Z7%jEh?c?Fq9P?rPDq?pw4 zIM>xY=e~@C{diJO6T?xbk6^fJ9pjVLZU>L`YiZVAGL^MiS*efb-|A?``_M06AeZ=! z7^@;nWSH2bq`=<;Whz~F>1wak`>q=5O}J6GYmnKV^5|okSK4CaNm_Vbd}-(nl!f03 zu@hmA@&akjk;TVnsGK1Jcg_H$#qPOy@;FV2NY{TH?xlr00{fe=HlCRGy7F9qMf*V8 zxxa)E20t;*7PtwwWLVf({_<4D5st~hWk*t!#oeFnABWpD%M?(es87NY8ib{ceeOb( zYBij7MXb*k2(G0FQy2H;);(G?nd+8#cuU1bfywnU+tr zXDgjn@JGqZOa>@zxOb=rZp#RL%fEFK*;i|2FPxIh6op{siixj3q4Ijp{b6_}AtTc* z_tck71Z8k^FKx=jbjmOAFv?-f3^}(n88_3k_|qxt(yG7QguKG_LPVz)hG3psGdQeW z1QvT%BWRbUy@F%NjIYpiYB8f1(f#LtLd!BW^rDtU5L|@ytZ#Wxqr6BNPA`~pGM%ZytWmh+7TU@a>UGD{dC1B`{z^o!$X_qaVWJ&RjNes z6#EZnzV~Gp_b8JF0qu*-ECr49fGXO$tr{!%o?3g+S1}jSss*peHKF-}SeqR6C<0pX zBg2eBcPmFr_T``cX!ZP;KJbAQ!})z8`!ENmy1KhGZ5OM|{M8z7E+k6{xnmJkxD+gey(Q9lgs{(>xHa6eG{dB?%zONm)5^B zAz=po|NREth_+t7;P2eSh2|#Hza_go{|{x<|LKN(P^9T53(EoZem@{@&_F&O24-(D zUMj>-w0Dd6=XAZov-VJ*!kWVht#hWVGsJVpNb2Ggbm;3V1xY{0=v7(_Mo5ZWw;h!n z!pZW;==$3`L|QM8>uC=eF?S$0RFa~UeXdB83|HL*{H8la2vpan1~OFT(T4+!=8Grx zaQ>@tKGD`VbYR|o%>;UTVxTKxPXEkq{;7&LHUCQRogF@6&#E>jr%i*FYUUZIDvz^F zl4)<&!8=n<&(oiK>(D2EyS(7aSD0;1ZQ;Q9UspxvDAjpmb}qdby^FEteJdl9nnQyk zxNSyxFs@jg79aZ(%y#wQ7D!=L9`ba%`xGNCmG;OMI)V9u+2 zh``h3E6_Y|gIrxdALl=Y(OY%PKhf?%2P>?L{Ac~Ji_vnS8RHUU4_?dxxeTTG^}y_@ zl5P`L)FNH^BdPsRn>4xln5{*3B*pUr{zxn{gt@%R^^8z!ULd}AzPQR_@ae-0k`A61 z(Ixq5`&+rC)R#Fge5VuvC6UNBBD|@lG~SIGreq;5-)?mP&vkU>^%vs38qWF+?S8S^vD$RHnofc}(`KdLZ>&Dpk$tFQ z+&gJpC1zHK^fCsXk?tx6N-z}Plo6wqg&m}(4@#=g-INqAAV5qgceQHAY8=}qT}eda zQ_4}UYI^w7GhFge%7m{b%T$V)i6C&KlE1X8OgJ-axk@U(cUma!v2oLw&%S7yPu&;t zs!a3awnvW=S~7W-#$W_uRs>UY?>%-hzAG4p zFzG&Z9Ou|ynUkb8y|uG*V)=k%kD>GX!p#)L3g)3Ygwea9TGL+Mk=(gQUZK;cdAWQ~ zosHBlXc(T`4!kK;AFnV`dj3|%pQpN|r9aVBe?|r~(^NIBc1dL9TXgf7Q7QGvljUI( zW7DZ$cE+CSM_7a^ZSY=<7WPK!&gl-N^h|s}iz$`0R;YkQ3kK^E*WDG|AWk@y7<|YI zWYmx;j(5LHErs2267V?Vve298=`w|_CFf{0Gck24?Y8h4Zq}QvC&Nfi99>yxQ+PFr zkPT`v%f{RZC>i6nfNMr%OHLv?~%p8GYzwCcw>sdeW~EcY~D`nRkX_?eC)IZ^U50eJdcWk%i`j z|Gv?X-VJkGzf6je8js5(`9epb^-~Rc&)uVzaj)UdjFe0G6vj?2L|a_O{o9p&k=I+y zGv56AUD0E06W<{{k>IJT^`R6#aDml)p9H0_2IiE)MFC{kDKYg0$UH0~yC_z|X3;CK%uROmM)=Tc05(4vC;aO$gI~9jQ!S(<`}S z>60gFu=&(`=Tb9|qnvuLa1^?xrO?*$z3TeQ>1Pm9JVv{og{Chf%rCMg@d7;xrum-Q z8{t2Y!4Ho1d>Ug+_ihzO^=D_gQ_mXNcHwA^tJI-21HxCRN?UXIf$ePT0XuB|G3%O? z-19|63IkDQIz$ z9MHjJ&Kr;4SNLTNk>-8-yxqh-gYHhwJ&Mgn9)Sxrj1%mJm8tFP3Xi;#xtBoSV)!=$ zc_o4VX1m@AC#@-NV0U@E47z@{xtb~qlM&2OyQK5L_D_FVet`26A;TT>Ib}BHH^Gso zSE1g+K5c~0rsc|i^Z}^}0&cAPtzmSxd;Bb)2+S_xC5h%iY63?c#m^-mtG9V~j+o%< zrWQl#A}6J@kMi!Kq2_Z#`N)U+o(cGenEvY^dKfF+!A!pX%vj4qQe_Bce)7Sde*yEv z3wm02s&&sB9CJ>UDB4ba6zT6S*-eAZW@0XT3Af|tSGoJGG8a!`IFtdC*33+2t0Y%p z9?{)4pz?gR6|u6t43^np#3&zuTNl{jZG~Ok9QtIAQc}C=emcD8Bw3{LNQXvBIoOwD zW=3E=;r{W@f2^W<5}VipKPY3zYLss9_#NIUC6D=0LhZ<%*dhbQ31ZSt!O? zfb>0PDj%!$8krjqFVF077y2}e7d@nTP^cyQGPQSa;@V_aRqPXgIdh#^UxTCjZ({fQ z6+>y8Y(T7x`z6+bZ07gJ0dLZ8wi*7rdGFNMH!Ob~0XHc}4|&4X zh(PmvOvlE^la(seNtb;9P^;4R<}~=n+8c89?W2;;3|r-dmc_V_tdV}naN-}hF0wT$ zEO{^Jx`B;B^p*+v1A*IJgG%!E^j2sd2(7JUi)g3$JuI5G!>NmrORp&JLNGWX3My?~ zf@9~E7^IJo88Q9cwv4Fl`QU*sEXUnnnUAScsM(9Oi(dyH$SwFi-E~qE%vT?f8gK`e z73VY;7fY0`?@WVBP2v3$c_!tQnFHrR#N@%~4?6d-ChPkPf#$iosaLhE)m0WaDAQ?; z*xUJ47G}lZnKyYlw9NZy#_AVhtmESRU{`hVZMK1_v{i2I^~KFs){UaGE2i9Cd>_YC zsMk+!9%me8X--Q;1J$S;ng>2{cBRm!6db?&!5S-(+_!+2nhQ$eM{snXyD8r`a_-~1 zBlV6e89UvWPfuEeS^^WyjAm?NtR$m40K4q1tM4lP zBT*E`=lNbR0WgI>ssvgsLmUC+&{iKL3pH>>;(Oa`V)Pf}GeFz=k{ z56X$h#hzu;SF+m5T>2sS(iB_mS!rsx5tz)6z zyYhV^do`&+ce2yDi39Q1l5@j3w(k~*0bR!i6Zsy^=u^$3s$9EEkhUyV&_D?}+HSPVe#-^E(*Qd%AoIJ^XN++{p(kZ+GkR{imWY;mBOQ9mhSv zP%WdvIn7*^csA+Ye8m#x6VI90SbHZh)_nO z7v)5@lN>}Fj1@^1s5L0q2q5Z_z7R;l6u)}^v5m-E%Y=M^Pfeg)xHhO{N0i7hE!V*v zqa@^i3)M)G@CfwF*0Iq1mJ0CX)7EK4h+i>nB$;pKobR0T{mJvhL>buhpuE0KWJ9MN9?B);*>Qu{ zw*!Z=BMSC+w~v|4G+93Eos*3%w`5$eBK-4@THWlA1c1UKiV6wVO|=i=N4WF^T&T!A z6X?!9lhe&l(kv!ovv;NOpvlDu46#keW^|o?PW#(LHN7Rj@>;d{)E8I1g}Ztt-lew^ zq2PXRzIH~q?sz4>p%HXu(m(kA6!e}&Wi;dCnhZ_P@f!r0uIzTo+IhfM=c1Dvg2<|& z_MEF?*{^ZrPTzrPzjjI14qGeg{r!{GBvH#!@P^VA_?Ma`(T?vxV#IdC+M_>(YK|Uw z25QJ})FEgwcvib`D?m~|6yY8yBsLz$3bTy}3!$(NbXN7qVwIj)lUHT02nW!MU#vKX zjtNKS4JPE>NVav3@*NH=wwl=gp@&8F|( zl9|kQ&bgV_6C^>*KR!$-ZW6r=G`pvdEV+AZBlvni1pRLG=*GbH7T319D<`kBqwCC@HbHtScGV|TTs_; zI@zFb2_eDDotOE$qxqHgXKL}x3${80S>$BS-h{ew&=pFlFQYQ6Zfk(Kr^(A}bTPFi z=Y5nMM^9ZK=WUd8=X38>b3aAgmI6f5fK@K%x-4ec;n^wTCEqSmRe{;)!iP6^BZ|fRIg~)65pgI!TwTp0 zo5}uxpEs!`WBd_o?B#^vJ+$pv>s_uv*03gwU-5x7Q;ucYaw3PdQP&zK|=FC+O4UD?NFf$G_%1d)blh!EW7_HG*{v}h8rH_nUpkCh zd=(@04~LdXMwFO(;H^pLh#$#<+DO%JbZpFP8?)P&c0u-kRTyo(+W6nGgE#>Pt4G3# zW*$4O{gzXlp7VVV;j3`jTO%Pb{exV_T*&y{GaLSW*G(s<)$|k7fot{Fh4P$id(vt^ zul4W1Ut}kJ-ojoUujmEjbzMyv9%^>Eb;pFG26`s4r$RvM$3En_H>6!>qWz@p_1TI# z4}qMDtph*ZeMV#}Y)Txm{(6Ly!gQv;mpV=t{>Dc5VAHx}Dqbx0)q6LC1X|^ojrm|5 zFlfsQQ{69mnb`KgSje)_!CG`QKhy%g))hfd%6akfh-~!^vnE%WH_f1^6CnHndcK8& z^$EAaBm0*Qc^B6fruJ<_@XvolvVFd5{99#CL)m0G#teD=-)XG>*Nnse+u+=P9~b<; z#wq>}Zfe(}>+Wp3NRhIKn70dIFsaT*ljyEE zOurp`ott0(qkuqmPpgQL6PHNKaH`)O=9uNBPRWb~-vD1T=`4_e`l4+<&3IU3Js|N) zG8vDQ)iOX4%(DAhjK23JmUAvlR|+O484QjYckknpD$4#4K2Di6Pi|))vlg-x_(;7| zWRU}vAG1v7w9y#e;J@5L_frSTfhBYJvzbp>b7p^#{*@lyxjW7 zP28g&Txp@hH-Z9&{L(y@G|?O`cTA-K9V6G!n{*3@MbZ(82v#8OOV^2+jBysP{e|W8 z;7h7(CmpJ%!@%k55s!`*?)x1>d;(4zSpDAxm)5EcmM`4ttO*(ShfgrQLWh5h?;7qEF=vFMP|zBx;dNp7_-S{mPek*ct?LoCXRXo(}G|+5Q7U`QaUs zA^C+W#8cv#F2b4{As~sr`1AQ{-2vXBHxj|P;OqDb$4vV0)NVe$h+tbe;rA!j8uq#2 z`@Mx>wG^r6DbregUtL_+!b;`pwWb?Z35*36R}0ZD|H0mTrd67rG1!ZVz_5AY8>1s6 zD)8LktNm9izd*OHJ>=Uu+?Jw`1OR0>DdEs`sYV@cvo(*)DY|-zRb85=3&IsdLY;xI~rxXm?G7QGk9t_LCMDRHuQchIF2%) zP)yOpb{C1!L|f11aXIUWHv6=le$AZ#_+OyR)uzJgYag^%Z{`^D*E|K z>RFlS< z(yPm?);%z2)ATk{yE1vck=*k2@j!3f7>5Hih{|k#T(47xTf#G_m`g|!#&a03F;=3@CVokkf($fr;ii9WLyY!vRZWXAVD*N)HADnbexug{MfV)29`_|lGD zZF*!@t+RTO842pQa|zm0b7#()Jj((;-F}H(`BpvwJELhdNAla{{C=<`H4!qYW!cfH z?{evJNDggJH;WHN1)wI4^cbV7Yyup5zz(RbR8=Qw2mlbgj>AupODA~)pu8%uQ~dZw z7|q?Rw^6vn=kMb99EpIfe_ z6q^rtHf@L&?|u^s?42R=;f7!R)M12KYvD06V%>U^4-vHO@!LQ7iX^0cKc{O1@<2ZJ z@Rx;}Q-msV@hq2cQT;ApMY6EWntYLx%qA+`!rTZF2R&6ipZ^w`cdpu|k}olJ_2J6? zZbzFQgOa041MAmV4|z<@tLI13bX^NL*}f96?<~#C!puu}6njx7e`Zi^k^BoaCbah~ zQ2FUtKQS)M?y)7Dni>)w2edw76(kr?2VSsk0(|hD^?n3{p{)~4C&gF-ZcKMR-ep!a z9Sk9lwNXpdEpwOc)5;!BgGu++EVt~2mZzKFoA@`{C}|VL@Vy^fO4HmuxkPUr8{XC2 zP#sCxkw@6^>(LUhN$rGWTf)%LHnZlmsd?hMv)e&_Is=zr40%Q_;{IWum^bgo30QS( ze)I1h=amxo#%KpEjVq=K&|rfGt<{th__R1f-K~9@;{v^2EWg?FBmz|G4>;x?tXT8t zqWtTi1#5C($lrQ0XexBG1HImL;D};E?jB*%*H`O*pD5u247PloK`jMoM!eJO?OF-2 z2bu7T4sB*i_4xB#e`~p8);u%U_NhjVA`QeRdnNs#n9xM^PYxVuu=_taaG*1buKx^u ztErur9cCtd=<&T`#(0iNTWh4ay5iJEA!EpL>9ON0%yjQgT_r0q-Z>KK0v8sWX+87h za+bsLG)K#PFk^pveq(WpfxPe52hJd$EU6z;a1Vj6GWFwMS zch?jiX8i3cc(g~?6SJf`*?A6TKqtVdi8jydefclsWB7+-xbgv18XF0ecXaf2C^~nD zVKoDlD((`(&soC{o^+TV@xLxUQr`ji9)9M#+iZQY> zbhbTE>*>H;bqLg-YOa{CwI;CW3yiHis>!8Hcl;-ftt9kuT0Ys(`j795zmsdvDyxaK z)nLc-1vX?xki8T&2zPAKl1uE1hU8yDUQJYPPDS~IuFNa`J;uF5=jJLGY5x_p))|rY zW2AU@H*RX1z!|dG5nUlt;Pa)YWPWG6we|OAV*0S3to=-4{6YI;^w2b!W~1uJ(7n^-Ce**X!{o{SF<4BVy!A8^O+! ze%$4nV+svy8c+PW*yB*kKLuuuy){sSeShC^thw=&Smbyc<!o9yeD2}@_Incp=_SxXD;Wr?qH)eZti0_&|VFsoN!%?LxctiM9UmC zI#fP%DfIaAo{?VB#K4|EdD?Xc$d^Grvp99!!Kg!+RwEKU4^^%*TrA#GL2G#2v}0s7 zP^B+~l{%t3L}Rqe@0?FeYtuawDX>o_CDmikL?}DEE$-jqSZFur?EH2|c_;>^>NEj8s^IAMAWfhv1@0xI)f4>6&)0@kkqxz4ilnvu27?bHvMX4< zfvd1@EQWW30<(Epqdo_1I&Urqp+-GEo4oc^fWYrad>?aIf6D!*d`24D`_PTuh?J3F zCmrkr^tSHBmh9cABC_-MoGbo>{Z&T#(h5ECSa1T|crC_IU8GV`DGw zNV*%tJTRNHv8e^@$P`CDu%F+}Y;+MDX36jNmRFw7@g+SgtKb>D>#GV=M4owwLalAv z=05d5=ge7(T?ATAn&pq?thLv*RA-YxfK@y(bPcsC!RMq3AH^ZRG6x3Pwak`3gm>s< zxS8L=u~{mW%KcLW%&@ene!KCO^+7vLU~su(NTb*yeJ&^SkGXTvj1)DGfr2fC(J0t% zA9QMsEBNaQmDzGDBVsLzI_RT&6oph2z`*Q>NPHH7ezDr&=1`nhGj^^^nO39?rGjfV z?!29u`z~2OR*gt52+l9zf>C7G%{e?`+2`S~_U7#UtH8y{%~ZZzqK!+`6N^g@%{ECk zC#k&7C8Z|Lylh->|JE#w>v-^_APojf($Bl}V9U=V)p;J3j|}V%uc%6qtQDoToP5_X zEYts%T^`ur6TTrkiAjEs8Igs{)NJkWCP3#w076=Lvep1B#?H zj3ME*-zV2cT>RMiK4oo@P#6Ycw_wU$3is~47KVbCX!?dpnqtLs@O(Pj>>h4v23hZk zNoV6#OT*tjfJ7~Yv?7Hhed+b>(fMOC!A#MF;LC?QmEB&p){dI|=tv_soiWj8hSkM3 z?~uI&yX}$A&qD7zBbQyZWA>ywm8(kkpz59*e{fqA5~KO#!sOy;@w zZuo>D!%y1R+MVKUkoxPz-$h0FVzffsQd{+NuEP?~6LT|`E#pUz#eF?ng=qLi=@AnTZ0+f7C?#V0(tY7M?-&oBVU9ln=xu=E-FvejyzX$R=uL z7qdG`AH%;D6LB0l!HP~=r|+ojBO15=O#=~kDE~j#tOvcq7X1tB{|_Mq?SChPaAmgc z6qZVxAj~dAo^l>F0zMJ*Jb-?UxX3jpz~M-^o~snf%1)v71Gmn8E5m$ptHD8=*BnS) z$z9cx%p5ep3{iZrZX&;beon6`@BsxWGq8bzh*n;tF&&V8jCy-mwQ}^ACNmMQ!Q_R; zYx?Bz76nyf3LtD70M^78Z1 zTqUM|z(e-yyhLZG-G%kk<3ADu(cHc3Ps=k8d58)@9xOe$JMlf9^1M1*Xmj~)ljCeO zRNN3=E>^eSd$K)%#!b-&OO9*3S}Ew0p^M1E{&~>G#d?qFo)(pYZmfPtvRp~`{j;{Q z!7Qy8+?zWd;w`!`B+F)GWXK#vrtH7M3s*!M9MYYQPD)`| z=OfjLt99nuv-Pi$S`Ks?X0Np3E3GhdO7Vu%L#*lSfyEqVS3?Pol&bFYfmClX?y?Z% zr~Q{ihNkx(e_ClKI%zWW(7x7&`=q{Xh7P4#+5|jqdRJ}_B zoS^2tB2!W0KT$mIL@|BrsVs1H-Vq4^d$xBUXFr#FKQh-RPaZ?{lDnvUPv9%^^xnGK z_N*bb?Na*_U6>@Y%2(&8Y+7BnGV$)}w^10n{obttmHVdhAp$r`Q(dFEDj=CAuz^~tXsvIB%V`lJadrmM#1r6uQH{I_ z^@%q80yG_cfjbM^9NQPc`>#o$%5l^dg>3GfoUJ>gLmqfH#~%pz%&3)@R0SW{9mIKt z=~X%RM`-vxo8miWHc8fuiEZjEdpz)rBikN~4@TJ}HVuq{53OmP z7kPVe$z`K#$iYw64XwKwOYY^z%y%0?7gnMyzRm+#HOmoDa-T5h9aYoU3M*W93OyK%l<8LIvgiZJcAqmKtXA zKW!yv@#3$Oxn$?JmczA=g;>42UX6tt4ZvLXKN*;`Cl3#vBEqmS+gntG(goS0lS0Nm z8k6NwKgOU;XxJRCPr2rwrS^0rn}yO%{ky4x^y4(Pq^RKve?|v@{J7P%CmlTb`()xg zjjxum!}}4owt>Ts=kx!?$FY(z=OBx1gR>{&8fp*}>!XHbX3De7Y^(o?LLx02r_^w~ z8M^ph9MLc`jtsy}Nly5$mT^Ri%T0rFc@kx^LcUL*lt1Dzi?z)o@i{$ey?tI}+Qw{~ zayF@hGhAcAB{9k17LVlBff^d|OKIesmL6yum&_g|P#3&Zry_mwf}ierKaKNFjacxL z^{Jm|Uq2Ud-VeA3M#l)~lw7vlVEYK#80iH_HAiX7i2CsvBCLhGC><`wiayb-7;lx0 zN@ z^~&Yw)m(CC;)mq=t(i#gT(o=dOAM>2m{VmPy2%R42qxVvjZiJYY*sKc(UnPDUjS)T zi->|DfsSXZm)SBMHsvmvB_A&f;_9%^LzaFL-r?@rkPRVDm?owZA`mwPpddv#Z_Hty z_|@TQ8EethjVi1=6m8@8^3;bLh;Glm`Iq$ovc8*=>%fIbit(g=ZsuauX;*DJK$GH= zFE$rJO#>SXVl&T-rW?LYyMdJi`Wjk23#O45>e{6$dR}~<>qQq5811Z*KtN zpEV}kJ;~~~_Qh_t${Lqdy6+aa;%q_X*x4T{n_Jd{oeSq@jrR;qNM1X7 zYTIek+~CBt+#A4Hk(VEQ>fudw>`CG2iJ}_shFNp1rI;;31sk&TtfKVW6=lnp-k(%1 ztHdK2n+=oZI%kIl^Q>j`3Oh7cw z$%OFqI=Xc%X-81)sOdtD42rXVz}p84!e4cvVobn#2(I_$L23-BF|EGPLk0dAbQV}H z*xw~~)Fht`8Xz4#hds*%J=r3%b%;ACpz!jno-exYRbLaW-s+GT7xMo01&b;>t-qHl zg(rQ1QYeGuki~P2&}9|WY|zG!cxVg#H6|isnDEhG^GZ+3LnJd^Nt(G)X<;EU#3bqb ze66OM)OZ(vMzt`_lHSiEkNt}T^hl(Jj^*5;S5U)P5 z#OM{KgvHuyZ}G@0aEO@}HmDy{;)v4i@(wt-w|i)Fp{>hq`Dc92U2M-sIGfSAx!n;S zDRIe325R*_x{f&5JQ7xe$X{g6bOg3>N))Fq%>T-BQ{Vtp^spvW8q$)%=rW^YCH zc&+TBLC$&?XDWC6((;KAXte)b6{PceEe^MZcokR{DHE$SVt~p@yuykSh@1J^`_!w=p)hehL&kpiFjM^(9_wh2uW+C_$BHf4mpw|H?QUY zqw-~f4Z91r0eIKdGP8AVG`8SEVpDg*sR2q*yAWjFpJy&)?j6OHI8TouR`%hL;Yq#{ z1D8qpP#2FeQD4RO@SaVn7;Io2<3Q6DNwB8Kj=laNf62#!*EE9PD)wf5?=4oykpOqd zMp9q3I=ek3jT;-|04`^ll1Wv)=DQLzFmFN0yE&JQr1TzRw`7>;wTQcyIB&p@$js>7 zsgn3Ia(5ok)r;35aY=DbhG1|MVE=3WfIH43$<5r3;ddlm6|tvGmfmCkG!bnS{L4gS z`O;(c#F}F^bYzW{PlXzMJ>-L&JwN7cZjM*e43T@wba;Pi{=}SnVqT92o0`6F{#3={ zFV{{47qs=q^xXnqhp9H_@?OK60Xquz(%$4b3ij5FD6aY~y ziauI0B15W+?DhLz=g4bw0Pp_1Mhcz|1xC4^3LohQZe=Hg+v;i{Wj-3d8*{~Vr&8Hf zy`4g{L(z4i5^lTY1SOH)mn}b1^CW(=7fDwBQRq5;gor5=*Upr~-Zo7ll*3ujl?@|+6Ox23p zMmbm%!DCSFZSQI>zU#d)lBOabg+ag^z0O*E3MGhzz@Eq}F45y8mhbu^yXQKamQrM` zv1a=VB#gkU>8T6-E`^W*We6$)GU{~}UL;;WTiXH`Q zC~5GZp)aVuKv~5@gq0=@(vvE;_h97}`Avz?IgERvvnJq1p?b2R00BDsr-umBOrK9< zt6WTL;Li=kv7#lxrQJY~AE#B`o;GPE?a2oHexNW%x|9etdLHFUZs*A&K&~1Gn^}_6 zsnTydubKUXnH04sy3lF0%n5z0^_-o!_`s}v{h3*I`P+$?J@bAe>~6#-)+FMFKhwH} zQdBmY)^2np#OreHK8wh?nQgnHO}-uW7AC$kRU#TSG@Ms`{mn+qHDm_{cLjf62^o)m z3(Km}WjQt&6hvSEscrV-Oi)nW(c-G?gfuy2rItP+9(@rClni#t5&ujnha+I8quf<+ zx1(zKS_P<9=Ldcp5E^YBT`@rV5IPZgc+_)+J8QpJZ8GhK%#26A@?M=Tg+%#;u=xv> zWmf*sD2lVF-la!cEP-^SnsYr4{P~myE$F(xw?BhJLonKomBP&q4Pb*@{`7rLxmAid zp3uF{c|5&&?%tCyKBz}0u|PRihf^#2%Il9u?J-yaS(;%0u~omEONuLl((`)qyMkI^3&#yVWuf&`JRB^?HDd z6Ln!Qo+HMSnkGlZUZ&rGWY^bq=me!RhH`Hv~nnwb*%d zxMSs4rZd;((oeqonU3*WJL4-h&T}Alpn?>w=b$MB%&D!pBf7Q$cw@%!xh0rjkvkp& zp0$6sro^-+Y*WRx&$yWk5_1`=AX)NxT*At-R8s{;aAh8oi9e;b{Y>xfQhBoR8{oD! zSEzV#KK-EoE~m_+X8F*rP zZlf1cJp9bLx8n6!Gb7qWCA(GACgL|7zqj{H`>E<=3Za1HySK-iJLI%i0YofSx#dBv z>^Xg@6M;Mzz2A!XQ0cL$V6fN8Hcg()IUZeXRGLrMHHSh~%XY--FS~jycf>{u?v_v6 z!Pu5-WIiG`tx7U`BC`D6tBq5QP}AVL%PzySj)!OzPn;{H(Wn1SuE&%4zKwcBBWtB2 z*H`gr<~2!8u#@ErCVU%v`a znAI&=E)>i7+lm4<8E4klM?DF?vn^lBsi-?z8OKW- zzdnb2q<0CfL9R(P(Aqyn+#^hD*42T}T(ed`^*ogw-bt9BTr<*Lsv{B+NHEIxhF1$x zPkyNsH!Q5=b?1lx35uaZT-`($2?d8nN}BOpGJ*(Hd`sf$b1a#8=Y}z{mS3zVK>MQn z(s?|<)f15 zp%G!%xOPn0)$76+=C8`R&)J7lPngF(cW@v_@0(#gstPO@Ue+KOeuc&DAsv5u^ICWS zLr;HBb}0?4ZM0lsF>fs#&{BjMFoTY_-T#?{Fe#-vnYL(no0aot@zwU`vv0T?Kn&2P zjb*XYj?7mr z5AwU*P+VB#3Q+&LlG^w_(8%k^t2L*&0YTzd*Gj^>0qPDOUO%THU7^B`O=~}M`b9QE zCLO_bi@pjjwWf}D@;1d7!L<=_NG>%A8*S+L94ne92fpz*Jk0e#l2uOz?teYrLY&Td zalCNRL<>d5B|w*9zn>1*b={o{{c%U%M(>cH4S#={;nz}Yz2B!&8Bc=B*TA(Yr7s%ZGHEyX+Y-#z%kMx! zh90=TIy47yX01+t&_>kC_VkF!+rW-@9Xa0E*xP`+$6ndX7Y=!6E^*5n&tEv+mfreT zeUhm3?yZcCi_VTa(C^&(&WrGuJL%41}#vwvgc>bM7kK+lu?e;VDhB8>bOKcvuuN${C~Fi`4z?}+_|8LcESF*|!EW84 zP?$S-qXK?D1KUA!xwT?GUv)82lOxvN<+fdaO27;~K@Z?ze%z+!{SMISM}xvqmicIz zwYK4sz1tl}|AzjvX)F=hTl%oHuLNq}*9)Xmjx;}ncpYaMBva;>$@c6}eloyidxB%L- zCN?E|>1(C^-uMWS#OKX{D%s;;aq-Ofs?oD`pa+oNaJ#NqEKekI@5^lTmbLu1jO)_x z(kzZNhzn4xI8Rq9%)o%}$1#xUfh;HYcHn?cE(p#OK~gi~JJ4d=L~d}}Xri_)6g6+t zvTjjX1&z`c^Zq7xt4({6O-sI3Lr15`tILgga|YJ${MH7utLCM>f(IqtYBW@XqjCgW zhuf8h)(mw&;>{(M;H@pzv94gorg*C#f^4&$(mEZ+HwU{WGB;$Fj7WB6#W@qpMgADm zZZZ%7Hc_m8MUPmS$d*&0Z(R9z2fB3 z>ETV%Ev{peV@A%~z-Ae4eHeXb_EV63uT{VTYRxf-3K+L6+4M=UqScWu~=w9uI;_X0r{IUhL2 zbWzKl&@#9H3ZCWQV_Ax!rtoV2G7(A;!1hWpaq(p0q2{0$+ zo;`Le!6-}hsn;E1Xku!j_U~^tD@{*QHU5QJ3Nxi7QGH?h!NwzGPg+)*X@Bh%WKYHr zK(p%U#-ORpY?xUc>#R#}C;jTF6~PI|ruchJoj^yifh4rf% z^dygWfAD9sYRYcnVeL@sobS{ok)0gM?C#j^e0;2Voo`UTXv;I(zNbAsVR_`?@CeQ? zD3Q(ok&x2UhTY-A3c8w<>{$EU94W8F@@9eOh0(K+=zNEFX3WaHpf2I;@(T=hls=g4 zcR_6{YE$JB^g@l*s|U}{P|IC~yWf{7pvuA4zQ z#*`T^Oap_a#PJkD>#3l=EB##z+Ja--)vuYN2)D0uo#a~kc&3yDn@Y^7Q!dr8?I4=j z@Sh$6pF7z3=uwxdw#@#n5AW2r*;P#A(-ZPo*dQMzkr`AC13NJ6$kGzZ|GG6mUUuR@ z+2`n@&`^C>6Y6Y1JcWqRIHr4wcB!q{Pfv>4I@;d4OnKb~@zgduC_6Eh^tt5q0OGLW z%k5nb#+<{r{Uht`>C)Jt7`?k!x>UOwO)j^x7u=tEW29*y3fsjv>%^466kk;_RVpmz zUS7BnHYEjaE+<Y{F~ph~+bBI=nmR{(yS(s+?y|A9 zaxvcyzdat^RVTCZL3OP%6DS33E)4%Vl9kznV>M(D#s$xLO{w9Li{37WV7754di2q+ z3v9{n;9j*b;e77v3ximKeT4kY?AD}q$j>?-3OCPn!`;(*6sPG#z|&2yyPs)^joQW7FPFIa&tq z2-fMojw{vs7}CTVbJWfxebMjk7wO5Fub7J2G>|??s(W7>H37T%SIld+C@@E?M;f?Q? zG^u1L61wIZahcCuG-G&~M&uiOyg#vtJw&nJ8-ZEyPWH1y?}$ele5{-8XV;3DFfcJM zYlfwKhcSk8pMeG3{DcV;q$qE*w~$AtDI`P$a)b#`z~@F|JBA#JyeEt3`cNbgG7I* zVgByy10}IscC)mYWFY<`6bIjm*IMLzYq6U(!9*LB?wuuutR>!X)&nu~j}B)lzneS{ z0(VK&yRIywj4@N==d882d$8BWpKVOU5SaUVLC0vXLX*6pk@@oHy04#ZBj()Dmj?0s$E1x; z4>3P@=jyDQv!iY(3XQD{5QH9)4OFt;xtYlkwc0DIx9Q@9C=^t?%WV~a(a;D4xwG&k z@j}2cN#s-XCxy)6zo;|75R%Tu6nNKfld${cgP)KH64IficA34QXAS%Q1_CettfZ~_ z&Z9S99*jjazxsjdYQK?zeW5Yd2p2V*@WzNJ1Eki$Xgi}`k|k)N?g?4HXn>@Cj1cJD z=VG9^Zl)CsFU-HM$p`O_*cCcgR^5e3`9oSW`oGF9#62p6Or<`Ep}-3T#cY?XBY&hT z1hmWEG+8o@Rpfh%fF`vMi-5ZKxqwWC82Z}|ZlWb`-7oKAT6IL*8@q3d=7meTuY%&n zN41)qt_}IIy|ZgO`&>SlykpQQAkLOeXHClghNwbz_(-AIR^8uwSi3n3W&lPusLg6E zoh99zT}P}1?sy-jH;1^!@- zNtQ`Q-tIPEPOaMth8KP8b$y%TzMIQ~1RsOk{(Mx0d-vJ?$t1!RwzPmxJm>tzx z(|J}*yg!-lqz!@Wo%%}L#dj6O-q-lJJp2VB8kK4ITg!15bn$0bReWF61Ou*(r2mZY zAAfEy|HE~NS5)+|_+Q;#yh3QAf7gGDb?<*~{b&{2!pL&5QrrU-v(_ zDL$PyAIvy%oT$?-y~IuO&ngR;^5KA$)O5p=z0w~WVcnd+%}{T<)gG~drbr*2JItpj zPmuf#+>aY9KSL9BP);M9h)w62Yl3ClOxfN>>I~(`yzX1VTS@LU*c@_>24t|=CS6vH z{V;y4ob?0cb0Ir-zpc3R_RbMavlS_w_0YAR!n1Qq?7~w5(tcRU*mmE`E2CRHV$&z> z)6GJcF{Qf+s6Ll|e;@v>>_1yQhh6E2+Mj7Zr=zcSvVK|W6YQt#taPKF!>y32n8Kjb zv^$*1mW|LntA}0=l-eFEI*Nc86-H={2<(hS?ySeIb4oBD>a|E#sWB>$E;tUL;?B>G z7y*{da7Cd5QYC4Hd(y{)f1eF!F)C)LImE3e<<{LL%{;&|_(V&cUtUWB?<3zNuOXeE z9!t8OhulBy;E!7IO&Ive9Rw=`k@3-=bg)^gkBC_7$Z+YN;G~(DWxuh{vh2G{o)(Uz zo>V)w#V5zJMfj;)H1WOnI43xkpIwo(p8omv#`+v=c(+XN*`w*!rsu*4gMO5&HqLko z^2PB+JycIb047u<#H#3x3mlt&nJ;jA-z3y47qc*f^aUU5ig)CNYawZ?aC4x&Gd#ztc+Kf~Na?8{p;}0~3$VSOtbgT0z}Jc*ee4SsuUl#MNRM}!xA!<0 z-nQtP=Y8xk^lUzIHli7eL(H{@$Y^tojjidmx4jK64V#Ugg*72->+i0x>?y{=sK1ME z`$Z(SaRPS?1giZMo#%^5h(F4|0ViNyWW~!wNSE+kcu_Ilc6ul(=wAM!a&|709t!EL zF&rT}k_|UFMLpSwusLa(k=ptUC{C{RQ;gQ){qnf#kh#{g66?MkEn(sGR!tku7fGuF z+5XaLz9WL?U!h7*SMC#I=kl8E$~ED0$n)6dH_uqxORS$Lj%sui28ubCl14pT+nj6) zFf`VZ$sg?|U|fF~*K?=pdwy(msY}@}tv9=_*ZumoidT>IS2jq@_RKK2ElUYvFK{c3 ztwX#xl^1|ev5)R%tL%H?JWVnjF0Z+8t3gcvD#q~Wwa3p>UHfMy(G_|-lIXXi4~g?% z@5wZ3V{v2LraTmwlm%X&9^BGBor<>ITuL!Le)fwYr2ho-XIRz6zG7O6!d@VfC30XV zC-AD;Re9BY@uCj#yS?tQ|o|o&I-uA-~irPFJfoX02!q*1q@F8}HM2PzD z>R~aNFUa#*a&12d8SjVt=q2zj-qOB`!Rqi$n#bk-*!?EU{4k(HH{UM%ov0N9jkl^8 zvOyAWHHYtB7}?)+{kGNs1GvkSTK0vDDI8K44?8h{hl?&n<8&LXh+o4!S!8>M4&7l~ zN!^sgx);47?@$Q7%uHc@CbVTIW^;edwpFHbVYL)CjzZa5Ldwn+`SbIe)RC(q)7OH> zq~E#znN$0dPnzDjAR!P3AE5uf4V*w|i$p`D-&g9_U6fib#RqPTvMstUK16#Re|LTo zZG7LT0Ly4S#fiv;A0xT3%8wY~K*c`9XkV&G4Q1J(E5Up@2^|M-+@q%a>T3bgd%s7n zTG;qYyfCfz5F~~jsu6ynJlRyg|7HiomEMnHBj+tV?b!Ck_?3!cdbi5MuKJzEOJ>hV z*R(0=A)I`>pN}jDj^Grpd2m`?gINr9>zluvOBjgr{L9_&YwJgaU>K;kOvt!KUkt?r z2>1j&{k1&Rz!)Xu_k)uJ^hsi}CeXU&;w+mpOX9YXDDI2#vxq$U8raZh!}aJC`uy#A zQ~*o)$o~0H%81#r?eX z|Ci8uPv!{&r?DpfdG2B*tka~P^IOYQL}vwWbs4GjIsqw*aLP0ydZN3WB+v(FW$&QG z=ZfJ;dC`TkwL^mpGowdI*6nWY18VGUaZk=T;xiJ4flw{eo9+VWSQf8za0%v`#=5?= z@tPgAJmh4+CGzDJU3SMq4$ALjD#RA_jjb3lkVr%8;O+BGNf#efGM%wAdC2m$^IQa@ z@RT#XU1tlLe5>C#ctkv;MM!7-T`0-s zw><^RE#@!o%jsIJea!(TRZcSfMxR9EpWQb>FXO~~NIN&37%_PKtdZXw>3f0S&FGb1owr_L6fNO&4L}{D@jEoBiBFxmE!nl(HU@zP>wWD_O z39h%jf4si#TO;I%KW3GAHheuwe_sFO%B{}i+Z3a<)!#R-&8_#xWv3~wQy!h*4+>s@ zDp}=6)En0!aV^&9%CiNw7d(t4eNzk9Mvp@{9;u@0_T1H=X+Agn&%wOW2e|YmEz1sk zXJ0q+%^MiVM@}TprS<4?v03TOk(88bt{Kr@1}w9u&iEX zaBe0gj7D4iN>v7@JxojOK>G{4by2iGF2?lPvZob0Z+PExV#6nyq4;0ay?0bo?YAzfq7>=UJA#5p?;R8s zq@yCe_gXkTj34x%M=;(-#mWwdS7(d1qm5mzyhS$f*HjD5xuQfpHlNdx10!?D zoAclmCh~!nAS;sev^OJif~G(3(SX;bO((izKaLx*+{FGky^qIsdPI#8Z^GoeT~3qn z_=L-G;oww;w53JBlSm-Za?N{Z0Y2w@dD^eFSpwq2oS2mAT$L52EEm~xl98&toERC{R+#1cG3Eb&Jy_GdM>(k>VYBqb^!bvX zzu5G_!1!MdEwFg6387II!~1@IE@FNkRKapu7H|8wGoxb#YTma={VI3-?(^FO)eUvh z`;re{4{-qo=Q1=A0Iv}2y6a?~t^1Y_oo)pES7fs;?|=H^-Mr>_zmWVGNjNqYwYGnR zSHDQwJ)xMXq$7L@G2c7{?(S$Dd-5b%AaqskUil?Ay9S@I`CHLTK9!*RvxSdiv-SV( z*;!*!{tHWC0Mgo<|Nn@iLCYQc{a~f9;f>tl7*~M2v*|w>Q;CA(`eG zh5592(;+MjcS&!Q=1H;s2JSkSf4VHHulOHt6!WEA{f)4H{Zs=F>wAeF_UKPbjlV!Q z22y9d{?R1-HwVj_-Tz$(_&+Mhcg&{;2qb;SP6%11=IGxO5SVKJyZQ>}v4`BR|U!na9bTOG= zTI<5r%f84ipXMHwt!+gj%qija$7HZjd^;||MT!RpQ#&F4@@ne4)lyX#oLa2h_TkCYhNP$K zMk*PkAdu}ewfc)|tUGJ-3%WERhZpCY-WfK_f6PTbU8|x3MJBg!dfC|@xaH$_&!R6cca%JuzhVzf@!v%pEZ?V=~Rml6o;VnT-P0S>r z<{4hjbqj!gKH>As|Dc3&Y4b$xcM)ABv2;%qTl06(Jc(f%F;kNEUTC?0VED1%)pIb2^S-ZfODwZKg-yIjBO}4v+q2$J8H(NZOxI(Z{7K{r^vk!<-xTk z!ckxOwD>HefI==kq>aHayf~pNotM|r{%3I1JIXPl-A6qAcXVFQRwumZEy)<>*BG}L z@*^t9f#5gfa7y19*Od++axJ7B+LF}0IhK21|LRvu=63>i*M}{*jgvL`b$em=+MbL1&yyAh!%_&fLM;&so=Zbu~ z>-=N;X<_)xuF8O;1)`9Ui$%~SDz^O(ZI z`oI$iL%#y;-sGQ7PTfx09NPbgB^#*z7ejR2R3XV@lS36s< zB1uz6eeJ)(=PzF>m5kk!OKv%T2#NOjFv?2Wz$ppeM_{=wV1x_Mc{i_>qfrpQX_4v5Fzl30_*lN z-r=6VFSsIMw++=SEkX`)3)Q_E(wxdHepQ!jlnpI8TpghDSzjIhjPUuggXqG5>c|3H z^DWI5_YGmQzFXPskSDHme;Ev56|i4WZoYtyR`FWW&h>@vh?r>lffr+si@sah;`S>< zVQ2BRjlB`cnYt&BPvQ({f7QKa-F@Gk-D8BwY9~TFwc^Nv<|MhhHj%0PK!tEy=n#%w zH+Ded;)lg@&;VOLmu~XN8!3?i8o&7q#A(W*(T-hgk1CDZylkKhp+&L>6B>e zGvCiL6Nw6}PSwsI{1kj^B!C0a8h6V2&qxQ;R3PYZ^1e0-pmaj<(^V<7v#9;ihv4Nr~GwUD3mH)|EFHBCa z0Ap{&Z#v^Ja6`=HB9xW74BYyUq}*G!e;KJO#P$g1xN+})Z>0SGfk|>zo*FU>6+7B@ z%+{9v#yEfe$O2){opb!ClqE{lzfR1SwV=>XBvby7G3!^3a~PZ402_zO=@qJ{>z(qB4;;V?BY zFmQ2mgX?*DVKgU^ntm+=Q$zeh&s${b|PA_JmjX80^6`YFp@>=_};ZMNl_ohX`v%zwgK{?Aan|H(}F_Ls!-E73ee32MSg zG%+^=9|U`SxyUR>i$f}6K@<9+bdB25BkDYB^JPwt>C55y;F9dfO{Ts^-@9i{XZfBj zd_6$J(T2ZHJh1X(;?H_BhcCZKQ~MOj4)-{e9xj2DNBCQHnu3Lj5+^QV!(~0sVvnw& zOovxHC*INsmv&yRbls|DKCK=82QoKNYhYpAYf;JC)H)+j?+zNKqW5a!F;l3=ADSqZ zL_IjsXFc$8LRm2tTBz6A!rrReiUV3Bve)F*wg{s`AL8H@1)Rmk)qApy8)f$IP9yJO zffu|+IV(vQ7S3=Z8$+K#Be)~M@gCPWDt;bpv`X}TRgkD!pm*2DPfEcbH5ri_s(Z5i&fS(tE=T_3+(IM%8*^D^ z@o~WJ+T;nfU_DdjZ0Kmg8|E|G&|igU<>oq3-uhZEQltbr*)|+uFl`1J@XNBKS`fR{ zAZ{$!T7%@jeTH4uxgF1|tsruIRRH*0gS%3D^<2n)F`?IJzVG`DW*)Q1v5q;=4vKH; zKgVC&Dw+7)u+wJh2?>}obMyQPn!&X{L6-mEEd(?hEq}PMz}&U z`ZG(mZjSaf#4>3takU$Z!D^T@X!DfG={rWYp3oea`mH=P0t$2~{y$?4ep`5oGi zh8OThPJ5c3JlM|DwEZLd*TIF&oN^`lVaVD0)OZ*#&ku}FfqL!r9#3M6Sb9F{I5{>X zY8C#}eu=83pB~aTe=GLJlH0A(JJ}ERwqkGN428DTGix<5SO?UW7%8mu;o$M*9-^vK zo4usaYLxM!;K3BE{KDEJVU{6|-D$rlfiiKa@+d$68zpYNF42M6@D6L(qHs*gD=fSr zaF|FhCeQA^vNz;!x;WJ7kcJdOL!V@AJuayqp6g4&5s^bNA1-(_-~5s=;&GvC3jR7t z<};Kpo({76s;v^a3AKKT8BU97*u>^cLLw^Fiz<_X9b@8}17s<2NVn!P-hRy)Ma`t~ zqu~`bNs%!6t8J{jfcG!66=bat)n1At{ZzWO^j5He!d+?0wW3$VZ*y`RIaFyaOa4l$ zHrPGgi_oyY!LH5xWB^&OcCvg_?#StH_;In8q^V}}NviUh7C}J3<0IHgxUo>i)Z|Bc zeEW5t!Sku}N@smq+XHz)$x$U9?3<>RzNQ_KFXgt}OuW?c1*8TB0XDM76iKDC&pJdE zcNde}LJAp~GLEry)5Z*D$57L~|6bLu7&Os+H?$2QBd2_e0{JeYsin0)JUPC7#T zpzJYVRW3xRiA1bK^*Y~})e33d#Y-ozVN@;=urbn{m`ACFUX;SDbq5w@wpVJ=3QKPr zLr(?KwR#D_s=sj2~3wr|uw`(XhlWuj_d4^M?m-6IlbfT}j8y_MU4T99DEW zM6jE#zRf!?_PXr%Mu(yj)=8^mvJ55TFPxy*l!#jA^J{22W@PTG`L8U5f2?JpSfUV# zo#nXoqRG9v^y(@cj`ZrB7SS)}mg6DZ_nh#-%+P5JgtfYWmPP|FFlu52Oo$tdE1U7G zzJVp}Qm3!%@(*8Tb*_VbThv#<-RIiPQ$7JdmTWg}IqZjUm)MW!G z`i3h$NOa1V7JdBLv%_zolfSbaGiuYdY1_6;tGXlVaCPN%E9yLI3GOs}SO$$MU6mgl zrZXt7VBJ5~Unpy;B8IrzzcOj@t&V97?eW18v*)~AzSTf|NPM6S)rvlJcA+{CS!?0{ z89{7H?3w4011nhkN%p;Neea7o>yDfe84yR?dEf7p^i$NAoo&_Y!*%bbj#SoA@eC~N zoH+ZFfwu0+wljHF`J9Jk21+~%fiI5I6$fuqy%5BfI>#;9ne3^1&dH)b+0@L{qCZ-s zt)M6RGrF!WZl?&EgET}u6A%Zx%_{YKyo(U}<89@xXpZQwsyjXuIdD7zwBOdO(yLfe zh)j}SFtYD%^udA&NUYD_*-I${5o5=gN?Nx&U~d~{I^quwE3ymEGX@F@IlMIYVm?3K zD{hi8nazMZ%w`RQyJ6ccSgf5kaB>x`Zso#85+Wr5fXh$*S%8a4{=n{#y$gOozpJai zy(h&v=fJ1$)u0V{B0c`W8Sz>R3!+djVl~kqMkI!zs_fIS@B~}Ary|F!ST*LXO2UlA z4x)6xcJ_~+5@;>nvdjIeUJjV3M1x!7w9r=DOySN^cAh)B6D-n)|5g5F5(ysnAoo7J zo}rb?Aco6a103#9^{Hai(7maXPHm5Uf3t#9{f3E+3abvgj^&&0_j2nJt&6X}Sd{f+ ztOqneNj2)DCxy{Ed@EG5aZ7sp8H&iX7na^HZYE#|Zu}!;?R0Cohq{M9s}o{jMz|}_Ls|uYHU9e07gWJi z-g%!|@>preppo|WAkHc5hThmfk)$?>SSG~&^+-irnlCk-Pm!G9J4NaEI;9#dN2d?N z$ibkN$H#~s3zv_WUWm)5_I|PuzFo87+5cxP|kNqL)ivz!f`^j$>LN3+n<9h2I$}OI)cukoRqItq9|%C$N`-cmAGq8lg6F%Ect15+Yh=pGH>@67o6!86oat{5Zs_x%% ziqP27`mDDqW1c|K_B!&{`aO`K&%>p9KQIz;;mv8-w03QF)eq(%t)7iP7XE4XwyW}zoch{E8Dee}Zo$`Az#pWu>9!q-Z4-a|;TXo+k zAo8Gsow`+Sn1gU{WABZ$kK|(Aq#mKQ9OMC0{H182YMFJ&$!J#UBL>(|^>TV@(t-Yq zqKdA?aa`74Vi&U1+D=_|FbFKDsr)Y1b4W2f=xtKYwILSGtQ{6F(6al1XktNqA<@Z1 zqbe(b@j*we7o#Dn>VD90R83f$o2$o(2FLhc`V{e|A0wwQxTk+iiyV$p`Q!yL$p?Mh zv4`e7KQpT|Lh`V6b6Jc54_L};NrT!0D?Fw3+#5k(^h|IWyFY0&=6W!&zISsl@Uxf9 zO1Y$ckwy;q@#P}|(mWt&c;`@q)rp#M@I?4T&Us15Nu?EJ58K*pXC?q+4~^U1K(jh zgkVx5y_?|BAvGgxN}`>QTX_R5->T zCC^)AW?`Xv-%9a)BSH7@Vti;m9o=a>b20GRSGM)@eC-Wv-)ennnE+@ns(bH2|N5^1 zs!e1cfehq{f1pF{Fk^pTqAa=31uIjF3VKGeul3VAv6gdu5hm2h%AzhFzV~UNWo`z} zMZydH+AqiY;txiYtWS=8qI|Y(837hzNG4F*Pzg9mHb;ExQSst%Kc^TJtlTbev*E(u z%YS*4e6bXUJopNMCcJH;63mNTU1pnc$U+LSCNo{6pH!z$e?I+C?aE1)AHCKc{kXcJ zXuedfhg7=0!2WW8yj6`eefP7^DHEDs)^PYGgk8Yx@NN>*rQeD1g~XGhPacWG`*pp? zn>Sr@NYrG%eJTRhk`)WUvzV}dmx@Zh`y4;h{?*wGu-jGn^+_e*X9{3R2?nJY1l65v z`SYP{*?JS59eDf~fb-MI!{5)@emReY+}T6*De#U1SFiy;C(QRKhH?hJyJV6>jWxRr z;7p=<+PQMj?PF^N0l_0Bs~ccTku22{%NBI^fHV&0o>U$SY|mK8x#cYpFzDt*={?f8 zqC!l1C-Q?-+%UT{>o;G4qb6P^A;EZ=^_kP-qkw9_+N7z;qb!8a}@8! z65{5ggxfAx9neBC^Z5fQyO+jcnZl8Yz4qfL{Zy&v>kcSUxZ;%v;wex|{l{T{ev?>| z{_|JwvF{BWGCiu3SI%aPSt-@ORoOpqMF!c1!m!w&)V8y5Fo6>gwwRVb6r`_n>F5Ix zN*t5THZ%le4jAVzd1z<_?+ip=F&L5SgA(7j=Gik7W(l+;yaGV2=N@jfcr%V@1) znB?*I8CI>vKVn|)yu0s{#~^%>FwYdwzO|%v0d&h=>q3jQrM=?!|G*dYQ}klxAPz5! z3X|d9$g$+QUKg{js^Y)+{0sOCc{d|`wVR5JKX~qC-ps%jC^kX&9FRpb8~6gBvi!q2 zC_^o6=n&FkBfWd?N(U0a_dE3-%m;~TV>Y&(@1$Vqf1^Bl+>&d+u6gvQNNWF`a_=I_oN z=V36@vS~}HpH8}I1$UoPjJa8PzM~-jYaSoOBHylcGxxf=?X)GF$UhuQcI`<(2OMI#ruWA2u+{|S zX?70mCo1b4zo$)gGMaGK3489?T~v9quC(JB|J$pU^dnef$( z55Gje*wq?~2ds!C?c8Z7auQJhRMd6uhRpk*;!J*u+caev51a2>%YI2n?Ac_OT~8uX zKlbmGRxzqf1flv?9BS$EmiDF2T=;|ocdNO%bgHuq!R>^i^C8+jKkQjux9%kE$tZea zUKHb57`;?jsWp^pwDgX+=0xq;+Dp@MS!4N!Y2@dhb+ z-V`u${OyhR;+?Y!mq|~+1=dgB$<@*<%v_lXT-ku3l<;0}lPMQDsle)38o@1U!^JQb zKSfe#A#mZlL;ny%)7>jI%a>p1zNoIGo9lWaO|0DA%vUA(yYe#DiX-WS=@j@1j3u|J zD-|r4l1I2)Su)%*byCH~y>y zZMf*sRaQLe;`5s10Z1IQ51-k`-Am!w!DX1RmKOEo^-X&WzV|jiB2l)4UHmx~BR%~q zo01jqAmp*V_JRjr%xki>o3CvvUQ-DvR*#{pY!Wfl3hFYP*$fNv$LYz?_k(+bDe05R z!9jO!b8;|oukLY&UUJh(IXm_Tq4zxbfv*t2+sTVW>+xr-6>b=|N8fmrI=#=*LMbxO zj5eA5U8n9C7BY;nSwqEIGf>B`dyZM##(!@&M^+I z$C(Ou)2iCr;2N>AUiDG7$Cet6&SONN)?T+flPbmp->$@DN&5oXuOIloXnhI3zNlQ4 zm;KsZd?x_)Xn$66;rVr$kFM;Ej*PVg5FVEB|?&SV_WZX9n-Y`;^QkKv1VrfDh!EW9j85`DDN8 z6TlL7tt>WS`qW&mjQd@tCg)FJ>(SI^#TvxgTX_T)B!L(MA9ni2GXYOlvPe6(-flov$`o<- zBm`Si#8;Og^hwX-BIwSqg`T(&iql6%rs0Pg*)`=y_8-K(jrq~dC_DJv7-;BvW~6a+ zQZB{5=eB0oE*g(ar%=99oZGH@^lgCm=Bu`XM`KhUtgOJkSUAb@)lhq>tEP4LkU4#( z+ZB9us_Ub?8N*lgWx&qyBCpJDmUL$9&ofIU^t0D`9rcM$1l|?AsvOxM`)%*$MtIb! z@6%f18`jiB=brMTUI!`FI#LrAYe+QO(g}P;bUY`tc+)me`>Oi}drPbS@z*)gh_IXS z_o!!^msk!ck#tFHD4g;g{x;z2>yCcUIX_pC)sU@Hr_ap|fr(A}0?k(&{x0P_0a?e7 zYrCG=h;S4omB-=c4cUc?g5%3=db(i;>g-(RN6WW*)M;YQg@N&6&MbqX^ZlF;m*O*3 zYtT|%VZP7~XV;gqbiK8!4^QbOK2-^_m5VQl8-@2>A0=9#L32B4$A@<>953ut)LUPI zd~box5COreizub07>w);@4yW81b!CcxNL#=hi!ZNi{F6s%fL5W21Bkxx{0rPH;nRX zk^?G*eJ4fqVx4fFO$pbHx_RSHmiDv3_wZB}KLloV9$2q*0tL*BD1)qsz7d#e0mK7^Mo+6W2L-^6GUU^nz0P=Ws+}w-*4WG)y%PN?$E$ z+#W;|_-wuZdgpHIKHl1l+GQWtQpkNZh<%y2ak-32(sLb2uvv@H@k0OJi! z66Hmjrph+lcU*@eoAE}_ic{juSO%5f0bR_E3oF<(;Y0qec>HI^R^QGkaV!}+;u7)0 zE?F~<#ybmF<5ZJ|2`hQ$5Kg>T}~tbie)92?}&#O&LAVo9kQu<;Tl^Sw+qg zX`>w&f`$b&hjB*}?cg#G=Fq$d5$z7bc$-3r zR15QRoz@+Z$dP5evy-jjEV|CP_0Cl3+S`mbiU{!~e;CW`GCro7Ahgz4iHFmaMv$!3 zvM;jifqy56{>p?hVd3UeBbnq3nD-|d-^N$h$V-llj)J6pMfq1-9#;9Y*ZiCh)^ zSy_+|<25mi!$;Pk>cP7BP-Nj(q}I;p-u=6xyp1iJ_C;MEO2z_lLSl0u9!@SOZ8Kw^ zaCNdy+u4x?P)3V*hBadY9>!rWrk4$ZcrB{Cq*Pq2W<@m>L)7P#M@N|Io0&um^miL3 z!k=V=BvJ`15_ZVi3viq}_NIHA#rkFT<>B@Y`DCIbgDpd#$@|2W{go6W8b^+qZlYtp z8sxXJ`;>Hh>O~jx_xFPEc-EV~RMvXncpMwN*~rvv1TYh{t;;_(}ivD?;`IK zEs(u>#$QC%(#go|aB@crfUUde>vG`M?!6YR0N>f+agoZSfI+{ywDp6N+XJIF+2wCzwip~^uD%aQ<{39`c!oV;z< z-JXE^O-$+vP@Ok!eEOpvlyI#fsh;_E@lc9UCy2G=vmB*{^avG*k2x0MGfzt3&NvGn%w{oJ*UVK zxjBwbwsukb>NkF$m-et-SVf_yfkJ@}F}d{Xr{M(a zDynyxB?k#1`jGX#-H(Ox3*b{sLatfi3rWcCIcak$b(<18Uw!Lp6jMljHv z>ALH{UxEXtL}$({<#axHu8H&u7S1~&a~r8g&fRfzHTIL=>=HlB)qOB@Oq&v1(Nbx3 zD=So}>fzz?vBrCUaDTbiJZR!zEJlJ6fs`ib*3y5zF&?=9#)TRsL-(bm4hyzJLirC4cBFS@ z$10WWnu0ADtX7Xb9%bDXg*vENTe}U?xQP1%lAn}(4p}dGa(oP5w_8)qs^Vu4=sQ-G z{o)f%XJHxV_l|N#qiZ{7%rPD5c1KyuX(Qi3R1EYyujKX&71krhxwlXmMfa8;kJ~+< zM?OXY^o65e+kH4gn$tf2I&PfFr60;OcN{1gG2APVbfwb=+CLxsx<}tA{P}iG4C(be z=q>_xnNsu?Q-_?BIXoZdV#~k3{k8&BeZ8GLM$@?`kj*E-wX>$4!cHO;XV5Dv6^Gbm zEhLYib-s16rnQFt?h^(m>9fflsbi-XUO8$e0ZtdYIDnyAC@AM3O=4i8pWG94`tYTHZi8`&kc>&wZ~VA1g8=%&eS(VP)>kbv78Y_A%^?>~Uc6zPvo6`Y{6z%VSv zI-IxYn`?Th2x*e-r6v+*oEdKGOtH5HvLx6h^>OJZ`!+|XryVE$o~<$yx9eb=h-X+? zfD?160~%EYGOFI3V}!>uesjH}0M)`W=pA}Uj_2yP*n$3@60TJXQ|M%#ErTCSU|w^z zvT}sm6Yxf(-`tnxI#Nj>4;Cr4C~SV()jc0cw@XDkS=uC02IhF!a$IeXV;R_f#PcfV zI#{B}tars%V;fL``-4U~QX1egic~r}Gb*r(%nYR{n2vO_(1zF_6~{;Rp7A{6$%6Vl z^CX(th)j>9#Efvq@kqKfcRfj|JpJ)wx;ABz*ZZE}H*En(O9KJKPyS?J4`bv*v#%Q# z_Z+`(9{s%VC!fK|QfG%RfiBK*d#-7}ZL7|G$g%JD;Yk)ig^-Y5hW=dp_)GTE6DFeu z3enB+nvt!9f0(U|4m$V90km?L5$?-d+;A4(v@npt=KChSBSQwo3#No3!h^M+Wi&VP z)*aa}s%>stI;fQfUpDE@jh`F?U7NmZanGqSu5KP^Gr<$MQD-}>&Q!Q9V!F`21LrX?lg7#9lT(xvh}BewLel*bNDp10m*V;%LW zS?#A#-}=zM%tiERq8Dt^?g##L^@A!*=%Xc)Kpv=mStpIgV&cBZC?4TGRw^JRDzjQE zUI7UlX#K$O`e}cYSC+uWG}?d0`VueSHjh=%bHu4$_hh3~3a?j5oQy{~V4a+75yJ6m z7u#p`5@w0h(LA{l^?10Hh9F#%A58RH^q+KOdR<>KdGhycs#l z?Q;cx`fA0+-Sr0i)}duXJH|&xk>1#RN)AY+Z5^}0Z@Hzc40e12Hr^EwEM8idUsnfz zX?H{@aDR2(M?p`~F((F$K##>IEN^Kv*L#;=^zeuroMi8~l?fcw6e7@h=;Wp1y)K}( zcZ3UT944eKNp_I0W((P-Wx8`y`q;<*j;tlt4ET8b2>+dus8h>)@=&f=ZR$ykVT`QN7g3*E-eqY<+OKTmmw?OofirvKO{0%{n7nf z1O-~WDSbxsHhXdM1CUFYD(1F8xoGU_RxqzL9SE+m9b9K)b!fg_W`Q-ch39bH{`%Q7 z)!yF5p3uN6=m)-si{i8t|W@=)8iGLJx-(D;!}qZFj?Y&U(>e?KRt*eFgng6@wE zjfE>$Ztca_HlR2BxQTruM4G-LpU= zuoSp{6mkDc(i1!)#t!c=oN%`?Lw8TUUQ0=D3oj-4Un5gJGqNk+zh%fo!f|3OZf}%4 za#HP?VkQCB#eq7(V`T6o zz1aA*Fie|W_rU|P&8a}ER?97_!KCC5XLZ4)CGmq4l~uctfm0VOfaDOV8_nR4+*Knn zztFwK=duQG)9zgrjt!zZm6EPig&d*L4>O%sPurRL(eGNjP@A#FV(wC93=XQy-SZ1X zN;gDe`af%pW{kiJ8HJI9;2z>chwueZYX=Ml(m|K*=qY2MAwOC z+b!SX*G(?z~dz%bP6M3^B_vW_P0`M=H@maA+1`#xP54+?wn zLQ^u%{mwMxSdvZxxidk4VGePKWnoDqRF3~lYpUYq%iIS=6P$9~i-6(wG;SX;bSGST zpSigI>AHUn=wqGnRs^4D8e(@)8sFUes6Y0o_)YAs1LcEV?XF*rrQ{8A@cL^qtpApY!rDqoGitZyp6yZkPyIllHq1HTq}x#PyGJ zDe8)&bJVW$UX}IL_k?Dt6ZX1IN@%qr?#UvvqG4yE4_qK7S>g5Rq)4^nk>hZwE6VzM zAC3IZTUoJO%f`q4`Xrt(xdq=V+oVY_C|N#HFf)6g26}7X&rdi3qz9R?Z>y3Q%+A_W zer-ekVl27b;%1zyp%nWp;MVTBmyb|udXtQCM{$1qQR|P}B|8f`jguTT^lOq*>Cw*J z<(J7^V#K0%-L1W!p~%r|OYHbM@$T`vCo}b_dShNLhD&_6^2w5q=8lB`g9w&yuv@-U zSS|+g2)7v1<99p#o+sZ%q=RS{^NKCCT+kb={sTG)Pa>ETnYI(2-K)0s$tXtB&;x1K z6c^{a`Y6%lIKP(q?gJ4i-kZSYbrDADxzsw!VKbc!I?)NDT(yPc{5greO`7IFIB(2j z1hz5l{O&y}Hu>b5BD30-=~g#M8QG2QS zA1Fs}Bki+FE^>WP+hvt)ahA+SO*hK9vH0(uJT22b%U+kqvaTAa#@6Vp&c=$R%zIH$ zl98~pg=$8zw5*s}Q&JC#G;m4iDZB!dT;abm-keC7RVQTr>ld!mZ6%sW>^8WsD8N7_ zcv9Bl3w&8Q^f{J|U7IWV?MtwZff3KOqh^RZ@6(mp#*2Cf9QZ7IE*XOtH-^R##y39~ zC^1>u9W4-(85|>d1P&H;ahpRq+7ewYn~mJ#*~vG$&ta&get`UvYESGkn?#6hEP=r1 z_~NAKI1f*gojF61YoWe8uMOp8IGKI!$-lVlNv9ehdN?|$Tp-So-BoL3kZIt#aG8XL zr_rBdbt4g;{Fq{~S#mv`yYKQf2V=|RjW=vmIJ>=n-$aqY^F+MXaWtsIoB( z^9~fIpt3PY)KX(icq?pGe6^<9T@!nf*RUv0k(iXkg_SP3wJUzds1|aYhwdC7UXx<~ zB>_HMW@y_pX0~xB=IXam34E|_3Sai-@x82HfWFD35R5(Iaq{Psaw6m!*3mgVNY3hn znO-hh{ala?iD?y$7yKr?YGmBg6T-TsqbW++qXY&ITKFu;36e0Y&Iwcqm5#4ggX9C0!PT;j}v9VriPAjq0IKTZZ}eoerH=jzg@#udifcLov?fCV5C5@{rkgbKad4$xI{ z`gfkDk+1@sT1~JReltG3s9~6{%{C95+3W2NU{8GU=H$uQo40HfLii&IiHj-WA`z=*AJTF&)@y4Jw3wst#+aIXB4N!o>hA;b*=Sc7Z&UO zmG-^oub$=`&qz5_@-H^M0befxJupKfbH~P|luA>20t)9UiTnqK&dDyf&K)X?yq6c9 zZUs@?r6A=HE&01ZI}TVpR*G9P$E*C{uVi<_{r>~$tNxuF`+sWHGvrK(Obm%>k_sUD z({RGV(%rc7tibDR`=1{k^Pa7ap1yU=|409R*Vg~8$NpbHTek7LS=>Q!#Wm}4jf7ng z@^7?ix%774T9&f`C<5G4kN4xqe^3crk^gR%%B3%D8cA@}<8|3ert zqm$CfY){0o>h^WSw8alrERnrLAEyfkL`Xd!a}rk0^kcKY`ZPxrHwsQ%V#(uUdpT}u30ZWl#+ z>Vkrn^G>ZOI9L7$f?JwiHKW^kKcjZ$zRI`eMT}(st_s!+d6;_;eb)<&A}x5cKUf4$PaSFlz^i*6iy?_6VE#=XVJJk>jVll7$UqUmgB z9|bC0pRdFLT6B)uX)#ZDA-XX#5P>4B_qf1z0FIIl4dN`3U2wUI15XNX|Lzm_+rW1y z3N%;l9vGfcbbpP-vVk-_(dLv~CwwfBd+(#8pWvCYeS4YP3Jt|{Amf2e)>D>a=M_wM zKGN0-Bc-Qjh$=733fWQ7bV7L0YBJFNdi@^D_TQURW=WyEHLmTu$bDbS` zK0wmYtg%5{GIgw0#*uBWdADhrop$Nu*IOk)*iD^yW4&l}kbLFUef(a;}HPrJNtUqb=X@_1WiDk%)vr5N49>&8oO1v-?2fd~(U%fL!>n10!YEy6JPN zvE%hSipBZMvI7qd#V6~7^dKWstT|Xa(ncPG6x{gT1OjhN| zhr}|+jXQb89Mw;cyb0b>{cs5}cp5b4W~G(_L6!72H>(Y%SnuEo@R533yWQ+uEIT)5 zT|FcoZBoE(RYL}fk&<%6yu+3Qqkb$gBVP}uUm8Q?tBbs__O|ES(7qy#T-18rpcSEr z-B0|U*pUdMw1E_Dh{=qzsXMNS!R)UG5X@kg%~KHD-6`j18cj}8b;m9Xcl!o#VuhF; zE(q468Jv=Gf<!dnOeV zB=%=_`nDl4W$|M>bMyce^#uQg8IA0jR>u$KGi_dyw_wr1W8~oFdW9i~9q4_*zpUj=l*~(`$WJa{1Q`2#Gg=yO=S1lbvYYC%pZQ9K3c>|mcrK8&9 zU(9$f=a?T2(UU6btYY64ae4vaSDpdknXDdeQ*A;=0MeKi_MR@C`GH3)ES6OmJ6vru zl{*2evzhuFa193g()5K}Yd$0MjY=OX$6>`I#LIJi?c7tM=;hDZ%$+&S(TPiJ7o|SW zhS|XILfT7hK>pZUWVo1;P<U;th*sIvEJ5g+RK`1);p;z^~dl|i28M$N;sp^dD!buSm`8l zXZO~5L7fGym{l>UAoJn~BKt*q)ncs&zP!G^4-Ih)qp$fIkou)50GnZ-zT@~*uuEq2 z?)Wg3le28k_7N6lsAz4nt%=xtj_8*pXH=uFzq1_H&O6yB@o4$7WsTN!#DG!$PEC+$`VG7 zDn69y=D&Mttx3f>nAhz>&_)XxYETrSyA(6MWaoUZBD8~{nlEZ)UQQQVpCe`h-$>{m zs|Lm(ZMv=79JER!Sy2h27i_KVD{ryA2;^n=fxaRKrOInN+|J|YA>KxQ!XXdN5d^F4 z*8vyH3Bt*r060@sN99b0z9Aal9_d9{!Si{?_a(5rR8=2YqKy^;x^O@|Z>k5vH&!q3 z+08AL9i$q(UbzB|Mze%o^oAGdHXU)UB%gO$!pWqNSpj2C(V1;I<8N(6T!j^{A6yzc zUziNtoyvTwZ{!G)?hMR+7kH7f>j~cM;q^ zVabu4*{E(oH4A@qs5|$g5w%|B{o!DH09jM|je)ZLF?+C2XGmp*9dO-gMtSTi+2;S@ z?kl6>*w$@vcY?cz;1FCo1Og#gfCLHd?oQ)Qa0xEKLJ02e?(Xi=cms{|I_Kg@0;_hIWt94lpIy;DvI?FZ?2|^D^jhS@E6K&j43f*J~~5H z3E=EH9WFM*V?S)|rr9>$NZl6oG6d*4_!HN$CYGRvd2)@W)pJRtWGPSg^3^Jkw3qWX zIQcxP#Nny(fOW`DF{uUGfb^ zvD-s*RmGDJBXTTJi7>4f{qF=~(8u;B4T;6a7XemW$McHs1x=uTh+BB*YGXsfw@8 z@i(qTQ1x^Q1_Fchnzv{g@B6?{jYFpIpRglMeCJ4YwDdS6mogFM9+yM(4QV+)XD@3F z6PC6>jK#F5WHlHYD)WqE!2uQTjaJO)-N3Dhj7R5Udfy; z=E&@`Q#fU?@64;X~-aBRg>hSHD^6emSXlc68tM?0xh8EW9%p!>0556g|$>7{QP6Clh zf}6kp%+`6)(xta&daho6v2cjF?Lyjp#wSLMAw_!ibrVqg!iDmstWJs5tsQ)#Y5?(4 zm0(RvOQGwSnbbRv3dfl*SV`BasjtMAd7N-40^onDE$!<$809Gq!9Z^@iAV1>1xP!(V_$kNQ{U}a-lVN${{q1_broN#%40Rz z=B)ShgfkWRr6Sq-`f~Qi)Xz2WCFXU<(o)E7M$=@o2lJADhi~>*KP`-UATj55hTbt> zhS^L%^6BB+*2;H$eOSB6bo+&rJrCD>*?K=)zT&#FYEgo*#j@u8=_#E#wMi@v;n`MR zPfvkRN<~PXk~4hpqW&_~MxP=uo|CM(ezmK&B7ph9h{vE9|4pt?Zza|56tlCzQAH1@ z)!netRnmvnGXG+rmllq_7C}raUP1490>kn+pfHgtyGv@SN#Ruypd8>dS!d1k7T)u> zuJbgfKbD`~DB0B1Y~R^8O9aIzkmMs&P!<&>7YGFW5*pO_kG69)(V!%#g;ct0(xP~E zJty*IxWOA@D_ttx3m#=ivFYc^FdIWDe3EtOC9xw<&pL|oJV}1b8fA}bF||GHjL#P! zwYoa#ABA#Sks01>8}$CufH3*U$DJ3W8`Aku$~gyVjGFIi zvh9f%pM~JImeFpwv;%xgM z9Ef{lz7yEvQnA8!@+<)N!eRZP?Rn_vFM81@;*OxjgOitUByJKb>~00F}_cDSL#ZXNlDrjP-ehbBS^;0bco%^dz(h8624ETt%rxTPZZ>ty}Q-5$&WR+;gxEcy*=PsGR+ zy6vzY3iHb7RgN2{8!T9CVW7SjNlY_Kp~zdiQ2Q{K%xn$}+l*wZ2R?s!vd|hl!tb=> zV~z1~J5n2|IYKAKswd8{_m1VE6|5n|pp{yTNA4(r&}_oy7hSBPd3cz@UQIxX7E`WIrV!*n4XRj zOix4>FCi5acQX+^iQPG3*6J?j+oO6`2SFY4Vf#TQCZiq!&$XFvj>lh0i3q1gT~)t= z3L<6kc_%p2J6-4%2zy*T*sQZL_1pxp`L%+9(6xVnAHdumFKv5 zJ!n92ihAI)97Yp6SCLYpG*=jmPvBp@yaTEV+ixnO;Y7bhkxP+&^T zqpKm|$wZf>(dqVTvPsU}5&L8yz`3#Fr0T_T9n;4q5b(95fNZ(LksDHS^SKMJelu<} zoN0x=@_S}R!l(<2b|e3Ytpjx$4q}Tg&t#bSdML z5&(k_eJD7Pd#z*lge|AO&4q){=DpvDX5q>sU1~!jc>c|aAlZx0VE)uIK7V%>R1(|#mE+gN+qPm4c5jf>7Da?fmOAdM2^GbSOil*zydZn&7 zekWd~DTKC%WCf%V4#WqCDH&n76KA=o0AJIQyk~?Np%=KXFN(tk(6OGo`+vgx-}e{0`1%-*v@0mEY6 zr|8)FgP&JBd;UK2R~lz*Cr2Oi>m6q4Ry3{^EqDbDv;>LXu>+&^cO#YZe&O3YM7{A{ zwCbz;eqMmLdCr(r-k?6mqSc(ao*Y35txNdf2$}UlVYD&77AU9iI!tAg%ZWn19`{Cg zuk7DK(fL{=`b)1<^rxl{st(b6kw`l3NV?v#59?YQTsqMln@WS{9Hz}tty^dZ-$217 z_wrATe&ZBL0AU z2)N~5T0{kL#in=fL3n~VQ){1a+yrbMW%9Cy%Wfq1bZ*S6X;d$~X<|P<@9o!))!*(N z)ibd|>r>FEpj0${RzoFsIpe&@0bAs0Cn*rOY4ksr3=5AE*>dvm1?*}IEo5CC7m!GNX6&FSL%-5awXu3Y%I-l!YpY4^txj*;m z(hFG;8@>o|K|e$~Yza;EUESDUed!UtAN*ZbUswK%{4!gvrtC@e{9upp%Jl0R)(`y5 zd<@Os?7+xPUyoiHkW?1=rE!<`%BAr1vggvT0jS?0bn9ks-QT*M&1VSiY3(_dg2;1R z=LGvEKKZDsZXjS-w;u=$GHIds(d5|U{dN_e7#q8O`7PkfcqMjj z@4NL1YuKsXGN!g|oct_;7_L2YLV|l-e!d)?v(G(#%b&MjXq0~$n!gxSo>dLTA^Utk zriSe*0POq_wDp>}Gc5c(*KI~?(si~ptIZRZBm_Q`3?J^Z%h4LF^RpbsTD+|O?QL5C ze6AGU^_Ui6zID#DMc0?OzD8@~NB~{+Viefu_({~xK=jPC_Qd=~ZfMsM+0Hvv{%#j< zu!QdeKdasXAAFZVu%7>-kBi!3VYwhjDvRb6)7O0%bdoYw>Vj_n8H;QuU6O0UY2!;P zWTwHJ;^E+{^2lI**?Z|8o}Z1iR9~Z)%1<=Mn&&P!F`}Wm=<$SUyYsTMzpkv9=Vj0R zxWBrVGC3=;6J&IfOyhqA44b&F<49efcT6ALQvq^v-&XKnPtyDPx=pTr5kK7j5wF4j z%Z^<5Lqm_lNuNuOarBIZY8G)$6Jf<>&&+nxLU~rXlD8d)=GVi!hDg|4*r=m5#fF); z4Ob6qWdH}{g09ZYXjf&A#*<~9KpdhS72xVgDaBCEkri5-4^{iOhy#YvE0#?xCPj6- zPqp8%p_vLpy%EkGz7PJ?X;VuNNU`nI#e36-!3UQ2^ht&%6f$U1DHwqpPgFh!4b=&e z`E@X|L;|u@O~FMIbhka=l=-`NcDmZ?8e5dz^`?wlZLV0j*|86s{O-h!v-f2sqQPfX z-k&`=84}%nY_@rPH@th_k==rHm(F$1apgyci|wImFuJSJPysb!E&;#kbTD?)=|h#< zN!@YJU2GFY_kIwz;S5X$6)yK9-C(?j_}OB5I$Y{_NIm@ z?Ae^S<*js_Dq$y>LvGv(N?$dwuDZIcXIEgK?f!}|=^BT=6SXn&nMCCEHEi?g(Rfa+ zynXmUG5{{x8vQ*vZ$h^Hlt%4ZbRPfe?py%qIe$l7+7?-($`F+TM}E=-KAKfqP8r6R zXm^6k>DGz8>qoPqAkr{1i@MmNOfP(;q0kJYA_Fn%(HUd^CgW!~( zk6w$<599~`pfdUIUDtvb6asPc(^l!Q;;-+L%78ei%<%`6rdZitwC?-)A|j2v=_7Mm z$2E&75ucjxUr)e~V92v|0^GUK`(~do_W|_5;+bh~4)asnuTkJvmhaD})52vghYeM= zj@Mp>mA&{lnh(05;t4um`T9PR+c2{{urrvsNLOTNlB(}?s-Zh51Xsu#H4EaEShojg z|MsN$rl(X+naU?{e_$^HtYiq{Q zg%IeZ9TMBc$uWczxHy#PW@l+|qJq+HvUZN?LeB4=Nscd5c*upc6rS(zv<7zNiC!C` zUsv~APR^G3w8i&iJ;a~dSvt9sStNU}9g94J{pK!-Z5XB3B8#49z*SlQ( zxO>CSZhz(5!^SmnqLfZsovW^M$!|g(6XPM8^QlFedI|j88N595X}%TCLifjuhxp9q zv!e*YF=)jCl=n>wkVVe^2uyo8^%iWd8LICPxS0Y=xF2HU;5@RnQMe*j;fm=FaBL>o z^$Q1v?1_#(&K(18bpyWqW~50syiAb|q@t-!E<@4?KHD)aX@TG@0v(&lTcRWsM8tBVxl<3qV{B#_Yp&(H3SHL}0E6w6{) zXDX~iN#HiJ6iGqRGx_cG?6~e*iC5_FXXAjlSO=kZar#tryf$Kg_-W*umD}Ag2^Ix= z!LygwmlC%>ZVS4y)f_(=Q9)d;3bdDMM@n70{)3}h$$#rc|9?DarBdANwo?58S)_0D zaJKaKNc?9jts@gcVbjJ7e-;%D(=ll{xfhDdd}G(|R9UPx7v%_cYQ)xP&vb+>iYzwQ zzx1}_-6>hno#DGKPLa}cSzv9Uvejfxo?$IW{jdOHpPB`??MSrmApum zh&<_Qb$Ru)!Wg?_R=(b@OxqO1WeHr_TV^_MD`06|dv*fJ&+i|wu9_EV>!|eR{LH*m zV6Gn({g>8Voe*S}{W~-73{c}fJ4l=h0$vD7d7+phe&$?UYuFDT;WHkfw>48^Shx7| z*L4vjlBgx55B$*>rL|;Mm(RhZmx~vIB_+z25>(}}v9ubtVi7cY+#V}!vB|RyNfkd# zedh#ma=1_@$)DEp(hs(qO)t5&6ZfMQ^P|~SMZqW(B2AU2;+(kygClk zty>LzCvWN=i(ekgWz8v}f^L_{#<1AN(%O=#FI(dmu%uea>I(S$+N{auI^TU$t8y@% zhrKmQSS{2Bh^F9EI||8Iez8mQaz+jRA-BnsfGlFXtJ2Ej5J#A33T_K=q>_3;CSgGY?@%?ixZZr=rZ>!^o?)8w(^R*|S z1A8*wfq0(|%?+6a;8s$ezEOpQ3?P;j*yxN!Q>}9R%#YB`!wl!L#|Nmw^Yv;dUa_Th z*~Q2Sc;IxtpsSCjl4{R2MVNpOI6K`As!##sAS17v)F>-qLe=V*MPZ59L3UsjS^(}7p>RCyRG_?ikfc}QsRqthv|&pK3UkD((AGEr5-Wp4+LJ>3ljA`%cvw z1;=M)sWEPW5xPE*_wqq8;p0P3&k$yY9C3wRUI%wUegc{&r}mlZOL#^A;GroP{OQoh zlb?gy8vG5h_0J!kR_!nt{cT1Q_ka*#Xa7$axeU+IM+E6e>Ki*gjXfQ>Pk)m}JBuYd z{e7C768p{Nm6ZbNDvZwGrMVWuqw(t-Sd;=4ls7z@ka_m`+5H79g@kjB6ikpl8PUqf zDpPPp3#-wH?qDJ}nd*?vBvi#rzu@Jj_u_oZrP`WqaEHqKFn?zrDq8n}=L%z2)Smn6 zxHflDK_JEYf0hwj#ut7J#vw5>URi`o zuZN{{x^#)*6;2$7ouIeoJL{k9p`StD_`BRkZK98=1wOF+8KUwHIYiEL>gdGJ+gN&u8q+eWH&2q&{VLbJOJq1lpFx`dA22pRsF zZKV$UZh;97M4OSh?8UlM(c^5Ri;zA%(#(BIcV)ob`RhNuU}80+(zd1xQ&|?y{+&HM zoPAc?i(Phom6&o{oH0KSW~4BZ!=USN)08q`j?MFY+A>O;RezkAKhJXHOL%pua^e@ zh_xjpw|`aJp2{5UzdSjmnq15e4PCylsi%HzDZ$>B`hcSSAYAA259?s)TvOY5f2)*O z>M0HFcR%KOFjT5;$(DuSPm3+teW<{ctH{^TWoqad{;dnW{YB+3Vp{C~;jTpx|6V~$;+m0@e_JyzX~C7%qacN%hLZA}5KH}<@I}pZ(n?{9Q3IW?lA-Z7s$|wsQwjdZRCz zym__4LF*0=c`PP+@sy_knu`v8sqYfuW4nsqaT8VDYF@(C3P_#zkb-3^Hagl`e~8kHwTpnoxSYY^$r|`8`|er z(e%!HjLJx9GK>4|ttNP_5T_nn1IBCUBM9)|;WK8J*~;Mx3Be`LeDk3;=yb0_5K_Wu zen}12boCwhp5ERZao%q;Xu=8GCpZ$5(c}w%^O!0G1uw^wU2A=Ls1bW`UyL#Hqief{ zl&S@7EREGc+C)>p~LgC6y%*RJ`nU zQpCblq1WKrPtJ@VgrNUfuX7b zLZpuGZ9OnjK6uEi#Awi` z0fK_&KqkIc<*`&>*$JO{orQ3g@hF466McuDD0^{T=8q*i<@8%}Y;08Fy0tuGMEPZQ zuY}@-_)rY&T%aEI1MnSQQe)V~A-Hd!iYEy|sK8KZi`{8L1cP;vqzJ95MSk)^#(nHo zR;D_USGVYBP(5x^i+=!%*H~Xi(z7$fZ+h&-ctI@U`erDzeAeD?CVrb{FSnw#Hh^}Z z<$zbfZ`&23GBXX6K0nl0$Gu?xaPK(wR^ba?EKSFaGe};2`jdB6L#*Z+wh=T;@BVp% zg7N13*FgjYU+8+K=ovN!ox`TGOQzWdF@JG(A!uE>Z)V!rKQf&OX@jUH!NBx*ez!ns zQq)3xW$#C6Q)4UfcvC4yCS9M0^WHr~;be?{XTuDd27L#*!7(rF)!CMEq)|Z78)@Ua zVOzKgtU5hNoPR6dL0i8(MWCwv_7on5(pX$(hQzF)_mM_TAg?iwz>ak-J9)sscyxj_ zGBd{rjq^H+cg8&>GdzY{q_(*Ef%xERXjzN=?8s=+3{75hnuNDFji!p{Jh$VkAz9y4 z?!>W7S^F~6g~qbv&gD9p#}q0`UoL6{M>8DlLq+Z)X2TU^L}KY)o?%eu*Ni0|4O4U) zeJz-E`sbd);l-Jh?cukB*T!5!34NC-MK2*}OwOwaBHUSqt1e_cw!``wpGBU9g~<({ zQ?{+V!`>^xckL26RA2H`{ZfU27p3Idj=lEKv3A=!k$pxs1-o3UehsgU5ks04Z3`S> zYo=QpvB>QT2p?Ez4iXh!)1R(jko&OmiA;!Z$|ZM;NO`U$3J*>3(qQqSZlQ6*IQWyb zkglz$e2xB?SE{rr(K>h@w0%0rWU7F&GxQ^Fejm(v>(QD>rBd_{nZKQGL+77oqQdqFP(xo|t`1!REP| zAOBD-LvK8X138p_L0|-p{o)}%zR{$wzR==O7dc6!)T9*OGgQILui~14o`a>M(Gix}vL(58-QFKl{;14b zcX%wvObv?!yot)E^LUH(dA>wXL8oK3nLIJl&zYxS?uoMDlP(|c$<_U_9izd^6wVi zNx7z z36YR?ug6mmlG#^9KwUX);&Z4NV^4)$V$}`** zTFEK449ANH|A45?5p`gXQJdSrFve5)dHGwEJr;?soqr#Sam$ggxOX$VC<_IPeYyv3 z<9RJ?*U#O~5v9;G4EJzbagmtgqKW?lAcb;@z92EW%UAU^=bd%%^KG^8;`FVJaC;B= zc~NL|4NE9^rlXARp^9{xLIclwqS7AndPna#WCl$}u3aL&s6r|e2hoaMn1akF0$Y^p zMqNLrUq|I=lfl4e<1=yYN1D##Ub3Rni~yF#EgsPdc3kPPbbL;le))Jzc=hjy;7{0X zkSJ-q^*Gd;tV=TJgU@A3P}99dcZyimaTBoqBmh(TZYg+3IKZ;_)BO4OuiP}Wg_~O0RM^YgBaP*;&zLWD9AKO*A>us<3D54rLh!0&u>~aK{;Ax zI9g`9a-pg0oi<`)NkEy&h=Ii<$=gzd-dB%{Sr#BmF~?Ab&nYFRXEi1_`JqdOl3@Jd z>F}e-- zEQvmEkk=afJ6Cx@w=f8kNQrBCdG8eJF?lWpkbJ1psY4z%B zxc&-YGg?Vt!FKqno1t)63Zu;bLb=%zSyPwX@Akoyr1$GBJ9KtEE)X|@5~MOr9sTNyut_Xr@G6yHJ-9IqWN` zs`UCo%M_0VX4S2U+O`kasUp;w%j*5Nt}lCx0>2twDJ)u`OTTL0-csRrT#y=F6cGvT z%kq(# zW7}&K|5*S_$0x>7t0!vH@dZ_{y$j}Zi0n%-o80A#$Lg9_Slgwv1^xarUwRYO5-V%D z1LuFjv`bCYwj@xx+BGivmJNiTZiQbQ?GXd4cN&PQ)E(DMEw4}vq;&-}tABWKSc<*O zy-!Bw^Z{%Q;V4{=MOe98vy(KjsZ(GTOMmEJ)A6S$HyNWb2I5rdc%|(y)4Uk<3BIgs zv|b|SBwg=+dQ8w{OVG@?iH^u=+wt0E8_2z^hrdT9%OcuQa=IC88rM1K9$9IRUKFyY zACnxnSXwi1EAEs$cyOtl#gkt#5mTb5or4fBQ}%G ztZCxBDGWf*O3T2S$=?1KAz@QiY2?-AVS zUIV+jSUE#q@D2ACM3Bdk>~DKQZeqNY+IAw9 zHs59eJ5-mXU$giU@bPWK7WWvWS4^d6VLIbdJ5wM+7L zlB|qpBxWEl4E;s$A0|OsuydGi@4I=dtBJ_6Lg`;y2pu59G>3XyaqI8M5|fA})Ze;0 zSM`bP?;lfJy0B)$=g2Htt;gnv%b>wn9FY%uhsh}E-#h||C&~ng1)mY|%V)fk%p!}@`WQUzE>obF)QO7u28J9N<%Ez zfee3Gk+mDFqIZIOKIe#AbOnHwRcFQeCPmY`nL6!T0jS`11ZBQ2-$6!+ZCtoz08#17 z^;IV-oPnEZtLp`hy^J{`?q>reR2`7}PaoplZp0U)!dY1~dz5dTRA;OQg*CQxwzbEMeP!+nmLxsz-jNGzSXE+f{Y)Bo zkJ)#zNSBNZC2N~tp8HhGJwLR+vnCD(C>)wG*+yZ~IZZnyej`Oan)k%~aYH2Ilfx6l z(TgYKiC4JPZuGhxa^CQtaLONr>3G+PSbYr9{O$>Hgx#pKyMDyo#Ud7DQz^Ebb59uY zn9qL8>4Q_YWlV)?kNpnZQdx&mK%6(rCDELRs>hR-#1&5smvt$5jxC*vn-{vC`I+Rju4QrLK&Is zR!?JPuZ&f;6k167bspWgy%1508M*9XfnOeul>fk1VSlsGpB)*qM#im;8H0@K>sGp@YOu}pT0Icf>Q}_1) z@A|4Vsz%;y7b&3`+938p;=ug-l=~qQE2E~CL^1ZPf!neCW+-UTZMSj)YM*CVY8VN) zbp8%f_=5!^{fOfsPt4g?9U!G^I&BUI`oL7};&&lYSgTxbfm-;^*i*y&yI~fJ_xY?9 zUQ?}$zC2IV7rFDFpyqgJcgLOogd#9sqBuwEZ9D~(Xa^0QXC=P7t)4B-A-IX8cAh~| z)@+KRYG)Jf{UbPcP;ppEV)!GQgeH{JO8<}06BMzk_5vzKB~V!(bN@;FEyiBtLea5> z-()Td|GMUup|o^`(~hv`y|uAr(w~?7{09?jnFKZBSoRg)e|(gvZ}WNokH7!;C-!Y9 zTJ{%v?*Bzd?7xMh{qG&rWE?PlVO(*8?G}|WQ=%QFl?X2zc0?#+p=3$)$B#!#%OC$= zrC{d@UH*=0B`TRS@|jJjc=?N|wdF^geRHhg;w||uyEdvU+t0_&)PWlt(f7kHIt6qV zg`l;%KRd8VYBNv$kJtcE&G~ZIdk`?3cOx{md_;T!vqeSzw*35Xu|m`OllI4=e^9IA z`#7Fu(i>4C%J^CO=ydP3Ruz1RheAJ{CM~p9{zLxn<7|1D+ND!8cWD1Grbq$Q^f^yDd)8-P0r1le;K)p4? zkOM^JT|h0!#4eR-l%Z(Yy`v)1$K2TZxC?2bX^(nS8EocMd02t>Rnbk~+l_mI1{UEO zgVw4ao*o0$%-v@emGTj$HxgaF_Vj@p)QH%8<%}@#h^fXGGb`c^He=n5S-o)ui9^oR z<9LQF`UV=py4%rB6Bp+cdH{B>sJx!P8RMJd)1hJ=$(MDY(zj`rQJLr2vbpDp5^68i zi6Y}>G^cJ3g7+k!`v}X;cIk6+X;DElY2zVDai=%lhD<#vW9Mfv<&HH!tjpNCTOAo> zxB^g)X5pV>%oy32>p3|I|5&SI$rdq51BK=`F{g(a>@5{)R>t;lUivw&YUIocjuU?;0hY!z*AZN1T7mz^o$Ps&j zxdg>Zpl5KWO|L%kyteYrkQ|d25!64qeKR^T`ZrW9ud?MEgxtIK#_9vs!BtuJ9fE77 z^$APbDg*N7_(Tn0Q3G9cbsG6ys~_wq2q*j68~2jR7bg6z zi-y!+TML~E8mebDeY3XAG&TcDPr(}f=AP+e4U^w^beJYsd;66?I?8xlJ;*3Mxgu** zYRf5{5TZGnjvLS6salo8>Opa)Kn=v@^L>Nb2f-{h+c6U>MR;-@`AtLHb>fEP42CSF zY7w+P&={w!rX_$BT6z7?_T{h_<8Aa_oYHvsxuK;gFB0HI^z-#vykkegd+dLpC^k7c z|AJA#*-4svIB$h#o_r+Uh{V(Cx!U0Kuz;45h87p-&T9HNA((U?i*OEuhe1wk zhl)Qt!uz*LFht4|sxkS#>OQjxKJx`75Vx^V$)0B62o_WMd5aOZJaS@V_dN@f%_bsb zJ9`oQ6_aQ_SXzhnr?!}C%d{8&$ohMRE`mKByg+3c3X4t6p17U>9nfQj(zXD`zh#3A zNU*L4T9i*G7fEs7>N;4RKz^otM0qWKE4}a{bu;DLJoeNvlIL9?{>spYjaJa}(U(64 zJZ=Nua#?GbW!YtyoJ;!4Y|d8^uc276qJTz{HI4p8I2m>5jHa$=TwfH z>5Y+g0S7IK^lf2{u2ack@#TsJ_Z>|uv;H>DpSA23zCjo0J={IW# z{Ix6pNb^JVe=w4|eDr>xH}b1qnQWF*_L?vzB;r7RHt;gN8eP@n+DN6YWFFeWls*uiZK@T-H?pK(Vv>L!numdRHAyMMVyc(=Q>pig3sG~;_u*JCHPmd5Stye0_=48 zo6Kwlj+7Ll-r=_636p>YLPto|fDj}u>+kYsFbAr`-;?Di^^*!gBkoGWYX5bve5q%w z>IlDUUWc%9m%~^#1+&PQEfas1pp8iLTtSqB1>FXT81D+vb)9lxGF)m40HiMq< zq5+O7eSm)M!@5rGi-r2v9JD@!;vvT@DK#b>JE~-}bPO*v)Blq!{~|>8U+Y;PCLwe; ziE9YsxR=6NurnxF!=Vi*F4ola#piDih+4&}H0i?=qE5{lL88=XOwRM*khL}CRz5$O zlEi)u-HB12w|iL0LGZrMF~msjHk$+bit$r=mEY5VfJ_fZuCPq^;jiKJPI|1r>vdv4P3WEmAP9jt%;vdbS>Tl95s@6j&EqSld!_AXb zgYQME(IMX3&8aLx1ir1r-Is~_GuERmHHR?W*Vh#Rju&gKU0TSjq<;S9rvB0TYyLw4 z>FS94UwC?y#=nO6Vej7EWpnO_Hv> zcOd&yhGx?rMF_D)(4y0qvTCilP)2?m>G#}!hE|dOi6nP3IGvwDk%@PbHaO5T{E4zb z>r4L^3qx1Z#m%7UZ;J<~%eRsm7V|F?TEiV9|kE0Uptr@c*u9win z_t|%EUSnku*(X4tJfYtvHjhwy%Y_B}9_v6{t8qt&aBbMxPCE+ps;nt^?>=8lmxaIU zROp{uU2IzS2uWaVcNm0ZjVEy@gyX?O@lem-bXR*XLwG>9DeOXwE8=uYFP0(6c?nap zFS^|=e`GG9!pzAQZ%(KbY+s$j*n5g>yJb>i3me;l#AVq8uH>)TGr3SQM%a?R)ovp# z?Qymf^xl8`lhMTNYpFr6w<*?DI@j*v$oQnLxOv$;dhhZO%S(2Yyw|}k*E2HbX`0{ZaVJD2$ztjB@FhDk?Q?M$8t&-Ld8b)p2%xJM37@BgY}K>~ zh=8gjM#OG+V!VQE>_mmH_)~bDm5zlswm*jQcW&{FoJ9vZGq-yY17)*!7i#W1G&*x8 zpzQApy*1G+eRxX4$o#MAOdf`f1;`Ua7Pk7er&=<~a@HA7G!t@Pl=Zodzf_7l_k~ICzMbmwug$0blk@1RV%8|g+V}mIT6I)n+jNU`z z6(g&~tG0#Z{*qJV%7J-fgHN6aNZ;LNoO-dyB<;p1Z;*p=1?`!I6|3zc$Y#ftgI{&k>Eq8n!foAAw8|)3^(}*Bzq3 zaZwS!gd^}0|6I~Y)IFkhtjwnGYO)HSeoI8-A3NOk53ILE0vG0}!9Pu9#ztvCT!8E1 zFP*8}DCrk`nnY0@M*Gr(wE+o9yD>s`2yLTY(Fw3f&Ap}Ht1qdIZM)}I89^p{Lx(uZ zt0OdR-(yOc#jH{UzwI!*ktZ249m}tutFl^AlhZ$0%6l5d#%?FZ@fUm@%6`R^GLuko z5&#!Lw?(q+tlu*Vg;=YCVmR4h?Bbp`KbagK$~l|?@Y4sQ3x2sH(NK9bz8_Z+d_M&#@$ z3F!C)yDyFQ3FK2f!``>2Kw0{YISGq!m#PGZ%2Nz(zU>&@Gsp+9a3zyitsf_$2RWL&5Gjs^WK}s=~UqGF@=jZkPL_a%DJ?? z`c-Ab&1Mgq4{%R(UUG?RJG5^+b&m>60a*r=H170>QZjitiUDUi7>( zizAH`a`)&W5TAGM$V^q4TwIN-bsVVu$GWdMB2OOZF>W}#MUREr*%nWgt+au#*=~cp zjOj+Q2&;F-smD3}gZ5Y?l6cWKt;08|05)L5QI!zaf7xtvBJOzkW13}b#kMf@|qnJv0)>-vd zq|kSzO>rpJgF0Az=WkFVvQA9f@G%}uIc>lC@eWkbx1P}3uVNt0u1wmVK{w<8KbK4- zjFXQ~N_;^-+)Nm*yPTR}v!2c+A(hJYr=IP5T{W`TOBxW zPHjFK*UgRggP%}iyY6uJ_W~xCu)$|`4{cTY*5;hsByZHS8eh-zgvwwC={*Z1Jq*fL zuXNwQu2YQW%3$LxPGPHz;YJ)<3h3H;Mb>Wo&M3*Tv*av10T1$G2vQ@|#?`SaRK*3C zIZ2$iIHUyPX1>_1t6~UP;nc%Z;z7rrZt8}=O8Us1IGz}pZpkhLNW}a!xWto%ZgI)4 zsCTKdY%4_g<0(#*L{hl@_1c=wPr)!%-XwnDEjhj~phWzR;sj(A&|yHKEKWA8PC3W# zLhjIvTb5y1vE&DTVgmdqTiM zST89dj{YFZ)D3_e!Y(zy6Iz~s6=9&xQT_$glRgq@pG&HRoFr5#tHtCd9doBF@_Fb7 z-s2~}9|bzQ1Jn{z_eG%a^$^pT*8(u{1JUhb;x%(mGnuDuK&m4M=K}BdSq?zW)(Ts_0 z7V(pnM%0=8U`e)O%WndIu&C?-QAo;`LnNK=6*-EL|DepRin%w$4h=L;JS`ZNd zQ4!1K(xekmK~PapQ86GzL3%Htgixdi(nN$vM?sJpS_nOK(14){1V};;2ni5M2!Uju zd#~5G%HM7 z>hp!|Q?n0*2vF%If)SovrSWV1_g?|U+>@%%w-1k{Sjyq=)Ri2$L2R6U0&UMcR_^>I zkxQi=p)cuW#Fj72eSv@sDVC0HVqN^;QP{4Nn8)8}Hrz-)<|aS6$U!_=@x*n}t6f%D z;oQJ=_5_cyCvWCVj#s(@JBM1Axzdq}Jd+A?YBcW{`t?Fa-DD{F1zZ^y2QIa28_t8A zbSSEdGN*b1a6r*pqbJR7(Cue(*V@bcB%P39X9O&$tNE!lj%RF~L`7StvFNi4sTLj+mNx)#^bvQ>tn(HM#}>XZOeBU-`^_JeZk|oA)9e zFgKQN3_@(EfY;I!sobbh;u-in=3J);8-Gj2<8B1>nCvAt%08^X@0LK|6`$mRKQ%ZI zbO@lmO-e;k7R5l;&C{TQR*9oxsC&-zfKg)sE_b7NL#t+cDND>HJ+O(;HOB{R7TLCA zX1C(hluezQhG*JotJi%uJ)$$KsN+%KB7mtz`t2>tmQIs0Hf(?^h`sHDb#uH!XRbcq zFS%`_Q&q1BkH#M>;^P8}^BEWEX1>Q2q}S!32r#0thx+yxZjz>!9~fWd#B-e2)ruAH zrTEyFV*MRmojxK}V=Zasp5J)zZfFcPih5qvf7a9%;W;(uJfZ89t{ew1l~_hRULN_5i>_IP!b~iTG=a(#7x_*khIW`7P6y;BRN|_=nTJ zq}aDcy|>iqeQzOwwMn|`jJ#Ltd%#Y3XGwz*R5z~0X z{8rNqbpy30AxcH1v$wK%x3v$A^;{d;`M9L+*lK^_sU?J+w5G*n(x3ZAnS~X6SsLy- z^=#+7nF4%09ZB+GQukS%V&@FikrgS%hwcC(T zG}fL2=Slj~Oga|(+Jj$Q z^<2;ygogG~`QcBMRPa6aI;o9JF}qL>y_?Y|Z_ICfe9P~Xv_3eBidPzgBuo#h=OLq~ zKAh%Da|Qm8)@=}Dl@o61OFq;M zA&!llhC5L?ntjPFf`DsXBXZEmLhi%_V{2SGlA5p*b)p@A7&6Z@1N ze`4hzAUp_bf*p(yQGeb0)bQqR*NcH(!1v*kY+Igu+3~!V+x`kaUs zj@g)Q9R&-0a5J?}UoIn}2-K-5_j=_!xAixW`}?gB+J#MM(CXv{rH67<>&x`y$z;v9 zP3%C;rnJ;z+dLyvFFRnhAZD?qWteWnANHD7C3;-UpRxC2xATFcS4YG%WOFQAM$uh0$<92zzTONVO3K5{5 z-1uVeql9yAmo9IZ$$(cEtBz>DP>6fJ% zH`8cX*4=GG*3P`-oSSQ<(WSF;iF-!BJyeLP}ZcZL4` zfysp@$k4$La*aiod&>;=qJ10`BTY@}N^^yDrE+}+y$GLy;m+6oWl!Kd8d|Gc>dI;! zDruSBGQfQBH+C@ULgh;g#amvh3`~wN#PD-Kz3G-PAz0H5UO3_F*;E z0we~=L33_8wa#RUj}tX>{`mZ3T!QZZzx~mSMCbXrx$x%RB=6zpmb>3Cea!%kjduP7 zM^B?76j8`#5~XfGlSZkosWEkjDRt%>Dj1b#r=*Z0q%~e%Z5QaVuZqcCxWbp9T+r6^-Xo&Z=EJ}R>QM|$bw$D%G&h1q+-J8#t-dU z#EmtLE!Q(x4Ny8Xa2$!$tC4-|M$40HxUU8thxcLs=LWO?ek4H3>g0CZjkJ{RT7IP}$c2*W8+_PvcPy#( z>c1A7Vv6Uw$!D3l2OH6=;*0AFjx>x~gvo^N3e@{9VYG8(FW`9pi^9vv%?&5h1E1

    zsEoa@wo8qw+s`nCMu)^!NPI|K)cWb?8)tje*bt6h`fX3sGLbU*RV`*`&HSPNT1*2{ zuTBB5>y9wfCo(&6NSO2(fi9KT(EpCW+FYza2f6(k0OACA2l5$o{s=$edQ0u*+d3ml z%BqyfSo8GDTJAzAtBwZI( zO|BYyCku+q0PXqBm}H>Fy)_VvwqSgB`1-(T&4uPUGs!hQKlDv3sFIFwpN~4z29kMW z3e|YuVm}?LMme?00{N7HI`dt?j7iR0%uSU<;-mhWHIVwomgRT=BW{Z!sQZ{PsT2D+ zw!g$wjhP(?6ca){PAL2d0|CcHrJ$D`n*c_lo>htc8;A#H})ThRCXInvG$6=^>FRGVvp#HY4k)M+w`)>!~{?_c>Ynzb35_ ziUdEaLX^(T)i-4q&BCRfTSrw=jON-WxLoIy>02*ov2=>bKtg4?6lxL+R)eA zcw}0r1XN|f;q-F1+%z38{zwxP$7}9&dNWMW=Mx6KH8rhJpKQ`CDEajYqi#X=*I-uU zLS$iE@yA)tFW46>n0du-1qJa6z`u zO_*iz44fZ~EyNx^;rWKOiwHbCZ^rSGa@HqCFuci-r?qJ)uyPhNV6#BTeshnE$33yn z8gvs5ue(Iw7&+4BH{8^xCYuMnM_4^;lBZnC`V7CR#;Y7WrRmi|Gf;S!9b4vn#j9|G zSnQ_oV_tXhIdIS^uOqk8v&s!PYlFU($@)IQbczvM7Eq7G( zXyO=OU3@pD-A6Yf=lWI;d1}>WP@&zm;~hGC2XGG$ z_o@cd(mFha-v&lgJ&EF7CGa4PiDLzQ^lDoKcG@k5YX)|eh`-=ngDs;AU?Adyzw6eU&rVpY9&-MT_kN@_{CrwX~U}tRYHa)#l7|Wg86eoq?38VpB-9jq=Snoq=LrPlmg61xob8%=ysJ z6d_k#S$d#UZnYm9S31RIX)bY{UF!=iVa-bjs zHEStkrsPnmfiXiWK$F~0e^a20%1Kic=c`ub&}X5#R4Nnrf(O(|xzVQnFZZXTff*qo~@ zy?GleU+-SZyIGK;ld9xZXthLacx*PxNrYa!c_Pc^FZ*woRLL$`bI-)0i@suwexD>` z3mqf2_H9_QdOCK~pN98ND^?ks*+v1Uj}_eJw*zddUYAWh>lnl4fgDYXF1xYA#BF@d zvO|g;@!Q~D?G>vB2BTGWQ8v1Pex8bofok-8#Ma!eu1l5~8C$FL<+1TQV~Rn#GFnr!2?u1dLlNb?$o=hRn4*M8?tND`2DMB^bveufZ?;RZvm ze65Np+N?74#OF!oZypZnS5{z>U=QNWqE2;OH3D?-Am}l355hz_?>#X1GurEWSJ$T-!0{7fN3x3zv}?CVy5-iUC{mn^>*K_{7jNaoo&&y~ zoee|u?Gl{Rlou=Vx5a7 zzSir#IdNi$QafyK~_F#?iRZ|IKnynu3fb4pm$bK35%C*jVcxGJ8 zn9${FbFyAsitRF*qEzn95GSz6?#$JMF_l^eK}q~*|88E0y-kQ8Ay(2tdiUMzvVYjZ z3_D~nQ1u#^@1P7+|<&ug}TzOOy@9v_+msFXz?#TPTIdL!Xkw@}Fg`UD) zFi#UnLgYq!WZ;VP)OZ1F5G zIfxE<5)Q~`wx;zzzaIlvbS4y6ooLxkn<+kEegp>Py?ZB(e$;xoVgyY+MKo^hy_y)R zC@0Y0yK4S!)q-52)e5X62pHVPT zDjQ@}vFR77<=9O!u=@{63>R|4gyKL3S{tiFzu~-UygyuApFM`4%qe>nT8pVkJx$n!;)5Qrv9U>bUVrRq_0;pZs-^pL;EhdAMowNzMny_a z>4B`Qs*HlFyz(U(8C4k>TzM$v9~wBhSlL@y|}QsrUh)4cpD@`r0MeEMEKvf7+=x literal 0 HcmV?d00001 diff --git a/docs/assets/identity-center-3.png b/docs/assets/identity-center-3.png new file mode 100644 index 0000000000000000000000000000000000000000..79414b119d3352d037ce3c3f04e7a0ec811fecc4 GIT binary patch literal 70839 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 literal 0 HcmV?d00001 diff --git a/docs/assets/identity-center-5.png b/docs/assets/identity-center-5.png new file mode 100644 index 0000000000000000000000000000000000000000..f170c8d5069e09b218959d85fdef2b7b2df45f5c GIT binary patch literal 52918 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%0DBy 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 VVIxri3unF|h=$(vylb}}{|5%TomBt; literal 0 HcmV?d00001 diff --git a/docs/assets/identity-center-6.png b/docs/assets/identity-center-6.png new file mode 100644 index 0000000000000000000000000000000000000000..01fe6f73f0642cf59958cb967d89c6d2fb0afa78 GIT binary patch literal 56086 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�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

    {O)*XwcS&x;wKZ0pj6#jKBs+~%v{MCDDn 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 T=N3;YP!EHrtDnm{r-UW|XDlN7 literal 0 HcmV?d00001 diff --git a/docs/operator-manual/user-management/identity-center.md b/docs/operator-manual/user-management/identity-center.md new file mode 100644 index 0000000000000..0fd78b1aaf62f --- /dev/null +++ b/docs/operator-manual/user-management/identity-center.md @@ -0,0 +1,79 @@ +# Identity Center (AWS SSO) + +!!! note "Are you using this? Please contribute!" + If you're using this IdP please consider [contributing](../../developer-guide/site.md) to this document. + +A working Single Sign-On configuration using Identity Center (AWS SSO) has been achieved using the following method: + +* [SAML (with Dex)](#saml-with-dex) + +## SAML (with Dex) + +1. Create a new SAML application in Identity Center and download the certificate. + * ![Identity Center SAML App 1](../../assets/identity-center-1.png) + * ![Identity Center SAML App 2](../../assets/identity-center-2.png) +2. Click `Assign Users` after creating the application in Identity Center, and select the users or user groups you wish to grant access to this application. + * ![Identity Center SAML App 3](../../assets/identity-center-3.png) +3. Copy the Argo CD URL into the `data.url` field in the `argocd-cm` ConfigMap. + + data: + url: https://argocd.example.com + +4. Configure Attribute mappings. + + !!! note "Group attribute mapping is not officially!" + Group attribute mapping is not officially supported in the AWS docs, however the workaround is currently working. + + * ![Identity Center SAML App 4](../../assets/identity-center-4.png) + * ![Identity Center SAML App 5](../../assets/identity-center-5.png) + + + +5. Download the CA certificate to use in the `argocd-cm` configuration. + * If using the `caData` field, you'll need to base64-encode the entire certificate, including the `-----BEGIN CERTIFICATE-----` and `-----END CERTIFICATE-----` stanzas (e.g., `base64 my_cert.pem`). + * If using the `ca` field and storing the CA certificate separately as a secret, you will need to mount the secret onto the `dex` container in the `argocd-dex-server` Deployment. + * ![Identity Center SAML App 6](../../assets/identity-center-6.png) +6. Edit the `argocd-cm` and configure the `data.dex.config` section: + + +```yaml +dex.config: | + logger: + level: debug + format: json + connectors: + - type: saml + id: aws + name: "AWS IAM Identity Center" + config: + # You need value of Identity Center APP SAML (IAM Identity Center sign-in URL) + ssoURL: https://portal.sso.yourregion.amazonaws.com/saml/assertion/id + # You need `caData` _OR_ `ca`, but not both. + caData: + # Path to mount the secret to the dex container + entityIssuer: https://external.path.to.argocd.io/api/dex/callback + redirectURI: https://external.path.to.argocd.io/api/dex/callback + usernameAttr: email + emailAttr: email + groupsAttr: groups +``` + + +### Connect Identity Center Groups to Argo CD Roles +Argo CD recognizes user memberships in Identity Center groups that match the **Group Attribute Statements** regex. + + In the example above, the regex `argocd-*` is used, making Argo CD aware of a group named `argocd-admins`. + +Modify the `argocd-rbac-cm` ConfigMap to connect the `ArgoCD-administrators` Identity Center group to the builtin Argo CD `admin` role. + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-rbac-cm +data: + policy.csv: | + g, , role:admin + scopes: '[groups, email]' +``` + diff --git a/mkdocs.yml b/mkdocs.yml index 35b0b30c10345..61abeae5f8725 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -40,6 +40,7 @@ nav: - operator-manual/user-management/openunison.md - operator-manual/user-management/google.md - operator-manual/user-management/zitadel.md + - operator-manual/user-management/identity-center.md - operator-manual/rbac.md - Security: - Overview: operator-manual/security.md From 4f8c147befb7e55003402321586155c8a2eb9439 Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Fri, 27 Oct 2023 16:07:31 +0200 Subject: [PATCH 047/269] chore: let docs approvers approve mkdocs.yml (#16134) @argocd-approvers-docs cannot approve #15689 since `mkdocs.yml` is not included in the `CODEOWNERS` file. This should be pretty benign to add. Signed-off-by: Blake Pettersson --- CODEOWNERS | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 507193dad5611..ec72eccbf416e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,8 +2,9 @@ ** @argoproj/argocd-approvers # Docs -/docs/** @argoproj/argocd-approvers @argoproj/argocd-approvers-docs -/USERS.md @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/docs/** @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/USERS.md @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/mkdocs.yml @argoproj/argocd-approvers @argoproj/argocd-approvers-docs # CI /.github/** @argoproj/argocd-approvers @argoproj/argocd-approvers-ci From 9556cd7bcb3fa1aa5378beb30d4eaeb9057c4b4a Mon Sep 17 00:00:00 2001 From: Dao Thanh Tung Date: Sat, 28 Oct 2023 00:03:20 +0100 Subject: [PATCH 048/269] feat(cli): Add examples to `argocd proj role` cli family (#15875) * Add examples to argocd project role cli Signed-off-by: dttung2905 * Revert accidentally changed file Signed-off-by: dttung2905 * Rebase from master Signed-off-by: dttung2905 --------- Signed-off-by: dttung2905 --- cmd/argocd/commands/project_role.go | 119 ++++++++++++++++-- .../commands/argocd_proj_role_add-policy.md | 29 +++++ .../commands/argocd_proj_role_create-token.md | 12 ++ .../commands/argocd_proj_role_delete-token.md | 32 +++++ .../commands/argocd_proj_role_delete.md | 3 +- .../commands/argocd_proj_role_get.md | 15 +++ .../commands/argocd_proj_role_list-tokens.md | 10 ++ .../argocd_proj_role_remove-policy.md | 29 +++++ 8 files changed, 234 insertions(+), 15 deletions(-) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index 8dca406a9dc30..0828d481a5e42 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -57,6 +57,30 @@ func NewProjectRoleAddPolicyCommand(clientOpts *argocdclient.ClientOptions) *cob var command = &cobra.Command{ Use: "add-policy PROJECT ROLE-NAME", Short: "Add a policy to a project role", + Example: `# Before adding new policy +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (3 hours ago) + +# Add a new policy to allow update to the project +$ argocd proj role add-policy test-project test-role -a update -p allow -o project + +# Policy should be updated +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +p, proj:test-project:test-role, applications, update, test-project/project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (3 hours ago) +`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -94,6 +118,30 @@ func NewProjectRoleRemovePolicyCommand(clientOpts *argocdclient.ClientOptions) * var command = &cobra.Command{ Use: "remove-policy PROJECT ROLE-NAME", Short: "Remove a policy from a role within a project", + Example: `List the policy of the test-role before removing a policy +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +p, proj:test-project:test-role, applications, update, test-project/project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (3 hours ago) + +# Remove the policy to allow update to objects +$ argocd proj role remove-policy test-project test-role -a update -p allow -o project + +# The role should be removed now. +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (4 hours ago) +`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -175,13 +223,9 @@ func NewProjectRoleCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. // NewProjectRoleDeleteCommand returns a new instance of an `argocd proj role delete` command func NewProjectRoleDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ - Use: "delete PROJECT ROLE-NAME", - Short: "Delete a project role", - Example: templates.Examples(` - # Delete a project role from the "my-project" project with the name "my-role". - argocd proj role delete my-project my-role - `), - + Use: "delete PROJECT ROLE-NAME", + Short: "Delete a project role", + Example: `$ argocd proj role delete test-project test-role`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -229,8 +273,15 @@ func NewProjectRoleCreateTokenCommand(clientOpts *argocdclient.ClientOptions) *c tokenID string ) var command = &cobra.Command{ - Use: "create-token PROJECT ROLE-NAME", - Short: "Create a project token", + Use: "create-token PROJECT ROLE-NAME", + Short: "Create a project token", + Example: `$ argocd proj role create-token test-project test-role +Create token succeeded for proj:test-project:test-role. + ID: f316c466-40bd-4cfd-8a8c-1392e92255d4 + Issued At: 2023-10-08T15:21:40+01:00 + Expires At: Never + Token: xxx +`, Aliases: []string{"token-create"}, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -294,8 +345,13 @@ func NewProjectRoleListTokensCommand(clientOpts *argocdclient.ClientOptions) *co useUnixTime bool ) var command = &cobra.Command{ - Use: "list-tokens PROJECT ROLE-NAME", - Short: "List tokens for a given role.", + Use: "list-tokens PROJECT ROLE-NAME", + Short: "List tokens for a given role.", + Example: `$ argocd proj role list-tokens test-project test-role +ID ISSUED AT EXPIRES AT +f316c466-40bd-4cfd-8a8c-1392e92255d4 2023-10-08T15:21:40+01:00 Never +fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never +`, Aliases: []string{"list-token", "token-list"}, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -345,8 +401,35 @@ func NewProjectRoleListTokensCommand(clientOpts *argocdclient.ClientOptions) *co // NewProjectRoleDeleteTokenCommand returns a new instance of an `argocd proj role delete-token` command func NewProjectRoleDeleteTokenCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ - Use: "delete-token PROJECT ROLE-NAME ISSUED-AT", - Short: "Delete a project token", + Use: "delete-token PROJECT ROLE-NAME ISSUED-AT", + Short: "Delete a project token", + Example: `#Create project test-project +$ argocd proj create test-project + +# Create a role associated with test-project +$ argocd proj role create test-project test-role +Role 'test-role' created + +# Create test-role associated with test-project +$ argocd proj role create-token test-project test-role +Create token succeeded for proj:test-project:test-role. + ID: c312450e-12e1-4e0d-9f65-fac9cb027b32 + Issued At: 2023-10-08T13:58:57+01:00 + Expires At: Never + Token: xxx + +# Get test-role id to input into the delete-token command below +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696769937 2023-10-08T13:58:57+01:00 (6 minutes ago) + +$ argocd proj role delete-token test-project test-role 1696769937 +`, Aliases: []string{"token-delete", "remove-token"}, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -439,6 +522,16 @@ func NewProjectRoleGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com var command = &cobra.Command{ Use: "get PROJECT ROLE-NAME", Short: "Get the details of a specific role", + Example: `$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696774900 2023-10-08T15:21:40+01:00 (4 minutes ago) +1696759698 2023-10-08T11:08:18+01:00 (4 hours ago) +`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_proj_role_add-policy.md b/docs/user-guide/commands/argocd_proj_role_add-policy.md index a19b51e405e95..d4804d31d66a1 100644 --- a/docs/user-guide/commands/argocd_proj_role_add-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_add-policy.md @@ -8,6 +8,35 @@ Add a policy to a project role argocd proj role add-policy PROJECT ROLE-NAME [flags] ``` +### Examples + +``` +# Before adding new policy +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (3 hours ago) + +# Add a new policy to allow update to the project +$ argocd proj role add-policy test-project test-role -a update -p allow -o project + +# Policy should be updated +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +p, proj:test-project:test-role, applications, update, test-project/project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (3 hours ago) + +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_role_create-token.md b/docs/user-guide/commands/argocd_proj_role_create-token.md index 3d88481a9bc5e..fc7eaf93c2307 100644 --- a/docs/user-guide/commands/argocd_proj_role_create-token.md +++ b/docs/user-guide/commands/argocd_proj_role_create-token.md @@ -8,6 +8,18 @@ Create a project token argocd proj role create-token PROJECT ROLE-NAME [flags] ``` +### Examples + +``` +$ argocd proj role create-token test-project test-role +Create token succeeded for proj:test-project:test-role. + ID: f316c466-40bd-4cfd-8a8c-1392e92255d4 + Issued At: 2023-10-08T15:21:40+01:00 + Expires At: Never + Token: xxx + +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_role_delete-token.md b/docs/user-guide/commands/argocd_proj_role_delete-token.md index c4aa602628144..006746f8faeeb 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete-token.md +++ b/docs/user-guide/commands/argocd_proj_role_delete-token.md @@ -8,6 +8,38 @@ Delete a project token argocd proj role delete-token PROJECT ROLE-NAME ISSUED-AT [flags] ``` +### Examples + +``` +#Create project test-project +$ argocd proj create test-project + +# Create a role associated with test-project +$ argocd proj role create test-project test-role +Role 'test-role' created + +# Create test-role associated with test-project +$ argocd proj role create-token test-project test-role +Create token succeeded for proj:test-project:test-role. + ID: c312450e-12e1-4e0d-9f65-fac9cb027b32 + Issued At: 2023-10-08T13:58:57+01:00 + Expires At: Never + Token: xxx + +# Get test-role id to input into the delete-token command below +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696769937 2023-10-08T13:58:57+01:00 (6 minutes ago) + +$ argocd proj role delete-token test-project test-role 1696769937 + +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_role_delete.md b/docs/user-guide/commands/argocd_proj_role_delete.md index 0d25facb22691..fe94a2231db60 100644 --- a/docs/user-guide/commands/argocd_proj_role_delete.md +++ b/docs/user-guide/commands/argocd_proj_role_delete.md @@ -11,8 +11,7 @@ argocd proj role delete PROJECT ROLE-NAME [flags] ### Examples ``` - # Delete a project role from the "my-project" project with the name "my-role". - argocd proj role delete my-project my-role +$ argocd proj role delete test-project test-role ``` ### Options diff --git a/docs/user-guide/commands/argocd_proj_role_get.md b/docs/user-guide/commands/argocd_proj_role_get.md index a469c4d695203..e21276ce85116 100644 --- a/docs/user-guide/commands/argocd_proj_role_get.md +++ b/docs/user-guide/commands/argocd_proj_role_get.md @@ -8,6 +8,21 @@ Get the details of a specific role argocd proj role get PROJECT ROLE-NAME [flags] ``` +### Examples + +``` +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696774900 2023-10-08T15:21:40+01:00 (4 minutes ago) +1696759698 2023-10-08T11:08:18+01:00 (4 hours ago) + +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_role_list-tokens.md b/docs/user-guide/commands/argocd_proj_role_list-tokens.md index 46e9e131f52bf..8d1fe93163dfc 100644 --- a/docs/user-guide/commands/argocd_proj_role_list-tokens.md +++ b/docs/user-guide/commands/argocd_proj_role_list-tokens.md @@ -8,6 +8,16 @@ List tokens for a given role. argocd proj role list-tokens PROJECT ROLE-NAME [flags] ``` +### Examples + +``` +$ argocd proj role list-tokens test-project test-role +ID ISSUED AT EXPIRES AT +f316c466-40bd-4cfd-8a8c-1392e92255d4 2023-10-08T15:21:40+01:00 Never +fa9d3517-c52d-434c-9bff-215b38508842 2023-10-08T11:08:18+01:00 Never + +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_role_remove-policy.md b/docs/user-guide/commands/argocd_proj_role_remove-policy.md index 3f77922eacb09..96aee05da86eb 100644 --- a/docs/user-guide/commands/argocd_proj_role_remove-policy.md +++ b/docs/user-guide/commands/argocd_proj_role_remove-policy.md @@ -8,6 +8,35 @@ Remove a policy from a role within a project argocd proj role remove-policy PROJECT ROLE-NAME [flags] ``` +### Examples + +``` +List the policy of the test-role before removing a policy +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +p, proj:test-project:test-role, applications, update, test-project/project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (3 hours ago) + +# Remove the policy to allow update to objects +$ argocd proj role remove-policy test-project test-role -a update -p allow -o project + +# The role should be removed now. +$ argocd proj role get test-project test-role +Role Name: test-role +Description: +Policies: +p, proj:test-project:test-role, projects, get, test-project, allow +JWT Tokens: +ID ISSUED-AT EXPIRES-AT +1696759698 2023-10-08T11:08:18+01:00 (4 hours ago) + +``` + ### Options ``` From 0c913959250b2b475b442e134a4c9f06759ed775 Mon Sep 17 00:00:00 2001 From: Ratan Gulati Date: Sat, 28 Oct 2023 04:37:30 +0530 Subject: [PATCH 049/269] feat: Add examples to --help output for remaining "create PROJECT ROLE-NAME" (#15983) * feat: Add examples to --help output for remaining create PROJECT ROLE-NAME Signed-off-by: Ratan Gulati * feat: Add examples to --help output for remaining create PROJECT ROLE-NAME Signed-off-by: Ratan Gulati --------- Signed-off-by: Ratan Gulati --- cmd/argocd/commands/project_role.go | 5 +++++ docs/user-guide/commands/argocd_proj_role_create.md | 7 +++++++ 2 files changed, 12 insertions(+) diff --git a/cmd/argocd/commands/project_role.go b/cmd/argocd/commands/project_role.go index 0828d481a5e42..5920bac0dc8e4 100644 --- a/cmd/argocd/commands/project_role.go +++ b/cmd/argocd/commands/project_role.go @@ -189,6 +189,11 @@ func NewProjectRoleCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. var command = &cobra.Command{ Use: "create PROJECT ROLE-NAME", Short: "Create a project role", + Example: templates.Examples(` + # Create a project role in the "my-project" project with the name "my-role". + argocd proj role create my-project my-role --description "My project role description" + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_proj_role_create.md b/docs/user-guide/commands/argocd_proj_role_create.md index 6bfbd0c077232..60974c9e1b4e6 100644 --- a/docs/user-guide/commands/argocd_proj_role_create.md +++ b/docs/user-guide/commands/argocd_proj_role_create.md @@ -8,6 +8,13 @@ Create a project role argocd proj role create PROJECT ROLE-NAME [flags] ``` +### Examples + +``` + # Create a project role in the "my-project" project with the name "my-role". + argocd proj role create my-project my-role --description "My project role description" +``` + ### Options ``` From 9b1fb1d98e32d2531bcbf4c3853bdde17fc35fa4 Mon Sep 17 00:00:00 2001 From: Ratan Gulati Date: Sat, 28 Oct 2023 04:52:15 +0530 Subject: [PATCH 050/269] feat(cli): Add examples to --help output for "gpg_list" (#16017) * feat: Add examples to --help output for list Signed-off-by: Ratan Gulati * updated file Signed-off-by: Ratan Gulati --------- Signed-off-by: Ratan Gulati --- cmd/argocd/commands/gpg.go | 11 +++++++++++ docs/user-guide/commands/argocd_gpg_list.md | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go index 3c0496d2f012a..e1fd1dd0ff3a8 100644 --- a/cmd/argocd/commands/gpg.go +++ b/cmd/argocd/commands/gpg.go @@ -43,6 +43,17 @@ func NewGPGListCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "list", Short: "List configured GPG public keys", + Example: templates.Examples(` + # List all configured GPG public keys in wide format (default). + argocd gpg list + + # List all configured GPG public keys in JSON format. + argocd gpg list -o json + + # List all configured GPG public keys in YAML format. + argocd gpg list -o yaml + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_gpg_list.md b/docs/user-guide/commands/argocd_gpg_list.md index 9e280cca30631..50f0e72e83c0d 100644 --- a/docs/user-guide/commands/argocd_gpg_list.md +++ b/docs/user-guide/commands/argocd_gpg_list.md @@ -8,6 +8,19 @@ List configured GPG public keys argocd gpg list [flags] ``` +### Examples + +``` + # List all configured GPG public keys in wide format (default). + argocd gpg list + + # List all configured GPG public keys in JSON format. + argocd gpg list -o json + + # List all configured GPG public keys in YAML format. + argocd gpg list -o yaml +``` + ### Options ``` From f5530355a9270fd53c127dd0f6d7306abf8a610f Mon Sep 17 00:00:00 2001 From: Ratan Gulati Date: Sat, 28 Oct 2023 04:54:25 +0530 Subject: [PATCH 051/269] feat(cli): Add examples to --help output for get KEYID (#16019) Signed-off-by: Ratan Gulati --- cmd/argocd/commands/gpg.go | 11 +++++++++++ docs/user-guide/commands/argocd_gpg_get.md | 13 +++++++++++++ 2 files changed, 24 insertions(+) diff --git a/cmd/argocd/commands/gpg.go b/cmd/argocd/commands/gpg.go index e1fd1dd0ff3a8..73768fc18a324 100644 --- a/cmd/argocd/commands/gpg.go +++ b/cmd/argocd/commands/gpg.go @@ -84,6 +84,17 @@ func NewGPGGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var command = &cobra.Command{ Use: "get KEYID", Short: "Get the GPG public key with ID from the server", + Example: templates.Examples(` + # Get a GPG public key with the specified KEYID in wide format (default). + argocd gpg get KEYID + + # Get a GPG public key with the specified KEYID in JSON format. + argocd gpg get KEYID -o json + + # Get a GPG public key with the specified KEYID in YAML format. + argocd gpg get KEYID -o yaml + `), + Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_gpg_get.md b/docs/user-guide/commands/argocd_gpg_get.md index 0810b880cd8d2..e0ad3d9ee25d6 100644 --- a/docs/user-guide/commands/argocd_gpg_get.md +++ b/docs/user-guide/commands/argocd_gpg_get.md @@ -8,6 +8,19 @@ Get the GPG public key with ID from the server argocd gpg get KEYID [flags] ``` +### Examples + +``` + # Get a GPG public key with the specified KEYID in wide format (default). + argocd gpg get KEYID + + # Get a GPG public key with the specified KEYID in JSON format. + argocd gpg get KEYID -o json + + # Get a GPG public key with the specified KEYID in YAML format. + argocd gpg get KEYID -o yaml +``` + ### Options ``` From 4124adc6937ac7f9ac784f8630e42925c64b3ec9 Mon Sep 17 00:00:00 2001 From: Kunal Singh Date: Sat, 28 Oct 2023 05:12:22 +0530 Subject: [PATCH 052/269] docs(appset): ApplicationSets generators docs to use go templates (#16109) (#16127) * docs: migrating fasttemplate to go-template; Git Generator Signed-off-by: Kunal Singh * docs: missing yaml language specifier stopping syntax highlighting Signed-off-by: Kunal Singh * docs: migrate List Generators page to go-templates Signed-off-by: Kunal Singh * docs: migrate Matrix, Merge & SCM Provider Generators page to go-templates Signed-off-by: Kunal Singh * docs: migrating fasttemplate to go-template Signed-off-by: Kunal Singh --------- Signed-off-by: Kunal Singh --- .../applicationset/Appset-Any-Namespace.md | 18 ++++++---- .../Generators-Cluster-Decision-Resource.md | 6 ++-- .../applicationset/Generators-Cluster.md | 32 +++++++++++------ .../applicationset/Generators-Git.md | 36 ++++++++++--------- .../applicationset/Generators-List.md | 13 +++---- .../applicationset/Generators-Matrix.md | 36 +++++++++++-------- .../applicationset/Generators-Merge.md | 26 ++++++++------ .../applicationset/Generators-Plugin.md | 9 +++-- .../Generators-Post-Selector.md | 8 +++-- .../applicationset/Generators-Pull-Request.md | 36 ++++++++++++++----- .../applicationset/Generators-SCM-Provider.md | 18 ++++++---- .../applicationset/Progressive-Syncs.md | 3 +- .../applicationset/Use-Cases.md | 22 ++++++++++-- docs/operator-manual/applicationset/index.md | 8 +++-- 14 files changed, 174 insertions(+), 97 deletions(-) diff --git a/docs/operator-manual/applicationset/Appset-Any-Namespace.md b/docs/operator-manual/applicationset/Appset-Any-Namespace.md index 61716414aeb69..bf3f8ffecfaf1 100644 --- a/docs/operator-manual/applicationset/Appset-Any-Namespace.md +++ b/docs/operator-manual/applicationset/Appset-Any-Namespace.md @@ -35,6 +35,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - scmProvider: gitea: @@ -137,17 +139,19 @@ metadata: name: team-one-product-one namespace: team-one-cd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: list: - - id: infra + - name: infra project: infra-project - - id: team-two + - name: team-two project: team-two-project - template: - metadata: - name: '{{name}}-escalation' - spec: - project: "{{project}}" + template: + metadata: + name: '{{.name}}-escalation' + spec: + project: "{{.project}}" ``` ### ApplicationSet names diff --git a/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md b/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md index 8f5bb491b8b44..44567884dccf8 100644 --- a/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md +++ b/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md @@ -8,6 +8,8 @@ metadata: name: guestbook namespace: argocd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - clusterDecisionResource: # ConfigMap with GVK information for the duck type resource @@ -26,7 +28,7 @@ spec: requeueAfterSeconds: 60 template: metadata: - name: '{{name}}-guestbook' + name: '{{.name}}-guestbook' spec: project: "default" source: @@ -34,7 +36,7 @@ spec: targetRevision: HEAD path: guestbook destination: - server: '{{clusterName}}' # 'server' field of the secret + server: '{{.clusterName}}' # 'server' field of the secret namespace: guestbook ``` The `quak` resource, referenced by the ApplicationSet `clusterDecisionResource` generator: diff --git a/docs/operator-manual/applicationset/Generators-Cluster.md b/docs/operator-manual/applicationset/Generators-Cluster.md index 92507645a4ffe..ca1a49aad295b 100644 --- a/docs/operator-manual/applicationset/Generators-Cluster.md +++ b/docs/operator-manual/applicationset/Generators-Cluster.md @@ -39,11 +39,13 @@ metadata: name: guestbook namespace: argocd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - clusters: {} # Automatically use all clusters defined within Argo CD template: metadata: - name: '{{name}}-guestbook' # 'name' field of the Secret + name: '{{.name}}-guestbook' # 'name' field of the Secret spec: project: "my-project" source: @@ -51,7 +53,7 @@ spec: targetRevision: HEAD path: guestbook destination: - server: '{{server}}' # 'server' field of the secret + server: '{{.server}}' # 'server' field of the secret namespace: guestbook ``` (*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/cluster).*) @@ -67,6 +69,8 @@ metadata: name: guestbook namespace: argocd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - clusters: selector: @@ -105,6 +109,8 @@ The cluster generator will automatically target both local and non-local cluster If you wish to target only remote clusters with your Applications (e.g. you want to exclude the local cluster), then use a cluster selector with labels, for example: ```yaml spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - clusters: selector: @@ -137,6 +143,8 @@ You may pass additional, arbitrary string key-value pairs via the `values` field In this example, a `revision` parameter value is passed, based on matching labels on the cluster secret: ```yaml spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - clusters: selector: @@ -154,16 +162,16 @@ spec: revision: stable template: metadata: - name: '{{name}}-guestbook' + name: '{{.name}}-guestbook' spec: project: "my-project" source: repoURL: https://github.com/argoproj/argocd-example-apps/ # The cluster values field for each generator will be substituted here: - targetRevision: '{{values.revision}}' + targetRevision: '{{.values.revision}}' path: guestbook destination: - server: '{{server}}' + server: '{{.server}}' namespace: guestbook ``` @@ -184,6 +192,8 @@ Extending the example above, we could do something like this: ```yaml spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - clusters: selector: @@ -192,8 +202,8 @@ spec: # A key-value map for arbitrary parameters values: # If `my-custom-annotation` is in your cluster secret, `revision` will be substituted with it. - revision: '{{metadata.annotations.my-custom-annotation}}' - clusterName: '{{name}}' + revision: '{{index .metadata.annotations "my-custom-annotation"}}' + clusterName: '{{.name}}' - clusters: selector: matchLabels: @@ -201,19 +211,19 @@ spec: values: # production uses a different revision value, for 'stable' branch revision: stable - clusterName: '{{name}}' + clusterName: '{{.name}}' template: metadata: - name: '{{name}}-guestbook' + name: '{{.name}}-guestbook' spec: project: "my-project" source: repoURL: https://github.com/argoproj/argocd-example-apps/ # The cluster values field for each generator will be substituted here: - targetRevision: '{{values.revision}}' + targetRevision: '{{.values.revision}}' path: guestbook destination: # In this case this is equivalent to just using {{name}} - server: '{{values.clusterName}}' + server: '{{.values.clusterName}}' namespace: guestbook ``` diff --git a/docs/operator-manual/applicationset/Generators-Git.md b/docs/operator-manual/applicationset/Generators-Git.md index 1dcd85ea24b2a..24fb3427d73b0 100644 --- a/docs/operator-manual/applicationset/Generators-Git.md +++ b/docs/operator-manual/applicationset/Generators-Git.md @@ -210,6 +210,8 @@ metadata: name: cluster-addons namespace: argocd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - git: repoURL: https://github.com/example/example-repo.git @@ -217,19 +219,19 @@ spec: directories: - path: '*' values: - cluster: '{{branch}}-{{path}}' + cluster: '{{.branch}}-{{.path.basename}}' template: metadata: - name: '{{path.basename}}' + name: '{{.path.basename}}' spec: project: "my-project" source: repoURL: https://github.com/example/example-repo.git targetRevision: HEAD - path: '{{path}}' + path: '{{.path.path}}' destination: server: https://kubernetes.default.svc - namespace: '{{values.cluster}}' + namespace: '{{.values.cluster}}' ``` !!! note @@ -323,15 +325,15 @@ As with other generators, clusters *must* already be defined within Argo CD, in In addition to the flattened key/value pairs from the configuration file, the following generator parameters are provided: -- `{{path}}`: The path to the directory containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json` -- `{{path[n]}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `path[0]: clusters`, `path[1]: clusterA` -- `{{path.basename}}`: Basename of the path to the directory containing the configuration file (e.g. `clusterA`, with the above example.) -- `{{path.basenameNormalized}}`: This field is the same as `path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `path.basename` of `directory_2` would produce `directory-2` here). -- `{{path.filename}}`: The matched filename. e.g., `config.json` in the above example. -- `{{path.filenameNormalized}}`: The matched filename with unsupported characters replaced with `-`. +- `{{.path.path}}`: The path to the directory containing matching configuration file within the Git repository. Example: `/clusters/clusterA`, if the config file was `/clusters/clusterA/config.json` +- `{{index .path n}}`: The path to the matching configuration file within the Git repository, split into array elements (`n` - array index). Example: `index .path 0: clusters`, `index .path 1: clusterA` +- `{{.path.basename}}`: Basename of the path to the directory containing the configuration file (e.g. `clusterA`, with the above example.) +- `{{.path.basenameNormalized}}`: This field is the same as `.path.basename` with unsupported characters replaced with `-` (e.g. a `path` of `/directory/directory_2`, and `.path.basename` of `directory_2` would produce `directory-2` here). +- `{{.path.filename}}`: The matched filename. e.g., `config.json` in the above example. +- `{{.path.filenameNormalized}}`: The matched filename with unsupported characters replaced with `-`. -**Note**: The right-most *directory* name always becomes `{{path.basename}}`. For example, from `- path: /one/two/three/four/config.json`, `{{path.basename}}` will be `four`. -The filename can always be accessed using `{{path.filename}}`. +**Note**: The right-most *directory* name always becomes `{{.path.basename}}`. For example, from `- path: /one/two/three/four/config.json`, `{{.path.basename}}` will be `four`. +The filename can always be accessed using `{{.path.filename}}`. **Note**: If the `pathParamPrefix` option is specified, all `path`-related parameter names above will be prefixed with the specified value and a dot separator. E.g., if `pathParamPrefix` is `myRepo`, then the generated parameter name would be `myRepo.path` instead of `path`. Using this option is necessary in a Matrix generator where both child generators are Git generators (to avoid conflicts when merging the child generators’ items). @@ -349,6 +351,8 @@ metadata: name: guestbook namespace: argocd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - git: repoURL: https://github.com/argoproj/argo-cd.git @@ -356,18 +360,18 @@ spec: files: - path: "applicationset/examples/git-generator-files-discovery/cluster-config/**/config.json" values: - base_dir: "{{path[0]}}/{{path[1]}}/{{path[2]}}" + base_dir: "{{index .path 0}}/{{index .path 1}}/{{index .path 2}}" template: metadata: - name: '{{cluster.name}}-guestbook' + name: '{{.cluster.name}}-guestbook' spec: project: default source: repoURL: https://github.com/argoproj/argo-cd.git targetRevision: HEAD - path: "{{values.base_dir}}/apps/guestbook" + path: "{{.values.base_dir}}/apps/guestbook" destination: - server: '{{cluster.address}}' + server: '{{.cluster.address}}' namespace: guestbook ``` diff --git a/docs/operator-manual/applicationset/Generators-List.md b/docs/operator-manual/applicationset/Generators-List.md index a99229f858da4..e5696f37b9745 100644 --- a/docs/operator-manual/applicationset/Generators-List.md +++ b/docs/operator-manual/applicationset/Generators-List.md @@ -8,25 +8,26 @@ metadata: name: guestbook namespace: argocd spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - list: elements: - cluster: engineering-dev url: https://kubernetes.default.svc -# - cluster: engineering-prod -# url: https://kubernetes.default.svc -# foo: bar + - cluster: engineering-prod + url: https://kubernetes.default.svc template: metadata: - name: '{{cluster}}-guestbook' + name: '{{.cluster}}-guestbook' spec: project: "my-project" source: repoURL: https://github.com/argoproj/argo-cd.git targetRevision: HEAD - path: applicationset/examples/list-generator/guestbook/{{cluster}} + path: applicationset/examples/list-generator/guestbook/{{.cluster}} destination: - server: '{{url}}' + server: '{{.url}}' namespace: guestbook ``` (*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/list-generator).*) diff --git a/docs/operator-manual/applicationset/Generators-Matrix.md b/docs/operator-manual/applicationset/Generators-Matrix.md index 6684cdc90f73b..0396b8c0e06d3 100644 --- a/docs/operator-manual/applicationset/Generators-Matrix.md +++ b/docs/operator-manual/applicationset/Generators-Matrix.md @@ -35,6 +35,8 @@ kind: ApplicationSet metadata: name: cluster-git spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: # matrix 'parent' generator - matrix: @@ -52,16 +54,16 @@ spec: argocd.argoproj.io/secret-type: cluster template: metadata: - name: '{{path.basename}}-{{name}}' + name: '{{.path.basename}}-{{.name}}' spec: - project: '{{metadata.labels.environment}}' + project: '{{index .metadata.labels "environment"}}' source: repoURL: https://github.com/argoproj/argo-cd.git targetRevision: HEAD - path: '{{path}}' + path: '{{.path.path}}' destination: - server: '{{server}}' - namespace: '{{path.basename}}' + server: '{{.server}}' + namespace: '{{.path.basename}}' ``` First, the Git directory generator will scan the Git repository, discovering directories under the specified path. It discovers the argo-workflows and prometheus-operator applications, and produces two corresponding sets of parameters: @@ -117,6 +119,8 @@ kind: ApplicationSet metadata: name: cluster-git spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: # matrix 'parent' generator - matrix: @@ -132,10 +136,10 @@ spec: selector: matchLabels: argocd.argoproj.io/secret-type: cluster - kubernetes.io/environment: '{{path.basename}}' + kubernetes.io/environment: '{{.path.basename}}' template: metadata: - name: '{{name}}-guestbook' + name: '{{.name}}-guestbook' spec: project: default source: @@ -143,7 +147,7 @@ spec: targetRevision: HEAD path: "examples/git-generator-files-discovery/apps/guestbook" destination: - server: '{{server}}' + server: '{{.server}}' namespace: guestbook ``` Here is the corresponding folder structure for the git repository used by the git-files generator: @@ -162,8 +166,8 @@ Here is the corresponding folder structure for the git repository used by the gi │ └── config.json └── git-generator-files.yaml ``` -In the above example, the `{{path.basename}}` parameters produced by the git-files generator will resolve to `dev` and `prod`. -In the 2nd child generator, the label selector with label `kubernetes.io/environment: {{path.basename}}` will resolve with the values produced by the first child generator's parameters (`kubernetes.io/environment: prod` and `kubernetes.io/environment: dev`). +In the above example, the `{{.path.basename}}` parameters produced by the git-files generator will resolve to `dev` and `prod`. +In the 2nd child generator, the label selector with label `kubernetes.io/environment: {{.path.basename}}` will resolve with the values produced by the first child generator's parameters (`kubernetes.io/environment: prod` and `kubernetes.io/environment: dev`). So in the above example, clusters with the label `kubernetes.io/environment: prod` will have only prod-specific configuration (ie. `prod/config.json`) applied to it, wheres clusters with the label `kubernetes.io/environment: dev` will have only dev-specific configuration (ie. `dev/config.json`) @@ -262,6 +266,8 @@ kind: ApplicationSet metadata: name: two-gits-with-path-param-prefix spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - matrix: generators: @@ -280,7 +286,7 @@ spec: repoURL: https://github.com/some-org/some-repo.git revision: HEAD files: - - path: "targets/{{appName}}/*.json" + - path: "targets/{{.appName}}/*.json" pathParamPrefix: target template: {} # ... ``` @@ -390,7 +396,7 @@ For example, the below example would be invalid (cluster-generator must come aft selector: matchLabels: argocd.argoproj.io/secret-type: cluster - kubernetes.io/environment: '{{path.basename}}' # {{path.basename}} is produced by git-files generator + kubernetes.io/environment: '{{.path.basename}}' # {{.path.basename}} is produced by git-files generator # git generator, 'child' #2 - git: repoURL: https://github.com/argoproj/applicationset.git @@ -398,7 +404,7 @@ For example, the below example would be invalid (cluster-generator must come aft files: - path: "examples/git-generator-files-discovery/cluster-config/**/config.json" -1. You cannot have both child generators consuming parameters from each another. In the example below, the cluster generator is consuming the `{{path.basename}}` parameter produced by the git-files generator, whereas the git-files generator is consuming the `{{name}}` parameter produced by the cluster generator. This will result in a circular dependency, which is invalid. +1. You cannot have both child generators consuming parameters from each another. In the example below, the cluster generator is consuming the `{{.path.basename}}` parameter produced by the git-files generator, whereas the git-files generator is consuming the `{{.name}}` parameter produced by the cluster generator. This will result in a circular dependency, which is invalid. - matrix: generators: @@ -407,13 +413,13 @@ For example, the below example would be invalid (cluster-generator must come aft selector: matchLabels: argocd.argoproj.io/secret-type: cluster - kubernetes.io/environment: '{{path.basename}}' # {{path.basename}} is produced by git-files generator + kubernetes.io/environment: '{{.path.basename}}' # {{.path.basename}} is produced by git-files generator # git generator, 'child' #2 - git: repoURL: https://github.com/argoproj/applicationset.git revision: HEAD files: - - path: "examples/git-generator-files-discovery/cluster-config/engineering/{{name}}**/config.json" # {{name}} is produced by cluster generator + - path: "examples/git-generator-files-discovery/cluster-config/engineering/{{.name}}**/config.json" # {{.name}} is produced by cluster generator 1. When using a Matrix generator nested inside another Matrix or Merge generator, [Post Selectors](Generators-Post-Selector.md) for this nested generator's generators will only be applied when enabled via `spec.applyNestedSelectors`. You may also need to enable this even if your Post Selectors are not within the nested matrix or Merge generator, but are instead a sibling of a nested Matrix or Merge generator. diff --git a/docs/operator-manual/applicationset/Generators-Merge.md b/docs/operator-manual/applicationset/Generators-Merge.md index 50da174cf349a..b2ccfe86fb66d 100644 --- a/docs/operator-manual/applicationset/Generators-Merge.md +++ b/docs/operator-manual/applicationset/Generators-Merge.md @@ -17,6 +17,8 @@ kind: ApplicationSet metadata: name: cluster-git spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: # merge 'parent' generator - merge: @@ -41,9 +43,9 @@ spec: values.redis: 'true' template: metadata: - name: '{{name}}' + name: '{{.name}}' spec: - project: '{{metadata.labels.environment}}' + project: '{{index .metadata.labels "environment"}}' source: repoURL: https://github.com/argoproj/argo-cd.git targetRevision: HEAD @@ -51,11 +53,11 @@ spec: helm: parameters: - name: kafka - value: '{{values.kafka}}' + value: '{{.values.kafka}}' - name: redis - value: '{{values.redis}}' + value: '{{.values.redis}}' destination: - server: '{{server}}' + server: '{{.server}}' namespace: default ``` @@ -122,6 +124,8 @@ kind: ApplicationSet metadata: name: cluster-git spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: # merge 'parent' generator: # Use the selector set by both child generators to combine them. @@ -135,7 +139,7 @@ spec: # Set the selector to this location. - clusters: values: - selector: '{{ metadata.labels.location }}' + selector: '{{index .metadata.labels "location"}}' # The git repo may have different directories which correspond to the # cluster locations, using these as a selector. - git: @@ -144,19 +148,19 @@ spec: directories: - path: '*' values: - selector: '{{ path }}' + selector: '{{.path.path}}' template: metadata: - name: '{{name}}' + name: '{{.name}}' spec: - project: '{{metadata.labels.environment}}' + project: '{{index .metadata.labels "environment"}}' source: repoURL: https://github.com/argoproj/argocd-example-apps/ # The cluster values field for each generator will be substituted here: targetRevision: HEAD - path: '{{path}}' + path: '{{.path.path}}' destination: - server: '{{server}}' + server: '{{.server}}' namespace: default ``` diff --git a/docs/operator-manual/applicationset/Generators-Plugin.md b/docs/operator-manual/applicationset/Generators-Plugin.md index 3747c38865df5..d0888b9949b8e 100644 --- a/docs/operator-manual/applicationset/Generators-Plugin.md +++ b/docs/operator-manual/applicationset/Generators-Plugin.md @@ -22,6 +22,8 @@ kind: ApplicationSet metadata: name: myplugin spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - plugin: # Specify the configMap where the plugin configuration is located. @@ -51,10 +53,10 @@ spec: metadata: name: myplugin annotations: - example.from.input.parameters: "{{ generator.input.parameters.map.key1 }}" - example.from.values: "{{ values.value1 }}" + example.from.input.parameters: "{{ index .generator.input.parameters.map "key1" }}" + example.from.values: "{{ .values.value1 }}" # The plugin determines what else it produces. - example.from.plugin.output: "{{ something.from.the.plugin }}" + example.from.plugin.output: "{{ .something.from.the.plugin }}" ``` - `configMapRef.name`: A `ConfigMap` name containing the plugin configuration to use for RPC call. @@ -230,6 +232,7 @@ metadata: name: fb-matrix spec: goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - matrix: generators: diff --git a/docs/operator-manual/applicationset/Generators-Post-Selector.md b/docs/operator-manual/applicationset/Generators-Post-Selector.md index d8570859084ff..aac134e0b6212 100644 --- a/docs/operator-manual/applicationset/Generators-Post-Selector.md +++ b/docs/operator-manual/applicationset/Generators-Post-Selector.md @@ -9,6 +9,8 @@ kind: ApplicationSet metadata: name: guestbook spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - list: elements: @@ -23,15 +25,15 @@ spec: env: staging template: metadata: - name: '{{cluster}}-guestbook' + name: '{{.cluster}}-guestbook' spec: project: default source: repoURL: https://github.com/argoproj-labs/applicationset.git targetRevision: HEAD - path: examples/list-generator/guestbook/{{cluster}} + path: examples/list-generator/guestbook/{{.cluster}} destination: - server: '{{url}}' + server: '{{.url}}' namespace: guestbook ``` diff --git a/docs/operator-manual/applicationset/Generators-Pull-Request.md b/docs/operator-manual/applicationset/Generators-Pull-Request.md index 298e5135392ce..e54fc385d7d28 100644 --- a/docs/operator-manual/applicationset/Generators-Pull-Request.md +++ b/docs/operator-manual/applicationset/Generators-Pull-Request.md @@ -8,6 +8,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: # When using a Pull Request generator, the ApplicationSet controller polls every `requeueAfterSeconds` interval (defaulting to every 30 minutes) to detect changes. @@ -33,6 +35,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: github: @@ -75,6 +79,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: gitlab: @@ -117,6 +123,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: gitea: @@ -153,6 +161,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: bitbucketServer: @@ -195,6 +205,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: bitbucket: @@ -251,6 +263,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: azuredevops: @@ -292,6 +306,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: # ... @@ -319,21 +335,23 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: # ... template: metadata: - name: 'myapp-{{branch}}-{{number}}' + name: 'myapp-{{.branch}}-{{.number}}' spec: source: repoURL: 'https://github.com/myorg/myrepo.git' - targetRevision: '{{head_sha}}' + targetRevision: '{{.head_sha}}' path: kubernetes/ helm: parameters: - name: "image.tag" - value: "pull-{{head_sha}}" + value: "pull-{{.head_sha}}" project: "my-project" destination: server: https://kubernetes.default.svc @@ -348,23 +366,25 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - pullRequest: # ... template: metadata: - name: 'myapp-{{branch}}-{{number}}' + name: 'myapp-{{.branch}}-{{.number}}' spec: source: repoURL: 'https://github.com/myorg/myrepo.git' - targetRevision: '{{head_sha}}' + targetRevision: '{{.head_sha}}' path: kubernetes/ kustomize: - nameSuffix: {{branch}} + nameSuffix: '{{.branch}}' commonLabels: - app.kubernetes.io/instance: {{branch}}-{{number}} + app.kubernetes.io/instance: '{{.branch}}-{{.number}}' images: - - ghcr.io/myorg/myrepo:{{head_sha}} + - 'ghcr.io/myorg/myrepo:{{.head_sha}}' project: "my-project" destination: server: https://kubernetes.default.svc diff --git a/docs/operator-manual/applicationset/Generators-SCM-Provider.md b/docs/operator-manual/applicationset/Generators-SCM-Provider.md index 5e3c4a6ab8aa4..6b11d344eac80 100644 --- a/docs/operator-manual/applicationset/Generators-SCM-Provider.md +++ b/docs/operator-manual/applicationset/Generators-SCM-Provider.md @@ -395,16 +395,18 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - scmProvider: # ... template: metadata: - name: '{{ repository }}' + name: '{{ .repository }}' spec: source: - repoURL: '{{ url }}' - targetRevision: '{{ branch }}' + repoURL: '{{ .url }}' + targetRevision: '{{ .branch }}' path: kubernetes/ project: default destination: @@ -433,6 +435,8 @@ kind: ApplicationSet metadata: name: myapps spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - scmProvider: bitbucketServer: @@ -445,15 +449,15 @@ spec: secretName: mypassword key: password values: - name: "{{organization}}-{{repository}}" + name: "{{.organization}}-{{.repository}}" template: metadata: - name: '{{ values.name }}' + name: '{{ .values.name }}' spec: source: - repoURL: '{{ url }}' - targetRevision: '{{ branch }}' + repoURL: '{{ .url }}' + targetRevision: '{{ .branch }}' path: kubernetes/ project: default destination: diff --git a/docs/operator-manual/applicationset/Progressive-Syncs.md b/docs/operator-manual/applicationset/Progressive-Syncs.md index 8864151e9dcb7..edfe0dad101f2 100644 --- a/docs/operator-manual/applicationset/Progressive-Syncs.md +++ b/docs/operator-manual/applicationset/Progressive-Syncs.md @@ -52,8 +52,7 @@ Once a change is pushed, the following will happen in order. * The rollout will wait for all `env-qa` Applications to be manually synced via the `argocd` CLI or by clicking the Sync button in the UI. * 10% of all `env-prod` Applications will be updated at a time until all `env-prod` Applications have been updated. -``` ---- +```yaml apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: diff --git a/docs/operator-manual/applicationset/Use-Cases.md b/docs/operator-manual/applicationset/Use-Cases.md index 0e9c65d3963ee..a13c6598072ca 100644 --- a/docs/operator-manual/applicationset/Use-Cases.md +++ b/docs/operator-manual/applicationset/Use-Cases.md @@ -68,10 +68,26 @@ Thus in the self-service use case, administrators desire to only allow some fiel Fortunately, the ApplicationSet controller presents an alternative solution to this use case: cluster administrators may safely create an `ApplicationSet` resource containing a Git generator that restricts deployment of application resources to fixed values with the `template` field, while allowing customization of 'safe' fields by developers, at will. +The `config.json` files contain information describing the app. + +```json +{ + (...) + "app": { + "source": "https://github.com/argoproj/argo-cd", + "revision": "HEAD", + "path": "applicationset/examples/git-generator-files-discovery/apps/guestbook" + } + (...) +} +``` + ```yaml kind: ApplicationSet # (...) spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - git: repoURL: https://github.com/argoproj/argo-cd.git @@ -82,9 +98,9 @@ spec: project: dev-team-one # project is restricted source: # developers may customize app details using JSON files from above repo URL - repoURL: {{app.source}} - targetRevision: {{app.revision}} - path: {{app.path}} + repoURL: {{.app.source}} + targetRevision: {{.app.revision}} + path: {{.app.path}} destination: name: production-cluster # cluster is restricted namespace: dev-team-one # namespace is restricted diff --git a/docs/operator-manual/applicationset/index.md b/docs/operator-manual/applicationset/index.md index 1fe83fb2a0952..ea7c0f3deaf5d 100644 --- a/docs/operator-manual/applicationset/index.md +++ b/docs/operator-manual/applicationset/index.md @@ -27,6 +27,8 @@ kind: ApplicationSet metadata: name: guestbook spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] generators: - list: elements: @@ -38,15 +40,15 @@ spec: url: https://9.8.7.6 template: metadata: - name: '{{cluster}}-guestbook' + name: '{{.cluster}}-guestbook' spec: project: my-project source: repoURL: https://github.com/infra-team/cluster-deployments.git targetRevision: HEAD - path: guestbook/{{cluster}} + path: guestbook/{{.cluster}} destination: - server: '{{url}}' + server: '{{.url}}' namespace: guestbook ``` From ce12527434a6e0e7a383d3acc7b2c6968153f1c4 Mon Sep 17 00:00:00 2001 From: Christopher Fry Date: Sat, 28 Oct 2023 08:35:39 -0700 Subject: [PATCH 053/269] chore: fix typo in declarative tests filename (#15934) Signed-off-by: Chris Fry --- test/e2e/{delarative_test.go => declarative_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/e2e/{delarative_test.go => declarative_test.go} (100%) diff --git a/test/e2e/delarative_test.go b/test/e2e/declarative_test.go similarity index 100% rename from test/e2e/delarative_test.go rename to test/e2e/declarative_test.go From 0cc0d46212f090d03147eeadf5705dc7fe138ee9 Mon Sep 17 00:00:00 2001 From: "Jayaraman N.R" Date: Sat, 28 Oct 2023 22:26:45 +0530 Subject: [PATCH 054/269] feat(cli): example for generate-allow-list (#16136) Signed-off-by: Jayaraman N R Signed-off-by: Jayaraman N.R Co-authored-by: Jayaraman N R --- cmd/argocd/commands/admin/project_allowlist.go | 2 ++ .../commands/argocd_admin_proj_generate-allow-list.md | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/cmd/argocd/commands/admin/project_allowlist.go b/cmd/argocd/commands/admin/project_allowlist.go index 57b855251daa9..460ea21d93329 100644 --- a/cmd/argocd/commands/admin/project_allowlist.go +++ b/cmd/argocd/commands/admin/project_allowlist.go @@ -41,6 +41,8 @@ func NewProjectAllowListGenCommand() *cobra.Command { var command = &cobra.Command{ Use: "generate-allow-list CLUSTERROLE_PATH PROJ_NAME", Short: "Generates project allow list from the specified clusterRole file", + Example: `# Generates project allow list from the specified clusterRole file +argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project`, Run: func(c *cobra.Command, args []string) { if len(args) != 2 { c.HelpFunc()(c, args) diff --git a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md index a16d6468cb446..83dc00a6096b4 100644 --- a/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md +++ b/docs/user-guide/commands/argocd_admin_proj_generate-allow-list.md @@ -8,6 +8,13 @@ Generates project allow list from the specified clusterRole file argocd admin proj generate-allow-list CLUSTERROLE_PATH PROJ_NAME [flags] ``` +### Examples + +``` +# Generates project allow list from the specified clusterRole file +argocd admin proj generate-allow-list /path/to/clusterrole.yaml my-project +``` + ### Options ``` From 91bd63af247b9ad5c168114ce13ed607abcf5f03 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 29 Oct 2023 18:56:38 -0400 Subject: [PATCH 055/269] [Bot] docs: Update Snyk reports (#16143) Signed-off-by: CI Co-authored-by: CI --- docs/snyk/index.md | 60 +- docs/snyk/master/argocd-iac-install.html | 26 +- .../master/argocd-iac-namespace-install.html | 26 +- docs/snyk/master/argocd-test.html | 2 +- .../master/ghcr.io_dexidp_dex_v2.37.0.html | 183 +- docs/snyk/master/haproxy_2.6.14-alpine.html | 201 +- .../quay.io_argoproj_argocd_latest.html | 610 +-- docs/snyk/master/redis_7.0.11-alpine.html | 199 +- docs/snyk/v2.6.15/argocd-iac-install.html | 2 +- .../v2.6.15/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.6.15/argocd-test.html | 8 +- .../v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html | 183 +- docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html | 201 +- .../quay.io_argoproj_argocd_v2.6.15.html | 236 +- docs/snyk/v2.6.15/redis_7.0.11-alpine.html | 199 +- docs/snyk/v2.7.14/argocd-iac-install.html | 2 +- .../v2.7.14/argocd-iac-namespace-install.html | 2 +- docs/snyk/v2.7.14/argocd-test.html | 8 +- .../v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html | 183 +- docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html | 201 +- .../quay.io_argoproj_argocd_v2.7.14.html | 236 +- docs/snyk/v2.7.14/redis_7.0.11-alpine.html | 199 +- docs/snyk/v2.8.4/argocd-test.html | 3684 ----------------- .../argocd-iac-install.html | 40 +- .../argocd-iac-namespace-install.html | 40 +- docs/snyk/v2.8.5/argocd-test.html | 1031 +++++ .../ghcr.io_dexidp_dex_v2.37.0.html | 183 +- .../haproxy_2.6.14-alpine.html | 201 +- .../quay.io_argoproj_argocd_v2.8.5.html} | 1922 ++------- .../redis_7.0.11-alpine.html | 199 +- .../argocd-iac-install.html | 2 +- .../argocd-iac-namespace-install.html | 2 +- .../argocd-test.html | 8 +- .../ghcr.io_dexidp_dex_v2.37.0.html | 183 +- .../haproxy_2.6.14-alpine.html | 201 +- .../quay.io_argoproj_argocd_v2.9.0-rc3.html} | 1902 ++------- .../redis_7.0.11-alpine.html | 199 +- 37 files changed, 5126 insertions(+), 7640 deletions(-) delete mode 100644 docs/snyk/v2.8.4/argocd-test.html rename docs/snyk/{v2.8.4 => v2.8.5}/argocd-iac-install.html (99%) rename docs/snyk/{v2.8.4 => v2.8.5}/argocd-iac-namespace-install.html (99%) create mode 100644 docs/snyk/v2.8.5/argocd-test.html rename docs/snyk/{v2.9.0-rc2 => v2.8.5}/ghcr.io_dexidp_dex_v2.37.0.html (91%) rename docs/snyk/{v2.8.4 => v2.8.5}/haproxy_2.6.14-alpine.html (53%) rename docs/snyk/{v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html => v2.8.5/quay.io_argoproj_argocd_v2.8.5.html} (66%) rename docs/snyk/{v2.9.0-rc2 => v2.8.5}/redis_7.0.11-alpine.html (81%) rename docs/snyk/{v2.9.0-rc2 => v2.9.0-rc3}/argocd-iac-install.html (99%) rename docs/snyk/{v2.9.0-rc2 => v2.9.0-rc3}/argocd-iac-namespace-install.html (99%) rename docs/snyk/{v2.9.0-rc2 => v2.9.0-rc3}/argocd-test.html (99%) rename docs/snyk/{v2.8.4 => v2.9.0-rc3}/ghcr.io_dexidp_dex_v2.37.0.html (91%) rename docs/snyk/{v2.9.0-rc2 => v2.9.0-rc3}/haproxy_2.6.14-alpine.html (53%) rename docs/snyk/{v2.8.4/quay.io_argoproj_argocd_v2.8.4.html => v2.9.0-rc3/quay.io_argoproj_argocd_v2.9.0-rc3.html} (68%) rename docs/snyk/{v2.8.4 => v2.9.0-rc3}/redis_7.0.11-alpine.html (81%) diff --git a/docs/snyk/index.md b/docs/snyk/index.md index a8e97a7018013..984cd3460c17d 100644 --- a/docs/snyk/index.md +++ b/docs/snyk/index.md @@ -15,38 +15,38 @@ recent minor releases. |---:|:--------:|:----:|:------:|:---:| | [go.mod](master/argocd-test.html) | 0 | 0 | 6 | 0 | | [ui/yarn.lock](master/argocd-test.html) | 0 | 0 | 0 | 0 | -| [dex:v2.37.0](master/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | -| [haproxy:2.6.14-alpine](master/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 19 | -| [redis:7.0.11-alpine](master/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | +| [dex:v2.37.0](master/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 1 | +| [haproxy:2.6.14-alpine](master/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:latest](master/quay.io_argoproj_argocd_latest.html) | 0 | 0 | 4 | 16 | +| [redis:7.0.11-alpine](master/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 1 | | [install.yaml](master/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](master/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.9.0-rc2 +### v2.9.0-rc3 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.9.0-rc2/argocd-test.html) | 0 | 2 | 6 | 0 | -| [ui/yarn.lock](v2.9.0-rc2/argocd-test.html) | 0 | 0 | 0 | 0 | -| [dex:v2.37.0](v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | -| [haproxy:2.6.14-alpine](v2.9.0-rc2/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.9.0-rc2](v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html) | 0 | 2 | 7 | 20 | -| [redis:7.0.11-alpine](v2.9.0-rc2/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | -| [install.yaml](v2.9.0-rc2/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.9.0-rc2/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.9.0-rc3/argocd-test.html) | 0 | 2 | 6 | 0 | +| [ui/yarn.lock](v2.9.0-rc3/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.37.0](v2.9.0-rc3/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 1 | +| [haproxy:2.6.14-alpine](v2.9.0-rc3/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.9.0-rc3](v2.9.0-rc3/quay.io_argoproj_argocd_v2.9.0-rc3.html) | 0 | 0 | 4 | 16 | +| [redis:7.0.11-alpine](v2.9.0-rc3/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 1 | +| [install.yaml](v2.9.0-rc3/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.9.0-rc3/argocd-iac-namespace-install.html) | - | - | - | - | -### v2.8.4 +### v2.8.5 | | Critical | High | Medium | Low | |---:|:--------:|:----:|:------:|:---:| -| [go.mod](v2.8.4/argocd-test.html) | 0 | 2 | 6 | 0 | -| [ui/yarn.lock](v2.8.4/argocd-test.html) | 0 | 0 | 0 | 0 | -| [dex:v2.37.0](v2.8.4/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | -| [haproxy:2.6.14-alpine](v2.8.4/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.8.4](v2.8.4/quay.io_argoproj_argocd_v2.8.4.html) | 0 | 2 | 7 | 20 | -| [redis:7.0.11-alpine](v2.8.4/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | -| [install.yaml](v2.8.4/argocd-iac-install.html) | - | - | - | - | -| [namespace-install.yaml](v2.8.4/argocd-iac-namespace-install.html) | - | - | - | - | +| [go.mod](v2.8.5/argocd-test.html) | 0 | 0 | 6 | 0 | +| [ui/yarn.lock](v2.8.5/argocd-test.html) | 0 | 0 | 0 | 0 | +| [dex:v2.37.0](v2.8.5/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 1 | +| [haproxy:2.6.14-alpine](v2.8.5/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.8.5](v2.8.5/quay.io_argoproj_argocd_v2.8.5.html) | 0 | 0 | 4 | 16 | +| [redis:7.0.11-alpine](v2.8.5/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 1 | +| [install.yaml](v2.8.5/argocd-iac-install.html) | - | - | - | - | +| [namespace-install.yaml](v2.8.5/argocd-iac-namespace-install.html) | - | - | - | - | ### v2.7.14 @@ -54,10 +54,10 @@ recent minor releases. |---:|:--------:|:----:|:------:|:---:| | [go.mod](v2.7.14/argocd-test.html) | 0 | 3 | 5 | 0 | | [ui/yarn.lock](v2.7.14/argocd-test.html) | 0 | 1 | 0 | 0 | -| [dex:v2.37.0](v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | -| [haproxy:2.6.14-alpine](v2.7.14/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 2 | 7 | 20 | -| [redis:7.0.11-alpine](v2.7.14/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | +| [dex:v2.37.0](v2.7.14/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 1 | +| [haproxy:2.6.14-alpine](v2.7.14/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.7.14](v2.7.14/quay.io_argoproj_argocd_v2.7.14.html) | 0 | 2 | 8 | 20 | +| [redis:7.0.11-alpine](v2.7.14/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 1 | | [install.yaml](v2.7.14/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.7.14/argocd-iac-namespace-install.html) | - | - | - | - | @@ -67,9 +67,9 @@ recent minor releases. |---:|:--------:|:----:|:------:|:---:| | [go.mod](v2.6.15/argocd-test.html) | 0 | 3 | 5 | 0 | | [ui/yarn.lock](v2.6.15/argocd-test.html) | 0 | 1 | 0 | 0 | -| [dex:v2.37.0](v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 0 | -| [haproxy:2.6.14-alpine](v2.6.15/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 0 | -| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 2 | 7 | 20 | -| [redis:7.0.11-alpine](v2.6.15/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 0 | +| [dex:v2.37.0](v2.6.15/ghcr.io_dexidp_dex_v2.37.0.html) | 1 | 0 | 3 | 1 | +| [haproxy:2.6.14-alpine](v2.6.15/haproxy_2.6.14-alpine.html) | 0 | 0 | 0 | 1 | +| [argocd:v2.6.15](v2.6.15/quay.io_argoproj_argocd_v2.6.15.html) | 0 | 2 | 8 | 20 | +| [redis:7.0.11-alpine](v2.6.15/redis_7.0.11-alpine.html) | 1 | 0 | 3 | 1 | | [install.yaml](v2.6.15/argocd-iac-install.html) | - | - | - | - | | [namespace-install.yaml](v2.6.15/argocd-iac-namespace-install.html) | - | - | - | - | diff --git a/docs/snyk/master/argocd-iac-install.html b/docs/snyk/master/argocd-iac-install.html index 418bfdecc40fa..28be7b9bb102b 100644 --- a/docs/snyk/master/argocd-iac-install.html +++ b/docs/snyk/master/argocd-iac-install.html @@ -456,7 +456,7 @@

    Scanned the following path: @@ -789,7 +789,7 @@

    Container could be running with outdated image

  • - Line number: 21630 + Line number: 21642
  • @@ -1137,7 +1137,7 @@

    Container has no CPU limit

  • - Line number: 21630 + Line number: 21642
  • @@ -1253,7 +1253,7 @@

    Container has no CPU limit

  • - Line number: 21715 + Line number: 21727
  • @@ -1311,7 +1311,7 @@

    Container has no CPU limit

  • - Line number: 22031 + Line number: 22043
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 21630 + Line number: 21642
  • @@ -1971,7 +1971,7 @@

    Container is running without memory limit

  • - Line number: 21630 + Line number: 21642
  • @@ -2087,7 +2087,7 @@

    Container is running without memory limit

  • - Line number: 21715 + Line number: 21727
  • @@ -2145,7 +2145,7 @@

    Container is running without memory limit

  • - Line number: 22031 + Line number: 22043
  • @@ -2481,7 +2481,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21637 + Line number: 21649
  • @@ -2537,7 +2537,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21603 + Line number: 21615
  • @@ -2593,7 +2593,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 21941 + Line number: 21953
  • @@ -2649,7 +2649,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 22179 + Line number: 22191
  • diff --git a/docs/snyk/master/argocd-iac-namespace-install.html b/docs/snyk/master/argocd-iac-namespace-install.html index d5402379c9056..e043d126f446c 100644 --- a/docs/snyk/master/argocd-iac-namespace-install.html +++ b/docs/snyk/master/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:17:28 am (UTC+00:00)

    +

    October 29th 2023, 12:17:54 am (UTC+00:00)

    Scanned the following path: @@ -789,7 +789,7 @@

    Container could be running with outdated image

  • - Line number: 1286 + Line number: 1298
  • @@ -1137,7 +1137,7 @@

    Container has no CPU limit

  • - Line number: 1286 + Line number: 1298
  • @@ -1253,7 +1253,7 @@

    Container has no CPU limit

  • - Line number: 1371 + Line number: 1383
  • @@ -1311,7 +1311,7 @@

    Container has no CPU limit

  • - Line number: 1687 + Line number: 1699
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 1286 + Line number: 1298
  • @@ -1971,7 +1971,7 @@

    Container is running without memory limit

  • - Line number: 1286 + Line number: 1298
  • @@ -2087,7 +2087,7 @@

    Container is running without memory limit

  • - Line number: 1371 + Line number: 1383
  • @@ -2145,7 +2145,7 @@

    Container is running without memory limit

  • - Line number: 1687 + Line number: 1699
  • @@ -2481,7 +2481,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1293 + Line number: 1305
  • @@ -2537,7 +2537,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1259 + Line number: 1271
  • @@ -2593,7 +2593,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1597 + Line number: 1609
  • @@ -2649,7 +2649,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1835 + Line number: 1847
  • diff --git a/docs/snyk/master/argocd-test.html b/docs/snyk/master/argocd-test.html index baf98e4e8af70..1b2486932df9e 100644 --- a/docs/snyk/master/argocd-test.html +++ b/docs/snyk/master/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:14:48 am (UTC+00:00)

    +

    October 29th 2023, 12:14:38 am (UTC+00:00)

    Scanned the following paths: diff --git a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html index d5818b81cb2f5..167a203368fb3 100644 --- a/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/master/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:15:00 am (UTC+00:00)

    +

    October 29th 2023, 12:14:53 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    27 known vulnerabilities
    -
    72 vulnerable dependency paths
    +
    28 known vulnerabilities
    +
    79 vulnerable dependency paths
    786 dependencies
    @@ -648,12 +648,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/master/haproxy_2.6.14-alpine.html b/docs/snyk/master/haproxy_2.6.14-alpine.html index b0b4060ee0d33..19c8202ec7564 100644 --- a/docs/snyk/master/haproxy_2.6.14-alpine.html +++ b/docs/snyk/master/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:15:08 am (UTC+00:00)

    +

    October 29th 2023, 12:15:02 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -484,7 +484,198 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/master/quay.io_argoproj_argocd_latest.html b/docs/snyk/master/quay.io_argoproj_argocd_latest.html index 4241230700e76..c9b59ef5e997f 100644 --- a/docs/snyk/master/quay.io_argoproj_argocd_latest.html +++ b/docs/snyk/master/quay.io_argoproj_argocd_latest.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,19 +456,19 @@

    Snyk test report

    -

    October 22nd 2023, 12:15:33 am (UTC+00:00)

    +

    October 29th 2023, 12:15:33 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:latest/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:latest/kustomize/kustomize/v5 (gomodules)
    • quay.io/argoproj/argocd:latest/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:latest/git-lfs/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:latest/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:latest/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:latest (gomodules)
    • quay.io/argoproj/argocd:latest/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:latest/git-lfs/git-lfs (gomodules)
    -
    31 known vulnerabilities
    -
    123 vulnerable dependency paths
    -
    2320 dependencies
    +
    28 known vulnerabilities
    +
    96 vulnerable dependency paths
    +
    2235 dependencies
    @@ -531,12 +531,15 @@

    Remediation

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    References


    @@ -1929,600 +1933,6 @@

    References

    More about this vulnerability

    -
    -
    -

    Improper Authentication

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3@3.0.2-0ubuntu1.10 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    Issue summary: The AES-SIV cipher implementation contains a bug that causes - it to ignore empty associated data entries which are unauthenticated as - a consequence.

    -

    Impact summary: Applications that use the AES-SIV algorithm and want to - authenticate empty data entries as associated data can be mislead by removing - adding or reordering such empty entries as these are ignored by the OpenSSL - implementation. We are currently unaware of any such applications.

    -

    The AES-SIV algorithm allows for authentication of multiple associated - data entries along with the encryption. To authenticate empty data the - application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with - NULL pointer as the output buffer and 0 as the input buffer length. - The AES-SIV implementation in OpenSSL just returns success for such a call - instead of performing the associated data authentication operation. - The empty data thus will not be authenticated.

    -

    As this issue does not affect non-empty associated data authentication and - we expect it to be rare for an application to use empty associated data - entries this is qualified as Low severity issue.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - - -
    -
    -

    Inefficient Regular Expression Complexity

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3@3.0.2-0ubuntu1.10 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    -

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long - delays. Where the key or parameters that are being checked have been obtained - from an untrusted source this may lead to a Denial of Service.

    -

    The function DH_check() performs various checks on DH parameters. One of those - checks confirms that the modulus ('p' parameter) is not too large. Trying to use - a very large modulus is slow and OpenSSL will not normally use a modulus which - is over 10,000 bits in length.

    -

    However the DH_check() function checks numerous aspects of the key or parameters - that have been supplied. Some of those checks use the supplied modulus value - even if it has already been found to be too large.

    -

    An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulernable to a Denial of Service attack.

    -

    The function DH_check() is itself called by a number of other OpenSSL functions. - An application calling any of those other functions may similarly be affected. - The other functions affected by this are DH_check_ex() and - EVP_PKEY_param_check().

    -

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications - when using the '-check' option.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue. - The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - - -
    -
    -

    Excessive Iteration

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - openssl/libssl3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@latest and openssl/libssl3@3.0.2-0ubuntu1.10 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@latest - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    Issue summary: Checking excessively long DH keys or parameters may be very slow.

    -

    Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long - delays. Where the key or parameters that are being checked have been obtained - from an untrusted source this may lead to a Denial of Service.

    -

    The function DH_check() performs various checks on DH parameters. After fixing - CVE-2023-3446 it was discovered that a large q parameter value can also trigger - an overly long computation during some of these checks. A correct q value, - if present, cannot be larger than the modulus p parameter, thus it is - unnecessary to perform these checks if q is larger than p.

    -

    An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulnerable to a Denial of Service attack.

    -

    The function DH_check() is itself called by a number of other OpenSSL functions. - An application calling any of those other functions may similarly be affected. - The other functions affected by this are DH_check_ex() and - EVP_PKEY_param_check().

    -

    Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications - when using the "-check" option.

    -

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    -

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    -

    References

    - - -
    - - -

    CVE-2023-28531

    diff --git a/docs/snyk/master/redis_7.0.11-alpine.html b/docs/snyk/master/redis_7.0.11-alpine.html index a63c98a15030a..5409d26e74695 100644 --- a/docs/snyk/master/redis_7.0.11-alpine.html +++ b/docs/snyk/master/redis_7.0.11-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:15:40 am (UTC+00:00)

    +

    October 29th 2023, 12:15:46 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    4 known vulnerabilities
    -
    32 vulnerable dependency paths
    +
    5 known vulnerabilities
    +
    41 vulnerable dependency paths
    18 dependencies
    @@ -1127,6 +1127,7 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • @@ -1136,6 +1137,196 @@

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.6.15/argocd-iac-install.html b/docs/snyk/v2.6.15/argocd-iac-install.html index 90c875983c384..6867e68c4bd18 100644 --- a/docs/snyk/v2.6.15/argocd-iac-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:27:56 am (UTC+00:00)

    +

    October 29th 2023, 12:30:07 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html index 1bd89d9664d2d..a0dbfd5315336 100644 --- a/docs/snyk/v2.6.15/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.6.15/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:28:06 am (UTC+00:00)

    +

    October 29th 2023, 12:30:19 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.6.15/argocd-test.html b/docs/snyk/v2.6.15/argocd-test.html index 2672f4aef0e82..cbf674fc20222 100644 --- a/docs/snyk/v2.6.15/argocd-test.html +++ b/docs/snyk/v2.6.15/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:25:59 am (UTC+00:00)

    +

    October 29th 2023, 12:27:33 am (UTC+00:00)

    Scanned the following paths: @@ -933,12 +933,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    @@ -648,12 +648,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html index e107d327e33f3..605a7d8b7d5bd 100644 --- a/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.6.15/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:26:13 am (UTC+00:00)

    +

    October 29th 2023, 12:27:48 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -484,7 +484,198 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html index 4afe990dd0ffb..759d3b81c634b 100644 --- a/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html +++ b/docs/snyk/v2.6.15/quay.io_argoproj_argocd_v2.6.15.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:26:35 am (UTC+00:00)

    +

    October 29th 2023, 12:28:36 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    47 known vulnerabilities
    -
    159 vulnerable dependency paths
    +
    48 known vulnerabilities
    +
    168 vulnerable dependency paths
    2063 dependencies
    @@ -699,12 +699,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    -

    Heap-based Buffer Overflow

    +

    Out-of-bounds Write

    @@ -1301,6 +1307,8 @@

    References


    @@ -1502,6 +1510,213 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-5363

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.6.15 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.6.15 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

    +

    References

    + + +
    + + +

    Out-of-bounds Read

    @@ -2078,6 +2293,7 @@

    References

  • cve@mitre.org
  • cve@mitre.org
  • cve@mitre.org
  • +
  • cve@mitre.org

  • @@ -3446,7 +3662,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu:22.04. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    Issue summary: The AES-SIV cipher implementation contains a bug that causes it to ignore empty associated data entries which are unauthenticated as @@ -3466,7 +3682,7 @@

    NVD Description

    we expect it to be rare for an application to use empty associated data entries this is qualified as Low severity issue.

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

    References

    • ADVISORY
    • @@ -3663,7 +3879,7 @@

      NVD Description

      The OpenSSL SSL/TLS implementation is not affected by this issue. The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

      References

      • ADVISORY
      • @@ -3863,7 +4079,7 @@

        NVD Description

        The OpenSSL SSL/TLS implementation is not affected by this issue.

        The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

        Remediation

        -

        There is no fixed version for Ubuntu:22.04 openssl.

        +

        Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

        References


        @@ -5075,6 +5292,7 @@

        References


        diff --git a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html index 4517b6875556d..ef98cc541da29 100644 --- a/docs/snyk/v2.6.15/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.6.15/redis_7.0.11-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

        Snyk test report

        -

        October 22nd 2023, 12:26:40 am (UTC+00:00)

        +

        October 29th 2023, 12:28:42 am (UTC+00:00)

        Scanned the following path: @@ -466,8 +466,8 @@

        Snyk test report

        -
        4 known vulnerabilities
        -
        32 vulnerable dependency paths
        +
        5 known vulnerabilities
        +
        41 vulnerable dependency paths
        18 dependencies
    @@ -1127,6 +1127,7 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • @@ -1136,6 +1137,196 @@

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.7.14/argocd-iac-install.html b/docs/snyk/v2.7.14/argocd-iac-install.html index ab8ddd883ddd9..602c76a57c103 100644 --- a/docs/snyk/v2.7.14/argocd-iac-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:25:32 am (UTC+00:00)

    +

    October 29th 2023, 12:27:04 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html index d185574255ccc..937ce3343905e 100644 --- a/docs/snyk/v2.7.14/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.7.14/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:25:44 am (UTC+00:00)

    +

    October 29th 2023, 12:27:17 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.7.14/argocd-test.html b/docs/snyk/v2.7.14/argocd-test.html index f004e6e9bd197..342599913dab0 100644 --- a/docs/snyk/v2.7.14/argocd-test.html +++ b/docs/snyk/v2.7.14/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:23:29 am (UTC+00:00)

    +

    October 29th 2023, 12:24:41 am (UTC+00:00)

    Scanned the following paths: @@ -933,12 +933,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    @@ -648,12 +648,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html index 007cb149e346e..953bbbe0d1e05 100644 --- a/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.7.14/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:23:41 am (UTC+00:00)

    +

    October 29th 2023, 12:24:59 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -484,7 +484,198 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html index 03bd4c6c6ccf8..5b4ea7a6ff4d0 100644 --- a/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html +++ b/docs/snyk/v2.7.14/quay.io_argoproj_argocd_v2.7.14.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:24:02 am (UTC+00:00)

    +

    October 29th 2023, 12:25:22 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    40 known vulnerabilities
    -
    150 vulnerable dependency paths
    +
    41 known vulnerabilities
    +
    159 vulnerable dependency paths
    2065 dependencies
    @@ -531,12 +531,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    -

    Heap-based Buffer Overflow

    +

    Out-of-bounds Write

    @@ -1058,6 +1064,8 @@

    References


    @@ -1259,6 +1267,213 @@

    References

    More about this vulnerability

    +
    +
    +

    CVE-2023-5363

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: ubuntu:22.04 +
    • +
    • + Vulnerable module: + + openssl/libssl3 +
    • + +
    • Introduced through: + + docker-image|quay.io/argoproj/argocd@v2.7.14 and openssl/libssl3@3.0.2-0ubuntu1.10 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + libfido2/libfido2-1@1.10.0-1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssh/openssh-client@1:8.9p1-3ubuntu0.3 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 + + openssl/libssl3@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.7.14 + + ca-certificates@20230311ubuntu0.22.04.1 + + openssl@3.0.2-0ubuntu1.10 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. + See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

    +

    References

    + + +
    + + +

    Out-of-bounds Read

    @@ -1835,6 +2050,7 @@

    References

  • cve@mitre.org
  • cve@mitre.org
  • cve@mitre.org
  • +
  • cve@mitre.org

  • @@ -2915,7 +3131,7 @@

    Detailed paths


    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu:22.04. +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    Issue summary: The AES-SIV cipher implementation contains a bug that causes it to ignore empty associated data entries which are unauthenticated as @@ -2935,7 +3151,7 @@

    NVD Description

    we expect it to be rare for an application to use empty associated data entries this is qualified as Low severity issue.

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 openssl.

    +

    Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

    References

    • ADVISORY
    • @@ -3132,7 +3348,7 @@

      NVD Description

      The OpenSSL SSL/TLS implementation is not affected by this issue. The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

      References

      • ADVISORY
      • @@ -3332,7 +3548,7 @@

        NVD Description

        The OpenSSL SSL/TLS implementation is not affected by this issue.

        The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

        Remediation

        -

        There is no fixed version for Ubuntu:22.04 openssl.

        +

        Upgrade Ubuntu:22.04 openssl to version 3.0.2-0ubuntu1.12 or higher.

        References


        @@ -4544,6 +4761,7 @@

        References


        diff --git a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html index abb0d46e599d1..bb89e05940bc5 100644 --- a/docs/snyk/v2.7.14/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.7.14/redis_7.0.11-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

        Snyk test report

        -

        October 22nd 2023, 12:24:07 am (UTC+00:00)

        +

        October 29th 2023, 12:25:30 am (UTC+00:00)

        Scanned the following path: @@ -466,8 +466,8 @@

        Snyk test report

        -
        4 known vulnerabilities
        -
        32 vulnerable dependency paths
        +
        5 known vulnerabilities
        +
        41 vulnerable dependency paths
        18 dependencies
    @@ -1127,6 +1127,7 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • @@ -1136,6 +1137,196 @@

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.8.4/argocd-test.html b/docs/snyk/v2.8.4/argocd-test.html deleted file mode 100644 index a1275415abd1f..0000000000000 --- a/docs/snyk/v2.8.4/argocd-test.html +++ /dev/null @@ -1,3684 +0,0 @@ - - - - - - - - - Snyk test report - - - - - - - - - -
    -
    -
    -
    - - - Snyk - Open Source Security - - - - - - - -
    -

    Snyk test report

    - -

    October 22nd 2023, 12:20:43 am (UTC+00:00)

    -
    -
    - Scanned the following paths: -
      -
    • /argo-cd/argoproj/argo-cd/v2 (gomodules)
    • /argo-cd (yarn)
    • -
    -
    - -
    -
    8 known vulnerabilities
    -
    162 vulnerable dependency paths
    -
    1851 dependencies
    -
    -
    -
    -
    - -
    -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/grpc -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and google.golang.org/grpc@1.56.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health/grpc_health_v1@1.56.1 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.56.1 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.56.1 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/otlpconfig@1.16.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - go.opentelemetry.io/proto/otlp/collector/trace/v1@0.19.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - google.golang.org/grpc/health/grpc_health_v1@1.56.1 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.56.1 - - google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.1 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.56.1 - - google.golang.org/grpc/health/grpc_health_v1@1.56.1 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.1 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    google.golang.org/grpc is a Go implementation of gRPC

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    -

    Remediation

    -

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - golang.org/x/net/http2 -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, k8s.io/apimachinery/pkg/util/net@0.24.2 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/soheilhy/cmux@0.1.5 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport/spdy@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/testing@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/record@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health/grpc_health_v1@1.56.1 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/auth@1.4.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/retry@1.4.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-prometheus@1.2.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc@1.16.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus@1.4.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc@0.42.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/listers/core/v1@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/clientcmd@0.24.2 - - k8s.io/client-go/tools/auth@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery/fake@0.24.2 - - k8s.io/client-go/testing@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/fake@0.24.2 - - k8s.io/client-go/testing@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/remotecommand@0.24.2 - - k8s.io/client-go/transport/spdy@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/api/rbac/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/errors@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/equality@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/transport/spdy@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/pkg/kubeclientmetrics@#d56162821bd1 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/testing@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/azure@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/gcp@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/plugin/pkg/client/auth/oidc@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/improbable-eng/grpc-web/go/grpcweb@0.15.0 - - google.golang.org/grpc/health/grpc_health_v1@1.56.1 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/reflection@1.56.1 - - google.golang.org/grpc/reflection/grpc_reflection_v1alpha@1.56.1 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - google.golang.org/grpc/health@1.56.1 - - google.golang.org/grpc/health/grpc_health_v1@1.56.1 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/cache@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 - - k8s.io/client-go/listers/core/v1@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/core/v1@0.24.2 - - k8s.io/client-go/listers/core/v1@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 - - k8s.io/client-go/tools/clientcmd@0.24.2 - - k8s.io/client-go/tools/auth@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/term@0.24.2 - - k8s.io/client-go/tools/remotecommand@0.24.2 - - k8s.io/client-go/transport/spdy@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - k8s.io/client-go/pkg/apis/clientauthentication/v1beta1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/resource@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/ignore@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/testing@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/util/managedfields@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/scheme@0.11.0 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/resource@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/health@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/util/retry@0.24.2 - - k8s.io/apimachinery/pkg/api/errors@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/portforward@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1@0.24.2 - - k8s.io/apimachinery/pkg/api/equality@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/api/validation@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/validation@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery/fake@0.24.2 - - k8s.io/client-go/testing@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/fake@0.24.2 - - k8s.io/client-go/testing@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/remotecommand@0.24.2 - - k8s.io/client-go/transport/spdy@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/health@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 - - k8s.io/client-go/restmapper@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/internal/testing/controlplane@0.11.0 - - k8s.io/client-go/tools/clientcmd@0.24.2 - - k8s.io/client-go/tools/auth@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/resource@#425d65e07695 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/listers/core/v1@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/record@0.24.2 - - k8s.io/client-go/tools/reference@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#425d65e07695 - - k8s.io/apimachinery/pkg/util/managedfields@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/term@0.24.2 - - k8s.io/client-go/tools/remotecommand@0.24.2 - - k8s.io/client-go/transport/spdy@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - k8s.io/client-go/transport@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/logging/logrus/ctxlogrus@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware/tags@1.4.0 - - github.com/grpc-ecosystem/go-grpc-middleware@1.4.0 - - google.golang.org/grpc@1.56.1 - - google.golang.org/grpc/internal/transport@1.56.1 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes@0.24.2 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 - - k8s.io/client-go/applyconfigurations/storage/v1beta1@0.24.2 - - k8s.io/client-go/applyconfigurations/meta/v1@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/admission@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/tools/clientcmd@0.24.2 - - k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 - - k8s.io/client-go/listers/core/v1@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/informers/core/v1@0.24.2 - - k8s.io/client-go/listers/core/v1@0.24.2 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/diff@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/utils/kube/scheme@#425d65e07695 - - k8s.io/apimachinery/pkg/util/managedfields@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/syncwaves@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/manager@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/internal/metrics@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/metrics@0.11.0 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/builder@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/envtest@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/webhook/conversion@0.11.0 - - k8s.io/apimachinery/pkg/runtime/serializer@0.24.2 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 - - k8s.io/client-go/tools/clientcmd@0.24.2 - - k8s.io/client-go/tools/clientcmd/api/latest@0.24.2 - - k8s.io/apimachinery/pkg/runtime/serializer/versioning@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - k8s.io/client-go/kubernetes@0.24.2 - - k8s.io/client-go/kubernetes/typed/storage/v1beta1@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync/ignore@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/hook@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/hook/helm@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/sync/common@#425d65e07695 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/client-go/rest@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/cache@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/sync@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/gitops-engine/pkg/utils/kube@#425d65e07695 - - k8s.io/kubectl/pkg/util/openapi@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/handler@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/runtime/inject@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/cache/internal@0.11.0 - - k8s.io/client-go/tools/cache@0.24.2 - - k8s.io/client-go/tools/pager@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller/controllerutil@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client/apiutil@0.11.0 - - k8s.io/client-go/restmapper@0.24.2 - - k8s.io/client-go/discovery@0.24.2 - - k8s.io/client-go/kubernetes/scheme@0.24.2 - - k8s.io/api/storage/v1beta1@0.24.2 - - k8s.io/api/core/v1@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - sigs.k8s.io/controller-runtime/pkg/controller@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/source/internal@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/predicate@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/event@0.11.0 - - sigs.k8s.io/controller-runtime/pkg/client@0.11.0 - - k8s.io/client-go/dynamic@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1/unstructured@0.24.2 - - k8s.io/apimachinery/pkg/apis/meta/v1@0.24.2 - - k8s.io/apimachinery/pkg/watch@0.24.2 - - k8s.io/apimachinery/pkg/util/net@0.24.2 - - golang.org/x/net/http2@0.11.0 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    golang.org/x/net/http2 is a work-in-progress HTTP/2 implementation for Go.

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    -

    Remediation

    -

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    LGPL-3.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - gopkg.in/retry.v1 -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/Azure/kubelogin/pkg/token@0.0.20 - - gopkg.in/retry.v1@1.0.3 - - - -
    • -
    - -
    - -
    - -

    LGPL-3.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/r3labs/diff -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/r3labs/diff@1.1.0 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-version -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.15.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - code.gitea.io/sdk/gitea@0.15.1 - - github.com/hashicorp/go-version@1.2.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-retryablehttp -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/xanzy/go-gitlab@0.86.0 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/hashicorp/go-cleanhttp -
    • - -
    • Introduced through: - - - github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.4 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/xanzy/go-gitlab@0.86.0 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/xanzy/go-gitlab@0.86.0 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 - - github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 - - github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 - - github.com/hashicorp/go-retryablehttp@0.7.4 - - github.com/hashicorp/go-cleanhttp@0.5.2 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/gosimple/slug -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.13.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@0.0.0 - - github.com/gosimple/slug@1.13.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -
    -
    - - - diff --git a/docs/snyk/v2.8.4/argocd-iac-install.html b/docs/snyk/v2.8.5/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.8.4/argocd-iac-install.html rename to docs/snyk/v2.8.5/argocd-iac-install.html index 74bfd26bd5685..3d4dd5fd52b45 100644 --- a/docs/snyk/v2.8.4/argocd-iac-install.html +++ b/docs/snyk/v2.8.5/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:22:54 am (UTC+00:00)

    +

    October 29th 2023, 12:24:06 am (UTC+00:00)

    Scanned the following path: @@ -789,7 +789,7 @@

    Container could be running with outdated image

  • - Line number: 19755 + Line number: 19761
  • @@ -1079,7 +1079,7 @@

    Container has no CPU limit

  • - Line number: 19498 + Line number: 19504
  • @@ -1137,7 +1137,7 @@

    Container has no CPU limit

  • - Line number: 19755 + Line number: 19761
  • @@ -1195,7 +1195,7 @@

    Container has no CPU limit

  • - Line number: 19555 + Line number: 19561
  • @@ -1253,7 +1253,7 @@

    Container has no CPU limit

  • - Line number: 19840 + Line number: 19846
  • @@ -1311,7 +1311,7 @@

    Container has no CPU limit

  • - Line number: 20156 + Line number: 20162
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 19498 + Line number: 19504
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 19755 + Line number: 19761
  • @@ -1913,7 +1913,7 @@

    Container is running without memory limit

  • - Line number: 19498 + Line number: 19504
  • @@ -1971,7 +1971,7 @@

    Container is running without memory limit

  • - Line number: 19755 + Line number: 19761
  • @@ -2029,7 +2029,7 @@

    Container is running without memory limit

  • - Line number: 19555 + Line number: 19561
  • @@ -2087,7 +2087,7 @@

    Container is running without memory limit

  • - Line number: 19840 + Line number: 19846
  • @@ -2145,7 +2145,7 @@

    Container is running without memory limit

  • - Line number: 20156 + Line number: 20162
  • @@ -2369,7 +2369,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19432 + Line number: 19438
  • @@ -2425,7 +2425,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19508 + Line number: 19514
  • @@ -2481,7 +2481,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19762 + Line number: 19768
  • @@ -2537,7 +2537,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 19728 + Line number: 19734
  • @@ -2593,7 +2593,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 20066 + Line number: 20072
  • @@ -2649,7 +2649,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 20304 + Line number: 20310
  • diff --git a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html b/docs/snyk/v2.8.5/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.8.4/argocd-iac-namespace-install.html rename to docs/snyk/v2.8.5/argocd-iac-namespace-install.html index ad9dd5a08070e..aae75827ee40d 100644 --- a/docs/snyk/v2.8.4/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.8.5/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:23:05 am (UTC+00:00)

    +

    October 29th 2023, 12:24:17 am (UTC+00:00)

    Scanned the following path: @@ -789,7 +789,7 @@

    Container could be running with outdated image

  • - Line number: 1261 + Line number: 1267
  • @@ -1079,7 +1079,7 @@

    Container has no CPU limit

  • - Line number: 1004 + Line number: 1010
  • @@ -1137,7 +1137,7 @@

    Container has no CPU limit

  • - Line number: 1261 + Line number: 1267
  • @@ -1195,7 +1195,7 @@

    Container has no CPU limit

  • - Line number: 1061 + Line number: 1067
  • @@ -1253,7 +1253,7 @@

    Container has no CPU limit

  • - Line number: 1346 + Line number: 1352
  • @@ -1311,7 +1311,7 @@

    Container has no CPU limit

  • - Line number: 1662 + Line number: 1668
  • @@ -1571,7 +1571,7 @@

    Container is running without liveness probe

  • - Line number: 1004 + Line number: 1010
  • @@ -1623,7 +1623,7 @@

    Container is running without liveness probe

  • - Line number: 1261 + Line number: 1267
  • @@ -1913,7 +1913,7 @@

    Container is running without memory limit

  • - Line number: 1004 + Line number: 1010
  • @@ -1971,7 +1971,7 @@

    Container is running without memory limit

  • - Line number: 1261 + Line number: 1267
  • @@ -2029,7 +2029,7 @@

    Container is running without memory limit

  • - Line number: 1061 + Line number: 1067
  • @@ -2087,7 +2087,7 @@

    Container is running without memory limit

  • - Line number: 1346 + Line number: 1352
  • @@ -2145,7 +2145,7 @@

    Container is running without memory limit

  • - Line number: 1662 + Line number: 1668
  • @@ -2369,7 +2369,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 938 + Line number: 944
  • @@ -2425,7 +2425,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1014 + Line number: 1020
  • @@ -2481,7 +2481,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1268 + Line number: 1274
  • @@ -2537,7 +2537,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1234 + Line number: 1240
  • @@ -2593,7 +2593,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1572 + Line number: 1578
  • @@ -2649,7 +2649,7 @@

    Container's or Pod's UID could clash with hos
  • - Line number: 1810 + Line number: 1816
  • diff --git a/docs/snyk/v2.8.5/argocd-test.html b/docs/snyk/v2.8.5/argocd-test.html new file mode 100644 index 0000000000000..3a5f08a08b860 --- /dev/null +++ b/docs/snyk/v2.8.5/argocd-test.html @@ -0,0 +1,1031 @@ + + + + + + + + + Snyk test report + + + + + + + + + +
    +
    +
    +
    + + + Snyk - Open Source Security + + + + + + + +
    +

    Snyk test report

    + +

    October 29th 2023, 12:21:29 am (UTC+00:00)

    +
    +
    + Scanned the following paths: +
      +
    • /argo-cd/argoproj/argo-cd/v2 (gomodules)
    • /argo-cd (yarn)
    • +
    +
    + +
    +
    6 known vulnerabilities
    +
    19 vulnerable dependency paths
    +
    1853 dependencies
    +
    +
    +
    +
    + +
    +
    +
    +

    LGPL-3.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + gopkg.in/retry.v1 +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/Azure/kubelogin/pkg/token@0.0.20 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/Azure/kubelogin/pkg/token@0.0.20 + + gopkg.in/retry.v1@1.0.3 + + + +
    • +
    + +
    + +
    + +

    LGPL-3.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/r3labs/diff +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/r3labs/diff@1.1.0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/r3labs/diff@1.1.0 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-version +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, code.gitea.io/sdk/gitea@0.15.1 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + code.gitea.io/sdk/gitea@0.15.1 + + github.com/hashicorp/go-version@1.2.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-retryablehttp +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/hashicorp/go-retryablehttp@0.7.4 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.86.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/hashicorp/go-cleanhttp +
    • + +
    • Introduced through: + + + github.com/argoproj/argo-cd/v2@0.0.0, github.com/hashicorp/go-retryablehttp@0.7.4 and others +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.86.0 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/xanzy/go-gitlab@0.86.0 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/cmd@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/api@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/argoproj/notifications-engine/pkg/controller@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/subscriptions@#3446d4ae8520 + + github.com/argoproj/notifications-engine/pkg/services@#3446d4ae8520 + + github.com/opsgenie/opsgenie-go-sdk-v2/client@1.0.5 + + github.com/hashicorp/go-retryablehttp@0.7.4 + + github.com/hashicorp/go-cleanhttp@0.5.2 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +

    MPL-2.0 license

    +
    + +
    + medium severity +
    + +
    + +
      +
    • + Package Manager: golang +
    • +
    • + Module: + + github.com/gosimple/slug +
    • + +
    • Introduced through: + + github.com/argoproj/argo-cd/v2@0.0.0 and github.com/gosimple/slug@1.13.1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + github.com/argoproj/argo-cd/v2@0.0.0 + + github.com/gosimple/slug@1.13.1 + + + +
    • +
    + +
    + +
    + +

    MPL-2.0 license

    + +
    + + + +
    +
    +
    +
    + + + diff --git a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html b/docs/snyk/v2.8.5/ghcr.io_dexidp_dex_v2.37.0.html similarity index 91% rename from docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html rename to docs/snyk/v2.8.5/ghcr.io_dexidp_dex_v2.37.0.html index 395c6ba1691e8..74f7da7894829 100644 --- a/docs/snyk/v2.9.0-rc2/ghcr.io_dexidp_dex_v2.37.0.html +++ b/docs/snyk/v2.8.5/ghcr.io_dexidp_dex_v2.37.0.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:17:57 am (UTC+00:00)

    +

    October 29th 2023, 12:21:38 am (UTC+00:00)

    Scanned the following paths: @@ -466,8 +466,8 @@

    Snyk test report

    -
    27 known vulnerabilities
    -
    72 vulnerable dependency paths
    +
    28 known vulnerabilities
    +
    79 vulnerable dependency paths
    786 dependencies

    @@ -648,12 +648,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html b/docs/snyk/v2.8.5/haproxy_2.6.14-alpine.html similarity index 53% rename from docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.8.5/haproxy_2.6.14-alpine.html index d69638239b8f3..020d8275f0dad 100644 --- a/docs/snyk/v2.8.4/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.8.5/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:20:56 am (UTC+00:00)

    +

    October 29th 2023, 12:21:43 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -484,7 +484,198 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html b/docs/snyk/v2.8.5/quay.io_argoproj_argocd_v2.8.5.html similarity index 66% rename from docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html rename to docs/snyk/v2.8.5/quay.io_argoproj_argocd_v2.8.5.html index 1bf83c3e87170..eb2bb47c67fc8 100644 --- a/docs/snyk/v2.9.0-rc2/quay.io_argoproj_argocd_v2.9.0-rc2.html +++ b/docs/snyk/v2.8.5/quay.io_argoproj_argocd_v2.8.5.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,19 +456,19 @@

    Snyk test report

    -

    October 22nd 2023, 12:18:24 am (UTC+00:00)

    +

    October 29th 2023, 12:22:15 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.9.0-rc2/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:v2.9.0-rc2/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc2/kustomize/kustomize/v5 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc2/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc2/git-lfs/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.8.5/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:v2.8.5/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:v2.8.5/kustomize/kustomize/v5 (gomodules)
    • quay.io/argoproj/argocd:v2.8.5/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:v2.8.5/git-lfs/git-lfs (gomodules)
    -
    39 known vulnerabilities
    -
    148 vulnerable dependency paths
    -
    2270 dependencies
    +
    29 known vulnerabilities
    +
    97 vulnerable dependency paths
    +
    2117 dependencies
    @@ -476,80 +476,6 @@

    Snyk test report

    -
    -

    Denial of Service (DoS)

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Vulnerable module: - - google.golang.org/grpc -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.56.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - google.golang.org/grpc@v1.56.2 - - - -
    • -
    - -
    - -
    - -

    Overview

    -

    google.golang.org/grpc is a Go implementation of gRPC

    -

    Affected versions of this package are vulnerable to Denial of Service (DoS) in the implementation of the HTTP/2 protocol. An attacker can cause a denial of service (including via DDoS) by rapidly resetting many streams through request cancellation.

    -

    Remediation

    -

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    -

    References

    - - -
    - - - -

    Denial of Service (DoS)

    @@ -572,7 +498,7 @@

    Denial of Service (DoS)

  • Introduced through: - github.com/argoproj/argo-cd/v2@* and golang.org/x/net/http2@v0.15.0 + helm.sh/helm/v3@* and golang.org/x/net/http2@v0.8.0
  • @@ -583,15 +509,6 @@

    Denial of Service (DoS)

    Detailed paths

    -
    -
    -

    Out-of-bounds Write

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - glibc/libc-bin -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and glibc/libc-bin@2.35-0ubuntu3.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - glibc/libc-bin@2.35-0ubuntu3.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - glibc/libc6@2.35-0ubuntu3.3 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A buffer overflow was discovered in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment variable. This issue could allow a local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when launching binaries with SUID permission to execute code with elevated privileges.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 glibc to version 2.35-0ubuntu3.4 or higher.

    -

    References

    - - -
    - - -

    Directory Traversal

    @@ -817,87 +639,6 @@

    References

    More about this vulnerability

    -
    -
    -

    Heap-based Buffer Overflow

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - curl/libcurl3-gnutls -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    This flaw makes curl overflow a heap based buffer in the SOCKS5 proxy - handshake.

    -

    When curl is asked to pass along the host name to the SOCKS5 proxy to allow - that to resolve the address instead of it getting done by curl itself, the - maximum length that host name can be is 255 bytes.

    -

    If the host name is detected to be longer, curl switches to local name - resolving and instead passes on the resolved address only. Due to this bug, - the local variable that means "let the host resolve the name" could get the - wrong value during a slow SOCKS5 handshake, and contrary to the intention, - copy the too long host name to the target buffer instead of copying just the - resolved address there.

    -

    The target buffer being a heap based buffer, and the host name coming from the - URL that curl has been told to operate with.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    -

    References

    - - -
    - - -

    CVE-2020-22916

    @@ -921,7 +662,7 @@

    CVE-2020-22916

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and xz-utils/liblzma5@5.2.5-2ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.8.5 and xz-utils/liblzma5@5.2.5-2ubuntu1
  • @@ -934,7 +675,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 xz-utils/liblzma5@5.2.5-2ubuntu1 @@ -995,7 +736,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others + docker-image|quay.io/argoproj/argocd@v2.8.5, git@1:2.34.1-1ubuntu1.10 and others
    @@ -1007,7 +748,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 @@ -1020,7 +761,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 @@ -1035,7 +776,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 @@ -1048,7 +789,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 @@ -1059,7 +800,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 perl/perl-base@5.34.0-3ubuntu1.2 @@ -1093,7 +834,7 @@

      References

    -

    Out-of-bounds Read

    +

    Access of Uninitialized Pointer

    @@ -1109,12 +850,12 @@

    Out-of-bounds Read

  • Vulnerable module: - libx11/libx11-data + krb5/libk5crypto3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + docker-image|quay.io/argoproj/argocd@v2.8.5 and krb5/libk5crypto3@1.19.2-2ubuntu0.2
  • @@ -1127,477 +868,114 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - libx11/libx11-data@2:1.7.5-1ubuntu0.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - libx11/libx11-data@2:1.7.5-1ubuntu0.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - libxext/libxext6@2:1.3.4-1build1 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 - libxmu/libxmuu1@2:1.1.3-3 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - xauth@1:1.1-1build2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A vulnerability was found in libX11 due to a boundary condition within the _XkbReadKeySyms() function. This flaw allows a local user to trigger an out-of-bounds read error and read the contents of memory on the system.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Loop with Unreachable Exit Condition ('Infinite Loop')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - libx11/libx11-data -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libxext/libxext6@2:1.3.4-1build1 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libxmu/libxmuu1@2:1.1.3-3 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - xauth@1:1.1-1build2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A vulnerability was found in libX11 due to an infinite loop within the PutSubImage() function. This flaw allows a local user to consume all available system resources and cause a denial of service condition.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Integer Overflow or Wraparound

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - libx11/libx11-data -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libxext/libxext6@2:1.3.4-1build1 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libxmu/libxmuu1@2:1.1.3-3 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - xauth@1:1.1-1build2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A vulnerability was found in libX11 due to an integer overflow within the XCreateImage() function. This flaw allows a local user to trigger an integer overflow and execute arbitrary code with elevated privileges.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Access of Uninitialized Pointer

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and krb5/libk5crypto3@1.19.2-2ubuntu0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - krb5/libk5crypto3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libk5crypto3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - krb5/libk5crypto3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.5 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + +
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -1606,11 +984,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 @@ -1621,7 +999,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 adduser@3.118ubuntu5 @@ -1640,7 +1018,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 krb5/libkrb5support0@1.19.2-2ubuntu0.2 @@ -1667,6 +1045,7 @@

      References

    • cve@mitre.org
    • cve@mitre.org
    • cve@mitre.org
    • +
    • cve@mitre.org

    @@ -1755,7 +1134,7 @@

    Memory Leak

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and glibc/libc-bin@2.35-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@v2.8.5 and glibc/libc-bin@2.35-0ubuntu3.4
  • @@ -1768,18 +1147,18 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - glibc/libc-bin@2.35-0ubuntu3.3 + glibc/libc-bin@2.35-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - glibc/libc6@2.35-0ubuntu3.3 + glibc/libc6@2.35-0ubuntu3.4 @@ -2102,258 +1481,28 @@

      Detailed paths

    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/gosimple/slug -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/gosimple/slug@v1.13.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    CVE-2022-46908

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - sqlite3/libsqlite3-0 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, gnupg2/gpg@2.2.27-3ubuntu2.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - sqlite3/libsqlite3-0@3.37.2-2ubuntu0.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream sqlite3 package and not the sqlite3 package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    SQLite through 3.40.0, when relying on --safe for execution of an untrusted CLI script, does not properly implement the azProhibitedFunctions protection mechanism, and instead allows UDF functions such as WRITEFILE.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 sqlite3.

    -

    References

    - - -
    - - - -
    -
    -

    Arbitrary Code Injection

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - shadow/passwd -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and shadow/passwd@1:4.8.1-2ubuntu2.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - shadow/login@1:4.8.1-2ubuntu2.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream shadow package and not the shadow package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 shadow.

    -

    References

    - - -
    - - - -
    -
    -

    Out-of-bounds Write

    +

    MPL-2.0 license

    -
    - low severity +
    + medium severity

    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - procps/libprocps8 + github.com/gosimple/slug
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and procps/libprocps8@2:3.3.17-6ubuntu2 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1
    @@ -2366,29 +1515,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - procps/libprocps8@2:3.3.17-6ubuntu2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - procps@2:3.3.17-6ubuntu2 - - procps/libprocps8@2:3.3.17-6ubuntu2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + github.com/argoproj/argo-cd/v2@* - procps@2:3.3.17-6ubuntu2 + github.com/gosimple/slug@v1.13.1 @@ -2399,28 +1528,17 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream procps package and not the procps package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Under some circumstances, this weakness allows a user who has access to run the “ps” utility on a machine, the ability to write almost unlimited amounts of unfiltered data into the process heap.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 procps.

      -

      References

      - +

      MPL-2.0 license


    -

    Uncontrolled Recursion

    +

    CVE-2022-46908

    @@ -2436,13 +1554,13 @@

    Uncontrolled Recursion

  • Vulnerable module: - pcre3/libpcre3 + sqlite3/libsqlite3-0
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.8.5, gnupg2/gpg@2.2.27-3ubuntu2.1 and others
  • @@ -2454,20 +1572,11 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - grep@3.7-1build1 + gnupg2/gpg@2.2.27-3ubuntu2.1 - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + sqlite3/libsqlite3-0@3.37.2-2ubuntu0.1 @@ -2479,32 +1588,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream pcre3 package and not the pcre3 package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream sqlite3 package and not the sqlite3 package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

      +

      SQLite through 3.40.0, when relying on --safe for execution of an untrusted CLI script, does not properly implement the azProhibitedFunctions protection mechanism, and instead allows UDF functions such as WRITEFILE.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 pcre3.

      +

      There is no fixed version for Ubuntu:22.04 sqlite3.

      References


    -

    Release of Invalid Pointer or Reference

    +

    Arbitrary Code Injection

    @@ -2520,12 +1626,12 @@

    Release of Invalid Pointer or Reference

  • Vulnerable module: - patch + shadow/passwd
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.8.5 and shadow/passwd@1:4.8.1-2ubuntu2.1
  • @@ -2538,9 +1644,40 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - patch@2.7.6-7build2 + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.5 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.5 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.5 + + shadow/login@1:4.8.1-2ubuntu2.1 @@ -2552,26 +1689,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream shadow package and not the shadow package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      +

      In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 patch.

      +

      There is no fixed version for Ubuntu:22.04 shadow.

      References


    -

    Double Free

    +

    Out-of-bounds Write

    @@ -2587,12 +1727,12 @@

    Double Free

  • Vulnerable module: - patch + procps/libprocps8
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.8.5 and procps/libprocps8@2:3.3.17-6ubuntu2
  • @@ -2605,9 +1745,29 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - patch@2.7.6-7build2 + procps/libprocps8@2:3.3.17-6ubuntu2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.5 + + procps@2:3.3.17-6ubuntu2 + + procps/libprocps8@2:3.3.17-6ubuntu2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.8.5 + + procps@2:3.3.17-6ubuntu2 @@ -2619,31 +1779,27 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream procps package and not the procps package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

      +

      Under some circumstances, this weakness allows a user who has access to run the “ps” utility on a machine, the ability to write almost unlimited amounts of unfiltered data into the process heap.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 patch.

      +

      There is no fixed version for Ubuntu:22.04 procps.

      References


    -

    Improper Authentication

    +

    Uncontrolled Recursion

    @@ -2659,12 +1815,12 @@

    Improper Authentication

  • Vulnerable module: - openssl/libssl3 + pcre3/libpcre3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssl/libssl3@3.0.2-0ubuntu1.10 + docker-image|quay.io/argoproj/argocd@v2.8.5 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
  • @@ -2677,113 +1833,20 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - openssl@3.0.2-0ubuntu1.10 + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - ca-certificates@20230311ubuntu0.22.04.1 + grep@3.7-1build1 - openssl@3.0.2-0ubuntu1.10 + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 @@ -2795,47 +1858,32 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream pcre3 package and not the pcre3 package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: The AES-SIV cipher implementation contains a bug that causes - it to ignore empty associated data entries which are unauthenticated as - a consequence.

      -

      Impact summary: Applications that use the AES-SIV algorithm and want to - authenticate empty data entries as associated data can be mislead by removing - adding or reordering such empty entries as these are ignored by the OpenSSL - implementation. We are currently unaware of any such applications.

      -

      The AES-SIV algorithm allows for authentication of multiple associated - data entries along with the encryption. To authenticate empty data the - application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with - NULL pointer as the output buffer and 0 as the input buffer length. - The AES-SIV implementation in OpenSSL just returns success for such a call - instead of performing the associated data authentication operation. - The empty data thus will not be authenticated.

      -

      As this issue does not affect non-empty associated data authentication and - we expect it to be rare for an application to use empty associated data - entries this is qualified as Low severity issue.

      +

      In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 pcre3.

      References


    -

    Inefficient Regular Expression Complexity

    +

    Release of Invalid Pointer or Reference

    @@ -2851,12 +1899,12 @@

    Inefficient Regular Expression Complexity

  • Vulnerable module: - openssl/libssl3 + patch
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssl/libssl3@3.0.2-0ubuntu1.10 + docker-image|quay.io/argoproj/argocd@v2.8.5 and patch@2.7.6-7build2
  • @@ -2869,113 +1917,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 + patch@2.7.6-7build2 @@ -2987,57 +1931,26 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: Checking excessively long DH keys or parameters may be very slow.

      -

      Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long - delays. Where the key or parameters that are being checked have been obtained - from an untrusted source this may lead to a Denial of Service.

      -

      The function DH_check() performs various checks on DH parameters. One of those - checks confirms that the modulus ('p' parameter) is not too large. Trying to use - a very large modulus is slow and OpenSSL will not normally use a modulus which - is over 10,000 bits in length.

      -

      However the DH_check() function checks numerous aspects of the key or parameters - that have been supplied. Some of those checks use the supplied modulus value - even if it has already been found to be too large.

      -

      An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulernable to a Denial of Service attack.

      -

      The function DH_check() is itself called by a number of other OpenSSL functions. - An application calling any of those other functions may similarly be affected. - The other functions affected by this are DH_check_ex() and - EVP_PKEY_param_check().

      -

      Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications - when using the '-check' option.

      -

      The OpenSSL SSL/TLS implementation is not affected by this issue. - The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

      +

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 patch.

      References


    -

    Excessive Iteration

    +

    Double Free

    @@ -3053,12 +1966,12 @@

    Excessive Iteration

  • Vulnerable module: - openssl/libssl3 + patch
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssl/libssl3@3.0.2-0ubuntu1.10 + docker-image|quay.io/argoproj/argocd@v2.8.5 and patch@2.7.6-7build2
  • @@ -3071,113 +1984,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssh/openssh-client@1:8.9p1-3ubuntu0.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - ca-certificates@20230311ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.8.5 - openssl@3.0.2-0ubuntu1.10 + patch@2.7.6-7build2 @@ -3189,50 +1998,26 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: Checking excessively long DH keys or parameters may be very slow.

      -

      Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long - delays. Where the key or parameters that are being checked have been obtained - from an untrusted source this may lead to a Denial of Service.

      -

      The function DH_check() performs various checks on DH parameters. After fixing - CVE-2023-3446 it was discovered that a large q parameter value can also trigger - an overly long computation during some of these checks. A correct q value, - if present, cannot be larger than the modulus p parameter, thus it is - unnecessary to perform these checks if q is larger than p.

      -

      An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulnerable to a Denial of Service attack.

      -

      The function DH_check() is itself called by a number of other OpenSSL functions. - An application calling any of those other functions may similarly be affected. - The other functions affected by this are DH_check_ex() and - EVP_PKEY_param_check().

      -

      Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications - when using the "-check" option.

      -

      The OpenSSL SSL/TLS implementation is not affected by this issue.

      -

      The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

      +

      A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 patch.

      References


    @@ -3258,7 +2043,7 @@

    CVE-2023-28531

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and openssh/openssh-client@1:8.9p1-3ubuntu0.4 + docker-image|quay.io/argoproj/argocd@v2.8.5 and openssh/openssh-client@1:8.9p1-3ubuntu0.4
  • @@ -3271,7 +2056,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 openssh/openssh-client@1:8.9p1-3ubuntu0.4 @@ -3328,7 +2113,7 @@

      NULL Pointer Dereference

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others + docker-image|quay.io/argoproj/argocd@v2.8.5, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others
    @@ -3340,7 +2125,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3351,11 +2136,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -3364,7 +2149,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 openldap/libldap-common@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -3426,7 +2211,7 @@

      Resource Exhaustion

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and libzstd/libzstd1@1.4.8+dfsg-3build1 + docker-image|quay.io/argoproj/argocd@v2.8.5 and libzstd/libzstd1@1.4.8+dfsg-3build1
    @@ -3439,7 +2224,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 libzstd/libzstd1@1.4.8+dfsg-3build1 @@ -3497,7 +2282,7 @@

      Integer Overflow or Wraparound

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and krb5/libk5crypto3@1.19.2-2ubuntu0.2 + docker-image|quay.io/argoproj/argocd@v2.8.5 and krb5/libk5crypto3@1.19.2-2ubuntu0.2
    @@ -3510,7 +2295,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 krb5/libk5crypto3@1.19.2-2ubuntu0.2 @@ -3519,7 +2304,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 adduser@3.118ubuntu5 @@ -3540,7 +2325,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 adduser@3.118ubuntu5 @@ -3563,7 +2348,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 krb5/libkrb5-3@1.19.2-2ubuntu0.2 @@ -3572,7 +2357,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 adduser@3.118ubuntu5 @@ -3593,7 +2378,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -3602,7 +2387,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 openssh/openssh-client@1:8.9p1-3ubuntu0.4 @@ -3613,11 +2398,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -3626,11 +2411,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 @@ -3641,7 +2426,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 adduser@3.118ubuntu5 @@ -3660,7 +2445,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 krb5/libkrb5support0@1.19.2-2ubuntu0.2 @@ -3717,7 +2502,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.8.5 and gnupg2/gpgv@2.2.27-3ubuntu2.1
    @@ -3730,7 +2515,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -3739,7 +2524,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 apt@2.4.10 @@ -3750,7 +2535,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3761,7 +2546,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3772,7 +2557,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3783,7 +2568,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3796,7 +2581,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3809,7 +2594,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3818,7 +2603,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3829,7 +2614,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3842,7 +2627,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 @@ -3851,7 +2636,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3862,7 +2647,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 @@ -3871,7 +2656,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3882,7 +2667,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3891,7 +2676,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3902,7 +2687,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3915,7 +2700,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3928,7 +2713,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpg-agent@2.2.27-3ubuntu2.1 @@ -3937,7 +2722,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3948,7 +2733,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3961,7 +2746,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3974,7 +2759,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 @@ -3983,7 +2768,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3994,7 +2779,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 @@ -4003,7 +2788,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4014,7 +2799,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gpgsm@2.2.27-3ubuntu2.1 @@ -4023,7 +2808,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4034,7 +2819,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4093,7 +2878,7 @@

      Allocation of Resources Without Limits or Throttling

      Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and glibc/libc-bin@2.35-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@v2.8.5 and glibc/libc-bin@2.35-0ubuntu3.4
    @@ -4106,18 +2891,18 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - glibc/libc-bin@2.35-0ubuntu3.3 + glibc/libc-bin@2.35-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 - glibc/libc6@2.35-0ubuntu3.3 + glibc/libc6@2.35-0ubuntu3.4 @@ -4172,7 +2957,7 @@

      Improper Input Validation

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others + docker-image|quay.io/argoproj/argocd@v2.8.5, git@1:2.34.1-1ubuntu1.10 and others
    @@ -4184,7 +2969,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 @@ -4195,7 +2980,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git@1:2.34.1-1ubuntu1.10 @@ -4204,7 +2989,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 git-lfs@3.0.2-1ubuntu0.2 @@ -4261,7 +3046,7 @@

      Uncontrolled Recursion

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + docker-image|quay.io/argoproj/argocd@v2.8.5 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    @@ -4274,7 +3059,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4283,7 +3068,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 apt@2.4.10 @@ -4294,7 +3079,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 apt@2.4.10 @@ -4307,7 +3092,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 @@ -4316,7 +3101,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -4349,89 +3134,6 @@

      References

      More about this vulnerability

    -
    -
    -

    CVE-2023-38546

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - curl/libcurl3-gnutls -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2, git@1:2.34.1-1ubuntu1.10 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    This flaw allows an attacker to insert cookies at will into a running program - using libcurl, if the specific series of conditions are met.

    -

    libcurl performs transfers. In its API, an application creates "easy handles" - that are the individual handles for single transfers.

    -

    libcurl provides a function call that duplicates en easy handle called - curl_easy_duphandle.

    -

    If a transfer has cookies enabled when the handle is duplicated, the - cookie-enable state is also cloned - but without cloning the actual - cookies. If the source handle did not read any cookies from a specific file on - disk, the cloned version of the handle would instead store the file name as - none (using the four ASCII letters, no quotes).

    -

    Subsequent use of the cloned handle that does not explicitly set a source to - load cookies from would then inadvertently load cookies from a file named - none - if such a file exists and is readable in the current directory of the - program using libcurl. And if using the correct file format of course.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    -

    References

    - - -
    - - -

    Improper Input Validation

    @@ -4455,7 +3157,7 @@

    Improper Input Validation

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and coreutils@8.32-4.1ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.8.5 and coreutils@8.32-4.1ubuntu1
  • @@ -4468,7 +3170,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 coreutils@8.32-4.1ubuntu1 @@ -4525,7 +3227,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 and bash@5.1-6ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.8.5 and bash@5.1-6ubuntu1
    @@ -4538,7 +3240,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.9.0-rc2 + docker-image|quay.io/argoproj/argocd@v2.8.5 bash@5.1-6ubuntu1 diff --git a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html b/docs/snyk/v2.8.5/redis_7.0.11-alpine.html similarity index 81% rename from docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html rename to docs/snyk/v2.8.5/redis_7.0.11-alpine.html index 329d39f6c5098..20730eb214f1d 100644 --- a/docs/snyk/v2.9.0-rc2/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.8.5/redis_7.0.11-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

      Snyk test report

      -

      October 22nd 2023, 12:18:30 am (UTC+00:00)

      +

      October 29th 2023, 12:22:23 am (UTC+00:00)

      Scanned the following path: @@ -466,8 +466,8 @@

      Snyk test report

      -
      4 known vulnerabilities
      -
      32 vulnerable dependency paths
      +
      5 known vulnerabilities
      +
      41 vulnerable dependency paths
      18 dependencies
    @@ -1127,6 +1127,7 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • @@ -1136,6 +1137,196 @@

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html b/docs/snyk/v2.9.0-rc3/argocd-iac-install.html similarity index 99% rename from docs/snyk/v2.9.0-rc2/argocd-iac-install.html rename to docs/snyk/v2.9.0-rc3/argocd-iac-install.html index 3d521f9f74881..207acd982d50e 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-iac-install.html +++ b/docs/snyk/v2.9.0-rc3/argocd-iac-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:20:12 am (UTC+00:00)

    +

    October 29th 2023, 12:20:57 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html b/docs/snyk/v2.9.0-rc3/argocd-iac-namespace-install.html similarity index 99% rename from docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html rename to docs/snyk/v2.9.0-rc3/argocd-iac-namespace-install.html index 8280d0891ebd1..9e4ae7e5224e8 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-iac-namespace-install.html +++ b/docs/snyk/v2.9.0-rc3/argocd-iac-namespace-install.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:20:23 am (UTC+00:00)

    +

    October 29th 2023, 12:21:10 am (UTC+00:00)

    Scanned the following path: diff --git a/docs/snyk/v2.9.0-rc2/argocd-test.html b/docs/snyk/v2.9.0-rc3/argocd-test.html similarity index 99% rename from docs/snyk/v2.9.0-rc2/argocd-test.html rename to docs/snyk/v2.9.0-rc3/argocd-test.html index edf48da06d740..8a9efc79fd7df 100644 --- a/docs/snyk/v2.9.0-rc2/argocd-test.html +++ b/docs/snyk/v2.9.0-rc3/argocd-test.html @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:17:48 am (UTC+00:00)

    +

    October 29th 2023, 12:18:17 am (UTC+00:00)

    Scanned the following paths: @@ -811,12 +811,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    @@ -648,12 +648,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|ghcr.io/dexidp/dex@v2.37.0 and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|ghcr.io/dexidp/dex@v2.37.0 + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    diff --git a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html b/docs/snyk/v2.9.0-rc3/haproxy_2.6.14-alpine.html similarity index 53% rename from docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html rename to docs/snyk/v2.9.0-rc3/haproxy_2.6.14-alpine.html index 87d2e9a0fef4b..d4837cba79b4d 100644 --- a/docs/snyk/v2.9.0-rc2/haproxy_2.6.14-alpine.html +++ b/docs/snyk/v2.9.0-rc3/haproxy_2.6.14-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

    Snyk test report

    -

    October 22nd 2023, 12:18:01 am (UTC+00:00)

    +

    October 29th 2023, 12:18:32 am (UTC+00:00)

    Scanned the following path: @@ -466,8 +466,8 @@

    Snyk test report

    -
    0 known vulnerabilities
    -
    0 vulnerable dependency paths
    +
    1 known vulnerabilities
    +
    9 vulnerable dependency paths
    18 dependencies
    @@ -484,7 +484,198 @@

    Snyk test report

    - No known vulnerabilities detected. +
    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|haproxy@2.6.14-alpine and openssl/libcrypto3@3.1.2-r0 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + openssl/libcrypto3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + .haproxy-rundeps@20230809.001942 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    • + Introduced through: + docker-image|haproxy@2.6.14-alpine + + busybox/ssl_client@1.36.1-r2 + + openssl/libssl3@3.1.2-r0 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    +
    diff --git a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html b/docs/snyk/v2.9.0-rc3/quay.io_argoproj_argocd_v2.9.0-rc3.html similarity index 68% rename from docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html rename to docs/snyk/v2.9.0-rc3/quay.io_argoproj_argocd_v2.9.0-rc3.html index 41972f87bb6f3..c815a4833afb8 100644 --- a/docs/snyk/v2.8.4/quay.io_argoproj_argocd_v2.8.4.html +++ b/docs/snyk/v2.9.0-rc3/quay.io_argoproj_argocd_v2.9.0-rc3.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,19 +456,19 @@

    Snyk test report

    -

    October 22nd 2023, 12:21:18 am (UTC+00:00)

    +

    October 29th 2023, 12:18:58 am (UTC+00:00)

    Scanned the following paths:
      -
    • quay.io/argoproj/argocd:v2.8.4/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:v2.8.4/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:v2.8.4/kustomize/kustomize/v5 (gomodules)
    • quay.io/argoproj/argocd:v2.8.4/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:v2.8.4/git-lfs/git-lfs (gomodules)
    • +
    • quay.io/argoproj/argocd:v2.9.0-rc3/argoproj/argocd (deb)
    • quay.io/argoproj/argocd:v2.9.0-rc3/argoproj/argo-cd/v2 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc3 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc3/helm/v3 (gomodules)
    • quay.io/argoproj/argocd:v2.9.0-rc3/git-lfs/git-lfs (gomodules)
    -
    39 known vulnerabilities
    -
    148 vulnerable dependency paths
    -
    2116 dependencies
    +
    30 known vulnerabilities
    +
    99 vulnerable dependency paths
    +
    2185 dependencies
    @@ -498,7 +498,7 @@

    Denial of Service (DoS)

  • Introduced through: - github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.56.1 + github.com/argoproj/argo-cd/v2@* and google.golang.org/grpc@v1.56.2
  • @@ -513,7 +513,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - google.golang.org/grpc@v1.56.1 + google.golang.org/grpc@v1.56.2 @@ -531,12 +531,15 @@

    Remediation

    Upgrade google.golang.org/grpc to version 1.56.3, 1.57.1, 1.58.3 or higher.

    References

    @@ -587,7 +590,7 @@

    Detailed paths

    Introduced through: github.com/argoproj/argo-cd/v2@* - golang.org/x/net/http2@v0.11.0 + golang.org/x/net/http2@v0.15.0 @@ -614,12 +617,15 @@

    Remediation

    Upgrade golang.org/x/net/http2 to version 0.17.0 or higher.

    References

    -
    -
    -

    Out-of-bounds Write

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - glibc/libc-bin -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.8.4 and glibc/libc-bin@2.35-0ubuntu3.3 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - glibc/libc-bin@2.35-0ubuntu3.3 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - glibc/libc6@2.35-0ubuntu3.3 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream glibc package and not the glibc package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A buffer overflow was discovered in the GNU C Library's dynamic loader ld.so while processing the GLIBC_TUNABLES environment variable. This issue could allow a local attacker to use maliciously crafted GLIBC_TUNABLES environment variables when launching binaries with SUID permission to execute code with elevated privileges.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 glibc to version 2.35-0ubuntu3.4 or higher.

    -

    References

    - - -
    - - -

    Directory Traversal

    @@ -817,87 +725,6 @@

    References

    More about this vulnerability

    -
    -
    -

    Heap-based Buffer Overflow

    -
    - -
    - high severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - curl/libcurl3-gnutls -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.8.4, git@1:2.34.1-1ubuntu1.10 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    This flaw makes curl overflow a heap based buffer in the SOCKS5 proxy - handshake.

    -

    When curl is asked to pass along the host name to the SOCKS5 proxy to allow - that to resolve the address instead of it getting done by curl itself, the - maximum length that host name can be is 255 bytes.

    -

    If the host name is detected to be longer, curl switches to local name - resolving and instead passes on the resolved address only. Due to this bug, - the local variable that means "let the host resolve the name" could get the - wrong value during a slow SOCKS5 handshake, and contrary to the intention, - copy the too long host name to the target buffer instead of copying just the - resolved address there.

    -

    The target buffer being a heap based buffer, and the host name coming from the - URL that curl has been told to operate with.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    -

    References

    - - -
    - - -

    CVE-2020-22916

    @@ -921,7 +748,7 @@

    CVE-2020-22916

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and xz-utils/liblzma5@5.2.5-2ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and xz-utils/liblzma5@5.2.5-2ubuntu1
  • @@ -934,7 +761,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 xz-utils/liblzma5@5.2.5-2ubuntu1 @@ -995,7 +822,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4, git@1:2.34.1-1ubuntu1.10 and others + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3, git@1:2.34.1-1ubuntu1.10 and others
    @@ -1007,7 +834,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 @@ -1020,7 +847,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 @@ -1035,7 +862,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 @@ -1048,7 +875,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 @@ -1059,7 +886,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 perl/perl-base@5.34.0-3ubuntu1.2 @@ -1093,7 +920,7 @@

      References

    -

    Out-of-bounds Read

    +

    Access of Uninitialized Pointer

    @@ -1109,12 +936,12 @@

    Out-of-bounds Read

  • Vulnerable module: - libx11/libx11-data + krb5/libk5crypto3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and krb5/libk5crypto3@1.19.2-2ubuntu0.2
  • @@ -1127,183 +954,159 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - libx11/libx11-data@2:1.7.5-1ubuntu0.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + adduser@3.118ubuntu5 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + shadow/passwd@1:4.8.1-2ubuntu2.1 - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - libxext/libxext6@2:1.3.4-1build1 + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 + + krb5/libkrb5-3@1.19.2-2ubuntu0.2 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libk5crypto3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - libxmu/libxmuu1@2:1.1.3-3 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - xauth@1:1.1-1build2 + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 + + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 + + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libkrb5-3@1.19.2-2ubuntu0.2
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A vulnerability was found in libX11 due to a boundary condition within the _XkbReadKeySyms() function. This flaw allows a local user to trigger an out-of-bounds read error and read the contents of memory on the system.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Loop with Unreachable Exit Condition ('Infinite Loop')

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - libx11/libx11-data -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.8.4 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - libx11/libx11-data@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + openssh/openssh-client@1:8.9p1-3ubuntu0.4 - libx11/libx11-data@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + git@1:2.34.1-1ubuntu1.10 + + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 - libxext/libxext6@2:1.3.4-1build1 + libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + pam/libpam-modules@1.4.0-11ubuntu2.3 + + libnsl/libnsl2@1.3.0-2build2 - libxmu/libxmuu1@2:1.1.3-3 + libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - xauth@1:1.1-1build2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 + krb5/libkrb5support0@1.19.2-2ubuntu0.2 @@ -1315,369 +1118,31 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      A vulnerability was found in libX11 due to an infinite loop within the PutSubImage() function. This flaw allows a local user to consume all available system resources and cause a denial of service condition.

      +

      lib/kadm5/kadm_rpc_xdr.c in MIT Kerberos 5 (aka krb5) before 1.20.2 and 1.21.x before 1.21.1 frees an uninitialized pointer. A remote authenticated user can trigger a kadmind crash. This occurs because _xdr_kadm5_principal_ent_rec does not validate the relationship between n_key_data and the key_data array count.

      Remediation

      -

      Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

      +

      There is no fixed version for Ubuntu:22.04 krb5.

      References


    -

    Integer Overflow or Wraparound

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - libx11/libx11-data -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.8.4 and libx11/libx11-data@2:1.7.5-1ubuntu0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - libx11/libx11-data@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libxext/libxext6@2:1.3.4-1build1 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libxmu/libxmuu1@2:1.1.3-3 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - xauth@1:1.1-1build2 - - libx11/libx11-6@2:1.7.5-1ubuntu0.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream libx11 package and not the libx11 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    A vulnerability was found in libX11 due to an integer overflow within the XCreateImage() function. This flaw allows a local user to trigger an integer overflow and execute arbitrary code with elevated privileges.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 libx11 to version 2:1.7.5-1ubuntu0.3 or higher.

    -

    References

    - - -
    - - - -
    -
    -

    Access of Uninitialized Pointer

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - krb5/libk5crypto3 -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.8.4 and krb5/libk5crypto3@1.19.2-2ubuntu0.2 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - krb5/libk5crypto3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libk5crypto3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - krb5/libk5crypto3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssh/openssh-client@1:8.9p1-3ubuntu0.3 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - krb5/libkrb5support0@1.19.2-2ubuntu0.2 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream krb5 package and not the krb5 package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    lib/kadm5/kadm_rpc_xdr.c in MIT Kerberos 5 (aka krb5) before 1.20.2 and 1.21.x before 1.21.1 frees an uninitialized pointer. A remote authenticated user can trigger a kadmind crash. This occurs because _xdr_kadm5_principal_ent_rec does not validate the relationship between n_key_data and the key_data array count.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 krb5.

    -

    References

    - - -
    - - - -
    -
    -

    LGPL-3.0 license

    +

    LGPL-3.0 license

    @@ -1755,7 +1220,7 @@

    Memory Leak

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and glibc/libc-bin@2.35-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and glibc/libc-bin@2.35-0ubuntu3.4
  • @@ -1768,18 +1233,18 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - glibc/libc-bin@2.35-0ubuntu3.3 + glibc/libc-bin@2.35-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - glibc/libc6@2.35-0ubuntu3.3 + glibc/libc6@2.35-0ubuntu3.4 @@ -2097,263 +1562,33 @@

      Detailed paths


      - -
    -
    -

    MPL-2.0 license

    -
    - -
    - medium severity -
    - -
    - -
      -
    • - Package Manager: golang -
    • -
    • - Module: - - github.com/gosimple/slug -
    • - -
    • Introduced through: - - github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - github.com/argoproj/argo-cd/v2@* - - github.com/gosimple/slug@v1.13.1 - - - -
    • -
    - -
    - -
    - -

    MPL-2.0 license

    - -
    - - - -
    -
    -

    CVE-2022-46908

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - sqlite3/libsqlite3-0 -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.8.4, gnupg2/gpg@2.2.27-3ubuntu2.1 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - gnupg2/gpg@2.2.27-3ubuntu2.1 - - sqlite3/libsqlite3-0@3.37.2-2ubuntu0.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream sqlite3 package and not the sqlite3 package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    SQLite through 3.40.0, when relying on --safe for execution of an untrusted CLI script, does not properly implement the azProhibitedFunctions protection mechanism, and instead allows UDF functions such as WRITEFILE.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 sqlite3.

    -

    References

    - - -
    - - - -
    -
    -

    Arbitrary Code Injection

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - shadow/passwd -
    • - -
    • Introduced through: - - docker-image|quay.io/argoproj/argocd@v2.8.4 and shadow/passwd@1:4.8.1-2ubuntu2.1 - -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssh/openssh-client@1:8.9p1-3ubuntu0.3 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - shadow/login@1:4.8.1-2ubuntu2.1 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream shadow package and not the shadow package as distributed by Ubuntu:22.04. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

    -

    Remediation

    -

    There is no fixed version for Ubuntu:22.04 shadow.

    -

    References

    - - -
    - -
    -
    -

    Out-of-bounds Write

    +
    +

    MPL-2.0 license

    -
    - low severity +
    + medium severity

    • - Package Manager: ubuntu:22.04 + Package Manager: golang
    • - Vulnerable module: + Module: - procps/libprocps8 + github.com/gosimple/slug
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and procps/libprocps8@2:3.3.17-6ubuntu2 + github.com/argoproj/argo-cd/v2@* and github.com/gosimple/slug@v1.13.1
    @@ -2366,29 +1601,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - procps/libprocps8@2:3.3.17-6ubuntu2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - procps@2:3.3.17-6ubuntu2 - - procps/libprocps8@2:3.3.17-6ubuntu2 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + github.com/argoproj/argo-cd/v2@* - procps@2:3.3.17-6ubuntu2 + github.com/gosimple/slug@v1.13.1 @@ -2399,28 +1614,17 @@

      Detailed paths


      -

      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream procps package and not the procps package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Under some circumstances, this weakness allows a user who has access to run the “ps” utility on a machine, the ability to write almost unlimited amounts of unfiltered data into the process heap.

      -

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 procps.

      -

      References

      - +

      MPL-2.0 license


    -

    Uncontrolled Recursion

    +

    CVE-2022-46908

    @@ -2436,13 +1640,13 @@

    Uncontrolled Recursion

  • Vulnerable module: - pcre3/libpcre3 + sqlite3/libsqlite3-0
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3, gnupg2/gpg@2.2.27-3ubuntu2.1 and others
  • @@ -2454,20 +1658,11 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - grep@3.7-1build1 + gnupg2/gpg@2.2.27-3ubuntu2.1 - pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 + sqlite3/libsqlite3-0@3.37.2-2ubuntu0.1 @@ -2479,32 +1674,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream pcre3 package and not the pcre3 package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream sqlite3 package and not the sqlite3 package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

      +

      SQLite through 3.40.0, when relying on --safe for execution of an untrusted CLI script, does not properly implement the azProhibitedFunctions protection mechanism, and instead allows UDF functions such as WRITEFILE.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 pcre3.

      +

      There is no fixed version for Ubuntu:22.04 sqlite3.

      References


    -

    Release of Invalid Pointer or Reference

    +

    Arbitrary Code Injection

    @@ -2520,12 +1712,12 @@

    Release of Invalid Pointer or Reference

  • Vulnerable module: - patch + shadow/passwd
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and shadow/passwd@1:4.8.1-2ubuntu2.1
  • @@ -2538,9 +1730,40 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - patch@2.7.6-7build2 + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + adduser@3.118ubuntu5 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + openssh/openssh-client@1:8.9p1-3ubuntu0.4 + + shadow/passwd@1:4.8.1-2ubuntu2.1 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + shadow/login@1:4.8.1-2ubuntu2.1 @@ -2552,26 +1775,29 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream shadow package and not the shadow package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      +

      In Shadow 4.13, it is possible to inject control characters into fields provided to the SUID program chfn (change finger). Although it is not possible to exploit this directly (e.g., adding a new user fails because \n is in the block list), it is possible to misrepresent the /etc/passwd file when viewed. Use of \r manipulations and Unicode characters to work around blocking of the : character make it possible to give the impression that a new user has been added. In other words, an adversary may be able to convince a system administrator to take the system offline (an indirect, social-engineered denial of service) by demonstrating that "cat /etc/passwd" shows a rogue user account.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 patch.

      +

      There is no fixed version for Ubuntu:22.04 shadow.

      References


    -

    Double Free

    +

    Out-of-bounds Write

    @@ -2587,12 +1813,12 @@

    Double Free

  • Vulnerable module: - patch + procps/libprocps8
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and patch@2.7.6-7build2 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and procps/libprocps8@2:3.3.17-6ubuntu2
  • @@ -2605,9 +1831,29 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - patch@2.7.6-7build2 + procps/libprocps8@2:3.3.17-6ubuntu2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + procps@2:3.3.17-6ubuntu2 + + procps/libprocps8@2:3.3.17-6ubuntu2 + + + +
    • +
    • + Introduced through: + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 + + procps@2:3.3.17-6ubuntu2 @@ -2619,31 +1865,27 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream procps package and not the procps package as distributed by Ubuntu. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

      +

      Under some circumstances, this weakness allows a user who has access to run the “ps” utility on a machine, the ability to write almost unlimited amounts of unfiltered data into the process heap.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 patch.

      +

      There is no fixed version for Ubuntu:22.04 procps.

      References


    -

    Improper Authentication

    +

    Uncontrolled Recursion

    @@ -2659,12 +1901,12 @@

    Improper Authentication

  • Vulnerable module: - openssl/libssl3 + pcre3/libpcre3
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and openssl/libssl3@3.0.2-0ubuntu1.10 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
  • @@ -2677,113 +1919,20 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssh/openssh-client@1:8.9p1-3ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - openssl@3.0.2-0ubuntu1.10 + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - ca-certificates@20230311ubuntu0.22.04.1 + grep@3.7-1build1 - openssl@3.0.2-0ubuntu1.10 + pcre3/libpcre3@2:8.39-13ubuntu0.22.04.1 @@ -2795,47 +1944,32 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu:22.04. +

      Note: Versions mentioned in the description apply only to the upstream pcre3 package and not the pcre3 package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: The AES-SIV cipher implementation contains a bug that causes - it to ignore empty associated data entries which are unauthenticated as - a consequence.

      -

      Impact summary: Applications that use the AES-SIV algorithm and want to - authenticate empty data entries as associated data can be mislead by removing - adding or reordering such empty entries as these are ignored by the OpenSSL - implementation. We are currently unaware of any such applications.

      -

      The AES-SIV algorithm allows for authentication of multiple associated - data entries along with the encryption. To authenticate empty data the - application has to call EVP_EncryptUpdate() (or EVP_CipherUpdate()) with - NULL pointer as the output buffer and 0 as the input buffer length. - The AES-SIV implementation in OpenSSL just returns success for such a call - instead of performing the associated data authentication operation. - The empty data thus will not be authenticated.

      -

      As this issue does not affect non-empty associated data authentication and - we expect it to be rare for an application to use empty associated data - entries this is qualified as Low severity issue.

      +

      In PCRE 8.41, the OP_KETRMAX feature in the match function in pcre_exec.c allows stack exhaustion (uncontrolled recursion) when processing a crafted regular expression.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 pcre3.

      References


    -

    Inefficient Regular Expression Complexity

    +

    Release of Invalid Pointer or Reference

    @@ -2851,12 +1985,12 @@

    Inefficient Regular Expression Complexity

  • Vulnerable module: - openssl/libssl3 + patch
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and openssl/libssl3@3.0.2-0ubuntu1.10 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and patch@2.7.6-7build2
  • @@ -2869,113 +2003,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssh/openssh-client@1:8.9p1-3ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - ca-certificates@20230311ubuntu0.22.04.1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - openssl@3.0.2-0ubuntu1.10 + patch@2.7.6-7build2 @@ -2987,57 +2017,26 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: Checking excessively long DH keys or parameters may be very slow.

      -

      Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long - delays. Where the key or parameters that are being checked have been obtained - from an untrusted source this may lead to a Denial of Service.

      -

      The function DH_check() performs various checks on DH parameters. One of those - checks confirms that the modulus ('p' parameter) is not too large. Trying to use - a very large modulus is slow and OpenSSL will not normally use a modulus which - is over 10,000 bits in length.

      -

      However the DH_check() function checks numerous aspects of the key or parameters - that have been supplied. Some of those checks use the supplied modulus value - even if it has already been found to be too large.

      -

      An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulernable to a Denial of Service attack.

      -

      The function DH_check() is itself called by a number of other OpenSSL functions. - An application calling any of those other functions may similarly be affected. - The other functions affected by this are DH_check_ex() and - EVP_PKEY_param_check().

      -

      Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications - when using the '-check' option.

      -

      The OpenSSL SSL/TLS implementation is not affected by this issue. - The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

      +

      An Invalid Pointer vulnerability exists in GNU patch 2.7 via the another_hunk function, which causes a Denial of Service.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 patch.

      References


    -

    Excessive Iteration

    +

    Double Free

    @@ -3053,12 +2052,12 @@

    Excessive Iteration

  • Vulnerable module: - openssl/libssl3 + patch
  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and openssl/libssl3@3.0.2-0ubuntu1.10 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and patch@2.7.6-7build2
  • @@ -3071,113 +2070,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - cyrus-sasl2/libsasl2-modules@2.1.27+dfsg2-3ubuntu1.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - libfido2/libfido2-1@1.10.0-1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - openssh/openssh-client@1:8.9p1-3ubuntu0.3 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - adduser@3.118ubuntu5 - - shadow/passwd@1:4.8.1-2ubuntu2.1 - - pam/libpam-modules@1.4.0-11ubuntu2.3 - - libnsl/libnsl2@1.3.0-2build2 - - libtirpc/libtirpc3@1.3.2-2ubuntu0.1 - - krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 - - krb5/libkrb5-3@1.19.2-2ubuntu0.2 - - openssl/libssl3@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - openssl@3.0.2-0ubuntu1.10 - - - -
    • -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - ca-certificates@20230311ubuntu0.22.04.1 - - openssl@3.0.2-0ubuntu1.10 + patch@2.7.6-7build2 @@ -3189,50 +2084,26 @@

      Detailed paths


      NVD Description

      -

      Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Ubuntu. +

      Note: Versions mentioned in the description apply only to the upstream patch package and not the patch package as distributed by Ubuntu:22.04. See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

      -

      Issue summary: Checking excessively long DH keys or parameters may be very slow.

      -

      Impact summary: Applications that use the functions DH_check(), DH_check_ex() - or EVP_PKEY_param_check() to check a DH key or DH parameters may experience long - delays. Where the key or parameters that are being checked have been obtained - from an untrusted source this may lead to a Denial of Service.

      -

      The function DH_check() performs various checks on DH parameters. After fixing - CVE-2023-3446 it was discovered that a large q parameter value can also trigger - an overly long computation during some of these checks. A correct q value, - if present, cannot be larger than the modulus p parameter, thus it is - unnecessary to perform these checks if q is larger than p.

      -

      An application that calls DH_check() and supplies a key or parameters obtained - from an untrusted source could be vulnerable to a Denial of Service attack.

      -

      The function DH_check() is itself called by a number of other OpenSSL functions. - An application calling any of those other functions may similarly be affected. - The other functions affected by this are DH_check_ex() and - EVP_PKEY_param_check().

      -

      Also vulnerable are the OpenSSL dhparam and pkeyparam command line applications - when using the "-check" option.

      -

      The OpenSSL SSL/TLS implementation is not affected by this issue.

      -

      The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this issue.

      +

      A double free exists in the another_hunk function in pch.c in GNU patch through 2.7.6.

      Remediation

      -

      There is no fixed version for Ubuntu:22.04 openssl.

      +

      There is no fixed version for Ubuntu:22.04 patch.

      References


    @@ -3258,7 +2129,7 @@

    CVE-2023-28531

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and openssh/openssh-client@1:8.9p1-3ubuntu0.3 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and openssh/openssh-client@1:8.9p1-3ubuntu0.4
  • @@ -3271,9 +2142,9 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - openssh/openssh-client@1:8.9p1-3ubuntu0.3 + openssh/openssh-client@1:8.9p1-3ubuntu0.4 @@ -3328,7 +2199,7 @@

      NULL Pointer Dereference

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3, gnupg2/dirmngr@2.2.27-3ubuntu2.1 and others
    @@ -3340,7 +2211,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3351,11 +2222,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 openldap/libldap-2.5-0@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -3364,7 +2235,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 openldap/libldap-common@2.5.16+dfsg-0ubuntu0.22.04.1 @@ -3426,7 +2297,7 @@

      Resource Exhaustion

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and libzstd/libzstd1@1.4.8+dfsg-3build1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and libzstd/libzstd1@1.4.8+dfsg-3build1
    @@ -3439,7 +2310,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 libzstd/libzstd1@1.4.8+dfsg-3build1 @@ -3497,7 +2368,7 @@

      Integer Overflow or Wraparound

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and krb5/libk5crypto3@1.19.2-2ubuntu0.2 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and krb5/libk5crypto3@1.19.2-2ubuntu0.2
    @@ -3510,7 +2381,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 krb5/libk5crypto3@1.19.2-2ubuntu0.2 @@ -3519,7 +2390,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 adduser@3.118ubuntu5 @@ -3540,7 +2411,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 adduser@3.118ubuntu5 @@ -3563,7 +2434,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 krb5/libkrb5-3@1.19.2-2ubuntu0.2 @@ -3572,7 +2443,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 adduser@3.118ubuntu5 @@ -3593,7 +2464,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -3602,9 +2473,9 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - openssh/openssh-client@1:8.9p1-3ubuntu0.3 + openssh/openssh-client@1:8.9p1-3ubuntu0.4 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -3613,11 +2484,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 krb5/libgssapi-krb5-2@1.19.2-2ubuntu0.2 @@ -3626,11 +2497,11 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 + curl/libcurl3-gnutls@7.81.0-1ubuntu1.14 libssh/libssh-4@0.9.6-2ubuntu0.22.04.1 @@ -3641,7 +2512,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 adduser@3.118ubuntu5 @@ -3660,7 +2531,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 krb5/libkrb5support0@1.19.2-2ubuntu0.2 @@ -3717,7 +2588,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and gnupg2/gpgv@2.2.27-3ubuntu2.1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and gnupg2/gpgv@2.2.27-3ubuntu2.1
    @@ -3730,7 +2601,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpgv@2.2.27-3ubuntu2.1 @@ -3739,7 +2610,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 apt@2.4.10 @@ -3750,7 +2621,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3761,7 +2632,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3772,7 +2643,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3783,7 +2654,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3796,7 +2667,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3809,7 +2680,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/dirmngr@2.2.27-3ubuntu2.1 @@ -3818,7 +2689,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3829,7 +2700,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3842,7 +2713,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg-l10n@2.2.27-3ubuntu2.1 @@ -3851,7 +2722,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3862,7 +2733,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg-utils@2.2.27-3ubuntu2.1 @@ -3871,7 +2742,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3882,7 +2753,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpg@2.2.27-3ubuntu2.1 @@ -3891,7 +2762,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3902,7 +2773,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3915,7 +2786,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3928,7 +2799,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpg-agent@2.2.27-3ubuntu2.1 @@ -3937,7 +2808,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3948,7 +2819,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3961,7 +2832,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3974,7 +2845,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpg-wks-client@2.2.27-3ubuntu2.1 @@ -3983,7 +2854,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -3994,7 +2865,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpg-wks-server@2.2.27-3ubuntu2.1 @@ -4003,7 +2874,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4014,7 +2885,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gpgsm@2.2.27-3ubuntu2.1 @@ -4023,7 +2894,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4034,7 +2905,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gnupg2/gnupg@2.2.27-3ubuntu2.1 @@ -4093,7 +2964,7 @@

      Allocation of Resources Without Limits or Throttling

      Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and glibc/libc-bin@2.35-0ubuntu3.3 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and glibc/libc-bin@2.35-0ubuntu3.4
    @@ -4106,18 +2977,18 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - glibc/libc-bin@2.35-0ubuntu3.3 + glibc/libc-bin@2.35-0ubuntu3.4
    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 - glibc/libc6@2.35-0ubuntu3.3 + glibc/libc6@2.35-0ubuntu3.4 @@ -4172,7 +3043,7 @@

      Improper Input Validation

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4, git@1:2.34.1-1ubuntu1.10 and others + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3, git@1:2.34.1-1ubuntu1.10 and others
    @@ -4184,7 +3055,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 @@ -4195,7 +3066,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git@1:2.34.1-1ubuntu1.10 @@ -4204,7 +3075,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 git-lfs@3.0.2-1ubuntu0.2 @@ -4261,7 +3132,7 @@

      Uncontrolled Recursion

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04
    @@ -4274,7 +3145,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gcc-12/libstdc++6@12.3.0-1ubuntu1~22.04 @@ -4283,7 +3154,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 apt@2.4.10 @@ -4294,7 +3165,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 apt@2.4.10 @@ -4307,7 +3178,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gcc-12/gcc-12-base@12.3.0-1ubuntu1~22.04 @@ -4316,7 +3187,7 @@

      Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 gcc-12/libgcc-s1@12.3.0-1ubuntu1~22.04 @@ -4349,89 +3220,6 @@

      References

      More about this vulnerability

    -
    -
    -

    CVE-2023-38546

    -
    - -
    - low severity -
    - -
    - -
      -
    • - Package Manager: ubuntu:22.04 -
    • -
    • - Vulnerable module: - - curl/libcurl3-gnutls -
    • - -
    • Introduced through: - - - docker-image|quay.io/argoproj/argocd@v2.8.4, git@1:2.34.1-1ubuntu1.10 and others -
    • -
    - -
    - - -

    Detailed paths

    - -
      -
    • - Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 - - git@1:2.34.1-1ubuntu1.10 - - curl/libcurl3-gnutls@7.81.0-1ubuntu1.13 - - - -
    • -
    - -
    - -
    - -

    NVD Description

    -

    Note: Versions mentioned in the description apply only to the upstream curl package and not the curl package as distributed by Ubuntu. - See How to fix? for Ubuntu:22.04 relevant fixed versions and status.

    -

    This flaw allows an attacker to insert cookies at will into a running program - using libcurl, if the specific series of conditions are met.

    -

    libcurl performs transfers. In its API, an application creates "easy handles" - that are the individual handles for single transfers.

    -

    libcurl provides a function call that duplicates en easy handle called - curl_easy_duphandle.

    -

    If a transfer has cookies enabled when the handle is duplicated, the - cookie-enable state is also cloned - but without cloning the actual - cookies. If the source handle did not read any cookies from a specific file on - disk, the cloned version of the handle would instead store the file name as - none (using the four ASCII letters, no quotes).

    -

    Subsequent use of the cloned handle that does not explicitly set a source to - load cookies from would then inadvertently load cookies from a file named - none - if such a file exists and is readable in the current directory of the - program using libcurl. And if using the correct file format of course.

    -

    Remediation

    -

    Upgrade Ubuntu:22.04 curl to version 7.81.0-1ubuntu1.14 or higher.

    -

    References

    - - -
    - - -

    Improper Input Validation

    @@ -4455,7 +3243,7 @@

    Improper Input Validation

  • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and coreutils@8.32-4.1ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and coreutils@8.32-4.1ubuntu1
  • @@ -4468,7 +3256,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 coreutils@8.32-4.1ubuntu1 @@ -4525,7 +3313,7 @@

      Out-of-bounds Write

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 and bash@5.1-6ubuntu1 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 and bash@5.1-6ubuntu1
    @@ -4538,7 +3326,7 @@

    Detailed paths

    • Introduced through: - docker-image|quay.io/argoproj/argocd@v2.8.4 + docker-image|quay.io/argoproj/argocd@v2.9.0-rc3 bash@5.1-6ubuntu1 diff --git a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html b/docs/snyk/v2.9.0-rc3/redis_7.0.11-alpine.html similarity index 81% rename from docs/snyk/v2.8.4/redis_7.0.11-alpine.html rename to docs/snyk/v2.9.0-rc3/redis_7.0.11-alpine.html index fe91f261fcc18..8efb859567ad3 100644 --- a/docs/snyk/v2.8.4/redis_7.0.11-alpine.html +++ b/docs/snyk/v2.9.0-rc3/redis_7.0.11-alpine.html @@ -7,7 +7,7 @@ Snyk test report - + @@ -456,7 +456,7 @@

      Snyk test report

      -

      October 22nd 2023, 12:21:23 am (UTC+00:00)

      +

      October 29th 2023, 12:19:03 am (UTC+00:00)

      Scanned the following path: @@ -466,8 +466,8 @@

      Snyk test report

      -
      4 known vulnerabilities
      -
      32 vulnerable dependency paths
      +
      5 known vulnerabilities
      +
      41 vulnerable dependency paths
      18 dependencies
    @@ -1127,6 +1127,7 @@

    References

  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • openssl-security@openssl.org
  • +
  • openssl-security@openssl.org

  • @@ -1136,6 +1137,196 @@

    References

    +
    +

    CVE-2023-5363

    +
    + +
    + low severity +
    + +
    + +
      +
    • + Package Manager: alpine:3.18 +
    • +
    • + Vulnerable module: + + openssl/libcrypto3 +
    • + +
    • Introduced through: + + docker-image|redis@7.0.11-alpine and openssl/libcrypto3@3.1.1-r1 + +
    • +
    + +
    + + +

    Detailed paths

    + +
      +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + openssl/libcrypto3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + .redis-rundeps@20230614.215749 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + apk-tools/apk-tools@2.14.0-r2 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    • + Introduced through: + docker-image|redis@7.0.11-alpine + + busybox/ssl_client@1.36.1-r0 + + openssl/libssl3@3.1.1-r1 + + + +
    • +
    + +
    + +
    + +

    NVD Description

    +

    Note: Versions mentioned in the description apply only to the upstream openssl package and not the openssl package as distributed by Alpine. + See How to fix? for Alpine:3.18 relevant fixed versions and status.

    +

    Issue summary: A bug has been identified in the processing of key and + initialisation vector (IV) lengths. This can lead to potential truncation + or overruns during the initialisation of some symmetric ciphers.

    +

    Impact summary: A truncation in the IV can result in non-uniqueness, + which could result in loss of confidentiality for some cipher modes.

    +

    When calling EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or + EVP_CipherInit_ex2() the provided OSSL_PARAM array is processed after + the key and IV have been established. Any alterations to the key length, + via the "keylen" parameter or the IV length, via the "ivlen" parameter, + within the OSSL_PARAM array will not take effect as intended, potentially + causing truncation or overreading of these values. The following ciphers + and cipher modes are impacted: RC2, RC4, RC5, CCM, GCM and OCB.

    +

    For the CCM, GCM and OCB cipher modes, truncation of the IV can result in + loss of confidentiality. For example, when following NIST's SP 800-38D + section 8.2.1 guidance for constructing a deterministic IV for AES in + GCM mode, truncation of the counter portion could lead to IV reuse.

    +

    Both truncations and overruns of the key and overruns of the IV will + produce incorrect results and could, in some cases, trigger a memory + exception. However, these issues are not currently assessed as security + critical.

    +

    Changing the key and/or IV lengths is not considered to be a common operation + and the vulnerable API was recently introduced. Furthermore it is likely that + application developers will have spotted this problem during testing since + decryption would fail unless both peers in the communication were similarly + vulnerable. For these reasons we expect the probability of an application being + vulnerable to this to be quite low. However if an application is vulnerable then + this issue is considered very serious. For these reasons we have assessed this + issue as Moderate severity overall.

    +

    The OpenSSL SSL/TLS implementation is not affected by this issue.

    +

    The OpenSSL 3.0 and 3.1 FIPS providers are not affected by this because + the issue lies outside of the FIPS provider boundary.

    +

    OpenSSL 3.1 and 3.0 are vulnerable to this issue.

    +

    Remediation

    +

    Upgrade Alpine:3.18 openssl to version 3.1.4-r0 or higher.

    +

    References

    + + +
    + + + +
    From f7a32fd346f6363becb3aa0db133cafa99c196bb Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Mon, 30 Oct 2023 07:44:04 +0530 Subject: [PATCH 056/269] Set cert resolver in notifications-controller (#15394) Signed-off-by: Siddhesh Ghadi --- notification_controller/controller/controller.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index a08c0cc1f9714..32dfac2b75a3b 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -12,6 +12,8 @@ import ( service "github.com/argoproj/argo-cd/v2/util/notification/argocd" + argocert "github.com/argoproj/argo-cd/v2/util/cert" + "k8s.io/apimachinery/pkg/runtime/schema" "github.com/argoproj/argo-cd/v2/util/notification/settings" @@ -21,6 +23,7 @@ import ( "github.com/argoproj/notifications-engine/pkg/controller" "github.com/argoproj/notifications-engine/pkg/services" "github.com/argoproj/notifications-engine/pkg/subscriptions" + httputil "github.com/argoproj/notifications-engine/pkg/util/http" log "github.com/sirupsen/logrus" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -160,6 +163,9 @@ type notificationController struct { } func (c *notificationController) Init(ctx context.Context) error { + // resolve certificates using injected "argocd-tls-certs-cm" ConfigMap + httputil.SetCertResolver(argocert.GetCertificateForConnect) + go c.appInformer.Run(ctx.Done()) go c.appProjInformer.Run(ctx.Done()) go c.secretInformer.Run(ctx.Done()) From 48f175baae293c6194f6a3c32548e32c273aec35 Mon Sep 17 00:00:00 2001 From: Ashin Sabu <139749674+ashinsabu3@users.noreply.github.com> Date: Mon, 30 Oct 2023 08:07:33 +0530 Subject: [PATCH 057/269] fix: rbac validate command can now take either namespace or policy-file (#15543) * fix: rbac validate command can now take either namespace or policy-file as arg Signed-off-by: Ashin Sabu * remove changes to generated text Signed-off-by: Ashin Sabu * unit test for rbacvalidatecommand Signed-off-by: Ashin Sabu * codegen changes Signed-off-by: Ashin Sabu * retrigger ci pipeline Signed-off-by: Ashin Sabu * retrigger ci pipeline Signed-off-by: Ashin Sabu * review comments and test changes Signed-off-by: Ashin Sabu * codegen changes Signed-off-by: Ashin Sabu * codegen changes - post rebase Signed-off-by: Ashin Sabu --------- Signed-off-by: Ashin Sabu --- cmd/argocd/commands/admin/settings_rbac.go | 50 +++++++++++--- .../commands/admin/settings_rbac_test.go | 47 ++++++++++++- .../argocd_admin_settings_rbac_validate.md | 67 ++++++++++++------- 3 files changed, 130 insertions(+), 34 deletions(-) diff --git a/cmd/argocd/commands/admin/settings_rbac.go b/cmd/argocd/commands/admin/settings_rbac.go index 8d94feeaad466..1c09fa0d1cfe7 100644 --- a/cmd/argocd/commands/admin/settings_rbac.go +++ b/cmd/argocd/commands/admin/settings_rbac.go @@ -189,7 +189,6 @@ argocd admin settings rbac can someuser create application 'default/app' --defau } }, } - clientConfig = cli.AddKubectlFlagsToCmd(command) command.Flags().StringVar(&policyFile, "policy-file", "", "path to the policy file to use") command.Flags().StringVar(&defaultRole, "default-role", "", "name of the default role to use") @@ -202,24 +201,55 @@ argocd admin settings rbac can someuser create application 'default/app' --defau // NewRBACValidateCommand returns a new rbac validate command func NewRBACValidateCommand() *cobra.Command { var ( - policyFile string + policyFile string + namespace string + clientConfig clientcmd.ClientConfig ) var command = &cobra.Command{ - Use: "validate --policy-file=POLICYFILE", + Use: "validate [--policy-file POLICYFILE] [--namespace NAMESPACE]", Short: "Validate RBAC policy", Long: ` Validates an RBAC policy for being syntactically correct. The policy must be -a local file, and in either CSV or K8s ConfigMap format. +a local file or a K8s ConfigMap in the provided namespace, and in either CSV or K8s ConfigMap format. +`, + Example: ` +# Check whether a given policy file is valid using a local policy.csv file. +argocd admin settings rbac validate --policy-file policy.csv + +# Policy file can also be K8s config map with data keys like argocd-rbac-cm, +# i.e. 'policy.csv' and (optionally) 'policy.default' +argocd admin settings rbac validate --policy-file argocd-rbac-cm.yaml + +# If --policy-file is not given, and instead --namespace is giventhe ConfigMap 'argocd-rbac-cm' +# from K8s is used. +argocd admin settings rbac validate --namespace argocd + +# Either --policy-file or --namespace must be given. `, Run: func(c *cobra.Command, args []string) { ctx := c.Context() - if policyFile == "" { + if len(args) > 0 { c.HelpFunc()(c, args) - log.Fatalf("Please specify policy to validate using --policy-file") + log.Fatalf("too many arguments") + } + + if (namespace == "" && policyFile == "") || (namespace != "" && policyFile != "") { + c.HelpFunc()(c, args) + log.Fatalf("please provide exactly one of --policy-file or --namespace") } - userPolicy, _, _ := getPolicy(ctx, policyFile, nil, "") + + restConfig, err := clientConfig.ClientConfig() + if err != nil { + log.Fatalf("could not get config to create k8s client: %v", err) + } + realClientset, err := kubernetes.NewForConfig(restConfig) + if err != nil { + log.Fatalf("could not create k8s client: %v", err) + } + + userPolicy, _, _ := getPolicy(ctx, policyFile, realClientset, namespace) if userPolicy != "" { if err := rbac.ValidatePolicy(userPolicy); err == nil { fmt.Printf("Policy is valid.\n") @@ -228,11 +258,15 @@ a local file, and in either CSV or K8s ConfigMap format. fmt.Printf("Policy is invalid: %v\n", err) os.Exit(1) } + } else { + log.Fatalf("Policy is empty or could not be loaded.") } }, } - + clientConfig = cli.AddKubectlFlagsToCmd(command) command.Flags().StringVar(&policyFile, "policy-file", "", "path to the policy file to use") + command.Flags().StringVar(&namespace, "namespace", "", "namespace to get argo rbac configmap from") + return command } diff --git a/cmd/argocd/commands/admin/settings_rbac_test.go b/cmd/argocd/commands/admin/settings_rbac_test.go index a4b4b437e114c..79835ffd0c14d 100644 --- a/cmd/argocd/commands/admin/settings_rbac_test.go +++ b/cmd/argocd/commands/admin/settings_rbac_test.go @@ -5,15 +5,42 @@ import ( "os" "testing" + "github.com/argoproj/argo-cd/v2/util/assets" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes/fake" - - "github.com/argoproj/argo-cd/v2/util/assets" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) +type FakeClientConfig struct { + clientConfig clientcmd.ClientConfig +} + +func NewFakeClientConfig(clientConfig clientcmd.ClientConfig) *FakeClientConfig { + return &FakeClientConfig{clientConfig: clientConfig} +} + +func (f *FakeClientConfig) RawConfig() (clientcmdapi.Config, error) { + config, err := f.clientConfig.RawConfig() + return config, err +} + +func (f *FakeClientConfig) ClientConfig() (*restclient.Config, error) { + return f.clientConfig.ClientConfig() +} + +func (f *FakeClientConfig) Namespace() (string, bool, error) { + return f.clientConfig.Namespace() +} + +func (f *FakeClientConfig) ConfigAccess() clientcmd.ConfigAccess { + return nil +} + func Test_isValidRBACAction(t *testing.T) { for k := range validRBACActions { t.Run(k, func(t *testing.T) { @@ -200,3 +227,19 @@ p, role:, certificates, get, .*, allow` require.True(t, ok) }) } + +func TestNewRBACCanCommand(t *testing.T) { + command := NewRBACCanCommand() + + require.NotNil(t, command) + assert.Equal(t, "can", command.Name()) + assert.Equal(t, "Check RBAC permissions for a role or subject", command.Short) +} + +func TestNewRBACValidateCommand(t *testing.T) { + command := NewRBACValidateCommand() + + require.NotNil(t, command) + assert.Equal(t, "validate", command.Name()) + assert.Equal(t, "Validate RBAC policy", command.Short) +} diff --git a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md index 75bc909882e19..b051c7c63694b 100644 --- a/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md +++ b/docs/user-guide/commands/argocd_admin_settings_rbac_validate.md @@ -8,18 +8,57 @@ Validate RBAC policy Validates an RBAC policy for being syntactically correct. The policy must be -a local file, and in either CSV or K8s ConfigMap format. +a local file or a K8s ConfigMap in the provided namespace, and in either CSV or K8s ConfigMap format. ``` -argocd admin settings rbac validate --policy-file=POLICYFILE [flags] +argocd admin settings rbac validate [--policy-file POLICYFILE] [--namespace NAMESPACE] [flags] +``` + +### Examples + +``` + +# Check whether a given policy file is valid using a local policy.csv file. +argocd admin settings rbac validate --policy-file policy.csv + +# Policy file can also be K8s config map with data keys like argocd-rbac-cm, +# i.e. 'policy.csv' and (optionally) 'policy.default' +argocd admin settings rbac validate --policy-file argocd-rbac-cm.yaml + +# If --policy-file is not given, and instead --namespace is giventhe ConfigMap 'argocd-rbac-cm' +# from K8s is used. +argocd admin settings rbac validate --namespace argocd + +# Either --policy-file or --namespace must be given. + ``` ### Options ``` - -h, --help help for validate - --policy-file string path to the policy file to use + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --context string The name of the kubeconfig context to use + --disable-compression If true, opt-out of response compression for all requests to the server + -h, --help help for validate + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + --namespace string namespace to get argo rbac configmap from + --password string Password for basic authentication to the API server + --policy-file string path to the policy file to use + --proxy-url string If provided, this URL will be used to connect via proxy + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server ``` ### Options inherited from parent commands @@ -27,49 +66,29 @@ argocd admin settings rbac validate --policy-file=POLICYFILE [flags] ``` --argocd-cm-path string Path to local argocd-cm.yaml file --argocd-secret-path string Path to local argocd-secret.yaml file - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation --auth-token string Authentication token - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS --client-crt string Client certificate file --client-crt-key string Client certificate key file - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use --config string Path to Argo CD config (default "/home/user/.config/argocd/config") - --context string The name of the kubeconfig context to use --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server - --disable-compression If true, opt-out of response compression for all requests to the server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) --http-retry-max int Maximum number of retries to establish http connection to Argo CD server --insecure Skip server certificate and domain verification - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kube-context string Directs the command to the given kube-context - --kubeconfig string Path to a kube config. Only required if out-of-cluster --load-cluster-settings Indicates that config map and secret should be loaded from cluster unless local file path is provided --logformat string Set the logging format. One of: text|json (default "text") --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") - -n, --namespace string If present, the namespace scope for this CLI request - --password string Password for basic authentication to the API server --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding - --proxy-url string If provided, this URL will be used to connect via proxy --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --server string The address and port of the Kubernetes API server --server-crt string Server certificate file --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") - --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server ``` ### SEE ALSO From 8241869050bffcfec37809719c0777be68f96818 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Mon, 30 Oct 2023 11:25:22 -0400 Subject: [PATCH 058/269] chore(appset): better structured logging for controller (#16149) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .../controllers/applicationset_controller.go | 140 ++++++++++-------- .../applicationset_controller_test.go | 20 +-- 2 files changed, 91 insertions(+), 69 deletions(-) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 45b6649685e6e..7466a2394bd9e 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -117,7 +117,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque // Log a warning if there are unrecognized generators _ = utils.CheckInvalidGenerators(&applicationSetInfo) // desiredApplications is the main list of all expected Applications from all generators in this appset. - desiredApplications, applicationSetReason, err := r.generateApplications(applicationSetInfo) + desiredApplications, applicationSetReason, err := r.generateApplications(logCtx, applicationSetInfo) if err != nil { _ = r.setApplicationSetStatusCondition(ctx, &applicationSetInfo, @@ -164,9 +164,9 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque if r.EnableProgressiveSyncs { if applicationSetInfo.Spec.Strategy == nil && len(applicationSetInfo.Status.ApplicationStatus) > 0 { // If appset used progressive sync but stopped, clean up the progressive sync application statuses - log.Infof("Removing %v unnecessary AppStatus entries from ApplicationSet %v", len(applicationSetInfo.Status.ApplicationStatus), applicationSetInfo.Name) + logCtx.Infof("Removing %v unnecessary AppStatus entries from ApplicationSet %v", len(applicationSetInfo.Status.ApplicationStatus), applicationSetInfo.Name) - err := r.setAppSetApplicationStatus(ctx, &applicationSetInfo, []argov1alpha1.ApplicationSetApplicationStatus{}) + err := r.setAppSetApplicationStatus(ctx, logCtx, &applicationSetInfo, []argov1alpha1.ApplicationSetApplicationStatus{}) if err != nil { return ctrl.Result{}, fmt.Errorf("failed to clear previous AppSet application statuses for %v: %w", applicationSetInfo.Name, err) } @@ -181,7 +181,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque appMap[app.Name] = app } - appSyncMap, err = r.performProgressiveSyncs(ctx, applicationSetInfo, applications, desiredApplications, appMap) + appSyncMap, err = r.performProgressiveSyncs(ctx, logCtx, applicationSetInfo, applications, desiredApplications, appMap) if err != nil { return ctrl.Result{}, fmt.Errorf("failed to perform progressive sync reconciliation for application set: %w", err) } @@ -219,7 +219,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque if r.EnableProgressiveSyncs { // trigger appropriate application syncs if RollingSync strategy is enabled if progressiveSyncsStrategyEnabled(&applicationSetInfo, "RollingSync") { - validApps, err = r.syncValidApplications(ctx, &applicationSetInfo, appSyncMap, appMap, validApps) + validApps, err = r.syncValidApplications(logCtx, &applicationSetInfo, appSyncMap, appMap, validApps) if err != nil { _ = r.setApplicationSetStatusCondition(ctx, @@ -237,7 +237,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque } if utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowUpdate() { - err = r.createOrUpdateInCluster(ctx, applicationSetInfo, validApps) + err = r.createOrUpdateInCluster(ctx, logCtx, applicationSetInfo, validApps) if err != nil { _ = r.setApplicationSetStatusCondition(ctx, &applicationSetInfo, @@ -251,7 +251,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, err } } else { - err = r.createInCluster(ctx, applicationSetInfo, validApps) + err = r.createInCluster(ctx, logCtx, applicationSetInfo, validApps) if err != nil { _ = r.setApplicationSetStatusCondition(ctx, &applicationSetInfo, @@ -267,7 +267,7 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque } if utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete() { - err = r.deleteInCluster(ctx, applicationSetInfo, desiredApplications) + err = r.deleteInCluster(ctx, logCtx, applicationSetInfo, desiredApplications) if err != nil { _ = r.setApplicationSetStatusCondition(ctx, &applicationSetInfo, @@ -492,7 +492,7 @@ func getTempApplication(applicationSetTemplate argov1alpha1.ApplicationSetTempla return &tmplApplication } -func (r *ApplicationSetReconciler) generateApplications(applicationSetInfo argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, argov1alpha1.ApplicationSetReasonType, error) { +func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, applicationSetInfo argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, argov1alpha1.ApplicationSetReasonType, error) { var res []argov1alpha1.Application var firstError error @@ -501,7 +501,7 @@ func (r *ApplicationSetReconciler) generateApplications(applicationSetInfo argov for _, requestedGenerator := range applicationSetInfo.Spec.Generators { t, err := generators.Transform(requestedGenerator, r.Generators, applicationSetInfo.Spec.Template, &applicationSetInfo, map[string]interface{}{}) if err != nil { - log.WithError(err).WithField("generator", requestedGenerator). + logCtx.WithError(err).WithField("generator", requestedGenerator). Error("error generating application from params") if firstError == nil { firstError = err @@ -516,7 +516,7 @@ func (r *ApplicationSetReconciler) generateApplications(applicationSetInfo argov for _, p := range a.Params { app, err := r.Renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) if err != nil { - log.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). + logCtx.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). Error("error generating application from params") if firstError == nil { @@ -529,8 +529,8 @@ func (r *ApplicationSetReconciler) generateApplications(applicationSetInfo argov } } - log.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res)) - log.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res) + logCtx.WithField("generator", requestedGenerator).Infof("generated %d applications", len(res)) + logCtx.WithField("generator", requestedGenerator).Debugf("apps from generator: %+v", res) } return res, applicationSetReason, firstError @@ -605,15 +605,15 @@ func (r *ApplicationSetReconciler) updateCache(ctx context.Context, obj client.O // - For new applications, it will call create // - For existing application, it will call update // The function also adds owner reference to all applications, and uses it to delete them. -func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error { +func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error { var firstError error // Creates or updates the application in appList for _, generatedApp := range desiredApplications { - - appLog := log.WithFields(log.Fields{"app": generatedApp.Name, "appSet": applicationSet.Name}) generatedApp.Namespace = applicationSet.Namespace + appLog := logCtx.WithFields(log.Fields{"app": generatedApp.QualifiedName()}) + // Normalize to avoid fighting with the application controller. generatedApp.Spec = *argoutil.NormalizeApplicationSpec(&generatedApp.Spec) @@ -763,7 +763,7 @@ func appToUnstructured(app *argov1alpha1.Application) (*unstructured.Unstructure // createInCluster will filter from the desiredApplications only the application that needs to be created // Then it will call createOrUpdateInCluster to do the actual create -func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error { +func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error { var createApps []argov1alpha1.Application current, err := r.getCurrentApplications(ctx, applicationSet) @@ -786,7 +786,7 @@ func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, applicat } } - return r.createOrUpdateInCluster(ctx, applicationSet, createApps) + return r.createOrUpdateInCluster(ctx, logCtx, applicationSet, createApps) } func (r *ApplicationSetReconciler) getCurrentApplications(_ context.Context, applicationSet argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) { @@ -803,7 +803,7 @@ func (r *ApplicationSetReconciler) getCurrentApplications(_ context.Context, app // deleteInCluster will delete Applications that are currently on the cluster, but not in appList. // The function must be called after all generators had been called and generated applications -func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error { +func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, desiredApplications []argov1alpha1.Application) error { // settingsMgr := settings.NewSettingsManager(context.TODO(), r.KubeClientset, applicationSet.Namespace) // argoDB := db.NewDB(applicationSet.Namespace, settingsMgr, r.KubeClientset) // clusterList, err := argoDB.ListClusters(ctx) @@ -827,15 +827,15 @@ func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, applicat // Delete apps that are not in m[string]bool var firstError error for _, app := range current { - appLog := log.WithFields(log.Fields{"app": app.Name, "appSet": applicationSet.Name}) + logCtx = logCtx.WithField("app", app.QualifiedName()) _, exists := m[app.Name] if !exists { // Removes the Argo CD resources finalizer if the application contains an invalid target (eg missing cluster) - err := r.removeFinalizerOnInvalidDestination(ctx, applicationSet, &app, clusterList, appLog) + err := r.removeFinalizerOnInvalidDestination(ctx, applicationSet, &app, clusterList, logCtx) if err != nil { - appLog.WithError(err).Error("failed to update Application") + logCtx.WithError(err).Error("failed to update Application") if firstError != nil { firstError = err } @@ -844,14 +844,14 @@ func (r *ApplicationSetReconciler) deleteInCluster(ctx context.Context, applicat err = r.Client.Delete(ctx, &app) if err != nil { - appLog.WithError(err).Error("failed to delete Application") + logCtx.WithError(err).Error("failed to delete Application") if firstError != nil { firstError = err } continue } r.Recorder.Eventf(&applicationSet, corev1.EventTypeNormal, "Deleted", "Deleted Application %q", app.Name) - appLog.Log(log.InfoLevel, "Deleted application") + logCtx.Log(log.InfoLevel, "Deleted application") } } return firstError @@ -929,21 +929,21 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte return nil } -func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, appset argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, desiredApplications []argov1alpha1.Application, appMap map[string]argov1alpha1.Application) (map[string]bool, error) { +func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, logCtx *log.Entry, appset argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, desiredApplications []argov1alpha1.Application, appMap map[string]argov1alpha1.Application) (map[string]bool, error) { - appDependencyList, appStepMap, err := r.buildAppDependencyList(ctx, appset, desiredApplications) + appDependencyList, appStepMap, err := r.buildAppDependencyList(logCtx, appset, desiredApplications) if err != nil { return nil, fmt.Errorf("failed to build app dependency list: %w", err) } - _, err = r.updateApplicationSetApplicationStatus(ctx, &appset, applications, appStepMap) + _, err = r.updateApplicationSetApplicationStatus(ctx, logCtx, &appset, applications, appStepMap) if err != nil { return nil, fmt.Errorf("failed to update applicationset app status: %w", err) } - log.Infof("ApplicationSet %v step list:", appset.Name) + logCtx.Infof("ApplicationSet %v step list:", appset.Name) for i, step := range appDependencyList { - log.Infof("step %v: %+v", i+1, step) + logCtx.Infof("step %v: %+v", i+1, step) } appSyncMap, err := r.buildAppSyncMap(ctx, appset, appDependencyList, appMap) @@ -951,9 +951,9 @@ func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, return nil, fmt.Errorf("failed to build app sync map: %w", err) } - log.Infof("Application allowed to sync before maxUpdate?: %+v", appSyncMap) + logCtx.Infof("Application allowed to sync before maxUpdate?: %+v", appSyncMap) - _, err = r.updateApplicationSetApplicationStatusProgress(ctx, &appset, appSyncMap, appStepMap, appMap) + _, err = r.updateApplicationSetApplicationStatusProgress(ctx, logCtx, &appset, appSyncMap, appStepMap, appMap) if err != nil { return nil, fmt.Errorf("failed to update applicationset application status progress: %w", err) } @@ -967,7 +967,7 @@ func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, } // this list tracks which Applications belong to each RollingUpdate step -func (r *ApplicationSetReconciler) buildAppDependencyList(ctx context.Context, applicationSet argov1alpha1.ApplicationSet, applications []argov1alpha1.Application) ([][]string, map[string]int, error) { +func (r *ApplicationSetReconciler) buildAppDependencyList(logCtx *log.Entry, applicationSet argov1alpha1.ApplicationSet, applications []argov1alpha1.Application) ([][]string, map[string]int, error) { if applicationSet.Spec.Strategy == nil || applicationSet.Spec.Strategy.Type == "" || applicationSet.Spec.Strategy.Type == "AllAtOnce" { return [][]string{}, map[string]int{}, nil @@ -994,9 +994,9 @@ func (r *ApplicationSetReconciler) buildAppDependencyList(ctx context.Context, a for _, matchExpression := range step.MatchExpressions { if val, ok := app.Labels[matchExpression.Key]; ok { - valueMatched := labelMatchedExpression(val, matchExpression) + valueMatched := labelMatchedExpression(logCtx, val, matchExpression) - if !valueMatched { // none of the matchExpression values was a match with the Application'ss labels + if !valueMatched { // none of the matchExpression values was a match with the Application's labels selected = false break } @@ -1009,7 +1009,7 @@ func (r *ApplicationSetReconciler) buildAppDependencyList(ctx context.Context, a if selected { appDependencyList[i] = append(appDependencyList[i], app.Name) if val, ok := appStepMap[app.Name]; ok { - log.Warnf("AppSet '%v' has a invalid matchExpression that selects Application '%v' label twice, in steps %v and %v", applicationSet.Name, app.Name, val+1, i+1) + logCtx.Warnf("AppSet '%v' has a invalid matchExpression that selects Application '%v' label twice, in steps %v and %v", applicationSet.Name, app.Name, val+1, i+1) } else { appStepMap[app.Name] = i } @@ -1020,9 +1020,9 @@ func (r *ApplicationSetReconciler) buildAppDependencyList(ctx context.Context, a return appDependencyList, appStepMap, nil } -func labelMatchedExpression(val string, matchExpression argov1alpha1.ApplicationMatchExpression) bool { +func labelMatchedExpression(logCtx *log.Entry, val string, matchExpression argov1alpha1.ApplicationMatchExpression) bool { if matchExpression.Operator != "In" && matchExpression.Operator != "NotIn" { - log.Errorf("skipping AppSet rollingUpdate step Application selection, invalid matchExpression operator provided: %q ", matchExpression.Operator) + logCtx.Errorf("skipping AppSet rollingUpdate step Application selection, invalid matchExpression operator provided: %q ", matchExpression.Operator) return false } @@ -1126,7 +1126,7 @@ func statusStrings(app argov1alpha1.Application) (string, string, string) { } // check the status of each Application's status and promote Applications to the next status if needed -func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, appStepMap map[string]int) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { +func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, appStepMap map[string]int) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { now := metav1.Now() appStatuses := make([]argov1alpha1.ApplicationSetApplicationStatus, 0, len(applications)) @@ -1159,7 +1159,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con } if appOutdated && currentAppStatus.Status != "Waiting" && currentAppStatus.Status != "Pending" { - log.Infof("Application %v is outdated, updating its ApplicationSet status to Waiting", app.Name) + logCtx.Infof("Application %v is outdated, updating its ApplicationSet status to Waiting", app.Name) currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = "Waiting" currentAppStatus.Message = "Application has pending changes, setting status to Waiting." @@ -1171,15 +1171,15 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con // this covers race conditions where syncs initiated by RollingSync miraculously have a sync time before the transition to Pending state occurred (could be a few seconds) if operationPhaseString == "Succeeded" && app.Status.OperationState.StartedAt.Add(time.Duration(10)*time.Second).After(currentAppStatus.LastTransitionTime.Time) { if !app.Status.OperationState.StartedAt.After(currentAppStatus.LastTransitionTime.Time) { - log.Warnf("Application %v was synced less than 10s prior to entering Pending status, we'll assume the AppSet controller triggered this sync and update its status to Progressing", app.Name) + logCtx.Warnf("Application %v was synced less than 10s prior to entering Pending status, we'll assume the AppSet controller triggered this sync and update its status to Progressing", app.Name) } - log.Infof("Application %v has completed a sync successfully, updating its ApplicationSet status to Progressing", app.Name) + logCtx.Infof("Application %v has completed a sync successfully, updating its ApplicationSet status to Progressing", app.Name) currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = "Progressing" currentAppStatus.Message = "Application resource completed a sync successfully, updating status from Pending to Progressing." currentAppStatus.Step = fmt.Sprint(appStepMap[currentAppStatus.Application] + 1) } else if operationPhaseString == "Running" || healthStatusString == "Progressing" { - log.Infof("Application %v has entered Progressing status, updating its ApplicationSet status to Progressing", app.Name) + logCtx.Infof("Application %v has entered Progressing status, updating its ApplicationSet status to Progressing", app.Name) currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = "Progressing" currentAppStatus.Message = "Application resource became Progressing, updating status from Pending to Progressing." @@ -1188,7 +1188,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con } if currentAppStatus.Status == "Waiting" && isApplicationHealthy(app) { - log.Infof("Application %v is already synced and healthy, updating its ApplicationSet status to Healthy", app.Name) + logCtx.Infof("Application %v is already synced and healthy, updating its ApplicationSet status to Healthy", app.Name) currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = healthStatusString currentAppStatus.Message = "Application resource is already Healthy, updating status from Waiting to Healthy." @@ -1196,7 +1196,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con } if currentAppStatus.Status == "Progressing" && isApplicationHealthy(app) { - log.Infof("Application %v has completed Progressing status, updating its ApplicationSet status to Healthy", app.Name) + logCtx.Infof("Application %v has completed Progressing status, updating its ApplicationSet status to Healthy", app.Name) currentAppStatus.LastTransitionTime = &now currentAppStatus.Status = healthStatusString currentAppStatus.Message = "Application resource became Healthy, updating status from Progressing to Healthy." @@ -1206,7 +1206,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con appStatuses = append(appStatuses, currentAppStatus) } - err := r.setAppSetApplicationStatus(ctx, applicationSet, appStatuses) + err := r.setAppSetApplicationStatus(ctx, logCtx, applicationSet, appStatuses) if err != nil { return nil, fmt.Errorf("failed to set AppSet application statuses: %w", err) } @@ -1215,7 +1215,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatus(ctx con } // check Applications that are in Waiting status and promote them to Pending if needed -func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appStepMap map[string]int, appMap map[string]argov1alpha1.Application) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { +func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appStepMap map[string]int, appMap map[string]argov1alpha1.Application) ([]argov1alpha1.ApplicationSetApplicationStatus, error) { now := metav1.Now() appStatuses := make([]argov1alpha1.ApplicationSetApplicationStatus, 0, len(applicationSet.Status.ApplicationStatus)) @@ -1257,7 +1257,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress if maxUpdate != nil { maxUpdateVal, err := intstr.GetScaledValueFromIntOrPercent(maxUpdate, totalCountMap[appStepMap[appStatus.Application]], false) if err != nil { - log.Warnf("AppSet '%v' has a invalid maxUpdate value '%+v', ignoring maxUpdate logic for this step: %v", applicationSet.Name, maxUpdate, err) + logCtx.Warnf("AppSet '%v' has a invalid maxUpdate value '%+v', ignoring maxUpdate logic for this step: %v", applicationSet.Name, maxUpdate, err) } // ensure that percentage values greater than 0% always result in at least 1 Application being selected @@ -1267,13 +1267,13 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress if updateCountMap[appStepMap[appStatus.Application]] >= maxUpdateVal { maxUpdateAllowed = false - log.Infof("Application %v is not allowed to update yet, %v/%v Applications already updating in step %v in AppSet %v", appStatus.Application, updateCountMap[appStepMap[appStatus.Application]], maxUpdateVal, appStepMap[appStatus.Application]+1, applicationSet.Name) + logCtx.Infof("Application %v is not allowed to update yet, %v/%v Applications already updating in step %v in AppSet %v", appStatus.Application, updateCountMap[appStepMap[appStatus.Application]], maxUpdateVal, appStepMap[appStatus.Application]+1, applicationSet.Name) } } if appStatus.Status == "Waiting" && appSyncMap[appStatus.Application] && maxUpdateAllowed { - log.Infof("Application %v moved to Pending status, watching for the Application to start Progressing", appStatus.Application) + logCtx.Infof("Application %v moved to Pending status, watching for the Application to start Progressing", appStatus.Application) appStatus.LastTransitionTime = &now appStatus.Status = "Pending" appStatus.Message = "Application moved to Pending status, watching for the Application resource to start Progressing." @@ -1286,7 +1286,7 @@ func (r *ApplicationSetReconciler) updateApplicationSetApplicationStatusProgress } } - err := r.setAppSetApplicationStatus(ctx, applicationSet, appStatuses) + err := r.setAppSetApplicationStatus(ctx, logCtx, applicationSet, appStatuses) if err != nil { return nil, fmt.Errorf("failed to set AppSet app status: %w", err) } @@ -1348,7 +1348,7 @@ func findApplicationStatusIndex(appStatuses []argov1alpha1.ApplicationSetApplica // setApplicationSetApplicationStatus updates the ApplicatonSet's status field // with any new/changed Application statuses. -func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet, applicationStatuses []argov1alpha1.ApplicationSetApplicationStatus) error { +func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Context, logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, applicationStatuses []argov1alpha1.ApplicationSetApplicationStatus) error { needToUpdateStatus := false if len(applicationStatuses) != len(applicationSet.Status.ApplicationStatus) { @@ -1382,7 +1382,7 @@ func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Contex err := r.Client.Status().Update(ctx, applicationSet) if err != nil { - log.Errorf("unable to set application set status: %v", err) + logCtx.Errorf("unable to set application set status: %v", err) return fmt.Errorf("unable to set application set status: %v", err) } @@ -1397,7 +1397,7 @@ func (r *ApplicationSetReconciler) setAppSetApplicationStatus(ctx context.Contex return nil } -func (r *ApplicationSetReconciler) syncValidApplications(ctx context.Context, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appMap map[string]argov1alpha1.Application, validApps []argov1alpha1.Application) ([]argov1alpha1.Application, error) { +func (r *ApplicationSetReconciler) syncValidApplications(logCtx *log.Entry, applicationSet *argov1alpha1.ApplicationSet, appSyncMap map[string]bool, appMap map[string]argov1alpha1.Application, validApps []argov1alpha1.Application) ([]argov1alpha1.Application, error) { rolloutApps := []argov1alpha1.Application{} for i := range validApps { pruneEnabled := false @@ -1417,7 +1417,7 @@ func (r *ApplicationSetReconciler) syncValidApplications(ctx context.Context, ap // check appSyncMap to determine which Applications are ready to be updated and which should be skipped if appSyncMap[validApps[i].Name] && appMap[validApps[i].Name].Status.Sync.Status == "OutOfSync" && appSetStatusPending { - log.Infof("triggering sync for application: %v, prune enabled: %v", validApps[i].Name, pruneEnabled) + logCtx.Infof("triggering sync for application: %v, prune enabled: %v", validApps[i].Name, pruneEnabled) validApps[i], _ = syncApplication(validApps[i], pruneEnabled) } rolloutApps = append(rolloutApps, validApps[i]) @@ -1461,29 +1461,51 @@ func getOwnsHandlerPredicates(enableProgressiveSyncs bool) predicate.Funcs { CreateFunc: func(e event.CreateEvent) bool { // if we are the owner and there is a create event, we most likely created it and do not need to // re-reconcile - log.Debugln("received create event from owning an application") + if log.IsLevelEnabled(log.DebugLevel) { + var appName string + app, isApp := e.Object.(*argov1alpha1.Application) + if isApp { + appName = app.QualifiedName() + } + log.WithField("app", appName).Debugln("received create event from owning an application") + } return false }, DeleteFunc: func(e event.DeleteEvent) bool { - log.Debugln("received delete event from owning an application") + if log.IsLevelEnabled(log.DebugLevel) { + var appName string + app, isApp := e.Object.(*argov1alpha1.Application) + if isApp { + appName = app.QualifiedName() + } + log.WithField("app", appName).Debugln("received delete event from owning an application") + } return true }, UpdateFunc: func(e event.UpdateEvent) bool { - log.Debugln("received update event from owning an application") appOld, isApp := e.ObjectOld.(*argov1alpha1.Application) if !isApp { return false } + logCtx := log.WithField("app", appOld.QualifiedName()) + logCtx.Debugln("received update event from owning an application") appNew, isApp := e.ObjectNew.(*argov1alpha1.Application) if !isApp { return false } requeue := shouldRequeueApplicationSet(appOld, appNew, enableProgressiveSyncs) - log.Debugf("requeue: %t caused by application %s\n", requeue, appNew.Name) + logCtx.WithField("requeue", requeue).Debugf("requeue: %t caused by application %s\n", requeue, appNew.Name) return requeue }, GenericFunc: func(e event.GenericEvent) bool { - log.Debugln("received generic event from owning an application") + if log.IsLevelEnabled(log.DebugLevel) { + var appName string + app, isApp := e.Object.(*argov1alpha1.Application) + if isApp { + appName = app.QualifiedName() + } + log.WithField("app", appName).Debugln("received generic event from owning an application") + } return true }, } diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index d734d26ff437e..1d282ac32423b 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -220,7 +220,7 @@ func TestExtractApplications(t *testing.T) { Cache: &fakeCache{}, } - got, reason, err := r.generateApplications(v1alpha1.ApplicationSet{ + got, reason, err := r.generateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "name", Namespace: "namespace", @@ -333,7 +333,7 @@ func TestMergeTemplateApplications(t *testing.T) { KubeClientset: kubefake.NewSimpleClientset(), } - got, _, _ := r.generateApplications(v1alpha1.ApplicationSet{ + got, _, _ := r.generateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ ObjectMeta: metav1.ObjectMeta{ Name: "name", Namespace: "namespace", @@ -1003,7 +1003,7 @@ func TestCreateOrUpdateInCluster(t *testing.T) { Cache: &fakeCache{}, } - err = r.createOrUpdateInCluster(context.TODO(), c.appSet, c.desiredApps) + err = r.createOrUpdateInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) assert.Nil(t, err) for _, obj := range c.expected { @@ -1491,7 +1491,7 @@ func TestCreateApplications(t *testing.T) { Cache: &fakeCache{}, } - err = r.createInCluster(context.TODO(), c.appSet, c.apps) + err = r.createInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.apps) assert.Nil(t, err) for _, obj := range c.expected { @@ -1635,7 +1635,7 @@ func TestDeleteInCluster(t *testing.T) { KubeClientset: kubefake.NewSimpleClientset(), } - err = r.deleteInCluster(context.TODO(), c.appSet, c.desiredApps) + err = r.deleteInCluster(context.TODO(), log.NewEntry(log.StandardLogger()), c.appSet, c.desiredApps) assert.Nil(t, err) // For each of the expected objects, verify they exist on the cluster @@ -2525,7 +2525,7 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { KubeClientset: kubefake.NewSimpleClientset(), } - gotApp, _, _ := appSetReconciler.generateApplications(v1alpha1.ApplicationSet{ + gotApp, _, _ := appSetReconciler.generateApplications(log.NewEntry(log.StandardLogger()), v1alpha1.ApplicationSet{ Spec: v1alpha1.ApplicationSetSpec{ GoTemplate: true, Generators: []v1alpha1.ApplicationSetGenerator{{ @@ -2814,7 +2814,7 @@ func TestSetApplicationSetApplicationStatus(t *testing.T) { KubeClientset: kubeclientset, } - err = r.setAppSetApplicationStatus(context.TODO(), &cc.appSet, cc.appStatuses) + err = r.setAppSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appStatuses) assert.Nil(t, err) assert.Equal(t, cc.expectedAppStatuses, cc.appSet.Status.ApplicationStatus) @@ -3577,7 +3577,7 @@ func TestBuildAppDependencyList(t *testing.T) { KubeClientset: kubeclientset, } - appDependencyList, appStepMap, err := r.buildAppDependencyList(context.TODO(), cc.appSet, cc.apps) + appDependencyList, appStepMap, err := r.buildAppDependencyList(log.NewEntry(log.StandardLogger()), cc.appSet, cc.apps) assert.Equal(t, err, nil, "expected no errors, but errors occured") assert.Equal(t, cc.expectedList, appDependencyList, "expected appDependencyList did not match actual") assert.Equal(t, cc.expectedStepMap, appStepMap, "expected appStepMap did not match actual") @@ -4831,7 +4831,7 @@ func TestUpdateApplicationSetApplicationStatus(t *testing.T) { KubeClientset: kubeclientset, } - appStatuses, err := r.updateApplicationSetApplicationStatus(context.TODO(), &cc.appSet, cc.apps, cc.appStepMap) + appStatuses, err := r.updateApplicationSetApplicationStatus(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.apps, cc.appStepMap) // opt out of testing the LastTransitionTime is accurate for i := range appStatuses { @@ -5585,7 +5585,7 @@ func TestUpdateApplicationSetApplicationStatusProgress(t *testing.T) { KubeClientset: kubeclientset, } - appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), &cc.appSet, cc.appSyncMap, cc.appStepMap, cc.appMap) + appStatuses, err := r.updateApplicationSetApplicationStatusProgress(context.TODO(), log.NewEntry(log.StandardLogger()), &cc.appSet, cc.appSyncMap, cc.appStepMap, cc.appMap) // opt out of testing the LastTransitionTime is accurate for i := range appStatuses { From d747eb3f144cfa7caae1c3059ef510a848e28b95 Mon Sep 17 00:00:00 2001 From: Mayursinh Sarvaiya Date: Mon, 30 Oct 2023 13:40:34 -0300 Subject: [PATCH 059/269] feat: PKCE authentication flow for web logins #9890 (#15889) feat: PKCE authentication flow for web logins #9890 (#15889) Signed-off-by: Mayursinh Sarvaiya --- assets/swagger.json | 3 + docs/operator-manual/user-management/index.md | 6 + pkg/apiclient/settings/settings.pb.go | 212 +++++++++++------- server/settings/settings.go | 11 +- server/settings/settings.proto | 1 + ui/package.json | 1 + ui/src/app/app.tsx | 4 +- ui/src/app/login/components/login.tsx | 17 +- ui/src/app/login/components/pkce-verify.scss | 8 + ui/src/app/login/components/pkce-verify.tsx | 45 ++++ ui/src/app/login/components/utils.ts | 155 +++++++++++++ ui/src/app/shared/models.ts | 4 + ui/yarn.lock | 5 + util/dex/config.go | 12 +- util/dex/dex_test.go | 8 +- util/settings/settings.go | 38 ++-- 16 files changed, 413 insertions(+), 117 deletions(-) create mode 100644 ui/src/app/login/components/pkce-verify.scss create mode 100644 ui/src/app/login/components/pkce-verify.tsx create mode 100644 ui/src/app/login/components/utils.ts diff --git a/assets/swagger.json b/assets/swagger.json index b9d4cbf21c563..7fc9142edcaff 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -4462,6 +4462,9 @@ "clientID": { "type": "string" }, + "enablePKCEAuthentication": { + "type": "boolean" + }, "idTokenClaims": { "type": "object", "additionalProperties": { diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index 8c3f2e169597c..09a33c4fed750 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -344,6 +344,12 @@ data: # for the 'localhost' (CLI) client to Dex. This field is optional. If omitted, the CLI will # use the same clientID as the Argo CD server cliClientID: vvvvwwwwxxxxyyyyzzzz + + # PKCE authentication flow processes authorization flow from browser only - default false + # uses the clientID + # make sure the Identity Provider (IdP) is public and doesn't need clientSecret + # make sure the Identity Provider (IdP) has this redirect URI registered: https://argocd.example.com/pkce/verify + enablePKCEAuthentication: true ``` !!! note diff --git a/pkg/apiclient/settings/settings.pb.go b/pkg/apiclient/settings/settings.pb.go index be5d129f6834f..b74110f9005d7 100644 --- a/pkg/apiclient/settings/settings.pb.go +++ b/pkg/apiclient/settings/settings.pb.go @@ -628,15 +628,16 @@ func (m *Connector) GetType() string { } type OIDCConfig struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` - ClientID string `protobuf:"bytes,3,opt,name=clientID,proto3" json:"clientID,omitempty"` - CLIClientID string `protobuf:"bytes,4,opt,name=cliClientID,proto3" json:"cliClientID,omitempty"` - Scopes []string `protobuf:"bytes,5,rep,name=scopes,proto3" json:"scopes,omitempty"` - IDTokenClaims map[string]*oidc.Claim `protobuf:"bytes,6,rep,name=idTokenClaims,proto3" json:"idTokenClaims,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Issuer string `protobuf:"bytes,2,opt,name=issuer,proto3" json:"issuer,omitempty"` + ClientID string `protobuf:"bytes,3,opt,name=clientID,proto3" json:"clientID,omitempty"` + CLIClientID string `protobuf:"bytes,4,opt,name=cliClientID,proto3" json:"cliClientID,omitempty"` + Scopes []string `protobuf:"bytes,5,rep,name=scopes,proto3" json:"scopes,omitempty"` + IDTokenClaims map[string]*oidc.Claim `protobuf:"bytes,6,rep,name=idTokenClaims,proto3" json:"idTokenClaims,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + EnablePKCEAuthentication bool `protobuf:"varint,7,opt,name=enablePKCEAuthentication,proto3" json:"enablePKCEAuthentication,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *OIDCConfig) Reset() { *m = OIDCConfig{} } @@ -714,6 +715,13 @@ func (m *OIDCConfig) GetIDTokenClaims() map[string]*oidc.Claim { return nil } +func (m *OIDCConfig) GetEnablePKCEAuthentication() bool { + if m != nil { + return m.EnablePKCEAuthentication + } + return false +} + func init() { proto.RegisterType((*SettingsQuery)(nil), "cluster.SettingsQuery") proto.RegisterType((*Settings)(nil), "cluster.Settings") @@ -732,82 +740,83 @@ func init() { func init() { proto.RegisterFile("server/settings/settings.proto", fileDescriptor_a480d494da040caa) } var fileDescriptor_a480d494da040caa = []byte{ - // 1194 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0xcf, 0x6f, 0x1b, 0xc5, - 0x17, 0xd7, 0xd6, 0x69, 0x62, 0x3f, 0x37, 0x75, 0x32, 0x6d, 0xd3, 0xad, 0xd5, 0x6f, 0xe2, 0xaf, - 0x0f, 0x95, 0x41, 0xb0, 0x6e, 0x52, 0x21, 0x10, 0xa2, 0x82, 0xda, 0xae, 0x5a, 0xd3, 0xb4, 0x0d, - 0xdb, 0xa6, 0x07, 0x2e, 0xd5, 0x64, 0xf7, 0xb1, 0x59, 0xb2, 0x9e, 0x59, 0xcd, 0xcc, 0x9a, 0xba, - 0x47, 0x6e, 0x5c, 0xb8, 0xc0, 0xdf, 0xc2, 0x81, 0x7f, 0x00, 0x8e, 0x48, 0xdc, 0x23, 0x64, 0xf1, - 0x87, 0xa0, 0x99, 0xfd, 0x91, 0xcd, 0xda, 0x2d, 0x48, 0xbd, 0xcd, 0x7c, 0x3e, 0xef, 0xd7, 0xbc, - 0x79, 0xf3, 0xe6, 0xc1, 0xb6, 0x44, 0x31, 0x45, 0xd1, 0x97, 0xa8, 0x54, 0xc8, 0x02, 0x59, 0x2c, - 0x9c, 0x58, 0x70, 0xc5, 0xc9, 0x9a, 0x17, 0x25, 0x52, 0xa1, 0x68, 0x5f, 0x0d, 0x78, 0xc0, 0x0d, - 0xd6, 0xd7, 0xab, 0x94, 0x6e, 0xdf, 0x0c, 0x38, 0x0f, 0x22, 0xec, 0xd3, 0x38, 0xec, 0x53, 0xc6, - 0xb8, 0xa2, 0x2a, 0xe4, 0x2c, 0x53, 0x6e, 0xef, 0x07, 0xa1, 0x3a, 0x4e, 0x8e, 0x1c, 0x8f, 0x4f, - 0xfa, 0x54, 0x18, 0xf5, 0x6f, 0xcd, 0xe2, 0x43, 0xcf, 0xef, 0x4f, 0xf7, 0xfa, 0xf1, 0x49, 0xa0, - 0x35, 0x65, 0x9f, 0xc6, 0x71, 0x14, 0x7a, 0x46, 0xb7, 0x3f, 0xdd, 0xa5, 0x51, 0x7c, 0x4c, 0x77, - 0xfb, 0x01, 0x32, 0x14, 0x54, 0xa1, 0x9f, 0x59, 0xfb, 0xe2, 0x5f, 0xac, 0x55, 0x4f, 0xc2, 0x43, - 0xdf, 0xeb, 0x7b, 0x11, 0x0d, 0x27, 0x59, 0x3c, 0xdd, 0x16, 0xac, 0x3f, 0xcb, 0xd8, 0xaf, 0x12, - 0x14, 0xb3, 0xee, 0x2f, 0x4d, 0xa8, 0xe7, 0x08, 0xb9, 0x01, 0xb5, 0x44, 0x44, 0xb6, 0xd5, 0xb1, - 0x7a, 0x8d, 0xc1, 0xda, 0xfc, 0x74, 0xa7, 0x76, 0xe8, 0xee, 0xbb, 0x1a, 0x23, 0xb7, 0xa1, 0xe1, - 0xe3, 0xab, 0x21, 0x67, 0xdf, 0x84, 0x81, 0x7d, 0xa1, 0x63, 0xf5, 0x9a, 0x7b, 0xc4, 0xc9, 0x32, - 0xe3, 0x8c, 0x72, 0xc6, 0x3d, 0x13, 0x22, 0x43, 0x00, 0xed, 0x3f, 0x53, 0xa9, 0x19, 0x95, 0x2b, - 0x85, 0xca, 0xd3, 0xf1, 0x68, 0x98, 0x52, 0x83, 0xcb, 0xf3, 0xd3, 0x1d, 0x38, 0xdb, 0xbb, 0x25, - 0x35, 0xd2, 0x81, 0x26, 0x8d, 0xe3, 0x7d, 0x7a, 0x84, 0xd1, 0x23, 0x9c, 0xd9, 0x2b, 0x3a, 0x32, - 0xb7, 0x0c, 0x91, 0x17, 0xb0, 0x29, 0x50, 0xf2, 0x44, 0x78, 0xf8, 0x74, 0x8a, 0x42, 0x84, 0x3e, - 0x4a, 0xfb, 0x62, 0xa7, 0xd6, 0x6b, 0xee, 0xf5, 0x0a, 0x6f, 0xf9, 0x09, 0x1d, 0xb7, 0x2a, 0x7a, - 0x9f, 0x29, 0x31, 0x73, 0x17, 0x4d, 0x10, 0x07, 0x88, 0x54, 0x54, 0x25, 0x72, 0x40, 0xfd, 0x00, - 0xef, 0x33, 0x7a, 0x14, 0xa1, 0x6f, 0xaf, 0x76, 0xac, 0x5e, 0xdd, 0x5d, 0xc2, 0x90, 0x87, 0xd0, - 0x4a, 0x2b, 0xe1, 0x1e, 0xa3, 0xd1, 0x4c, 0x85, 0x9e, 0xb4, 0xd7, 0xcc, 0x99, 0xb7, 0x8b, 0x28, - 0x1e, 0x9c, 0xe7, 0xb3, 0xe3, 0x56, 0xd5, 0xc8, 0x6b, 0xd8, 0x38, 0x49, 0xa4, 0xe2, 0x93, 0xf0, - 0x35, 0x3e, 0x8d, 0x4d, 0x35, 0xd9, 0x75, 0x63, 0xea, 0x89, 0x73, 0x56, 0x00, 0x4e, 0x5e, 0x00, - 0x66, 0xf1, 0xd2, 0xf3, 0x9d, 0xe9, 0x9e, 0x13, 0x9f, 0x04, 0x8e, 0x2e, 0x27, 0xa7, 0x54, 0x4e, - 0x4e, 0x5e, 0x4e, 0xce, 0xa3, 0x8a, 0x55, 0x77, 0xc1, 0x0f, 0xf9, 0x3f, 0xac, 0x1c, 0x63, 0x14, - 0xdb, 0x0d, 0xe3, 0x6f, 0xbd, 0x08, 0xfd, 0x21, 0x46, 0xb1, 0x6b, 0x28, 0xf2, 0x1e, 0xac, 0xc5, - 0x51, 0x12, 0x84, 0x4c, 0xda, 0x60, 0xd2, 0xdc, 0x2a, 0xa4, 0x0e, 0x0c, 0xee, 0xe6, 0xbc, 0xce, - 0x61, 0x22, 0x51, 0xec, 0x73, 0xbd, 0x1b, 0x85, 0x32, 0xcd, 0x61, 0x33, 0xcd, 0xe1, 0x22, 0x43, - 0x7e, 0xb4, 0xe0, 0xba, 0x67, 0xb2, 0xf2, 0x98, 0x32, 0x1a, 0xe0, 0x04, 0x99, 0x3a, 0xc8, 0x7c, - 0x5d, 0x32, 0xbe, 0x9e, 0xbf, 0x5b, 0x06, 0x86, 0x4b, 0x8d, 0xbb, 0x6f, 0x72, 0x4a, 0x3e, 0x80, - 0xcd, 0x22, 0x45, 0x2f, 0x50, 0x48, 0x73, 0x17, 0xeb, 0x9d, 0x5a, 0xaf, 0xe1, 0x2e, 0x12, 0xa4, - 0x0d, 0xf5, 0x24, 0x1c, 0x4a, 0x79, 0xe8, 0xee, 0xdb, 0x97, 0x4d, 0xa5, 0x16, 0x7b, 0xd2, 0x83, - 0x56, 0x12, 0x0e, 0x28, 0x63, 0x28, 0x86, 0x9c, 0x29, 0x64, 0xca, 0x6e, 0x19, 0x91, 0x2a, 0xac, - 0x4b, 0x3e, 0x87, 0xb4, 0xa1, 0x8d, 0xb4, 0xe4, 0x4b, 0x90, 0xb6, 0x15, 0x53, 0x29, 0xbf, 0xe3, - 0xc2, 0x3f, 0xa0, 0x4a, 0xa1, 0x60, 0xf6, 0x66, 0x6a, 0xab, 0x02, 0x93, 0x5b, 0x70, 0x59, 0x09, - 0xea, 0x9d, 0x84, 0x2c, 0x78, 0x8c, 0xea, 0x98, 0xfb, 0x36, 0x31, 0x82, 0x15, 0x54, 0x9f, 0x33, - 0x77, 0x70, 0x80, 0x62, 0x42, 0x99, 0x8e, 0xef, 0x8a, 0xb9, 0xa7, 0x45, 0x82, 0xbc, 0x0f, 0x1b, - 0x05, 0xc8, 0x65, 0xa8, 0x53, 0x6c, 0x5f, 0x35, 0x76, 0x17, 0xf0, 0xca, 0x33, 0x72, 0x39, 0x57, - 0x87, 0x22, 0xb2, 0xaf, 0x19, 0xe9, 0x25, 0x8c, 0x3e, 0x3d, 0xbe, 0x42, 0x2f, 0x7f, 0x6f, 0x5b, - 0x26, 0x86, 0x32, 0x44, 0x6e, 0xc3, 0x15, 0x8f, 0x33, 0x25, 0x78, 0x14, 0xa1, 0x78, 0x42, 0x27, - 0x28, 0x63, 0xea, 0xa1, 0x7d, 0xdd, 0x98, 0x5c, 0x46, 0x91, 0xcf, 0xe0, 0x06, 0x8d, 0x63, 0x39, - 0x66, 0xf7, 0xd8, 0xac, 0x40, 0x73, 0x0f, 0xb6, 0xf1, 0xf0, 0x66, 0x81, 0xf6, 0xcf, 0x16, 0x6c, - 0x2d, 0x6f, 0x1b, 0x64, 0x03, 0x6a, 0x27, 0x38, 0x4b, 0xfb, 0xa5, 0xab, 0x97, 0xc4, 0x87, 0x8b, - 0x53, 0x1a, 0x25, 0x98, 0xb5, 0xc8, 0x77, 0x7c, 0xb0, 0x55, 0xb7, 0x6e, 0x6a, 0xfc, 0xd3, 0x0b, - 0x9f, 0x58, 0xdd, 0x97, 0x70, 0x6d, 0x69, 0x3f, 0x21, 0xdb, 0x00, 0xf9, 0xed, 0x8e, 0x47, 0x59, - 0x6c, 0x25, 0x44, 0xd7, 0x04, 0x65, 0x9c, 0xcd, 0x74, 0xe9, 0x1e, 0x4a, 0x14, 0xd2, 0xc4, 0x5a, - 0x77, 0x2b, 0x68, 0x77, 0x04, 0xd7, 0xf3, 0xb6, 0x99, 0x3d, 0x07, 0x17, 0x65, 0xcc, 0x99, 0xc4, - 0x72, 0x0b, 0xb0, 0xde, 0xde, 0x02, 0xba, 0xbf, 0x5a, 0xb0, 0xa2, 0x9b, 0x07, 0xb1, 0x61, 0xcd, - 0x3b, 0xa6, 0xe6, 0xf6, 0xd3, 0x98, 0xf2, 0xad, 0x7e, 0x36, 0x7a, 0xf9, 0x1c, 0x5f, 0x29, 0x13, - 0x4a, 0xc3, 0x2d, 0xf6, 0xe4, 0x2e, 0xc0, 0x51, 0xc8, 0xa8, 0x98, 0x1d, 0x8a, 0x48, 0xda, 0x35, - 0xe3, 0xec, 0x7f, 0xe7, 0xba, 0x92, 0x33, 0x28, 0xf8, 0xb4, 0x97, 0x97, 0x14, 0xda, 0x77, 0xa1, - 0x55, 0xa1, 0x97, 0xdc, 0xd9, 0xd5, 0xf2, 0x9d, 0x35, 0xca, 0x39, 0xbe, 0x09, 0xab, 0xe9, 0x79, - 0x08, 0x81, 0x15, 0x46, 0x27, 0x98, 0xa9, 0x99, 0x75, 0xf7, 0x73, 0x68, 0x14, 0x1f, 0x1f, 0xd9, - 0x03, 0xf0, 0x38, 0x63, 0xe8, 0x29, 0x2e, 0xf2, 0xac, 0x9c, 0x7d, 0x90, 0xc3, 0x9c, 0x72, 0x4b, - 0x52, 0xdd, 0x3b, 0xd0, 0x28, 0x88, 0x65, 0x1e, 0x34, 0xa6, 0x66, 0x71, 0x1e, 0x98, 0x59, 0x77, - 0x7f, 0xa8, 0x41, 0xe9, 0xb3, 0x5c, 0xaa, 0xb6, 0x05, 0xab, 0xa1, 0x94, 0x09, 0x8a, 0x4c, 0x31, - 0xdb, 0x91, 0x1e, 0xd4, 0xbd, 0x28, 0x44, 0xa6, 0xc6, 0x23, 0xf3, 0x1f, 0x37, 0x06, 0x97, 0xe6, - 0xa7, 0x3b, 0xf5, 0x61, 0x86, 0xb9, 0x05, 0x4b, 0x76, 0xa1, 0xe9, 0x45, 0x61, 0x4e, 0xa4, 0xdf, - 0xee, 0xa0, 0x35, 0x3f, 0xdd, 0x69, 0x0e, 0xf7, 0xc7, 0x85, 0x7c, 0x59, 0x46, 0x3b, 0x95, 0x1e, - 0x8f, 0xb3, 0xcf, 0xb7, 0xe1, 0x66, 0x3b, 0xf2, 0x12, 0xd6, 0x43, 0xff, 0x39, 0x3f, 0x41, 0x36, - 0x34, 0x83, 0x88, 0xbd, 0x6a, 0x72, 0x73, 0x6b, 0xc9, 0x24, 0xe0, 0x8c, 0xcb, 0x82, 0xe6, 0xba, - 0x06, 0x9b, 0xf3, 0xd3, 0x9d, 0xf5, 0xf1, 0xa8, 0x84, 0xbb, 0xe7, 0xed, 0xb5, 0x67, 0x40, 0x16, - 0xf5, 0x96, 0x5c, 0xf3, 0xe3, 0xf3, 0x4f, 0xf3, 0xe3, 0xb7, 0x3e, 0xcd, 0x74, 0x92, 0x72, 0x8a, - 0x51, 0x50, 0x8f, 0x24, 0x8e, 0xb1, 0x5f, 0xaa, 0x8f, 0xbd, 0xdf, 0x2c, 0x68, 0xe5, 0x6f, 0xe4, - 0x19, 0x8a, 0x69, 0xe8, 0x21, 0xf9, 0x12, 0x6a, 0x0f, 0x50, 0x91, 0xad, 0x85, 0xd9, 0xc3, 0xcc, - 0x5b, 0xed, 0xcd, 0x05, 0xbc, 0x6b, 0x7f, 0xff, 0xe7, 0xdf, 0x3f, 0x5d, 0x20, 0x64, 0xc3, 0xcc, - 0x90, 0xd3, 0xdd, 0x62, 0x7e, 0x23, 0xc7, 0x00, 0x0f, 0xb0, 0xf8, 0x8c, 0xde, 0x64, 0xb2, 0xb3, - 0x80, 0x57, 0xde, 0x6b, 0xb7, 0x63, 0x3c, 0xb4, 0x89, 0x5d, 0xf5, 0xd0, 0xcf, 0x9e, 0xe9, 0x60, - 0xf8, 0xfb, 0x7c, 0xdb, 0xfa, 0x63, 0xbe, 0x6d, 0xfd, 0x35, 0xdf, 0xb6, 0xbe, 0xfe, 0xe8, 0xbf, - 0x4d, 0xad, 0x69, 0xb9, 0x14, 0xc6, 0x8e, 0x56, 0xcd, 0x8c, 0x79, 0xe7, 0x9f, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xc5, 0x72, 0xeb, 0x5e, 0x52, 0x0b, 0x00, 0x00, + // 1215 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x56, 0x4f, 0x6f, 0x1b, 0x45, + 0x14, 0xd7, 0xd6, 0x69, 0x62, 0x3f, 0x37, 0x75, 0x32, 0x6d, 0xd3, 0xad, 0x55, 0x12, 0xe3, 0x43, + 0x65, 0x10, 0xac, 0x9b, 0x54, 0x08, 0x54, 0x51, 0x41, 0x6d, 0x57, 0xad, 0x69, 0xda, 0x86, 0x69, + 0xd3, 0x03, 0x97, 0x6a, 0xb2, 0x7e, 0xac, 0x97, 0xac, 0x67, 0x56, 0x33, 0xb3, 0xa6, 0xee, 0x91, + 0x0f, 0xc0, 0x05, 0x3e, 0x0b, 0x07, 0xee, 0x08, 0x8e, 0x48, 0xdc, 0x23, 0x64, 0xf1, 0x41, 0xd0, + 0xce, 0xfe, 0xc9, 0x66, 0xed, 0x14, 0xa4, 0xde, 0x66, 0x7e, 0xbf, 0xf7, 0x6f, 0xde, 0xbc, 0x37, + 0xf3, 0x60, 0x5b, 0xa1, 0x9c, 0xa2, 0xec, 0x2a, 0xd4, 0xda, 0xe7, 0x9e, 0xca, 0x17, 0x4e, 0x28, + 0x85, 0x16, 0x64, 0xcd, 0x0d, 0x22, 0xa5, 0x51, 0x36, 0xaf, 0x7a, 0xc2, 0x13, 0x06, 0xeb, 0xc6, + 0xab, 0x84, 0x6e, 0xde, 0xf4, 0x84, 0xf0, 0x02, 0xec, 0xb2, 0xd0, 0xef, 0x32, 0xce, 0x85, 0x66, + 0xda, 0x17, 0x3c, 0x55, 0x6e, 0xee, 0x7b, 0xbe, 0x1e, 0x47, 0x47, 0x8e, 0x2b, 0x26, 0x5d, 0x26, + 0x8d, 0xfa, 0x77, 0x66, 0xf1, 0xb1, 0x3b, 0xea, 0x4e, 0xf7, 0xba, 0xe1, 0xb1, 0x17, 0x6b, 0xaa, + 0x2e, 0x0b, 0xc3, 0xc0, 0x77, 0x8d, 0x6e, 0x77, 0xba, 0xcb, 0x82, 0x70, 0xcc, 0x76, 0xbb, 0x1e, + 0x72, 0x94, 0x4c, 0xe3, 0x28, 0xb5, 0xf6, 0xe5, 0x7f, 0x58, 0x2b, 0x9f, 0x44, 0xf8, 0x23, 0xb7, + 0xeb, 0x06, 0xcc, 0x9f, 0xa4, 0xf1, 0xb4, 0x1b, 0xb0, 0xfe, 0x3c, 0x65, 0xbf, 0x8e, 0x50, 0xce, + 0xda, 0xbf, 0xd4, 0xa1, 0x9a, 0x21, 0xe4, 0x06, 0x54, 0x22, 0x19, 0xd8, 0x56, 0xcb, 0xea, 0xd4, + 0x7a, 0x6b, 0xf3, 0x93, 0x9d, 0xca, 0x21, 0xdd, 0xa7, 0x31, 0x46, 0x6e, 0x43, 0x6d, 0x84, 0xaf, + 0xfb, 0x82, 0x7f, 0xeb, 0x7b, 0xf6, 0x85, 0x96, 0xd5, 0xa9, 0xef, 0x11, 0x27, 0xcd, 0x8c, 0x33, + 0xc8, 0x18, 0x7a, 0x2a, 0x44, 0xfa, 0x00, 0xb1, 0xff, 0x54, 0xa5, 0x62, 0x54, 0xae, 0xe4, 0x2a, + 0xcf, 0x86, 0x83, 0x7e, 0x42, 0xf5, 0x2e, 0xcf, 0x4f, 0x76, 0xe0, 0x74, 0x4f, 0x0b, 0x6a, 0xa4, + 0x05, 0x75, 0x16, 0x86, 0xfb, 0xec, 0x08, 0x83, 0xc7, 0x38, 0xb3, 0x57, 0xe2, 0xc8, 0x68, 0x11, + 0x22, 0x2f, 0x61, 0x53, 0xa2, 0x12, 0x91, 0x74, 0xf1, 0xd9, 0x14, 0xa5, 0xf4, 0x47, 0xa8, 0xec, + 0x8b, 0xad, 0x4a, 0xa7, 0xbe, 0xd7, 0xc9, 0xbd, 0x65, 0x27, 0x74, 0x68, 0x59, 0xf4, 0x01, 0xd7, + 0x72, 0x46, 0x17, 0x4d, 0x10, 0x07, 0x88, 0xd2, 0x4c, 0x47, 0xaa, 0xc7, 0x46, 0x1e, 0x3e, 0xe0, + 0xec, 0x28, 0xc0, 0x91, 0xbd, 0xda, 0xb2, 0x3a, 0x55, 0xba, 0x84, 0x21, 0x8f, 0xa0, 0x91, 0x54, + 0xc2, 0x7d, 0xce, 0x82, 0x99, 0xf6, 0x5d, 0x65, 0xaf, 0x99, 0x33, 0x6f, 0xe7, 0x51, 0x3c, 0x3c, + 0xcb, 0xa7, 0xc7, 0x2d, 0xab, 0x91, 0x37, 0xb0, 0x71, 0x1c, 0x29, 0x2d, 0x26, 0xfe, 0x1b, 0x7c, + 0x16, 0x9a, 0x6a, 0xb2, 0xab, 0xc6, 0xd4, 0x53, 0xe7, 0xb4, 0x00, 0x9c, 0xac, 0x00, 0xcc, 0xe2, + 0x95, 0x3b, 0x72, 0xa6, 0x7b, 0x4e, 0x78, 0xec, 0x39, 0x71, 0x39, 0x39, 0x85, 0x72, 0x72, 0xb2, + 0x72, 0x72, 0x1e, 0x97, 0xac, 0xd2, 0x05, 0x3f, 0xe4, 0x7d, 0x58, 0x19, 0x63, 0x10, 0xda, 0x35, + 0xe3, 0x6f, 0x3d, 0x0f, 0xfd, 0x11, 0x06, 0x21, 0x35, 0x14, 0xf9, 0x00, 0xd6, 0xc2, 0x20, 0xf2, + 0x7c, 0xae, 0x6c, 0x30, 0x69, 0x6e, 0xe4, 0x52, 0x07, 0x06, 0xa7, 0x19, 0x1f, 0xe7, 0x30, 0x52, + 0x28, 0xf7, 0x45, 0xbc, 0x1b, 0xf8, 0x2a, 0xc9, 0x61, 0x3d, 0xc9, 0xe1, 0x22, 0x43, 0x7e, 0xb4, + 0xe0, 0xba, 0x6b, 0xb2, 0xf2, 0x84, 0x71, 0xe6, 0xe1, 0x04, 0xb9, 0x3e, 0x48, 0x7d, 0x5d, 0x32, + 0xbe, 0x5e, 0xbc, 0x5b, 0x06, 0xfa, 0x4b, 0x8d, 0xd3, 0xf3, 0x9c, 0x92, 0x8f, 0x60, 0x33, 0x4f, + 0xd1, 0x4b, 0x94, 0xca, 0xdc, 0xc5, 0x7a, 0xab, 0xd2, 0xa9, 0xd1, 0x45, 0x82, 0x34, 0xa1, 0x1a, + 0xf9, 0x7d, 0xa5, 0x0e, 0xe9, 0xbe, 0x7d, 0xd9, 0x54, 0x6a, 0xbe, 0x27, 0x1d, 0x68, 0x44, 0x7e, + 0x8f, 0x71, 0x8e, 0xb2, 0x2f, 0xb8, 0x46, 0xae, 0xed, 0x86, 0x11, 0x29, 0xc3, 0x71, 0xc9, 0x67, + 0x50, 0x6c, 0x68, 0x23, 0x29, 0xf9, 0x02, 0x14, 0xdb, 0x0a, 0x99, 0x52, 0xdf, 0x0b, 0x39, 0x3a, + 0x60, 0x5a, 0xa3, 0xe4, 0xf6, 0x66, 0x62, 0xab, 0x04, 0x93, 0x5b, 0x70, 0x59, 0x4b, 0xe6, 0x1e, + 0xfb, 0xdc, 0x7b, 0x82, 0x7a, 0x2c, 0x46, 0x36, 0x31, 0x82, 0x25, 0x34, 0x3e, 0x67, 0xe6, 0xe0, + 0x00, 0xe5, 0x84, 0xf1, 0x38, 0xbe, 0x2b, 0xe6, 0x9e, 0x16, 0x09, 0xf2, 0x21, 0x6c, 0xe4, 0xa0, + 0x50, 0x7e, 0x9c, 0x62, 0xfb, 0xaa, 0xb1, 0xbb, 0x80, 0x97, 0xda, 0x88, 0x0a, 0xa1, 0x0f, 0x65, + 0x60, 0x5f, 0x33, 0xd2, 0x4b, 0x98, 0xf8, 0xf4, 0xf8, 0x1a, 0xdd, 0xac, 0xdf, 0xb6, 0x4c, 0x0c, + 0x45, 0x88, 0xdc, 0x86, 0x2b, 0xae, 0xe0, 0x5a, 0x8a, 0x20, 0x40, 0xf9, 0x94, 0x4d, 0x50, 0x85, + 0xcc, 0x45, 0xfb, 0xba, 0x31, 0xb9, 0x8c, 0x22, 0x9f, 0xc3, 0x0d, 0x16, 0x86, 0x6a, 0xc8, 0xef, + 0xf3, 0x59, 0x8e, 0x66, 0x1e, 0x6c, 0xe3, 0xe1, 0x7c, 0x81, 0xe6, 0xcf, 0x16, 0x6c, 0x2d, 0x7f, + 0x36, 0xc8, 0x06, 0x54, 0x8e, 0x71, 0x96, 0xbc, 0x97, 0x34, 0x5e, 0x92, 0x11, 0x5c, 0x9c, 0xb2, + 0x20, 0xc2, 0xf4, 0x89, 0x7c, 0xc7, 0x86, 0x2d, 0xbb, 0xa5, 0x89, 0xf1, 0xbb, 0x17, 0x3e, 0xb3, + 0xda, 0xaf, 0xe0, 0xda, 0xd2, 0xf7, 0x84, 0x6c, 0x03, 0x64, 0xb7, 0x3b, 0x1c, 0xa4, 0xb1, 0x15, + 0x90, 0xb8, 0x26, 0x18, 0x17, 0x7c, 0x16, 0x97, 0xee, 0xa1, 0x42, 0xa9, 0x4c, 0xac, 0x55, 0x5a, + 0x42, 0xdb, 0x03, 0xb8, 0x9e, 0x3d, 0x9b, 0x69, 0x3b, 0x50, 0x54, 0xa1, 0xe0, 0x0a, 0x8b, 0x4f, + 0x80, 0xf5, 0xf6, 0x27, 0xa0, 0xfd, 0xab, 0x05, 0x2b, 0xf1, 0xe3, 0x41, 0x6c, 0x58, 0x73, 0xc7, + 0xcc, 0xdc, 0x7e, 0x12, 0x53, 0xb6, 0x8d, 0xdb, 0x26, 0x5e, 0xbe, 0xc0, 0xd7, 0xda, 0x84, 0x52, + 0xa3, 0xf9, 0x9e, 0xdc, 0x03, 0x38, 0xf2, 0x39, 0x93, 0xb3, 0x43, 0x19, 0x28, 0xbb, 0x62, 0x9c, + 0xbd, 0x77, 0xe6, 0x55, 0x72, 0x7a, 0x39, 0x9f, 0xbc, 0xe5, 0x05, 0x85, 0xe6, 0x3d, 0x68, 0x94, + 0xe8, 0x25, 0x77, 0x76, 0xb5, 0x78, 0x67, 0xb5, 0x62, 0x8e, 0x6f, 0xc2, 0x6a, 0x72, 0x1e, 0x42, + 0x60, 0x85, 0xb3, 0x09, 0xa6, 0x6a, 0x66, 0xdd, 0xfe, 0x02, 0x6a, 0xf9, 0xc7, 0x47, 0xf6, 0x00, + 0x5c, 0xc1, 0x39, 0xba, 0x5a, 0xc8, 0x2c, 0x2b, 0xa7, 0x1f, 0x64, 0x3f, 0xa3, 0x68, 0x41, 0xaa, + 0x7d, 0x07, 0x6a, 0x39, 0xb1, 0xcc, 0x43, 0x8c, 0xe9, 0x59, 0x98, 0x05, 0x66, 0xd6, 0xed, 0xdf, + 0x2a, 0x50, 0xf8, 0x2c, 0x97, 0xaa, 0x6d, 0xc1, 0xaa, 0xaf, 0x54, 0x84, 0x32, 0x55, 0x4c, 0x77, + 0xa4, 0x03, 0x55, 0x37, 0xf0, 0x91, 0xeb, 0xe1, 0xc0, 0xfc, 0xc7, 0xb5, 0xde, 0xa5, 0xf9, 0xc9, + 0x4e, 0xb5, 0x9f, 0x62, 0x34, 0x67, 0xc9, 0x2e, 0xd4, 0xdd, 0xc0, 0xcf, 0x88, 0xe4, 0xdb, 0xed, + 0x35, 0xe6, 0x27, 0x3b, 0xf5, 0xfe, 0xfe, 0x30, 0x97, 0x2f, 0xca, 0xc4, 0x4e, 0x95, 0x2b, 0xc2, + 0xf4, 0xf3, 0xad, 0xd1, 0x74, 0x47, 0x5e, 0xc1, 0xba, 0x3f, 0x7a, 0x21, 0x8e, 0x91, 0xf7, 0xcd, + 0x20, 0x62, 0xaf, 0x9a, 0xdc, 0xdc, 0x5a, 0x32, 0x09, 0x38, 0xc3, 0xa2, 0xa0, 0xb9, 0xae, 0xde, + 0xe6, 0xfc, 0x64, 0x67, 0x7d, 0x38, 0x28, 0xe0, 0xf4, 0xac, 0x3d, 0x72, 0x17, 0x6c, 0x34, 0xad, + 0x7a, 0xf0, 0xb8, 0xff, 0xe0, 0x7e, 0xa4, 0xc7, 0xc8, 0x75, 0xda, 0x49, 0xe6, 0x07, 0xae, 0xd2, + 0x73, 0xf9, 0xe6, 0x0c, 0xc8, 0xa2, 0xcf, 0x25, 0x25, 0xf2, 0xe4, 0x6c, 0x5b, 0x7f, 0xfa, 0xd6, + 0xb6, 0x4e, 0xa6, 0x30, 0x27, 0x1f, 0x23, 0xe3, 0x71, 0xc6, 0x31, 0xf6, 0x0b, 0xb5, 0xb5, 0xf7, + 0xbb, 0x05, 0x8d, 0xac, 0xbf, 0x9e, 0xa3, 0x9c, 0xfa, 0x2e, 0x92, 0xaf, 0xa0, 0xf2, 0x10, 0x35, + 0xd9, 0x5a, 0x98, 0x5b, 0xcc, 0xac, 0xd6, 0xdc, 0x5c, 0xc0, 0xdb, 0xf6, 0x0f, 0x7f, 0xfd, 0xf3, + 0xd3, 0x05, 0x42, 0x36, 0xcc, 0xfc, 0x39, 0xdd, 0xcd, 0x67, 0x3f, 0x32, 0x06, 0x78, 0x88, 0xf9, + 0x47, 0x76, 0x9e, 0xc9, 0xd6, 0x02, 0x5e, 0xea, 0xf5, 0x76, 0xcb, 0x78, 0x68, 0x12, 0xbb, 0xec, + 0xa1, 0x9b, 0xb6, 0x78, 0xaf, 0xff, 0xc7, 0x7c, 0xdb, 0xfa, 0x73, 0xbe, 0x6d, 0xfd, 0x3d, 0xdf, + 0xb6, 0xbe, 0xf9, 0xe4, 0xff, 0x4d, 0xbc, 0x49, 0xa9, 0xe5, 0xc6, 0x8e, 0x56, 0xcd, 0x7c, 0x7a, + 0xe7, 0xdf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf1, 0x4f, 0xb0, 0x2d, 0x8e, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -1530,6 +1539,16 @@ func (m *OIDCConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.EnablePKCEAuthentication { + i-- + if m.EnablePKCEAuthentication { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x38 + } if len(m.IDTokenClaims) > 0 { for k := range m.IDTokenClaims { v := m.IDTokenClaims[k] @@ -1897,6 +1916,9 @@ func (m *OIDCConfig) Size() (n int) { n += mapEntrySize + 1 + sovSettings(uint64(mapEntrySize)) } } + if m.EnablePKCEAuthentication { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -3871,6 +3893,26 @@ func (m *OIDCConfig) Unmarshal(dAtA []byte) error { } m.IDTokenClaims[mapkey] = mapvalue iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field EnablePKCEAuthentication", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowSettings + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.EnablePKCEAuthentication = bool(v != 0) default: iNdEx = preIndex skippy, err := skipSettings(dAtA[iNdEx:]) diff --git a/server/settings/settings.go b/server/settings/settings.go index 2f797d552f4ce..32f5016419b4b 100644 --- a/server/settings/settings.go +++ b/server/settings/settings.go @@ -131,11 +131,12 @@ func (s *Server) Get(ctx context.Context, q *settingspkg.SettingsQuery) (*settin } if oidcConfig := argoCDSettings.OIDCConfig(); oidcConfig != nil { set.OIDCConfig = &settingspkg.OIDCConfig{ - Name: oidcConfig.Name, - Issuer: oidcConfig.Issuer, - ClientID: oidcConfig.ClientID, - CLIClientID: oidcConfig.CLIClientID, - Scopes: oidcConfig.RequestedScopes, + Name: oidcConfig.Name, + Issuer: oidcConfig.Issuer, + ClientID: oidcConfig.ClientID, + CLIClientID: oidcConfig.CLIClientID, + Scopes: oidcConfig.RequestedScopes, + EnablePKCEAuthentication: oidcConfig.EnablePKCEAuthentication, } if len(argoCDSettings.OIDCConfig().RequestedIDTokenClaims) > 0 { set.OIDCConfig.IDTokenClaims = argoCDSettings.OIDCConfig().RequestedIDTokenClaims diff --git a/server/settings/settings.proto b/server/settings/settings.proto index 9f95c9433b545..a6aa97120c8de 100644 --- a/server/settings/settings.proto +++ b/server/settings/settings.proto @@ -85,6 +85,7 @@ message OIDCConfig { string cliClientID = 4 [(gogoproto.customname) = "CLIClientID"]; repeated string scopes = 5; map idTokenClaims = 6 [(gogoproto.customname) = "IDTokenClaims"]; + bool enablePKCEAuthentication = 7; } // SettingsService diff --git a/ui/package.json b/ui/package.json index d5a4896ec78be..7c7b0df9c4f52 100644 --- a/ui/package.json +++ b/ui/package.json @@ -31,6 +31,7 @@ "minimatch": "^3.1.2", "moment": "^2.29.4", "monaco-editor": "^0.33.0", + "oauth4webapi": "^2.3.0", "path": "^0.12.7", "prop-types": "^15.8.1", "react": "^16.9.3", diff --git a/ui/src/app/app.tsx b/ui/src/app/app.tsx index 2cc63effeed2f..d0a58d3fbdc7f 100644 --- a/ui/src/app/app.tsx +++ b/ui/src/app/app.tsx @@ -18,6 +18,7 @@ import {hashCode} from './shared/utils'; import {Banner} from './ui-banner/ui-banner'; import userInfo from './user-info'; import {AuthSettings} from './shared/models'; +import {PKCEVerification} from './login/components/pkce-verify'; services.viewPreferences.init(); const bases = document.getElementsByTagName('base'); @@ -32,7 +33,8 @@ const routes: Routes = { '/applications': {component: applications.component}, '/settings': {component: settings.component}, '/user-info': {component: userInfo.component}, - '/help': {component: help.component} + '/help': {component: help.component}, + '/pkce/verify': {component: PKCEVerification, noLayout: true} }; interface NavItem { diff --git a/ui/src/app/login/components/login.tsx b/ui/src/app/login/components/login.tsx index db67ff185cf78..b00ef04bcacc4 100644 --- a/ui/src/app/login/components/login.tsx +++ b/ui/src/app/login/components/login.tsx @@ -1,4 +1,4 @@ -import {FormField} from 'argo-ui'; +import {FormField, NotificationType} from 'argo-ui'; import * as PropTypes from 'prop-types'; import * as React from 'react'; import {Form, Text} from 'react-form'; @@ -7,6 +7,7 @@ import {RouteComponentProps} from 'react-router'; import {AppContext} from '../../shared/context'; import {AuthSettings} from '../../shared/models'; import {services} from '../../shared/services'; +import {getPKCERedirectURI, pkceLogin} from './utils'; require('./login.scss'); @@ -61,7 +62,19 @@ export class Login extends React.Component, State> {
    {ssoConfigured && (
    - + { + pkceLogin(authSettings.oidcConfig, getPKCERedirectURI().toString()).catch(err => { + this.appContext.apis.notifications.show({ + type: NotificationType.Error, + content: err?.message || JSON.stringify(err) + }); + }); + } + } + : {href: `auth/login?return_url=${encodeURIComponent(this.state.returnUrl)}`})}>
    -
    0 ? 'columns small-2' : 'columns small-1'}> -
    - - - - -
    -
    -
    -
    - Project: -
    -
    {app.spec.project}
    +
    +
    +
    + Project:
    -
    -
    - Labels: -
    -
    - - {Object.keys(app.metadata.labels || {}) - .map(label => ({label, value: app.metadata.labels[label]})) - .map(item => ( -
    - {item.label}={item.value} -
    - ))} -
    - }> - +
    {app.spec.project}
    +
    +
    +
    + Labels: +
    +
    + {Object.keys(app.metadata.labels || {}) - .map(label => `${label}=${app.metadata.labels[label]}`) - .join(', ')} - - -
    + .map(label => ({label, value: app.metadata.labels[label]})) + .map(item => ( +
    + {item.label}={item.value} +
    + ))} +
    + }> + + {Object.keys(app.metadata.labels || {}) + .map(label => `${label}=${app.metadata.labels[label]}`) + .join(', ')} + +
    -
    -
    - Status: -
    -
    - {app.status.health.status} -   - {app.status.sync.status} -   - -
    +
    +
    +
    + Status:
    -
    -
    - Repository: -
    -
    - - {source.repoURL} - -
    +
    + {app.status.health.status} +   + {app.status.sync.status} +   +
    -
    -
    - Target Revision: -
    -
    {source.targetRevision || 'HEAD'}
    +
    +
    +
    + Repository:
    - {source.path && ( -
    -
    - Path: -
    -
    {source.path}
    -
    - )} - {source.chart && ( -
    -
    - Chart: -
    -
    {source.chart}
    -
    - )} -
    -
    - Destination: -
    -
    - -
    +
    + + {source.repoURL} +
    +
    +
    +
    + Target Revision: +
    +
    {source.targetRevision || 'HEAD'}
    +
    + {source.path && (
    -
    - Namespace: +
    + Path:
    -
    {app.spec.destination.namespace}
    +
    {source.path}
    + )} + {source.chart && (
    -
    - Created At: +
    + Chart:
    -
    {AppUtils.formatCreationTimestamp(app.metadata.creationTimestamp)}
    +
    {source.chart}
    - {app.status.operationState && ( -
    -
    - Last Sync: -
    -
    - {AppUtils.formatCreationTimestamp(app.status.operationState.finishedAt || app.status.operationState.startedAt)} -
    -
    - )} + )} +
    +
    + Destination: +
    +
    + +
    +
    +
    +
    + Namespace: +
    +
    {app.spec.destination.namespace}
    +
    +
    +
    + Created At: +
    +
    {AppUtils.formatCreationTimestamp(app.metadata.creationTimestamp)}
    +
    + {app.status.operationState && (
    - + )} +
    From d9e1b32eb9d59a66eb37bcc59f7f54a58c9a53a3 Mon Sep 17 00:00:00 2001 From: Rafal Date: Tue, 31 Oct 2023 19:10:37 +0100 Subject: [PATCH 065/269] fix(ui): Missing data in Sync Status if application never been synced (#16184) Signed-off-by: Rafal Pelczar --- .../application-status-panel.tsx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx index c82252144849c..0e4104f3f12b3 100644 --- a/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx +++ b/ui/src/app/applications/components/application-status-panel/application-status-panel.tsx @@ -89,20 +89,18 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh hasMultipleSources, () => showMetadataInfo(application.status.sync ? application.status.sync.revision : '') )} - {appOperationState && ( -
    -
    - {application.status.sync.status === models.SyncStatuses.OutOfSync ? ( - showDiff && showDiff()}> - - - ) : ( +
    +
    + {application.status.sync.status === models.SyncStatuses.OutOfSync ? ( + showDiff && showDiff()}> - )} -
    -
    {syncStatusMessage(application)}
    +
    + ) : ( + + )}
    - )} +
    {syncStatusMessage(application)}
    +
    {application.spec.syncPolicy?.automated ? 'Auto sync is enabled.' : 'Auto sync is not enabled.'}
    From 2d70f890b98eae45ba833f006a9e36a01235ff42 Mon Sep 17 00:00:00 2001 From: Chris Dolan Date: Tue, 31 Oct 2023 13:31:47 -0600 Subject: [PATCH 066/269] docs: Add Semgrep as a user (#16185) Signed-off-by: Chris Dolan --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 6c4bc8e5e3eac..85fe16196ce9b 100644 --- a/USERS.md +++ b/USERS.md @@ -247,6 +247,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Schwarz IT](https://jobs.schwarz/it-mission) 1. [SCRM Lidl International Hub](https://scrm.lidl) 1. [SEEK](https://seek.com.au) +1. [Semgrep](https://semgrep.com) 1. [SI Analytics](https://si-analytics.ai) 1. [Skit](https://skit.ai/) 1. [Skyscanner](https://www.skyscanner.net/) From 5fc9fae74e673d18bcbae31e78edd1ae9c350c04 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 31 Oct 2023 17:00:34 -0400 Subject: [PATCH 067/269] chore(deps): bump slsa-github-generator to 1.9.0 (#16188) * chore(deps): bump slsa-github-generator to 1.9.0 Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * catch more Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .github/workflows/release.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 7e9303f288ae4..9448b98e5c631 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -38,7 +38,7 @@ jobs: packages: write # for uploading attestations. (https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#known-issues) # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator if: github.repository == 'argoproj/argo-cd' - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.7.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.9.0 with: image: quay.io/argoproj/argocd digest: ${{ needs.argocd-image.outputs.image-digest }} @@ -120,7 +120,7 @@ jobs: contents: write # Needed for release uploads if: github.repository == 'argoproj/argo-cd' # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.7.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 with: base64-subjects: "${{ needs.goreleaser.outputs.hashes }}" provenance-name: "argocd-cli.intoto.jsonl" @@ -204,7 +204,7 @@ jobs: contents: write # Needed for release uploads if: github.repository == 'argoproj/argo-cd' # Must be refernced by a tag. https://github.com/slsa-framework/slsa-github-generator/blob/main/internal/builders/container/README.md#referencing-the-slsa-generator - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.7.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.9.0 with: base64-subjects: "${{ needs.generate-sbom.outputs.hashes }}" provenance-name: "argocd-sbom.intoto.jsonl" From e36ce86b829a7f05723b8756bd51d2a6cd54cd71 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 31 Oct 2023 21:47:06 -0400 Subject: [PATCH 068/269] docs(cmp): fix CMP param getter example (#16077) (#16190) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- examples/plugins/helm/get-parameters.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/plugins/helm/get-parameters.sh b/examples/plugins/helm/get-parameters.sh index d89c29c46656e..5e7823a7c8c72 100755 --- a/examples/plugins/helm/get-parameters.sh +++ b/examples/plugins/helm/get-parameters.sh @@ -1,8 +1,8 @@ #!/bin/sh -yq e -o=json values.yaml | jq '{ +yq e -o=json values.yaml | jq '[{ name: "helm-parameters", title: "Helm Parameters", collectionType: "map", map: [leaf_paths as $path | {"key": $path | join("."), "value": getpath($path)|tostring}] | from_entries -}' +}]' From 9b4fc572bf490e16adf321d48388b012e38b6d46 Mon Sep 17 00:00:00 2001 From: Priyanshu Thapliyal <114170980+Priyanshuthapliyal2005@users.noreply.github.com> Date: Wed, 1 Nov 2023 07:39:24 +0530 Subject: [PATCH 069/269] fix api docs (#16186) Signed-off-by: Priyanshu Thapliyal <114170980+Priyanshuthapliyal2005@users.noreply.github.com> --- docs/developer-guide/api-docs.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/developer-guide/api-docs.md b/docs/developer-guide/api-docs.md index 289e4d466652e..63e3cd901e3d3 100644 --- a/docs/developer-guide/api-docs.md +++ b/docs/developer-guide/api-docs.md @@ -24,10 +24,9 @@ $ curl $ARGOCD_SERVER/api/v1/applications -H "Authorization: Bearer $ARGOCD_TOKE #### How to Avoid 403 Errors for Missing Applications -All endpoints of the Applications API accept an optional `project` query string parameter. If the parameter is -specified, and the specified Application does not exist, or if the Application does exist but is not in the given -project, the API will return a `404` error. +All endpoints of the Applications API accept an optional `project` query string parameter. If the parameter +is specified, and the specified Application does not exist, the API will return a `404` error. -If the `project` query string parameter is specified, and the Application does not exist, the API will return a `403` -error. This is to prevent leaking information about the existence of Applications to users who do not have access to -them. +Additionally, if the `project` query string parameter is specified and the Application exists but is not in +the given `project`, the API will return a `403` error. This is to prevent leaking information about the +existence of Applications to users who do not have access to them. \ No newline at end of file From 26264b87d063720e1665e5caaf2f0a6b09cb3532 Mon Sep 17 00:00:00 2001 From: navist2020 <74897901+navist2020@users.noreply.github.com> Date: Wed, 1 Nov 2023 10:31:38 +0800 Subject: [PATCH 070/269] Remove unnecessary error checking (#16150) Signed-off-by: lijun --- .../commands/argocd_application_controller.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 39d8e017b7f26..391751b0d95d1 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -143,7 +143,6 @@ func NewCommand() *cobra.Command { })) kubectl := kubeutil.NewKubectl() clusterFilter := getClusterFilter(kubeClient, settingsMgr, shardingAlgorithm, enableDynamicClusterDistribution) - errors.CheckError(err) appController, err = controller.NewApplicationController( namespace, settingsMgr, From 8e612b24f357f51a3c4fdbdea310ea1d096a21ea Mon Sep 17 00:00:00 2001 From: Christopher Fry Date: Wed, 1 Nov 2023 07:35:46 -0700 Subject: [PATCH 071/269] chore: specify namespace when restarting deployments in remote e2e tests (#16192) Signed-off-by: Chris Fry --- test/e2e/fixture/fixture.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/e2e/fixture/fixture.go b/test/e2e/fixture/fixture.go index 0d8affabf5fca..f8dd60cb74974 100644 --- a/test/e2e/fixture/fixture.go +++ b/test/e2e/fixture/fixture.go @@ -938,8 +938,8 @@ func RestartRepoServer() { if prefix != "" { workload = prefix + "-repo-server" } - FailOnErr(Run("", "kubectl", "rollout", "restart", "deployment", workload)) - FailOnErr(Run("", "kubectl", "rollout", "status", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) // wait longer to avoid error on s390x time.Sleep(10 * time.Second) } @@ -955,8 +955,8 @@ func RestartAPIServer() { if prefix != "" { workload = prefix + "-server" } - FailOnErr(Run("", "kubectl", "rollout", "restart", "deployment", workload)) - FailOnErr(Run("", "kubectl", "rollout", "status", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "restart", "deployment", workload)) + FailOnErr(Run("", "kubectl", "rollout", "-n", TestNamespace(), "status", "deployment", workload)) } } From 9eca44b4b7b8e3819b640dc2f8b57a25f90ac83b Mon Sep 17 00:00:00 2001 From: Zadkiel Aharonian Date: Wed, 1 Nov 2023 15:51:26 +0100 Subject: [PATCH 072/269] fix(ui): prevent app panel to open on app direct link click (#15040) Signed-off-by: Zadkiel Aharonian --- .../application-details/application-resource-list.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ui/src/app/applications/components/application-details/application-resource-list.tsx b/ui/src/app/applications/components/application-details/application-resource-list.tsx index dba61c5135492..e5cad1bc0a93b 100644 --- a/ui/src/app/applications/components/application-details/application-resource-list.tsx +++ b/ui/src/app/applications/components/application-details/application-resource-list.tsx @@ -85,7 +85,10 @@ export const ApplicationResourceList = ({ {ctx => ( - + e.stopPropagation()} + title='Open application'> From c70e1b7163bf31a4502b58498f7b4e86e4617f99 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Ferrero Date: Wed, 1 Nov 2023 15:55:21 +0100 Subject: [PATCH 073/269] fix(server): appset list uses argocd's namespace instead of all (#15429) (#15432) * fix(server): appset list uses argocd's namespace instead of all Signed-off-by: Jorge Turrado * use lister to scope the observed namespaces based on which namespaces monitors for apps Signed-off-by: Jorge Turrado * apply feedback Signed-off-by: Jorge Turrado * add missing change :facepalm: Signed-off-by: Jorge Turrado * update generated manifests Signed-off-by: Jorge Turrado --------- Signed-off-by: Jorge Turrado --- .../server/argocd-server-clusterrole.yaml | 1 + manifests/ha/install.yaml | 1 + manifests/install.yaml | 1 + server/applicationset/applicationset.go | 30 ++++----- server/applicationset/applicationset_test.go | 64 +++++++++++++++---- server/server.go | 7 +- 6 files changed, 73 insertions(+), 31 deletions(-) diff --git a/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml b/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml index f81f529086fb5..b33820950fcb6 100644 --- a/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml +++ b/manifests/cluster-rbac/server/argocd-server-clusterrole.yaml @@ -32,6 +32,7 @@ rules: - "argoproj.io" resources: - "applications" + - "applicationsets" verbs: - get - list diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 043083de6be84..cd532b40b13ad 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -20609,6 +20609,7 @@ rules: - argoproj.io resources: - applications + - applicationsets verbs: - get - list diff --git a/manifests/install.yaml b/manifests/install.yaml index a08c3a5cd1302..211cdf31d92de 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -20568,6 +20568,7 @@ rules: - argoproj.io resources: - applications + - applicationsets verbs: - get - list diff --git a/server/applicationset/applicationset.go b/server/applicationset/applicationset.go index 5dbff2d309a05..d67815bd9a53d 100644 --- a/server/applicationset/applicationset.go +++ b/server/applicationset/applicationset.go @@ -25,7 +25,6 @@ import ( "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" - servercache "github.com/argoproj/argo-cd/v2/server/cache" "github.com/argoproj/argo-cd/v2/server/rbacpolicy" "github.com/argoproj/argo-cd/v2/util/argo" "github.com/argoproj/argo-cd/v2/util/collections" @@ -40,11 +39,9 @@ type Server struct { ns string db db.ArgoDB enf *rbac.Enforcer - cache *servercache.Cache appclientset appclientset.Interface - appLister applisters.ApplicationLister appsetInformer cache.SharedIndexInformer - appsetLister applisters.ApplicationSetNamespaceLister + appsetLister applisters.ApplicationSetLister projLister applisters.AppProjectNamespaceLister auditLogger *argo.AuditLogger settings *settings.SettingsManager @@ -57,11 +54,9 @@ func NewServer( db db.ArgoDB, kubeclientset kubernetes.Interface, enf *rbac.Enforcer, - cache *servercache.Cache, appclientset appclientset.Interface, - appLister applisters.ApplicationLister, appsetInformer cache.SharedIndexInformer, - appsetLister applisters.ApplicationSetNamespaceLister, + appsetLister applisters.ApplicationSetLister, projLister applisters.AppProjectNamespaceLister, settings *settings.SettingsManager, namespace string, @@ -70,11 +65,9 @@ func NewServer( ) applicationset.ApplicationSetServiceServer { s := &Server{ ns: namespace, - cache: cache, db: db, enf: enf, appclientset: appclientset, - appLister: appLister, appsetInformer: appsetInformer, appsetLister: appsetLister, projLister: projLister, @@ -94,7 +87,7 @@ func (s *Server) Get(ctx context.Context, q *applicationset.ApplicationSetGetQue return nil, security.NamespaceNotPermittedError(namespace) } - a, err := s.appclientset.ArgoprojV1alpha1().ApplicationSets(namespace).Get(ctx, q.Name, metav1.GetOptions{}) + a, err := s.appsetLister.ApplicationSets(namespace).Get(q.Name) if err != nil { return nil, fmt.Errorf("error getting ApplicationSet: %w", err) @@ -113,14 +106,19 @@ func (s *Server) List(ctx context.Context, q *applicationset.ApplicationSetListQ return nil, fmt.Errorf("error parsing the selector: %w", err) } - appIf := s.appclientset.ArgoprojV1alpha1().ApplicationSets(q.AppsetNamespace) - appsetList, err := appIf.List(ctx, metav1.ListOptions{LabelSelector: selector.String()}) + var appsets []*v1alpha1.ApplicationSet + if q.AppsetNamespace == "" { + appsets, err = s.appsetLister.List(selector) + } else { + appsets, err = s.appsetLister.ApplicationSets(q.AppsetNamespace).List(selector) + } + if err != nil { return nil, fmt.Errorf("error listing ApplicationSets with selectors: %w", err) } newItems := make([]v1alpha1.ApplicationSet, 0) - for _, a := range appsetList.Items { + for _, a := range appsets { // Skip any application that is neither in the conrol plane's namespace // nor in the list of enabled namespaces. @@ -129,7 +127,7 @@ func (s *Server) List(ctx context.Context, q *applicationset.ApplicationSetListQ } if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceApplicationSets, rbacpolicy.ActionGet, a.RBACName(s.ns)) { - newItems = append(newItems, a) + newItems = append(newItems, *a) } } @@ -140,7 +138,7 @@ func (s *Server) List(ctx context.Context, q *applicationset.ApplicationSetListQ return newItems[i].Name < newItems[j].Name }) - appsetList = &v1alpha1.ApplicationSetList{ + appsetList := &v1alpha1.ApplicationSetList{ ListMeta: metav1.ListMeta{ ResourceVersion: s.appsetInformer.LastSyncResourceVersion(), }, @@ -336,7 +334,7 @@ func (s *Server) waitSync(appset *v1alpha1.ApplicationSet) { return } for { - if currAppset, err := s.appsetLister.Get(appset.Name); err == nil { + if currAppset, err := s.appsetLister.ApplicationSets(appset.Namespace).Get(appset.Name); err == nil { currVersion, err := strconv.Atoi(currAppset.ResourceVersion) if err == nil && currVersion >= minVersion { return diff --git a/server/applicationset/applicationset_test.go b/server/applicationset/applicationset_test.go index aef61f289d494..c5a299c85f358 100644 --- a/server/applicationset/applicationset_test.go +++ b/server/applicationset/applicationset_test.go @@ -50,10 +50,21 @@ func newTestAppSetServer(objects ...runtime.Object) *Server { _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) enf.SetDefaultRole("role:admin") } - return newTestAppSetServerWithEnforcerConfigure(f, objects...) + scopedNamespaces := "" + return newTestAppSetServerWithEnforcerConfigure(f, scopedNamespaces, objects...) } -func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), objects ...runtime.Object) *Server { +// return an ApplicationServiceServer which returns fake data +func newTestNamespacedAppSetServer(objects ...runtime.Object) *Server { + f := func(enf *rbac.Enforcer) { + _ = enf.SetBuiltinPolicy(assets.BuiltinPolicyCSV) + enf.SetDefaultRole("role:admin") + } + scopedNamespaces := "argocd" + return newTestAppSetServerWithEnforcerConfigure(f, scopedNamespaces, objects...) +} + +func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), namespace string, objects ...runtime.Object) *Server { kubeclientset := fake.NewSimpleClientset(&v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Namespace: testNamespace, @@ -97,7 +108,7 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), objects .. objects = append(objects, defaultProj, myProj) fakeAppsClientset := apps.NewSimpleClientset(objects...) - factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(""), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) + factory := appinformer.NewSharedInformerFactoryWithOptions(fakeAppsClientset, 0, appinformer.WithNamespace(namespace), appinformer.WithTweakListOptions(func(options *metav1.ListOptions) {})) fakeProjLister := factory.Argoproj().V1alpha1().AppProjects().Lister().AppProjects(testNamespace) enforcer := rbac.NewEnforcer(kubeclientset, testNamespace, common.ArgoCDRBACConfigMapName, nil) @@ -114,6 +125,12 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), objects .. if !k8scache.WaitForCacheSync(ctx.Done(), appInformer.HasSynced) { panic("Timed out waiting for caches to sync") } + // populate the appset informer with the fake objects + appsetInformer := factory.Argoproj().V1alpha1().ApplicationSets().Informer() + go appsetInformer.Run(ctx.Done()) + if !k8scache.WaitForCacheSync(ctx.Done(), appsetInformer.HasSynced) { + panic("Timed out waiting for caches to sync") + } projInformer := factory.Argoproj().V1alpha1().AppProjects().Informer() go projInformer.Run(ctx.Done()) @@ -125,11 +142,9 @@ func newTestAppSetServerWithEnforcerConfigure(f func(*rbac.Enforcer), objects .. db, kubeclientset, enforcer, - nil, fakeAppsClientset, - factory.Argoproj().V1alpha1().Applications().Lister(), appInformer, - factory.Argoproj().V1alpha1().ApplicationSets().Lister().ApplicationSets(testNamespace), + factory.Argoproj().V1alpha1().ApplicationSets().Lister(), fakeProjLister, settingsMgr, testNamespace, @@ -223,21 +238,22 @@ func testListAppsetsWithLabels(t *testing.T, appsetQuery applicationset.Applicat } func TestListAppSetsInNamespaceWithLabels(t *testing.T) { + testNamespace := "test-namespace" appSetServer := newTestAppSetServer(newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet1" - appset.ObjectMeta.Namespace = "test-namespace" + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet2" - appset.ObjectMeta.Namespace = "test-namespace" + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value2"}) }), newTestAppSet(func(appset *appsv1.ApplicationSet) { appset.Name = "AppSet3" - appset.ObjectMeta.Namespace = "test-namespace" + appset.ObjectMeta.Namespace = testNamespace appset.SetLabels(map[string]string{"key1": "value3"}) })) - appSetServer.ns = "test-namespace" - appsetQuery := applicationset.ApplicationSetListQuery{AppsetNamespace: "test-namespace"} + appSetServer.enabledNamespaces = []string{testNamespace} + appsetQuery := applicationset.ApplicationSetListQuery{AppsetNamespace: testNamespace} testListAppsetsWithLabels(t, appsetQuery, appSetServer) } @@ -258,6 +274,32 @@ func TestListAppSetsInDefaultNSWithLabels(t *testing.T) { testListAppsetsWithLabels(t, appsetQuery, appSetServer) } +// This test covers https://github.com/argoproj/argo-cd/issues/15429 +// If the namespace isn't provided during listing action, argocd's +// default namespace must be used and not all the namespaces +func TestListAppSetsWithoutNamespace(t *testing.T) { + testNamespace := "test-namespace" + appSetServer := newTestNamespacedAppSetServer(newTestAppSet(func(appset *appsv1.ApplicationSet) { + appset.Name = "AppSet1" + appset.ObjectMeta.Namespace = testNamespace + appset.SetLabels(map[string]string{"key1": "value1", "key2": "value1"}) + }), newTestAppSet(func(appset *appsv1.ApplicationSet) { + appset.Name = "AppSet2" + appset.ObjectMeta.Namespace = testNamespace + appset.SetLabels(map[string]string{"key1": "value2"}) + }), newTestAppSet(func(appset *appsv1.ApplicationSet) { + appset.Name = "AppSet3" + appset.ObjectMeta.Namespace = testNamespace + appset.SetLabels(map[string]string{"key1": "value3"}) + })) + appSetServer.enabledNamespaces = []string{testNamespace} + appsetQuery := applicationset.ApplicationSetListQuery{} + + res, err := appSetServer.List(context.Background(), &appsetQuery) + assert.NoError(t, err) + assert.Equal(t, 0, len(res.Items)) +} + func TestCreateAppSet(t *testing.T) { testAppSet := newTestAppSet() appServer := newTestAppSetServer() diff --git a/server/server.go b/server/server.go index b4225dfdc51b8..e52416927143b 100644 --- a/server/server.go +++ b/server/server.go @@ -178,7 +178,7 @@ type ArgoCDServer struct { appInformer cache.SharedIndexInformer appLister applisters.ApplicationLister appsetInformer cache.SharedIndexInformer - appsetLister applisters.ApplicationSetNamespaceLister + appsetLister applisters.ApplicationSetLister db db.ArgoDB // stopCh is the channel which when closed, will shutdown the Argo CD server @@ -264,7 +264,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer { appLister := appFactory.Argoproj().V1alpha1().Applications().Lister() appsetInformer := appFactory.Argoproj().V1alpha1().ApplicationSets().Informer() - appsetLister := appFactory.Argoproj().V1alpha1().ApplicationSets().Lister().ApplicationSets(opts.Namespace) + appsetLister := appFactory.Argoproj().V1alpha1().ApplicationSets().Lister() userStateStorage := util_session.NewUserStateStorage(opts.RedisClient) sessionMgr := util_session.NewSessionManager(settingsMgr, projLister, opts.DexServerAddr, opts.DexTLSConfig, userStateStorage) @@ -471,6 +471,7 @@ func (a *ArgoCDServer) Listen() (*Listeners, error) { func (a *ArgoCDServer) Init(ctx context.Context) { go a.projInformer.Run(ctx.Done()) go a.appInformer.Run(ctx.Done()) + go a.appsetInformer.Run(ctx.Done()) go a.configMapInformer.Run(ctx.Done()) go a.secretInformer.Run(ctx.Done()) } @@ -852,9 +853,7 @@ func newArgoCDServiceSet(a *ArgoCDServer) *ArgoCDServiceSet { a.db, a.KubeClientset, a.enf, - a.Cache, a.AppClientset, - a.appLister, a.appsetInformer, a.appsetLister, a.projLister, From 51b4b20211580e79bfb853f9779be510787311bf Mon Sep 17 00:00:00 2001 From: Jimmy Neville Date: Wed, 1 Nov 2023 12:18:51 -0400 Subject: [PATCH 074/269] feat: Allow 'both' option for uibannerposition (#14623) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(ui): Drop ready from Completed container status (#14434) (#14629) Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/go-git/go-git/v5 from 5.7.0 to 5.8.0 (#14641) Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.7.0 to 5.8.0. - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.7.0...v5.8.0) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 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> Signed-off-by: Jimmy Neville * fix: webhook handler fails to refresh when alternate application namespaces are configured (#13976) * fix: Add failing test for webhooks in all namespaces This adds a failing test that properly exercises this functionality over all namespaces. The issue with the code that is under test is that it does not pass the namespace correctly to the patch of the application, resulting in the patch not taking place in the correct namespace Signed-off-by: Nikolas Skoufis * fix: queue webhook refresh for apps in all namespaces This passes the test in the previous commit, to ensure that webhooks correctly refresh applications across all namespaces. Signed-off-by: Nikolas Skoufis * fix: Use existing NamespacedName type Use the existing type instead of a custom type Signed-off-by: Nikolas Skoufis --------- Signed-off-by: Nikolas Skoufis Signed-off-by: Jimmy Neville * fix: ApplicationSet Controller crashes when tag is not closed; panic: Cannot find end tag="}}"(#14227) (#14651) * ApplicationSet bug fix Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * Update applicationset/utils/utils_test.go Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * oops Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ui): The default pod group filter should be removed if fewer than 15 pods (#14590) Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(deep-links): sprig support (#14660) Signed-off-by: daftping <21245083+daftping@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: Print in-cluster svr addr disabled warning when server starts (#14553) * chore: Print in-cluster svr addr disabled warning when server starts Signed-off-by: Yuan Tang * fix: mock Signed-off-by: Yuan Tang * no interface change Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Yuan Tang Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: Upgrade semver to avoid cve (#14710) Signed-off-by: Yi Cai Signed-off-by: Jimmy Neville * feat: adding a autosync_enabled field to the argocd_app_info gauge (#14424) Signed-off-by: Gerardo Corea Signed-off-by: Jimmy Neville * fix(controller): log failed attempts to update operation state (#14273) * fix(controller): log failed attempts to update operation state Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * new package name Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update controller/appcontroller_test.go Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(server): handle PATCH in http/s server (#2677) (#14530) Signed-off-by: mmerrill3 Signed-off-by: Jimmy Neville * fix: manifest generation error with null annotations (#14336) (#14680) * fix: manifest generation error with null annotations Signed-off-by: Alexandre Gaudreault * fix test Signed-off-by: Alexandre Gaudreault * fix unit tests Signed-off-by: Alexandre Gaudreault --------- Signed-off-by: Alexandre Gaudreault Signed-off-by: Jimmy Neville * Clean up repeated package import (#13889) Signed-off-by: Zechun Chen Signed-off-by: Jimmy Neville * fix(sso): Set redirectURI for gitea, google, oauth Dex connectors (#11237) Signed-off-by: ylxianzhe Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(appset): Restrict scm provider urls (#14286) * 9353: Restrict scm provider urls Signed-off-by: gmuselli * 9353: Enforce restriction Signed-off-by: gmuselli * 9353: Fix after review Signed-off-by: gmuselli * 9353: Remove comment Signed-off-by: gmuselli * 9353: Fix units tests Signed-off-by: Geoffrey Muselli * 9353: Code review, update comment Signed-off-by: gmuselli * 9353: Code review, update comment 2 Signed-off-by: gmuselli * 9353: Remove doc issues Signed-off-by: gmuselli * 9353: Fix e2e Signed-off-by: gmuselli * 9353: Fix e2e goTemplate Signed-off-by: gmuselli * 9353: Fix e2e pullRequestGenerator Signed-off-by: gmuselli --------- Signed-off-by: gmuselli Signed-off-by: Geoffrey Muselli Signed-off-by: Jimmy Neville * chore(deps): bump github.com/go-git/go-git/v5 from 5.8.0 to 5.8.1 (#14744) Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.8.0 to 5.8.1. - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.8.0...v5.8.1) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 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> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/aws/aws-sdk-go from 1.44.305 to 1.44.309 (#14746) Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.44.305 to 1.44.309. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.305...v1.44.309) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go 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> Signed-off-by: Jimmy Neville * fix(ui): display valuesobject if set (#14257) * fix: display valuesobject if set With #11538 we now have the ability to set helm values as an object instead of a string, but we also need to be able to correctly display it in the UI if it is set. Signed-off-by: Blake Pettersson * fix: set valuesobject on save If `valuesObject` is present, set it to the value of `input.spec.source.helm.values` on save, as an unmarshaled json string. Signed-off-by: Blake Pettersson * fix: set `helm.values` to empty string on save If `valuesObject` exists, set `input.spec.source.helm.values` to an empty string once `valuesObject` has been unmarshalled from the values input. This is to prevent unnecessary duplication of the values. Signed-off-by: Blake Pettersson * chore: eslint Signed-off-by: Blake Pettersson * chore: eslint Signed-off-by: Blake Pettersson * fix: deep clone app This is so that we can conditionally set `source.helm.values` without inadvertently affecting other parts of the app. Only when the edit button is pressed do we toggle `source.helm.values`. Signed-off-by: Blake Pettersson * chore: eslint Signed-off-by: Blake Pettersson --------- Signed-off-by: Blake Pettersson Signed-off-by: Jimmy Neville * fix: OCI dependency url can't contain part of repository (#14699) Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * docs: Add missing value (#14538) Signed-off-by: felix Signed-off-by: Jimmy Neville * [Bot] docs: Update Snyk reports (#14781) Signed-off-by: CI Co-authored-by: CI Signed-off-by: Jimmy Neville * chore(deps): bump github.com/aws/aws-sdk-go from 1.44.309 to 1.44.312 (#14782) Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.44.309 to 1.44.312. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.309...v1.44.312) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go 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> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/xanzy/go-gitlab from 0.88.0 to 0.89.0 (#14784) Bumps [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) from 0.88.0 to 0.89.0. - [Changelog](https://github.com/xanzy/go-gitlab/blob/master/releases_test.go) - [Commits](https://github.com/xanzy/go-gitlab/compare/v0.88.0...v0.89.0) --- updated-dependencies: - dependency-name: github.com/xanzy/go-gitlab 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> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/casbin/casbin/v2 from 2.72.1 to 2.73.0 (#14783) Bumps [github.com/casbin/casbin/v2](https://github.com/casbin/casbin) from 2.72.1 to 2.73.0. - [Release notes](https://github.com/casbin/casbin/releases) - [Changelog](https://github.com/casbin/casbin/blob/master/.releaserc.json) - [Commits](https://github.com/casbin/casbin/compare/v2.72.1...v2.73.0) --- updated-dependencies: - dependency-name: github.com/casbin/casbin/v2 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> Signed-off-by: Jimmy Neville * chore: add Autodesk to USERS.md (#14778) Signed-off-by: Dylan Page Signed-off-by: Jimmy Neville * chore: Add query-scoped cluster URL in Cluster Secret E2E tests (#14446) * Add query-scoped cluster URL in Cluster Secret E2E tests Signed-off-by: Jonathan West * Respond to review comments Signed-off-by: Jonathan West --------- Signed-off-by: Jonathan West Signed-off-by: Jimmy Neville * docs: Clarify that security policy covers last 3 versions (#14786) * docs: Clarify that security policy covers last 3 versions Signed-off-by: Kostis Kapelonis * Update SECURITY.md Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Kostis Kapelonis Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(controller): cache deadlock on delete and re-add cluster (#14780) Signed-off-by: Nathan Romriell Signed-off-by: Jimmy Neville * chore: make `helm template` errors less verbose (#14772) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(deep-links): alias `application` as `apps` for consistency with notifications engine (#14761) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ui): no hyphen for "create job" action + nice icon (#14776) (#14777) * chore(actions): space instead of hyphen in action name (#14776) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * new field for backwards-compatibility Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * align icons for maximum synergy Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * delete unused function Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * revert unnecessary changes Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update docs/operator-manual/upgrading/2.7-2.8.md Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix: Correct broken `forever` option in pod logs viewer. Fixes #14762 (#14763) Signed-off-by: Alex Collins Signed-off-by: Jimmy Neville * docs: Update application.yaml (#14742) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * docs: add ignoreDifferences name and namespace fields (#14741) * Update application.yaml Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update docs/operator-manual/application.yaml Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.4.0 to 20.5.0 (#14664) Bumps library/node from 20.4.0 to 20.5.0. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.4.0 to 20.5.0 in /ui-test (#14662) Bumps library/node from 20.4.0 to 20.5.0. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * docs: Update Controlling-Resource-Modification.md (#14751) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(notifications-catalog): Add nil check for notifications_catalog triggers (#14795) * Add nil check for notifications_catalog triggers Signed-off-by: Trung * Use correct nil check Signed-off-by: Trung * Add missing catalog generation to makefile Signed-off-by: Trung * Revert changes to update-manifests.sh Signed-off-by: Trung --------- Signed-off-by: Trung Signed-off-by: Jimmy Neville * fix: ManagedResources API should not return diff for hooks (#14816) Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * docs: Change Generator docs for List Generator to note any key/value pairs can be used (#14825) This is no longer limited to cluster/url value pairs. Signed-off-by: JesseBot Signed-off-by: Jimmy Neville * chore: improve app destination docstrings (#14836) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat: Adding kubelogin capability to argocd-k8s-auth (#9460) (#10700) Signed-off-by: mmerrill3 Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: Add header support for proxy extension requests (#14800) * chore: add server URL in the header of proxy extensions Signed-off-by: Leonardo Luz Almeida * feat: add header support for proxy extension requests Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida * address review comments Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida --------- Signed-off-by: Leonardo Luz Almeida Signed-off-by: Jimmy Neville * docs: use consistent password in plugin generator examples (#14837) * docs: use consistent password in plugin generator examples The example secret with the token is using `strong-password`, but the later examples use `string-password`. This updates all of the examples to use `strong-password`. Signed-off-by: Nicholas Morey * docs: update another-secret example to include `strong-password` Consistent with above example of client token in argocd-secret Signed-off-by: Nicholas Morey --------- Signed-off-by: Nicholas Morey Signed-off-by: Jimmy Neville * chore: give context to error logs #10592 (#14851) * chore: give context to error logs Signed-off-by: ashinsabu3 * Update reposerver/repository/repository.go Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: ashinsabu3 Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: add more tests in proxy extension headers (#14842) Signed-off-by: Leonardo Luz Almeida Signed-off-by: Jimmy Neville * chore: revert #12255 (#14858) This reverts commit c651bd8de551c85fc897c997c1976d6777259921. Due to the imminent release of 2.8, this needs to be rolled back since the proposed fix in #14210 cannot make it in time. Signed-off-by: Blake Pettersson Signed-off-by: Jimmy Neville * fix: Repo URL link for unsupported sources links to https:///null/path/to/chart (#14861) * Fix #14860 Fix #14860 Signed-off-by: Talia Stocks <928827+taliastocks@users.noreply.github.com> * Update USERS.md Signed-off-by: Talia Stocks <928827+taliastocks@users.noreply.github.com> --------- Signed-off-by: Talia Stocks <928827+taliastocks@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix: correct discrepancies in generated swagger file (#14813) Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * chore: wrap ComparisonError messages (#14886) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ui): Fixes health icon positioning (#14708) (#14852) * fix: Fixes health icon positioning #14708 Signed-off-by: ashinsabu3 * fix: Fixes alignment of app health application status panel #14708 Signed-off-by: ashinsabu3 * fix: Added line height to App Status to fix its positioning #14708 Signed-off-by: ashinsabu3 --------- Signed-off-by: ashinsabu3 Signed-off-by: Jimmy Neville * chore: fix non-deterministic test (#14905) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix: Change underscore (_) back to plus (+) to get valid SemVer when when reading tags from OCI registry (#14537) * fix: Change underscore (_) back to plus (+) to get valid SemVer when reading tags from OCI registry Signed-off-by: xashr * Add test coverage for SemVer tags in TestGetTagsFromUrl Signed-off-by: xashr --------- Signed-off-by: xashr Signed-off-by: Jimmy Neville * fix(appset): typo in ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS (#14902) (#14913) Signed-off-by: gmuselli Signed-off-by: Jimmy Neville * feat: provide short revision in ARGOCD_APP_REVISION_SHORT env variable (#14926) Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * chore(deps): bump github.com/aws/aws-sdk-go from 1.44.312 to 1.44.317 (#14925) Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.44.312 to 1.44.317. - [Release notes](https://github.com/aws/aws-sdk-go/releases) - [Commits](https://github.com/aws/aws-sdk-go/compare/v1.44.312...v1.44.317) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go 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> Signed-off-by: Jimmy Neville * chore(deps): bump golang.org/x/oauth2 from 0.10.0 to 0.11.0 (#14922) Bumps [golang.org/x/oauth2](https://github.com/golang/oauth2) from 0.10.0 to 0.11.0. - [Commits](https://github.com/golang/oauth2/compare/v0.10.0...v0.11.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> Signed-off-by: Jimmy Neville * docs: Update Generators-Git.md (#14921) Remove a misleading symbol from the pattern for the path.Match function. The pipe symbol doesn't have any special meaning. Signed-off-by: German Lashevich Signed-off-by: Jimmy Neville * docs: Update helm.md - add missing syntax highlighting for YAML and Dockerfile blocks (#14911) Signed-off-by: JesseBot Signed-off-by: Jimmy Neville * fix(ui): COPY JSON for ArgoCD version should include trailing newline (#5117) (#14917) Signed-off-by: Vipin M S Signed-off-by: Jimmy Neville * [Bot] docs: Update Snyk reports (#14919) Signed-off-by: CI Co-authored-by: CI Signed-off-by: Jimmy Neville * chore: give context to error logs (#10592) (#14915) * chore: wrap error objects to include context Signed-off-by: Vipin M S * chore: wrap error objects to include context Signed-off-by: Vipin M S * chore: wrap error objects to include context Signed-off-by: Vipin M S * chore: wrap error objects to include context Signed-off-by: Vipin M S * Update applicationset/controllers/applicationset_controller.go Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Vipin M S Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(appset): Add SCM Provider option for Gitlab generator to filter shared projects from subgroups projects (#14831) * added option to disable gitlab to fetch shared project from a subgroup Signed-off-by: Prune * Correct gitlab SCM provider mock test Signed-off-by: Prune * updated test to validate shared-groups Signed-off-by: Prune * reworked shared project tests Signed-off-by: Prune * added subgroups only test Signed-off-by: Prune --------- Signed-off-by: Prune Signed-off-by: Jimmy Neville * fix(cmp): send sigterm to cmp commands before sigkill to allow for potential cleanup (#9180) (#14955) * fix: send sigterm to cmp commands before sigkill to allow for potential cleanup Signed-off-by: Ashin Sabu * fix: unit test for runCommand in cmpserver to test cleanup modified Signed-off-by: Ashin Sabu * fix: change unit test for plugin/runCommand to avoid bad trap along with lint fix Signed-off-by: Ashin Sabu --------- Signed-off-by: Ashin Sabu Signed-off-by: Jimmy Neville * docs: Feature bounty proposal (Experimental) (#14234) * Create bounty proposal Signed-off-by: Dan Garfield * Update docs/proposals/feature-bounties.md Signed-off-by: Dan Garfield Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Dan Garfield * Update docs/proposals/feature-bounties.md Signed-off-by: Dan Garfield Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Dan Garfield * Update docs/proposals/feature-bounties.md Signed-off-by: Dan Garfield * Update docs/proposals/feature-bounties.md Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update docs/proposals/feature-bounties.md Signed-off-by: Dan Garfield Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Dan Garfield * Update docs/proposals/feature-bounties.md Signed-off-by: Dan Garfield * Update docs/proposals/feature-bounties.md Signed-off-by: Dan Garfield --------- Signed-off-by: Dan Garfield Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(actions): check if CronWorkflow has labels in create-workflow action (#14962) (#14974) Signed-off-by: Mickaël Canévet Signed-off-by: Jimmy Neville * chore: add Jellysmack in USERS.md (#14975) Signed-off-by: Mickaël Canévet Signed-off-by: Jimmy Neville * chore(deps): bump actions/setup-go from 4.0.1 to 4.1.0 (#14970) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4.0.1 to 4.1.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/fac708d6674e30b6ba41289acaab6d4b75aa0753...93397bea11091df50f3d7e59dc26a7711a8bcfbe) --- updated-dependencies: - dependency-name: actions/setup-go 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> Signed-off-by: Jimmy Neville * docs: Adding native OCI support proposal (#13516) Signed-off-by: Andrew Block Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: space in 'Argo CD' (#14987) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat: Add Support for AzureDevops Webhooks (#14969) * feat: Add Support for AzureDevops Webhooks Signed-off-by: Alexander Matyushentsev * document azure devops webhook configuration Signed-off-by: Alexander Matyushentsev --------- Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * fix: api server fails to call dex with istio (#14995) Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * fix(ui): Update default and max count for maxCookieNumber (#14979) * Update default and max count for maxCookieNumber Signed-off-by: zvlb Signed-off-by: Jimmy Neville * fix: correct the swagger ui link to support --rootpath (#14845) Signed-off-by: Kevin Yue Signed-off-by: Jimmy Neville * chore(deps): upgrade nhooyr.io/websocket dependency (#15000) Upgrade from 1.8.6 to 1.8.7 due to high security issue Was solved in dependency with https://github.com/nhooyr/websocket/pull/291 Signed-off-by: jmeridth Signed-off-by: Jimmy Neville * chore: upgrade to go 1.21 (#14992) Signed-off-by: Robin Lieb Signed-off-by: Jimmy Neville * chore(deps): bump goreleaser/goreleaser-action from 4.3.0 to 4.4.0 (#14996) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 4.3.0 to 4.4.0. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/336e29918d653399e599bfca99fadc1d7ffbc9f7...3fa32b8bb5620a2c1afe798654bbad59f9da4906) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-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> Signed-off-by: Jimmy Neville * fix: bump ubuntu base image (#15020) (#15021) Latest version of the ubuntu image addresses CVE-2023-38408. https://ubuntu.com/security/notices/USN-6242-1 https://github.com/docker-library/repo-info/blob/master/repos/ubuntu/remote/22.04.md resolves #15020 Signed-off-by: Mason Cole Signed-off-by: Jimmy Neville * chore: give context to errors (#10592) (#15022) * chore: give context to errors Signed-off-by: Vipin M S * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/tls/tls.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/settings/settings.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/tls/tls.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Update util/tls/tls.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> * Apply suggestions from code review Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Vipin M S Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: give context to errors (#15019) * chore: give context to error logs in reposerver Signed-off-by: Ashin Sabu * chore: give context to errors in applicationset Signed-off-by: Ashin Sabu * chore: give context to errors(tweaks in error messages) Signed-off-by: Ashin Sabu * chore: give context to errors(fix unit test) Signed-off-by: Ashin Sabu --------- Signed-off-by: Ashin Sabu Signed-off-by: Jimmy Neville * chore: add Carrefour Group to USERS.md (#15039) Signed-off-by: Zadkiel Aharonian Signed-off-by: Jimmy Neville * fix(health): spec.executor.instances is Optional, Support a flexible number of executors (#11877) Support a flexible number of executors. For example with a mounted ConfigMap inside the Spark-Operator. Signed-off-by: Philipp Dallig Signed-off-by: Jimmy Neville * [Bot] docs: Update Snyk reports (#15031) Signed-off-by: CI Co-authored-by: CI Signed-off-by: Jimmy Neville * fix(reposerver): loosen source not permitted helm errors (#14210) * fix: loosen source not permitted helm errors With #12255, we check if a source is first permitted before running `helm template`. This works a bit too well, since this may break previously working manifests. If an `AppProject` has a set of `sourceRepos` which are more restrictive than `*`, and it also has Helm public dependencies (repos with credentials would not work with 2.7x due to the fact they get filtered out before ending up on the repo server). Whereas before this would work, this currently fails on `HEAD` but not in `2.7x`. What we instead do here is that we only run this check if the chart failed to download - if it does then we run a check to see if the repo is in the allowed repos list. If the repo is not in the allowed repos list, we return the same error as in #12555, otherwise we bubble up the error. Should fix #13833. Signed-off-by: Blake Pettersson * fix: check for 401 unauthorized in error The regex check works fine for OCI artifacts, but the flow is slightly different for standard Helm charts (specifically when running `helm repo add`). To get around that, we also check the error for `401 Unauthorized`. Signed-off-by: Blake Pettersson * fix: loosen string check Signed-off-by: Blake Pettersson * Revert "chore: revert #12255 (#14858)" This reverts commit c8ae5bc3e79fa985632861f75669c07523f5ded6. Signed-off-by: Blake Pettersson * wip Signed-off-by: Blake Pettersson * wip Signed-off-by: Blake Pettersson * chore: reword test to reduce confusion Signed-off-by: Blake Pettersson --------- Signed-off-by: Blake Pettersson Signed-off-by: Jimmy Neville * fix(appset): Fix helm valuesObject with ApplicationSet (#14912) (#14920) Signed-off-by: Geoffrey Muselli Signed-off-by: Jimmy Neville * feat(cli): support apply out of sync flag only (#14624) * feat: support apply out of sync flag only Signed-off-by: pashakostohrys * update engine version Signed-off-by: pashakostohrys * update gitops engine version Signed-off-by: pashakostohrys * add cli option Signed-off-by: pashakostohrys * feat: verify apply out of sync flag Signed-off-by: pashakostohrys * redundant comment Signed-off-by: pashakostohrys * improve test logic Signed-off-by: pashakostohrys * change command description and do codegen Signed-off-by: pashakostohrys --------- Signed-off-by: pashakostohrys Signed-off-by: Jimmy Neville * docs(github): comment out notational pieces of PR template (#14888) - the DCO and FAQ sentences are not filled out during PRs and are purely notational - comment them out with HTML comments, as is common practice - example from argo-helm: https://github.com/argoproj/argo-helm/blob/962342fe2acef6022ac5c1a3eb352b336308b3eb/.github/pull_request_template.md?plain=1#L1 - copied this practice from other repos I maintain and from other repos before that - these comments are still visible to the PR author, just not visible when rendered, keeping the PR more concise Signed-off-by: Anton Gilgur Signed-off-by: Jimmy Neville * chore(deps): bump golangci/golangci-lint-action from 3.6.0 to 3.7.0 (#15053) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.6.0 to 3.7.0. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/639cd343e1d3b897ff35927a75193d57cfcba299...3a919529898de77ec3da873e3063ca4b10e7f5cc) --- updated-dependencies: - dependency-name: golangci/golangci-lint-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> Signed-off-by: Jimmy Neville * chore(deps): bump actions/setup-node from 3.7.0 to 3.8.0 (#15054) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.7.0 to 3.8.0. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/e33196f7422957bea03ed53f6fbb155025ffc7b8...bea5baf987ba7aa777a8a0b4ace377a21c45c381) --- updated-dependencies: - dependency-name: actions/setup-node 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> Signed-off-by: Jimmy Neville * docs: Update bank vaults link to point to the new org (#15069) Bank-Vaults recently migrated to a new organization. The old repository is archived. Signed-off-by: Anton Lindholm Signed-off-by: Jimmy Neville * chore: improve error logs (#10592) (#15059) * chore: improve error logs Signed-off-by: AvhiMaz * chore: Changes made according to the reviewer Signed-off-by: AvhiMaz * chore: Chnages according to the reviewerI" Signed-off-by: AvhiMaz * Update cmpserver/apiclient/plugin.pb.go Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: AvhiMaz Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * docs: Update link to KubeCon China 2021 talk in README.md (#14887) Signed-off-by: Yuan (Terry) Tang Signed-off-by: Jimmy Neville * docs: document permitOnlyProjectScopedClusters field (#15076) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * docs: kubectl to synchronize argocd apps (#14881) We can use kubectl to synchronize argocd applications the same way we can use the argocd cli or ui, however there's no documentation. This PR adds documentation for kubectl. Signed-off-by: Jordi Grant Esteve Signed-off-by: Jimmy Neville * docs: fix typo (#15083) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat: add timeout for update cluster info (#14511) * chore: simplified parsing of startup parameters Signed-off-by: yyzxw <1020938856@qq.com> * feat: add timeout for update cluster info Signed-off-by: yyzxw <1020938856@qq.com> --------- Signed-off-by: yyzxw <1020938856@qq.com> Signed-off-by: Jimmy Neville * fix: requeue ApplicationSet if there are validation errors (#14429) Signed-off-by: Chetan Banavikalmutt Signed-off-by: Jimmy Neville * docs: fix link for `argocd-repo-creds.yaml` sample (#15091) Signed-off-by: SHIMADA Kento Signed-off-by: Jimmy Neville * chore: wrap error objects to include context (#10592) (#15055) * chore: wrap error objects to include context (#10592) Signed-off-by: Pawank06 * chore: resolved common_test.go file as per reviewer's feedback Signed-off-by: Pawank06 * chore:changes in ulits.go Signed-off-by: Pawank06 * chore: resolving utils_test.go file Signed-off-by: Pawank06 --------- Signed-off-by: Pawank06 Signed-off-by: B Pawan Kumar Signed-off-by: Jimmy Neville * fix(#12862): Update FlinkDeployment health check to support Flink v1.x (#15065) Signed-off-by: Dylan Slavin Signed-off-by: Jimmy Neville * docs: add docs for various annotations and labels (#14020) * docs: add docs for various annotations Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * more info Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * more docs Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(appset): bitbucket server scm provider EOF on empty repo (#14411) * fix bitbucket server scm provider EOF on empty repo default branch check Signed-off-by: Jedrzej Kotkowski * add unit test for bitbucketServer empty repo Signed-off-by: Jedrzej Kotkowski * check for EOF explicitly Signed-off-by: Jedrzej Kotkowski --------- Signed-off-by: Jedrzej Kotkowski Signed-off-by: Jimmy Neville * chore: update confusing variable name (#15106) Signed-off-by: jmcshane Signed-off-by: Jimmy Neville * docs(progressive syncs): specify which ConfigMap to use (#15119) Signed-off-by: Gaël Jourdan-Weil Signed-off-by: Jimmy Neville * feat(appset): added topic filter for Gitlab SCM (#14965) * added topic (tag) filter for Gitlab SCM Signed-off-by: Prune * corrected few comments Signed-off-by: Prune * removed latest tag references Signed-off-by: Prune --------- Signed-off-by: Prune Signed-off-by: Jimmy Neville * chore: Add kustomization.yaml for server app RBAC (#15124) This change adds a `kustomization.yaml` file for the example RBAC role/rolebinding for argocd server applications. This makes it easier to include them as resources in another `kustomization.yaml`. Instead of including ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.0/examples/k8s-rbac/argocd-server-applications/argocd-server-rbac-clusterrole.yaml - https://raw.githubusercontent.com/argoproj/argo-cd/v2.8.0/examples/k8s-rbac/argocd-server-applications/argocd-server-rbac-clusterrolebinding.yaml ``` the user can now instead include ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - github.com/argoproj/argo-cd/examples/k8s-rbac/argocd-server-applications?ref=v2.8.0 ``` This change was performed by running: ```console kustomize create kustomize edit add resource argocd-server-rbac-clusterrole.yaml kustomize edit add resource argocd-server-rbac-clusterrolebinding.yaml ``` Signed-off-by: Andreas Lindhé Signed-off-by: Jimmy Neville * docs: ✏️ fix typo on configmap name for private certs (#9596) Signed-off-by: Gaël Jourdan-Weil Signed-off-by: Jimmy Neville * Merge pull request from GHSA-c8xw-vjgf-94hr Signed-off-by: pashakostohrys Signed-off-by: Jimmy Neville * fix(ui): code lint (#15150) Signed-off-by: ebuildy Signed-off-by: Jimmy Neville * fix: windows build (#15154) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat: run refresh from UI in parallel (#15138) Signed-off-by: Lukas Wöhrl Signed-off-by: Jimmy Neville * fix(cli): add support for components with non-default names (#10200) (#14605) * fix(cli): add support for components with non-default names (#10200) Co-Authored-By: maheshbaliga Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: maheshbaliga Signed-off-by: Jimmy Neville * fix: Updated docs about using a slash in ignoreDifferences (#15144) Signed-off-by: Christian Hernandez Signed-off-by: Jimmy Neville * fix: stop creating new otel interceptor to avoid memory leak (#15174) Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * chore: add example jq path expression (#15130) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * docs: document sourceNamespaces field (#15195) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(appset): Matrix Generator Override not Working for Booleans (#14498) (#14573) * Fix AppSet matrix generator parameter override Signed-off-by: Alexander Bellhäuser * Add test case for parameter override fix Signed-off-by: Alexander Bellhäuser --------- Signed-off-by: Alexander Bellhäuser Signed-off-by: Jimmy Neville * docs: remove unnecessary version number (#15198) We have versioned docs now, no need for this. Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ui): switch podgroup notification to tooltip message (#14821) * improve pod grouping ux Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> fix: update log view on container select Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * fix(ui): improve pod grouping ux Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * fix(ui):update the pod grouping messages to tooltip Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * fix(ui):update the pod grouping messages to tooltip Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * fix: GroupNodes notification Signed-off-by: AS <11219262+ashutosh16@users.noreply.github.com> * fix: GroupNodes notification Signed-off-by: AS <11219262+ashutosh16@users.noreply.github.com> --------- Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: AS <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: add upsider to USERS.md (#15228) Signed-off-by: Vlad Fratila Signed-off-by: Jimmy Neville * docs: clarify argocd-repo-server repo-cache-expiration HA use case (#15239) Signed-off-by: phanama Signed-off-by: Jimmy Neville * chore: better logs for jq expression errors (#15226) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ui): Helm chart empty maintainers blow up Argo UI (#15225) Signed-off-by: Carlos Castro carlos.castro@jumo.world Signed-off-by: Carlos Castro carlos.castro@jumo.world Signed-off-by: Carlos Castro Signed-off-by: Jimmy Neville * chore: add Kvist to USERS.md (#15240) Signed-off-by: Fredrik A. Madsen-Malmo Signed-off-by: Jimmy Neville * docs: improve doc on labels parameter on scmProvider generator (#15255) Signed-off-by: Jedrzej Kotkowski Signed-off-by: Jimmy Neville * docs: Update ApplicationSet docs (#15269) Signed-off-by: David Muckle Signed-off-by: Jimmy Neville * feat: support extra attributes for opentelemetry (#15071) Signed-off-by: penglongli Signed-off-by: Jimmy Neville * docs: Add Twilio Segment to USERS.md (#15267) Thank you to the Argo community! Signed-off-by: Prasad Katti Co-authored-by: jannfis Signed-off-by: Jimmy Neville * fix: make WatchResourceTree use namespaced cache key (#15258) * fix: make WatchResourceTree use namespaced application cache key Signed-off-by: Torbjørn Fjørtoft * chore: add PGS to USERS.md Signed-off-by: Torbjørn Fjørtoft --------- Signed-off-by: Torbjørn Fjørtoft Signed-off-by: Jimmy Neville * chore: remove duplicate function (#15123) Signed-off-by: yyzxw <1020938856@qq.com> Signed-off-by: Jimmy Neville * fix: Cache control 404 asset requests (#15327) * backfill cache control header tests for ui assets Signed-off-by: Scott Windsor * Set cache-control header non-cache for assets not found Signed-off-by: Scott Windsor * fix golang-cilint warning Signed-off-by: Scott Windsor --------- Signed-off-by: Scott Windsor Signed-off-by: Jimmy Neville * docs: Fixes a markdown typo in USERS.md (#15362) This removes the whitespace between the link text and the link URL. Signed-off-by: Prasad Katti Signed-off-by: Jimmy Neville * feat: upgrade notification engine (#15359) * Update notifications-engine dependencies Signed-off-by: Mike Splain * Update docs Signed-off-by: Mike Splain --------- Signed-off-by: Mike Splain Co-authored-by: pasha-codefresh Signed-off-by: Jimmy Neville * feat: add Dott to users (#15370) Signed-off-by: Jake Burn Signed-off-by: Jimmy Neville * fix(notifications-catalog): Add nil check for on-deployed trigger (#15363) Signed-off-by: Fs02 Co-authored-by: pasha-codefresh Signed-off-by: Jimmy Neville * feat: auto respect rbac for discovery/sync (#14381) feat: auto respect rbac for discovery/sync (#14381) Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: Jimmy Neville * feat: Add ARGOCD_CLUSTER_CACHE_LIST_PAGE_BUFFER_SIZE environment variable (#15159) Signed-off-by: Brad West Signed-off-by: Jimmy Neville * fix(appset): Revert applicationset-name labels (#15324) * fix(15282) Revert applicationset-name labels Signed-off-by: gmuselli * fix(15282) fix unit test Signed-off-by: gmuselli --------- Signed-off-by: gmuselli Signed-off-by: Jimmy Neville * chore(deps): bump library/golang from 1.21.0 to 1.21.1 (#15391) Bumps library/golang from 1.21.0 to 1.21.1. --- updated-dependencies: - dependency-name: library/golang 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/golang from 1.21.0 to 1.21.1 in /test/remote (#15387) Bumps library/golang from 1.21.0 to 1.21.1. --- updated-dependencies: - dependency-name: library/golang 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.4.0 to 20.6.0 in /test/container (#15366) Bumps library/node from 20.4.0 to 20.6.0. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * Merge pull request from GHSA-g687-f2gx-6wm8 * feat: use untar with limiter Signed-off-by: pashakostohrys * feat: use untar with limiter Signed-off-by: pashakostohrys --------- Signed-off-by: pashakostohrys Signed-off-by: Jimmy Neville * Merge pull request from GHSA-fwr2-64vr-xv9m * fix: prevent seeing/editing 'kubectl.kubernetes.io/last-applied-configuration' cluster annotation Signed-off-by: Alexander Matyushentsev * fix: failing unit test Signed-off-by: iam-veeramalla --------- Signed-off-by: Alexander Matyushentsev Signed-off-by: iam-veeramalla Co-authored-by: iam-veeramalla Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.5.0 to 20.6.0 in /ui-test (#15364) Bumps library/node from 20.5.0 to 20.6.0. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * fix: handle annotations for resources with ':' in the name (#15101) (#15380) * fix: handle annotations for resources with ':' in the name Signed-off-by: Oreon Lothamer * fix: switch to using splitN for handling annotation splitting Signed-off-by: Oreon Lothamer * fix: check len(parts) !=3 Signed-off-by: Oreon Lothamer * Retrigger CI pipeline Signed-off-by: Oreon Lothamer --------- Signed-off-by: Oreon Lothamer Signed-off-by: Jimmy Neville * docs: Improve RBAC documentation (#15430) * Improve staging-db project name This change renames the project to distinguish it from the role. Signed-off-by: Andreas Lindhé * Rename db-staging role to singular form Role names should be singular ("User x has the role admin" as opposed to "User x has the role admins"). Signed-off-by: Andreas Lindhé * Remove trailing newlines Signed-off-by: Andreas Lindhé * Consistently mark `AppProject` as code Signed-off-by: Andreas Lindhé * Replace ```shell with ```console in suitable places Signed-off-by: Andreas Lindhé * Use consistent style for unordered list https://github.com/DavidAnson/markdownlint/blob/main/doc/md004.md Signed-off-by: Andreas Lindhé * Use consistent emphasis style https://github.com/DavidAnson/markdownlint/blob/main/doc/md049.md Signed-off-by: Andreas Lindhé * Fix incorrect description of the staging-db example Signed-off-by: Andreas Lindhé --------- Signed-off-by: Andreas Lindhé Signed-off-by: Jimmy Neville * fix(appsets): gotemplate can cause panic from nil dereference (#15377) (#15378) * fix(appsets): gotemplate can cause panic from nil deference Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com> * fix(appsets): gotemplate can cause panic from nil dereference Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com> --------- Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore: Fix flaky cluster test (#15433) Signed-off-by: Jimmy Neville * Fix requeue after for Matrix/Merge with SCM or ClusterDecision generators (#15407) Signed-off-by: Cezar Sa Espinola Signed-off-by: Jimmy Neville * feat: added shorthand flags for follow and conatainre in app logs (#15400) * feat: added shorthand flags for follow and conatainre in app logs Signed-off-by: ashu * doc: re-generated cli docs Signed-off-by: ashu --------- Signed-off-by: ashu Co-authored-by: jannfis Signed-off-by: Jimmy Neville * [Bot] docs: Update Snyk reports (#15437) Signed-off-by: CI Co-authored-by: CI Co-authored-by: jannfis Signed-off-by: Jimmy Neville * fix: Better enforcement of application namespace restrictions (#15431) * fix: Better enforce application namespace restrictions Signed-off-by: jannfis * Only call ValidateDestination when allowed Signed-off-by: jannfis --------- Signed-off-by: jannfis Signed-off-by: Jimmy Neville * docs: fix bullets (#15446) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix: failed to add cluster when the cluster server address is ipv6 (#8204) (#15350) * fix: failed to add cluster when the cluster server address is ipv6 (#8204) Signed-off-by: huyinhou * fix: failed to add cluster when the cluster server address is ipv6 (#8204) Signed-off-by: huyinhou * remove unused import Signed-off-by: huyinhou * fix: lowercase URI secret name; abbreviated IPv6 address Signed-off-by: huyinhou --------- Signed-off-by: huyinhou Signed-off-by: Jimmy Neville * feat: Enable haproxy metrics through helm Chart (#15459) Signed-off-by: Mathias Petermann Signed-off-by: Jimmy Neville * Stop appending :443 to the server address when using grpc-web (#15435) Signed-off-by: David Marby Co-authored-by: jannfis Signed-off-by: Jimmy Neville * feat: appset preserve labels and global preserve fields (#15445) * feat: appset preserve labels and global preserve fields Signed-off-by: Soumya Ghosh Dastidar * feat: appset preserve labels and global preserve fields Signed-off-by: Soumya Ghosh Dastidar * docs: updated docs Signed-off-by: Soumya Ghosh Dastidar * docs: updated docs Signed-off-by: Soumya Ghosh Dastidar --------- Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: Jimmy Neville * fix: Gitlab scm_provider - don't create transport from scratch (#15424) (#15425) * fix : don't create transport from scratch, clone it instead Signed-off-by: Antoine Jouve * feat: clone http.transport for gitea and gitlab providers Signed-off-by: Antoine Jouve * chore: properly format gitea providers with gofmt Signed-off-by: Antoine Jouve --------- Signed-off-by: Antoine Jouve Signed-off-by: Jimmy Neville * chore: add Factorial to USERS.md (#15473) Signed-off-by: Alejandro López Sánchez Signed-off-by: Jimmy Neville * Fix incorrect wording in ApplicationSet git generator docs (#15374) Signed-off-by: Liam Wyllie Signed-off-by: Jimmy Neville * fix: Allow retrieving badges in other namespaces (#15468) Signed-off-by: jannfis Signed-off-by: Jimmy Neville * chore(deps): bump docker/setup-buildx-action from 2.9.1 to 3.0.0 (#15476) Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2.9.1 to 3.0.0. - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/4c0219f9ac95b02789c1075625400b2acbff50b1...f95db51fddba0c2d1ec667646a06c2ce06100226) --- updated-dependencies: - dependency-name: docker/setup-buildx-action 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.6.0 to 20.6.1 in /test/container (#15451) Bumps library/node from 20.6.0 to 20.6.1. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.6.0 to 20.6.1 in /ui-test (#15452) Bumps library/node from 20.6.0 to 20.6.1. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * chore(deps): bump gitpod/workspace-full from `d578722` to `511cecd` (#15453) Bumps gitpod/workspace-full from `d578722` to `511cecd`. --- updated-dependencies: - dependency-name: gitpod/workspace-full dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump argo-ui from `13cea62` to `002d01b` in /ui (#15440) Bumps [argo-ui](https://github.com/argoproj/argo-ui) from `13cea62` to `002d01b`. - [Release notes](https://github.com/argoproj/argo-ui/releases) - [Commits](https://github.com/argoproj/argo-ui/compare/13cea62a4a0e4a14a2dd6908490e1e907709aa86...002d01b18e8aaf4b21307a3b87341ab05230483f) --- updated-dependencies: - dependency-name: argo-ui dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump library/golang in /test/remote (#15419) Bumps library/golang from `970907c` to `62e5883`. --- updated-dependencies: - dependency-name: library/golang 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/golang from `970907c` to `62e5883` (#15415) Bumps library/golang from `970907c` to `62e5883`. --- updated-dependencies: - dependency-name: library/golang 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> Signed-off-by: Jimmy Neville * fix(controller): make managed namespaces more 'prune-proof' (#13999) * fix: make managed namespaces more 'prune-proof' In the cases where someone would want to set resource tracking on a managed namespace, or if someone would want to migrate from having a namespace in Git to using `managedNamespaceMetadata`, we need to take steps to ensure that the namespace does not get pruned. In order to do that, we add the live namespace to the list of `targetObjs` (so that it's considered a part of the source even though it's not). Finally, we need to also ensure that the managed namespace is not considered `OutOfSync` (due to the same reason as above). This is a subset of #11350, the main difference being that this commit does not set resource tracking on its own, but can be opted into if people choose to do so. Signed-off-by: Blake Pettersson * refactor: extract managed namespace check Signed-off-by: Blake Pettersson --------- Signed-off-by: Blake Pettersson Signed-off-by: Jimmy Neville * fix: extends CR to allow cronjob/workflow triggers (#15300) Signed-off-by: Marcelo Moreira de Mello Co-authored-by: Nicholas Morey Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.5.0 to 20.6.1 (#15454) Bumps library/node from 20.5.0 to 20.6.1. --- updated-dependencies: - dependency-name: library/node 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> Co-authored-by: jannfis Signed-off-by: Jimmy Neville * chore(deps): bump github.com/cyphar/filepath-securejoin (#15401) Bumps [github.com/cyphar/filepath-securejoin](https://github.com/cyphar/filepath-securejoin) from 0.2.3 to 0.2.4. - [Release notes](https://github.com/cyphar/filepath-securejoin/releases) - [Commits](https://github.com/cyphar/filepath-securejoin/compare/v0.2.3...v0.2.4) --- updated-dependencies: - dependency-name: github.com/cyphar/filepath-securejoin dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Jimmy Neville * (docs) Add clarification on migration for CMP plugins (#15405) * Add clarification on migration for CMP plugins Signed-off-by: Dan Garfield * Fix table Signed-off-by: Dan Garfield * Add warning on blank manifests for #15340 Signed-off-by: Dan Garfield --------- Signed-off-by: Dan Garfield Signed-off-by: Jimmy Neville * chore(deps): bump sigstore/cosign-installer from 3.1.1 to 3.1.2 (#15330) Bumps [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/sigstore/cosign-installer/releases) - [Commits](https://github.com/sigstore/cosign-installer/compare/6e04d228eb30da1757ee4e1dd75a0ec73a653e06...11086d25041f77fe8fe7b9ea4e48e3b9192b8f19) --- updated-dependencies: - dependency-name: sigstore/cosign-installer 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> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/xanzy/go-gitlab from 0.89.0 to 0.91.1 (#15331) Bumps [github.com/xanzy/go-gitlab](https://github.com/xanzy/go-gitlab) from 0.89.0 to 0.91.1. - [Changelog](https://github.com/xanzy/go-gitlab/blob/master/releases_test.go) - [Commits](https://github.com/xanzy/go-gitlab/compare/v0.89.0...v0.91.1) --- updated-dependencies: - dependency-name: github.com/xanzy/go-gitlab 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> Signed-off-by: Jimmy Neville * docs: Add KPMG to users (#15323) Signed-off-by: Ansuman Swain Co-authored-by: jannfis Signed-off-by: Jimmy Neville * Fix broken links for post selectors, fix ordering of args for dig example (#15346) Signed-off-by: David Muckle Signed-off-by: Jimmy Neville * chore(deps): bump library/golang in /test/container (#15502) Bumps library/golang from 1.21.0 to 1.21.1. --- updated-dependencies: - dependency-name: library/golang 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> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/casbin/casbin/v2 from 2.73.0 to 2.77.2 (#15501) Bumps [github.com/casbin/casbin/v2](https://github.com/casbin/casbin) from 2.73.0 to 2.77.2. - [Release notes](https://github.com/casbin/casbin/releases) - [Changelog](https://github.com/casbin/casbin/blob/master/.releaserc.json) - [Commits](https://github.com/casbin/casbin/compare/v2.73.0...v2.77.2) --- updated-dependencies: - dependency-name: github.com/casbin/casbin/v2 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> Signed-off-by: Jimmy Neville * chore(deps): bump actions/upload-artifact from 3.1.2 to 3.1.3 (#15497) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/0b7f8abb1508181956e8e162db84b466c27e18ce...a8a3f3ad30e3422c9c7b888a15615d19a852ae32) --- updated-dependencies: - dependency-name: actions/upload-artifact 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> Co-authored-by: jannfis Signed-off-by: Jimmy Neville * fix(cli): fix header in resource-overrides list-actions output (#15375) Signed-off-by: Maxime Brunet Signed-off-by: Jimmy Neville * chore: adding tests for apiclient package: clientset tests (#15193) Signed-off-by: zhaque44 Signed-off-by: Jimmy Neville * fix: Applicationset upsert for any namespaces (#15520) * fix: Applicationset upsert for any namespaces PR implements a small change to the argocd command adding the AppsetNamespace for the existing Appset check. Signed-off-by: Harm Matthias Harms * Retrigger CI pipeline Signed-off-by: Harm Matthias Harms * Retrigger CI pipeline Signed-off-by: Harm Matthias Harms --------- Signed-off-by: Harm Matthias Harms Signed-off-by: Jimmy Neville * chore: update ordering of support steps (#15508) Signed-off-by: Kurt King Signed-off-by: Jimmy Neville * feat: add option in output flag for app get and app resources cli command for tree view(#13370) (#15386) * tree view feature for app get cli comand Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * including application details Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * testcase included for printTreeView Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * removed the unnecessary variables Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * Adding changes to the documentation Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * change in the argocd doc Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * included tee_test.go Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * tree view changes for app get and app resources Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * go.mod and go.sum by running go mod tidy Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * changes after review Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * changes after review Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> --------- Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/go-playground/webhooks/v6 (#15516) Bumps [github.com/go-playground/webhooks/v6](https://github.com/go-playground/webhooks) from 6.2.1-0.20230808162451-10570b0a59e8 to 6.3.0. - [Release notes](https://github.com/go-playground/webhooks/releases) - [Commits](https://github.com/go-playground/webhooks/commits/v6.3.0) --- updated-dependencies: - dependency-name: github.com/go-playground/webhooks/v6 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> Signed-off-by: Jimmy Neville * fix: ApplicationSet deletes Application status (#15514) * fix: ApplicationSet deletes Application status Signed-off-by: Alexander Matyushentsev * apply reviewer notes Signed-off-by: Alexander Matyushentsev --------- Signed-off-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * docs: Update Application Set Webhook Instructions (#13764, #11532) (#15527) * Update Generators-Pull-Request.md Add note to clarify that the ApplicationSet controller requires its own Ingress resource. This seems to be a common issue for Argo CD users. Signed-off-by: Kurt Madel * Update Generators-Git.md Updating note to match webhook note on pr generator. Signed-off-by: Kurt Madel --------- Signed-off-by: Kurt Madel Signed-off-by: Jimmy Neville * chore: Add 4data to users (#15531) Signed-off-by: LStuker Signed-off-by: Jimmy Neville * docs: fix kubectl apply in apps-in-any-namespace doc (#15197) There's a kustomization.yaml file in that directory, so we should apply it with `-k`. Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * docs: Fix docs for destinations in AppProjects (#15153) (#15182) Signed-off-by: Andreas Lindhé Signed-off-by: Jimmy Neville * chore(deps): bump github.com/ktrysmt/go-bitbucket from 0.9.63 to 0.9.67 (#15500) Bumps [github.com/ktrysmt/go-bitbucket](https://github.com/ktrysmt/go-bitbucket) from 0.9.63 to 0.9.67. - [Release notes](https://github.com/ktrysmt/go-bitbucket/releases) - [Commits](https://github.com/ktrysmt/go-bitbucket/compare/v0.9.63...v0.9.67) --- updated-dependencies: - dependency-name: github.com/ktrysmt/go-bitbucket 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> Co-authored-by: jannfis Signed-off-by: Jimmy Neville * chore(deps): bump goreleaser/goreleaser-action from 4.4.0 to 5.0.0 (#15496) Bumps [goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action) from 4.4.0 to 5.0.0. - [Release notes](https://github.com/goreleaser/goreleaser-action/releases) - [Commits](https://github.com/goreleaser/goreleaser-action/compare/3fa32b8bb5620a2c1afe798654bbad59f9da4906...7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8) --- updated-dependencies: - dependency-name: goreleaser/goreleaser-action 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> Signed-off-by: Jimmy Neville * [Bot] docs: Update Snyk reports (#15532) Signed-off-by: CI Co-authored-by: CI Signed-off-by: Jimmy Neville * chore(deps): bump actions/checkout from 3.5.3 to 4.0.0 (#15348) * chore(deps): bump actions/checkout from 3.5.3 to 4.0.0 Bumps [actions/checkout](https://github.com/actions/checkout) from 3.5.3 to 4.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/c85c95e3d7251135ab7dc9ce3241c5835cc595a9...3df4ab11eba7bda6032a0b82a6bb43b11571feac) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Apply suggestions from code review Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: dependabot[bot] Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(ui): Add button for wrapping lines in pod logs viewer (#15506) * Add back wrap log line button Signed-off-by: Yi Cai * Fixed lint issue Signed-off-by: Yi Cai * Updated icon and location of Wrap Lines btn Signed-off-by: Yi Cai * Fixed lint issue Signed-off-by: Yi Cai * Put back pre tag and Ansi component Signed-off-by: Yi Cai --------- Signed-off-by: Yi Cai Signed-off-by: Jimmy Neville * chore: add CODEOWNERS (#14693) * chore: add CODEOWNERS Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * new owners Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * use teams Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * restore old owners file Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix: reflect expected integers in swagger doc (#13046) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump oras.land/oras-go/v2 from 2.2.1 to 2.3.0 (#15549) Bumps [oras.land/oras-go/v2](https://github.com/oras-project/oras-go) from 2.2.1 to 2.3.0. - [Release notes](https://github.com/oras-project/oras-go/releases) - [Commits](https://github.com/oras-project/oras-go/compare/v2.2.1...v2.3.0) --- updated-dependencies: - dependency-name: oras.land/oras-go/v2 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> Signed-off-by: Jimmy Neville * chore(deps): bump github.com/antonmedv/expr from 1.12.7 to 1.15.2 (#15548) Bumps [github.com/antonmedv/expr](https://github.com/antonmedv/expr) from 1.12.7 to 1.15.2. - [Release notes](https://github.com/antonmedv/expr/releases) - [Commits](https://github.com/antonmedv/expr/compare/v1.12.7...v1.15.2) --- updated-dependencies: - dependency-name: github.com/antonmedv/expr 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> Signed-off-by: Jimmy Neville * fix(repo-server): avoid fetching commit sha for multisource applications (#15037) (#15067) * Rebase Signed-off-by: ozlevka-work Signed-off-by: Lev * Remove test file Signed-off-by: ozlevka-work Signed-off-by: Lev * Go linter fmt Signed-off-by: ozlevka-work Signed-off-by: Lev * Additional linter fmt Signed-off-by: ozlevka-work Signed-off-by: Lev Signed-off-by: Lev * Add unit test for changes Signed-off-by: Lev Signed-off-by: Lev * Update reposerver/repository/repository.go Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Lev Ozeryansky Signed-off-by: Lev * Trigger CI Signed-off-by: Lev --------- Signed-off-by: Lev Signed-off-by: Lev Signed-off-by: Lev Ozeryansky Co-authored-by: Lev Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * doc: adds vals-operator to secrets list (#11795) Vals-Operator can also be used for managing secrets in Kubernetes. Signed-off-by: Sergio Rua <58211930+digiserg@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump actions/cache from 3.3.1 to 3.3.2 (#15552) Bumps [actions/cache](https://github.com/actions/cache) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8...704facf57e6136b1bc63b828d79edcd491f0ee84) --- updated-dependencies: - dependency-name: actions/cache 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> Co-authored-by: jannfis Signed-off-by: Jimmy Neville * docs: better command reference titles (#15567) (#15568) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.6.1 to 20.7.0 in /ui-test (#15583) Bumps library/node from 20.6.1 to 20.7.0. --- updated-dependencies: - dependency-name: library/node 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> Signed-off-by: Jimmy Neville * chore(deps): bump library/node from 20.6.1 to 20.7.0 in /test/container (#15585) Bumps library/node from 20.6.1 to 20.7.0. --- updated-dependencies: - dependency-name: library/node 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> Co-authored-by: pasha-codefresh Signed-off-by: Jimmy Neville * docs: Add documentation on how to specify shard number for a cluster in "high availibility" doc (#5348) (#13258) Signed-off-by: Sridhar Nandigam Signed-off-by: Jimmy Neville * docs: 'action' RBAC example for Kind without group (#15589) Signed-off-by: Jimmy Neville * chore: add gdsoumya to reviewers (#15596) Signed-off-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat: added patch_ms and setop_ms timings to reconciliation logs (#15595) * feat: added patch_ms to reconciliation logs Signed-off-by: Soumya Ghosh Dastidar * feat: added patch_ms and setop_ms timings to logs Signed-off-by: Soumya Ghosh Dastidar --------- Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: Jimmy Neville * chore(action): minor lua changes (#15580) * chore(action): add newlines at eof Signed-off-by: Josh Soref * chore(action): fix whitespace indentation Signed-off-by: Josh Soref * chore(action): use local annotations Signed-off-by: Josh Soref --------- Signed-off-by: Josh Soref Signed-off-by: Jimmy Neville * chore(deps): bump library/golang from `cffaba7` to `2270a40` (#15615) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(extensions): Automatically apply extension configs without restarting API-Server (#15574) * feat: auto configure extensions Signed-off-by: Leonardo Luz Almeida * feat: auto-reload extension configs without restarting api-server Signed-off-by: Leonardo Luz Almeida * clean unused gorilla mux Signed-off-by: Leonardo Luz Almeida * update docs Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida * Add more test cases Signed-off-by: Leonardo Luz Almeida * refactoring to reduce unnecessary function Signed-off-by: Leonardo Luz Almeida * Add log Signed-off-by: Leonardo Luz Almeida * fix bugs found during manual tests Signed-off-by: Leonardo Luz Almeida --------- Signed-off-by: Leonardo Luz Almeida Signed-off-by: Jimmy Neville * Update the supported version policy in Operator Manual Installation doc (#15619) The supported version policy mentioned in the operator manual installation document diverges from the official policy that is mentioned in the security policy and the release cadence. This change brings the version policy in line by referring the readers to the release and cadence documentation to check the specified policy. Signed-off-by: Muhammad Mooneeb Hussain Signed-off-by: Jimmy Neville * doc: resource tracking custom label configuration (#15587) Signed-off-by: Timoses Signed-off-by: Jimmy Neville * feat(cli): tree option in output flag for app sync, app wait and app rollback for tree view (#15572) * app sync and app wait tree view changes Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * documentation changes Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * included the json,yaml and wide formats and removed the value assignment to the flag Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * Reoved extra spaces Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * removed extra spaces Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * refactored the code Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> * better log statements Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> --------- Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat: dynamic rebalancing of clusters across shards (#15036) * Migrate Application Controller from Statefulset to Deployment Signed-off-by: ishitasequeira * Add sharding deployment logic Signed-off-by: ishitasequeira * Update sharding logic and add comments Signed-off-by: ishitasequeira * Add heartbeat as an environment variable Signed-off-by: ishitasequeira * Add retry logic, heartbeat timeout environment variable Signed-off-by: ishitasequeira * use the logic of pre-specified shard number on application controller pod Signed-off-by: ishitasequeira * fix manifests Signed-off-by: ishitasequeira * fix lint and e2e tests Signed-off-by: ishitasequeira * comment out failing e2e test Signed-off-by: ishitasequeira * increase readiness probe interval period Signed-off-by: ishitasequeira * "comment out readiness probe to see if e2e tests succeed" Signed-off-by: ishitasequeira * revert commented readiness probe Signed-off-by: ishitasequeira * revert commented test case Signed-off-by: ishitasequeira * read environment variable for application controller deployment name Signed-off-by: ishitasequeira * Add nil check on replica count for deployment of application controller Signed-off-by: ishitasequeira * Address comments Signed-off-by: ishitasequeira * Add Informer, Update documentation, add unit tests Signed-off-by: ishitasequeira * update godoc Signed-off-by: ishitasequeira * remove unwanted code and logs Signed-off-by: ishitasequeira * Add more documentation Signed-off-by: ishitasequeira * revert ApplicationController manifest to StatefulSet Signed-off-by: ishitasequeira * reverting updated docs Signed-off-by: ishitasequeira * Add documentation for the new dynamic distribution feature Signed-off-by: ishitasequeira * update documentation Signed-off-by: ishitasequeira * Add an overlay for application controller deployment and update documentation Signed-off-by: ishitasequeira * fix nit Signed-off-by: ishitasequeira * Marking the feature as alpha Signed-off-by: ishitasequeira * Add feature status link Signed-off-by: ishitasequeira * revert go,mod changes Signed-off-by: ishitasequeira * update docs to avoid focusing on StatefulSet/Deployment (#26) * update docs to avoid focusing on StatefulSet/Deployment Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * minor update to the doc Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump node version (#15616) * chore(deps): bump node version Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix version Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * update lockfile Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(appset): add Support for AzureDevops Webhooks (#15047) Signed-off-by: Robin Lieb Signed-off-by: Jimmy Neville * fix(cli): get latest app state before printing tree (#15639) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(deps): bump actions/setup-node from 3.8.0 to 3.8.1 (#15108) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3.8.0 to 3.8.1. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/bea5baf987ba7aa777a8a0b4ace377a21c45c381...5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d) --- updated-dependencies: - dependency-name: actions/setup-node 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> Co-authored-by: Justin Marquis <76892343+34fathombelow@users.noreply.github.com> Co-authored-by: pasha-codefresh Signed-off-by: Jimmy Neville * feat(kustomize): add patches field (#5114) (#14648) Signed-off-by: Jimmy Neville * feat(health): Implement AnsibleJob CRD health checks (#14483) Signed-off-by: Mike Ng Signed-off-by: Jimmy Neville * feat(health): add PushSecret health status and force-sync action (#14375) * feat(health): add `PushSecret` health status Signed-off-by: Alexandre Gaudreault * add status healthy Signed-off-by: Alexandre Gaudreault * Push action Signed-off-by: Alexandre Gaudreault * fix test Signed-off-by: Alexandre Gaudreault --------- Signed-off-by: Alexandre Gaudreault Signed-off-by: Jimmy Neville * fix(kustomize): no concurrent processing if Kustomize patches are used (#15654) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * feat(appset): ignoreApplicationDifferences (#9101) (#14743) * feat(appset): ignoreDifferences (#9101) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * better error messages Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * do better Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * docs Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * more tests, update docs Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * e2e test Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * expect auto-added fields Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * correct label Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * better Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * remove line that was reverted Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update docs/operator-manual/applicationset.yaml Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * remove line that mysteriously causes applicationset/utils unit tests to fail Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * login to fix test Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * maybe this will work, who knows Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * burn it all down Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * works on my machine Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(applicationset): cannot validate inherited project permissions (#9298) (#15026) * fix(applicationset): cannot validate inherited project permissions Signed-off-by: Alexandre Gaudreault * update tests to reflect behavior Signed-off-by: Alexandre Gaudreault --------- Signed-off-by: Alexandre Gaudreault Signed-off-by: Jimmy Neville * chore(deps): bump semver from 5.7.1 to 5.7.2 in /ui-test (#14457) Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Signed-off-by: Jimmy Neville * chore(ci): free up disk space (#15674) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix: add a not found check for application controller deployment (#15678) Signed-off-by: ishitasequeira Signed-off-by: Jimmy Neville * [fix] sidebar style (#15652) Signed-off-by: ymktmk Co-authored-by: Blake Pettersson Signed-off-by: Jimmy Neville * fix(ci): free up disk space (#15683) * fix(ci): free up disk space Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update .github/workflows/image-reuse.yaml Co-authored-by: Justin Marquis <76892343+34fathombelow@users.noreply.github.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * Update .github/workflows/image-reuse.yaml Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Justin Marquis <76892343+34fathombelow@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ci): do not fail fast on e2e test failures (#15694) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(ci): misplaced config option (#15698) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Jimmy Neville * fix(applicationset): git generator ignores empty files (#15661) Signed-off-by: Alexandre Gaudreault Signed-off-by: Jimmy Neville * fix(appset): don't emit k8s events for unchanged apps, log at debug (#15659) (#15660) * fix(appset): don't emit k8s events for unchanged application events and move that scenario to debug logging level Signed-off-by: Eric Blackburn * Retrigger CI pipeline Signed-off-by: Eric Blackburn * Retrigger CI pipeline Signed-off-by: Eric Blackburn --------- Signed-off-by: Eric Blackburn Co-authored-by: Alexander Matyushentsev Signed-off-by: Jimmy Neville * feat(ci): retry individual e2e tests (#15696) Signed-off-by: Jimmy Neville * docs: Maintaining Uniformity In Documentation Writing Style (#15713) In the Projects section there are two words 'what' and 'where' are written in italic(in the first two sentences) but in the third sentence 'what' is written in normal text. So i changed the two words written in italic to normal text to maintain the uniformity of writing style of documentation. See this issue in the Projects section : "https://argo-cd.readthedocs.io/en/stable/user-guide/projects/" Signed-off-by: PranitRout07 <102309095+PranitRout07@users.noreply.github.com> Signed-off-by: Jimmy Neville * docs: add dynamic cluster distribution doc in the menu (#15716) Signed-off-by: Jimmy Neville * Converted italic text to normal text (#15692) To see the issue , go to this link "https://argo-cd.readthedocs.io/en/stable/operator-manual/app-any-namespace/" In Prerequisites section ,the word 'not' is unnecessarily written in italic. It should be written in normal text to maintain the uniformity. Signed-off-by: PranitRout07 <102309095+PranitRout07@users.noreply.github.com> Co-authored-by: Dan Garfield Signed-off-by: Jimmy Neville * fix(action): populate all fields of Job from CronJob (#15259) (#15727) Signed-off-by: sergey.ladutko Co-authored-by: sergey.ladutko Signed-off-by: Jimmy Neville * fix(application-controller): Fix panic error when trying to scale application controller shards (#15725) * Added error checking to determine if application controller deployment is found or not Signed-off-by: Anand Francis Joseph * Fixed the informer to list deployments in namespace scope Signed-off-by: Anand Francis Joseph * Fixed readiness check probe for application controller when running as deployment Signed-off-by: Anand Francis Joseph --------- Signed-off-by: Anand Francis Joseph Signed-off-by: Jimmy Neville * docs: move self-signed certs gitlab scm docs (#15720) Signed-off-by: Jimmy Neville * fix: only enable dynamic cluster sharding feature explicitly (#15734) * fix: only enable dynamic cluster sharding feature explicitly Signed-off-by: Remington Breeze --------- Signed-off-by: Remington Breeze Signed-off-by: Jimmy Neville * Fixed Custom Link Text not Hyperlinked (#15747) Visit this link to see the issue : https://argo-cd.readthedocs.io/en/stable/developer-guide/ci/#public-cd Signed-off-by: PranitRout07 <102309095+PranitRout07@users.noreply.github.com> Signed-off-by: Jimmy Neville * Update docs Signed-off-by: Jimmy Neville --------- Signed-off-by: schakrad <58915923+schakrad@users.noreply.github.com> Signed-off-by: Jimmy Neville Signed-off-by: dependabot[bot] Signed-off-by: Nikolas Skoufis Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: daftping <21245083+daftping@users.noreply.github.com> Signed-off-by: Yuan Tang Signed-off-by: Yi Cai Signed-off-by: Gerardo Corea Signed-off-by: mmerrill3 Signed-off-by: Alexandre Gaudreault Signed-off-by: Zechun Chen Signed-off-by: ylxianzhe Signed-off-by: gmuselli Signed-off-by: Geoffrey Muselli Signed-off-by: Blake Pettersson Signed-off-by: Alexander Matyushentsev Signed-off-by: felix Signed-off-by: CI Signed-off-by: Dylan Page Signed-off-by: Jonathan West Signed-off-by: Kostis Kapelonis Signed-off-by: Nathan Romriell Signed-off-by: Alex Collins Signed-off-by: Trung Signed-off-by: JesseBot Signed-off-by: Leonardo Luz Almeida Signed-off-by: Nicholas Morey Signed-off-by: ashinsabu3 Signed-off-by: Talia Stocks <928827+taliastocks@users.noreply.github.com> Signed-off-by: xashr Signed-off-by: German Lashevich Signed-off-by: Vipin M S Signed-off-by: Prune Signed-off-by: Ashin Sabu Signed-off-by: Dan Garfield Signed-off-by: Mickaël Canévet Signed-off-by: Andrew Block Signed-off-by: zvlb Signed-off-by: Kevin Yue Signed-off-by: jmeridth Signed-off-by: Robin Lieb Signed-off-by: Mason Cole Signed-off-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> Signed-off-by: Zadkiel Aharonian Signed-off-by: Philipp Dallig Signed-off-by: pashakostohrys Signed-off-by: Anton Gilgur Signed-off-by: Anton Lindholm Signed-off-by: AvhiMaz Signed-off-by: Yuan (Terry) Tang Signed-off-by: Jordi Grant Esteve Signed-off-by: yyzxw <1020938856@qq.com> Signed-off-by: Chetan Banavikalmutt Signed-off-by: SHIMADA Kento Signed-off-by: Pawank06 Signed-off-by: B Pawan Kumar Signed-off-by: Dylan Slavin Signed-off-by: Jedrzej Kotkowski Signed-off-by: jmcshane Signed-off-by: Gaël Jourdan-Weil Signed-off-by: Andreas Lindhé Signed-off-by: Gaël Jourdan-Weil Signed-off-by: ebuildy Signed-off-by: Lukas Wöhrl Signed-off-by: Christian Hernandez Signed-off-by: Alexander Bellhäuser Signed-off-by: AS <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: Vlad Fratila Signed-off-by: phanama Signed-off-by: Carlos Castro carlos.castro@jumo.world Signed-off-by: Carlos Castro Signed-off-by: Fredrik A. Madsen-Malmo Signed-off-by: David Muckle Signed-off-by: penglongli Signed-off-by: Prasad Katti Signed-off-by: Torbjørn Fjørtoft Signed-off-by: Scott Windsor Signed-off-by: Mike Splain Signed-off-by: Jake Burn Signed-off-by: Fs02 Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: Brad West Signed-off-by: iam-veeramalla Signed-off-by: Oreon Lothamer Signed-off-by: rumstead <37445536+rumstead@users.noreply.github.com> Signed-off-by: Cezar Sa Espinola Signed-off-by: ashu Signed-off-by: jannfis Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Signed-off-by: huyinhou Signed-off-by: Mathias Petermann Signed-off-by: David Marby Signed-off-by: Antoine Jouve Signed-off-by: Alejandro López Sánchez Signed-off-by: Liam Wyllie Signed-off-by: Marcelo Moreira de Mello Signed-off-by: Ansuman Swain Signed-off-by: Maxime Brunet Signed-off-by: zhaque44 Signed-off-by: Harm Matthias Harms Signed-off-by: Kurt King Signed-off-by: Kurt Madel Signed-off-by: LStuker Signed-off-by: Lev Signed-off-by: Lev Signed-off-by: Lev Ozeryansky Signed-off-by: Sergio Rua <58211930+digiserg@users.noreply.github.com> Signed-off-by: Sridhar Nandigam Signed-off-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Signed-off-by: Josh Soref Signed-off-by: Muhammad Mooneeb Hussain Signed-off-by: Timoses Signed-off-by: ishitasequeira Signed-off-by: Mike Ng Signed-off-by: ymktmk Signed-off-by: Eric Blackburn Signed-off-by: PranitRout07 <102309095+PranitRout07@users.noreply.github.com> Signed-off-by: sergey.ladutko Signed-off-by: Anand Francis Joseph Signed-off-by: Remington Breeze Co-authored-by: schakrad <58915923+schakrad@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nik Skoufis Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: asingh <11219262+ashutosh16@users.noreply.github.com> Co-authored-by: daftping <21245083+daftping@users.noreply.github.com> Co-authored-by: Yuan Tang Co-authored-by: Yi Cai Co-authored-by: Gerardo Corea Co-authored-by: Michael Merrill Co-authored-by: Alexandre Gaudreault Co-authored-by: Fish-pro Co-authored-by: XianzheTM Co-authored-by: Geoffrey MUSELLI Co-authored-by: Blake Pettersson Co-authored-by: Alexander Matyushentsev Co-authored-by: Felix Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: CI Co-authored-by: Dylan Page Co-authored-by: Jonathan West Co-authored-by: Kostis (Codefresh) <39800303+kostis-codefresh@users.noreply.github.com> Co-authored-by: Nathan Romriell Co-authored-by: Alex Collins Co-authored-by: Hoang Quoc Trung Co-authored-by: JesseBot Co-authored-by: Leonardo Luz Almeida Co-authored-by: Nicholas Morey Co-authored-by: Ashin Sabu <139749674+ashinsabu3@users.noreply.github.com> Co-authored-by: Talia Stocks <928827+taliastocks@users.noreply.github.com> Co-authored-by: xashr <103113861+xashr@users.noreply.github.com> Co-authored-by: German Lashevich Co-authored-by: Vipin M S <40431065+vipinachar@users.noreply.github.com> Co-authored-by: Prune Sebastien THOMAS Co-authored-by: Dan Garfield Co-authored-by: Mickaël Canévet Co-authored-by: Andrew Block Co-authored-by: Vladimir <31961982+zvlb@users.noreply.github.com> Co-authored-by: Kevin Yue Co-authored-by: Jason Meridth Co-authored-by: Robin Lieb Co-authored-by: Mason Cole <117116981+bt-macole@users.noreply.github.com> Co-authored-by: Zadkiel Aharonian Co-authored-by: Philipp Dallig Co-authored-by: pasha-codefresh Co-authored-by: Anton Gilgur <4970083+agilgur5@users.noreply.github.com> Co-authored-by: Anton Lindholm Co-authored-by: Avhi Mazumder <102310138+AvhiMaz@users.noreply.github.com> Co-authored-by: selaci Co-authored-by: yyzxw <34639446+yyzxw@users.noreply.github.com> Co-authored-by: Chetan Banavikalmutt Co-authored-by: SHIMADA Kento Co-authored-by: B Pawan Kumar Co-authored-by: Dylan Slavin Co-authored-by: jjsiv <96917147+jjsiv@users.noreply.github.com> Co-authored-by: James McShane Co-authored-by: Gaël Jourdan-Weil Co-authored-by: Andreas Lindhé Co-authored-by: Gaël Jourdan-Weil Co-authored-by: Thomas Decaux Co-authored-by: Lukas Wöhrl Co-authored-by: maheshbaliga Co-authored-by: Christian Hernandez Co-authored-by: Alexander Bellhäuser Co-authored-by: Vlad Fratila Co-authored-by: Yudi A Phanama <11147376+phanama@users.noreply.github.com> Co-authored-by: Carlos Castro Co-authored-by: Fredrik A. Madsen-Malmo Co-authored-by: David Muckle Co-authored-by: Pelen Co-authored-by: Prasad Katti Co-authored-by: jannfis Co-authored-by: Torbjørn Fjørtoft Co-authored-by: Scott Windsor Co-authored-by: Mike Splain Co-authored-by: Jake Burn Co-authored-by: Surya Asriadie Co-authored-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Co-authored-by: Brad West Co-authored-by: iam-veeramalla Co-authored-by: Oreon Lothamer <73498677+oreonl@users.noreply.github.com> Co-authored-by: rumstead <37445536+rumstead@users.noreply.github.com> Co-authored-by: Cezar Sá Espinola Co-authored-by: Ashutosh Pednekar Co-authored-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: HYH <82195407@qq.com> Co-authored-by: Mathias Petermann Co-authored-by: David Marby Co-authored-by: Antoine Jouve Co-authored-by: Alejandro López Co-authored-by: Liam Wyllie Co-authored-by: Marcelo Mello Co-authored-by: Ansuman Swain Co-authored-by: Maxime Brunet Co-authored-by: Zubair Haque Co-authored-by: Harm Matthias Harms Co-authored-by: Kurt King Co-authored-by: Kurt Madel Co-authored-by: LStuker Co-authored-by: Lev Ozeryansky Co-authored-by: Lev Co-authored-by: Sergio Rua <58211930+digiserg@users.noreply.github.com> Co-authored-by: Sridhar Nandigam Co-authored-by: Muhammad Mooneeb Hussain Co-authored-by: Timoses Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Co-authored-by: Justin Marquis <76892343+34fathombelow@users.noreply.github.com> Co-authored-by: Mike Ng Co-authored-by: ymktmk <73768462+ymktmk@users.noreply.github.com> Co-authored-by: ericblackburn Co-authored-by: PranitRout07 <102309095+PranitRout07@users.noreply.github.com> Co-authored-by: SergeyLadutko <40435115+SergeyLadutko@users.noreply.github.com> Co-authored-by: sergey.ladutko Co-authored-by: Anand Francis Joseph Co-authored-by: Remington Breeze --- docs/operator-manual/custom-styles.md | 2 +- ui/src/app/ui-banner/ui-banner.tsx | 96 +++++++++++++++++++-------- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/docs/operator-manual/custom-styles.md b/docs/operator-manual/custom-styles.md index 8f2499a2d636a..893720f7bc9c0 100644 --- a/docs/operator-manual/custom-styles.md +++ b/docs/operator-manual/custom-styles.md @@ -100,7 +100,7 @@ experience, you may wish to build a separate project using the [Argo CD UI dev s ## Banners -Argo CD can optionally display a banner that can be used to notify your users of upcoming maintenance and operational changes. This feature can be enabled by specifying the banner message using the `ui.bannercontent` field in the `argocd-cm` ConfigMap and Argo CD will display this message at the top of every UI page. You can optionally add a link to this message by setting `ui.bannerurl`. You can also make the banner sticky (permanent) by setting `ui.bannerpermanent` to `true` and change it's position to the bottom by using `ui.bannerposition: "bottom"` +Argo CD can optionally display a banner that can be used to notify your users of upcoming maintenance and operational changes. This feature can be enabled by specifying the banner message using the `ui.bannercontent` field in the `argocd-cm` ConfigMap and Argo CD will display this message at the top of every UI page. You can optionally add a link to this message by setting `ui.bannerurl`. You can also make the banner sticky (permanent) by setting `ui.bannerpermanent` to true and change its position to "both" or "bottom" by using `ui.bannerposition: "both"`, allowing the banner to display on both the top and bottom, or `ui.bannerposition: "bottom"` to display it exclusively at the bottom. ### argocd-cm ```yaml diff --git a/ui/src/app/ui-banner/ui-banner.tsx b/ui/src/app/ui-banner/ui-banner.tsx index 53508b67690f7..29dbc45eadfbc 100644 --- a/ui/src/app/ui-banner/ui-banner.tsx +++ b/ui/src/app/ui-banner/ui-banner.tsx @@ -8,6 +8,46 @@ import {DataLoader} from '../shared/components'; import {services, ViewPreferences} from '../shared/services'; import './ui-banner.scss'; +const CustomBanner = (props: { + combinedBannerClassName: string; + show: boolean; + heightOfBanner: string; + leftOffset: string; + permanent: boolean; + url: string; + content: string; + setVisible: (visible: boolean) => void; + prefs: object; +}) => { + return ( +
    +
    + {props.url !== undefined ? ( + + {props.content} + + ) : ( + {props.content} + )} +
    + {!props.permanent ? ( + <> + + + + ) : ( + <> + )} +
    + ); +}; + export const Banner = (props: React.Props) => { const [visible, setVisible] = React.useState(true); return ( @@ -60,9 +100,8 @@ export const Banner = (props: React.Props) => { const isTop = position !== 'bottom'; const bannerClassName = isTop ? 'ui-banner-top' : 'ui-banner-bottom'; const wrapperClassname = bannerClassName + '--wrapper ' + (!permanent ? bannerClassName + '--wrapper-multiline' : bannerClassName + '--wrapper-singleline'); - const combinedBannerClassName = isTop ? 'ui-banner ui-banner-top' : 'ui-banner ui-banner-bottom'; let chatBottomPosition = 10; - if (show && !isTop) { + if (show && (!isTop || position === 'both')) { if (permanent) { chatBottomPosition = 40; } else { @@ -77,33 +116,36 @@ export const Banner = (props: React.Props) => { chatUrl = 'invalid-url'; } } + const shouldRenderTop = position === 'top' || position === 'both'; + const shouldRenderBottom = position === 'bottom' || position === 'both'; return ( -
    -
    - {url !== undefined ? ( - - {content} - - ) : ( - {content} - )} -
    - {!permanent ? ( - <> - - - - ) : ( - <> - )} -
    + {shouldRenderTop && ( + + )} + {shouldRenderBottom && ( + + )} {show ?
    {props.children}
    : props.children} {chatUrl && (
    From 8d6c0927e34ba2678fbfbc1062571e2a91f8f05a Mon Sep 17 00:00:00 2001 From: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:05:01 -0400 Subject: [PATCH 075/269] docs: Ensure consistent proper case of Kubernetes (#16205) * docs: Consistent proper case of Kubernetes Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> * docs: Fix minor typo Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> * fix: Proper case Kubernetes Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --------- Signed-off-by: Adam Harvey <33203301+adamdmharvey@users.noreply.github.com> --- cmd/argocd/commands/project.go | 2 +- docs/developer-guide/extensions/ui-extensions.md | 2 +- docs/developer-guide/site.md | 3 ++- docs/index.md | 2 +- .../Generators-Cluster-Decision-Resource.md | 2 +- docs/operator-manual/applicationset/Generators-Git.md | 6 +++--- .../applicationset/Generators-Post-Selector.md | 2 +- docs/operator-manual/health.md | 2 +- docs/operator-manual/metrics.md | 8 ++++---- docs/operator-manual/security.md | 4 ++-- docs/operator-manual/troubleshooting.md | 2 +- docs/operator-manual/upgrading/2.7-2.8.md | 2 +- docs/operator-manual/user-management/index.md | 2 +- docs/operator-manual/webhook.md | 6 +++--- docs/proposals/config-management-plugin-v2.md | 2 +- docs/user-guide/best_practices.md | 2 +- docs/user-guide/ci_automation.md | 2 +- docs/user-guide/commands/argocd_proj_create.md | 2 +- docs/user-guide/kustomize.md | 2 +- docs/user-guide/sync-options.md | 2 +- 20 files changed, 29 insertions(+), 28 deletions(-) diff --git a/cmd/argocd/commands/project.go b/cmd/argocd/commands/project.go index dc894b4a79f27..32fb9e779e8ed 100644 --- a/cmd/argocd/commands/project.go +++ b/cmd/argocd/commands/project.go @@ -106,7 +106,7 @@ func NewProjectCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm # Create a new project with name PROJECT argocd proj create PROJECT - # Create a new project with name PROJECT from a file or URL to a kubernetes manifest + # Create a new project with name PROJECT from a file or URL to a Kubernetes manifest argocd proj create PROJECT -f FILE|URL `), Run: func(c *cobra.Command, args []string) { diff --git a/docs/developer-guide/extensions/ui-extensions.md b/docs/developer-guide/extensions/ui-extensions.md index 2c25748beb148..ec1631038ad53 100644 --- a/docs/developer-guide/extensions/ui-extensions.md +++ b/docs/developer-guide/extensions/ui-extensions.md @@ -36,7 +36,7 @@ registerResourceExtension(component: ExtensionComponent, group: string, kind: st - `component: ExtensionComponent` is a React component that receives the following properties: - application: Application - Argo CD Application resource; - - resource: State - the kubernetes resource object; + - resource: State - the Kubernetes resource object; - tree: ApplicationTree - includes list of all resources that comprise the application; See properties interfaces in [models.ts](https://github.com/argoproj/argo-cd/blob/master/ui/src/app/shared/models.ts) diff --git a/docs/developer-guide/site.md b/docs/developer-guide/site.md index 47c1f57e29bb7..af32753a323e2 100644 --- a/docs/developer-guide/site.md +++ b/docs/developer-guide/site.md @@ -2,13 +2,14 @@ ## Developing And Testing -The website is build using `mkdocs` and `mkdocs-material`. +The website is built using `mkdocs` and `mkdocs-material`. To test: ```bash make serve-docs ``` + Once running, you can view your locally built documentation at [http://0.0.0.0:8000/](http://0.0.0.0:8000/). ## Deploying diff --git a/docs/index.md b/docs/index.md index 6315ced37efad..ddb17c2bdc36a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -53,7 +53,7 @@ meeting: ![Argo CD Architecture](assets/argocd_architecture.png) -Argo CD is implemented as a kubernetes controller which continuously monitors running applications +Argo CD is implemented as a Kubernetes controller which continuously monitors running applications and compares the current, live state against the desired target state (as specified in the Git repo). A deployed application whose live state deviates from the target state is considered `OutOfSync`. Argo CD reports & visualizes the differences, while providing facilities to automatically or diff --git a/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md b/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md index 44567884dccf8..95c60d95cd68c 100644 --- a/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md +++ b/docs/operator-manual/applicationset/Generators-Cluster-Decision-Resource.md @@ -1,6 +1,6 @@ # Cluster Decision Resource Generator -The cluster decision resource generates a list of Argo CD clusters. This is done using [duck-typing](https://pkg.go.dev/knative.dev/pkg/apis/duck), which does not require knowledge of the full shape of the referenced kubernetes resource. The following is an example of a cluster-decision-resource-based ApplicationSet generator: +The cluster decision resource generates a list of Argo CD clusters. This is done using [duck-typing](https://pkg.go.dev/knative.dev/pkg/apis/duck), which does not require knowledge of the full shape of the referenced Kubernetes resource. The following is an example of a cluster-decision-resource-based ApplicationSet generator: ```yaml apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet diff --git a/docs/operator-manual/applicationset/Generators-Git.md b/docs/operator-manual/applicationset/Generators-Git.md index 24fb3427d73b0..7e4aa5fdb1c24 100644 --- a/docs/operator-manual/applicationset/Generators-Git.md +++ b/docs/operator-manual/applicationset/Generators-Git.md @@ -409,15 +409,15 @@ the contents of webhook payloads are considered untrusted, and will only result application (a process which already occurs at three-minute intervals). If ApplicationSet is publicly accessible, then configuring a webhook secret is recommended to prevent a DDoS attack. -In the `argocd-secret` kubernetes secret, include the Git provider's webhook secret configured in step 1. +In the `argocd-secret` Kubernetes secret, include the Git provider's webhook secret configured in step 1. -Edit the Argo CD kubernetes secret: +Edit the Argo CD Kubernetes secret: ```bash kubectl edit secret argocd-secret -n argocd ``` -TIP: for ease of entering secrets, kubernetes supports inputting secrets in the `stringData` field, +TIP: for ease of entering secrets, Kubernetes supports inputting secrets in the `stringData` field, which saves you the trouble of base64 encoding the values and copying it to the `data` field. Simply copy the shared webhook secret created in step 1, to the corresponding GitHub/GitLab/BitBucket key under the `stringData` field: diff --git a/docs/operator-manual/applicationset/Generators-Post-Selector.md b/docs/operator-manual/applicationset/Generators-Post-Selector.md index aac134e0b6212..896e89e267d7c 100644 --- a/docs/operator-manual/applicationset/Generators-Post-Selector.md +++ b/docs/operator-manual/applicationset/Generators-Post-Selector.md @@ -1,6 +1,6 @@ # Post Selector all generators -The Selector allows to post-filter based on generated values using the kubernetes common labelSelector format. In the example, the list generator generates a set of two application which then filter by the key value to only select the `env` with value `staging`: +The Selector allows to post-filter based on generated values using the Kubernetes common labelSelector format. In the example, the list generator generates a set of two application which then filter by the key value to only select the `env` with value `staging`: ## Example: List generator + Post Selector ```yaml diff --git a/docs/operator-manual/health.md b/docs/operator-manual/health.md index 5cc80de6538c5..8566d6460e6db 100644 --- a/docs/operator-manual/health.md +++ b/docs/operator-manual/health.md @@ -3,7 +3,7 @@ ## Overview Argo CD provides built-in health assessment for several standard Kubernetes types, which is then surfaced to the overall Application health status as a whole. The following checks are made for -specific types of kubernetes resources: +specific types of Kubernetes resources: ### Deployment, ReplicaSet, StatefulSet, DaemonSet * Observed generation is equal to desired generation. diff --git a/docs/operator-manual/metrics.md b/docs/operator-manual/metrics.md index 174b08fd75c2c..2bde146a786a2 100644 --- a/docs/operator-manual/metrics.md +++ b/docs/operator-manual/metrics.md @@ -8,12 +8,12 @@ Metrics about applications. Scraped at the `argocd-metrics:8082/metrics` endpoin | Metric | Type | Description | |--------|:----:|-------------| | `argocd_app_info` | gauge | Information about Applications. It contains labels such as `sync_status` and `health_status` that reflect the application state in Argo CD. | -| `argocd_app_k8s_request_total` | counter | Number of kubernetes requests executed during application reconciliation | +| `argocd_app_k8s_request_total` | counter | Number of Kubernetes requests executed during application reconciliation | | `argocd_app_labels` | gauge | Argo Application labels converted to Prometheus labels. Disabled by default. See section below about how to enable it. | | `argocd_app_reconcile` | histogram | Application reconciliation performance. | | `argocd_app_sync_total` | counter | Counter for application sync history | | `argocd_cluster_api_resource_objects` | gauge | Number of k8s resource objects in the cache. | -| `argocd_cluster_api_resources` | gauge | Number of monitored kubernetes API resources. | +| `argocd_cluster_api_resources` | gauge | Number of monitored Kubernetes API resources. | | `argocd_cluster_cache_age_seconds` | gauge | Cluster cache age in seconds. | | `argocd_cluster_connection_status` | gauge | The k8s cluster current connection status. | | `argocd_cluster_events_total` | counter | Number of processes k8s resource events. | @@ -67,7 +67,7 @@ Scraped at the `argocd-server-metrics:8083/metrics` endpoint. | Metric | Type | Description | |--------|:----:|-------------| | `argocd_redis_request_duration` | histogram | Redis requests duration. | -| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application reconciliation. | +| `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. | | `grpc_server_handled_total` | counter | Total number of RPCs completed on the server, regardless of success or failure. | | `grpc_server_msg_sent_total` | counter | Total number of gRPC stream messages sent by the server. | @@ -80,7 +80,7 @@ Scraped at the `argocd-repo-server:8084/metrics` endpoint. | `argocd_git_request_duration_seconds` | histogram | Git requests duration seconds. | | `argocd_git_request_total` | counter | Number of git requests performed by repo server | | `argocd_redis_request_duration_seconds` | histogram | Redis requests duration seconds. | -| `argocd_redis_request_total` | counter | Number of kubernetes requests executed during application reconciliation. | +| `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. | | `argocd_repo_pending_request_total` | gauge | Number of pending requests requiring repository lock | ## Prometheus Operator diff --git a/docs/operator-manual/security.md b/docs/operator-manual/security.md index 3ba9fdfe39363..47c5d3aa1accc 100644 --- a/docs/operator-manual/security.md +++ b/docs/operator-manual/security.md @@ -45,7 +45,7 @@ Communication with Redis is performed over plain HTTP by default. TLS can be set Git and helm repositories are managed by a stand-alone service, called the repo-server. The repo-server does not carry any Kubernetes privileges and does not store credentials to any services (including git). The repo-server is responsible for cloning repositories which have been permitted -and trusted by Argo CD operators, and generating kubernetes manifests at a given path in the +and trusted by Argo CD operators, and generating Kubernetes manifests at a given path in the repository. For performance and bandwidth efficiency, the repo-server maintains local clones of these repositories so that subsequent commits to the repository are efficiently downloaded. @@ -109,7 +109,7 @@ The information is used to reconstruct a REST config and kubeconfig to the clust services. To rotate the bearer token used by Argo CD, the token can be deleted (e.g. using kubectl) which -causes kubernetes to generate a new secret with a new bearer token. The new token can be re-inputted +causes Kubernetes to generate a new secret with a new bearer token. The new token can be re-inputted to Argo CD by re-running `argocd cluster add`. Run the following commands against the *_managed_* cluster: diff --git a/docs/operator-manual/troubleshooting.md b/docs/operator-manual/troubleshooting.md index 884045410b0b8..0e0159e5def4f 100644 --- a/docs/operator-manual/troubleshooting.md +++ b/docs/operator-manual/troubleshooting.md @@ -25,7 +25,7 @@ argocd admin settings resource-overrides ignore-differences ./deploy.yaml --argo **Health Assessment** -Argo CD provides built-in [health assessment](./health.md) for several kubernetes resources which can be further +Argo CD provides built-in [health assessment](./health.md) for several Kubernetes resources which can be further customized by writing your own health checks in [Lua](https://www.lua.org/). The health checks are configured in the `resource.customizations` field of `argocd-cm` ConfigMap. diff --git a/docs/operator-manual/upgrading/2.7-2.8.md b/docs/operator-manual/upgrading/2.7-2.8.md index 1e403bf981ab4..c42a97a1f429c 100644 --- a/docs/operator-manual/upgrading/2.7-2.8.md +++ b/docs/operator-manual/upgrading/2.7-2.8.md @@ -11,7 +11,7 @@ to upgrade your plugin. With the 2.8 release `entrypoint.sh` will be removed from the containers, because starting with 2.7, the implicit entrypoint is set to `tini` in the -`Dockerfile` explicitly, and the kubernetes manifests has been updated to use +`Dockerfile` explicitly, and the Kubernetes manifests has been updated to use it. Simply updating the containers without updating the deployment manifests will result in pod startup failures, as the old manifests are relying on `entrypoint.sh` instead of `tini`. Please make sure the manifests are updated diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index 09a33c4fed750..8e459202456eb 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -442,7 +442,7 @@ Add a `rootCA` to your `oidc.config` which contains the PEM encoded root certifi #### Example -SSO `clientSecret` can thus be stored as a kubernetes secret with the following manifests +SSO `clientSecret` can thus be stored as a Kubernetes secret with the following manifests `argocd-secret`: ```yaml diff --git a/docs/operator-manual/webhook.md b/docs/operator-manual/webhook.md index 1d5ad5ec79c96..eb15c4cb02369 100644 --- a/docs/operator-manual/webhook.md +++ b/docs/operator-manual/webhook.md @@ -41,7 +41,7 @@ the contents of webhook payloads are considered untrusted, and will only result application (a process which already occurs at three-minute intervals). If Argo CD is publicly accessible, then configuring a webhook secret is recommended to prevent a DDoS attack. -In the `argocd-secret` kubernetes secret, configure one of the following keys with the Git +In the `argocd-secret` Kubernetes secret, configure one of the following keys with the Git provider's webhook secret configured in step 1. | Provider | K8s Secret Key | @@ -54,13 +54,13 @@ provider's webhook secret configured in step 1. | Azure DevOps | `webhook.azuredevops.username` | | | `webhook.azuredevops.password` | -Edit the Argo CD kubernetes secret: +Edit the Argo CD Kubernetes secret: ```bash kubectl edit secret argocd-secret -n argocd ``` -TIP: for ease of entering secrets, kubernetes supports inputting secrets in the `stringData` field, +TIP: for ease of entering secrets, Kubernetes supports inputting secrets in the `stringData` field, which saves you the trouble of base64 encoding the values and copying it to the `data` field. Simply copy the shared webhook secret created in step 1, to the corresponding GitHub/GitLab/BitBucket key under the `stringData` field: diff --git a/docs/proposals/config-management-plugin-v2.md b/docs/proposals/config-management-plugin-v2.md index d5d68cc0af942..549ed3967ef49 100644 --- a/docs/proposals/config-management-plugin-v2.md +++ b/docs/proposals/config-management-plugin-v2.md @@ -291,7 +291,7 @@ There aren't any major drawbacks to this proposal. Also, the advantages supersed However following are few minor drawbacks, * With addition of plugin.yaml, there will be more yamls to manage -* Operators need to be aware of the modified kubernetes manifests in the subsequent version. +* Operators need to be aware of the modified Kubernetes manifests in the subsequent version. * The format of the CMP manifest is a new "contract" that would need to adhere the usual Argo CD compatibility promises in future. diff --git a/docs/user-guide/best_practices.md b/docs/user-guide/best_practices.md index 2326cce9a430e..718ab022f3e50 100644 --- a/docs/user-guide/best_practices.md +++ b/docs/user-guide/best_practices.md @@ -2,7 +2,7 @@ ## Separating Config Vs. Source Code Repositories -Using a separate Git repository to hold your kubernetes manifests, keeping the config separate +Using a separate Git repository to hold your Kubernetes manifests, keeping the config separate from your application source code, is highly recommended for the following reasons: 1. It provides a clean separation of application code vs. application config. There will be times diff --git a/docs/user-guide/ci_automation.md b/docs/user-guide/ci_automation.md index 9aafa385f0461..14d35dc3cb2cd 100644 --- a/docs/user-guide/ci_automation.md +++ b/docs/user-guide/ci_automation.md @@ -18,7 +18,7 @@ docker push mycompany/guestbook:v2.0 ## Update The Local Manifests Using Your Preferred Templating Tool, And Push The Changes To Git !!! tip - The use of a different Git repository to hold your kubernetes manifests (separate from + The use of a different Git repository to hold your Kubernetes manifests (separate from your application source code), is highly recommended. See [best practices](best_practices.md) for further rationale. diff --git a/docs/user-guide/commands/argocd_proj_create.md b/docs/user-guide/commands/argocd_proj_create.md index d99c66a19555d..fd8687c1b2982 100644 --- a/docs/user-guide/commands/argocd_proj_create.md +++ b/docs/user-guide/commands/argocd_proj_create.md @@ -14,7 +14,7 @@ argocd proj create PROJECT [flags] # Create a new project with name PROJECT argocd proj create PROJECT - # Create a new project with name PROJECT from a file or URL to a kubernetes manifest + # Create a new project with name PROJECT from a file or URL to a Kubernetes manifest argocd proj create PROJECT -f FILE|URL ``` diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index 9c7f7c9889b1c..7007ac17675da 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -9,7 +9,7 @@ The following configuration options are available for Kustomize: * `commonLabels` is a string map of additional labels * `forceCommonLabels` is a boolean value which defines if it's allowed to override existing labels * `commonAnnotations` is a string map of additional annotations -* `namespace` is a kubernetes resources namespace +* `namespace` is a Kubernetes resources namespace * `forceCommonAnnotations` is a boolean value which defines if it's allowed to override existing annotations * `commonAnnotationsEnvsubst` is a boolean value which enables env variables substition in annotation values * `patches` is a list of Kustomize patches that supports inline updates diff --git a/docs/user-guide/sync-options.md b/docs/user-guide/sync-options.md index 817fabbe5fb45..e5b1fe55e8e66 100644 --- a/docs/user-guide/sync-options.md +++ b/docs/user-guide/sync-options.md @@ -29,7 +29,7 @@ The app will be out of sync if Argo CD expects a resource to be pruned. You may ## Disable Kubectl Validation -For a certain class of objects, it is necessary to `kubectl apply` them using the `--validate=false` flag. Examples of this are kubernetes types which uses `RawExtension`, such as [ServiceCatalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/pkg/apis/servicecatalog/v1beta1/types.go#L497). You can do using this annotations: +For a certain class of objects, it is necessary to `kubectl apply` them using the `--validate=false` flag. Examples of this are Kubernetes types which uses `RawExtension`, such as [ServiceCatalog](https://github.com/kubernetes-incubator/service-catalog/blob/master/pkg/apis/servicecatalog/v1beta1/types.go#L497). You can do using this annotations: ```yaml From f8416996bd4409366e6167788b00928408e4115e Mon Sep 17 00:00:00 2001 From: Christian Hernandez Date: Wed, 1 Nov 2023 17:46:02 -0700 Subject: [PATCH 076/269] Added an example of project scoped cluster (#16210) Signed-off-by: Christian Hernandez --- docs/user-guide/projects.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/user-guide/projects.md b/docs/user-guide/projects.md index 6fb59b1ef3456..9876405febdeb 100644 --- a/docs/user-guide/projects.md +++ b/docs/user-guide/projects.md @@ -321,6 +321,28 @@ stringData: All the examples above talk about Git repositories, but the same principles apply to clusters as well. +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: mycluster-secret + labels: + argocd.argoproj.io/secret-type: cluster +type: Opaque +stringData: + name: mycluster.com + project: my-project1 # Project scoped + server: https://mycluster.com + config: | + { + "bearerToken": "", + "tlsClientConfig": { + "insecure": false, + "caData": "" + } + } +``` + With project-scoped clusters we can also restrict projects to only allow applications whose destinations belong to the same project. The default behavior allows for applications to be installed onto clusters which are not a part of the same project, as the example below demonstrates: From 7525b603f7f82ca3075cf0c0134ff6fc354e36a3 Mon Sep 17 00:00:00 2001 From: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> Date: Thu, 2 Nov 2023 06:28:59 +0530 Subject: [PATCH 077/269] feat: add examples to --help ouput for argocd_server.go file (#16032) * add examples to argocd_server.go Signed-off-by: Harshvir Potpose * Update argocd-server.md Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> * fix Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> * fix Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> * fix Signed-off-by: Harshvir Potpose * fix Signed-off-by: Harshvir Potpose * Update argocd_server.go Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> --------- Signed-off-by: Harshvir Potpose Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> --- cmd/argocd-server/commands/argocd_server.go | 8 ++++++++ docs/operator-manual/server-commands/argocd-server.md | 10 ++++++++++ 2 files changed, 18 insertions(+) diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index eea346eaed03d..8709c7de09523 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -25,6 +25,7 @@ import ( "github.com/argoproj/argo-cd/v2/util/env" "github.com/argoproj/argo-cd/v2/util/errors" "github.com/argoproj/argo-cd/v2/util/kube" + "github.com/argoproj/argo-cd/v2/util/templates" "github.com/argoproj/argo-cd/v2/util/tls" traceutil "github.com/argoproj/argo-cd/v2/util/trace" ) @@ -211,6 +212,13 @@ func NewCommand() *cobra.Command { } } }, + Example: templates.Examples(` + # Start the Argo CD API server with default settings + $ argocd-server + + # Start the Argo CD API server on a custom port and enable tracing + $ argocd-server --port 8888 --otlp-address localhost:4317 + `), } clientConfig = cli.AddKubectlFlagsToCmd(command) diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index 980383df7848e..c33cf0bedcbcf 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -12,6 +12,16 @@ The API server is a gRPC/REST server which exposes the API consumed by the Web U argocd-server [flags] ``` +### Examples + +``` + # Start the Argo CD API server with default settings + $ argocd-server + + # Start the Argo CD API server on a custom port and enable tracing + $ argocd-server --port 8888 --otlp-address localhost:4317 +``` + ### Options ``` From 8796307344accebf60c3a6d38b76c018d6733646 Mon Sep 17 00:00:00 2001 From: Gestalt LUR <1104224+nyanshell@users.noreply.github.com> Date: Thu, 2 Nov 2023 08:59:32 +0800 Subject: [PATCH 078/269] fix(docs): repo field name in GCP Cloud Source Repositories should be `url` (#16107) Signed-off-by: Gestalt LUR <1104224+nyanshell@users.noreply.github.com> --- docs/operator-manual/declarative-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index 5353f70cf14ef..1694429ffc25c 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -266,7 +266,7 @@ metadata: argocd.argoproj.io/secret-type: repository stringData: type: git - repo: https://source.developers.google.com/p/my-google-project/r/my-repo + url: https://source.developers.google.com/p/my-google-project/r/my-repo gcpServiceAccountKey: | { "type": "service_account", From 481cf81279736540926cdf0d2f6afcd5f30aa809 Mon Sep 17 00:00:00 2001 From: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> Date: Thu, 2 Nov 2023 07:33:21 +0530 Subject: [PATCH 079/269] feat: add examples to --help output for admin.go file (#16030) * add examples to admin.go Signed-off-by: Harshvir Potpose * Update argocd_admin.md Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> --------- Signed-off-by: Harshvir Potpose Signed-off-by: Harshvir Potpose <122517264+akagami-harsh@users.noreply.github.com> --- cmd/argocd/commands/admin/admin.go | 81 ++++++++++++++++++++++ docs/user-guide/commands/argocd_admin.md | 86 ++++++++++++++++++++++++ 2 files changed, 167 insertions(+) diff --git a/cmd/argocd/commands/admin/admin.go b/cmd/argocd/commands/admin/admin.go index 92cad10479d68..0615166175259 100644 --- a/cmd/argocd/commands/admin/admin.go +++ b/cmd/argocd/commands/admin/admin.go @@ -48,6 +48,87 @@ func NewAdminCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { Run: func(c *cobra.Command, args []string) { c.HelpFunc()(c, args) }, + Example: `# List all clusters +$ argocd admin cluster list + +# Add a new cluster +$ argocd admin cluster add my-cluster --name my-cluster --in-cluster-context + +# Remove a cluster +argocd admin cluster remove my-cluster + +# List all projects +$ argocd admin project list + +# Create a new project +$argocd admin project create my-project --src-namespace my-source-namespace --dest-namespace my-dest-namespace + +# Update a project +$ argocd admin project update my-project --src-namespace my-updated-source-namespace --dest-namespace my-updated-dest-namespace + +# Delete a project +$ argocd admin project delete my-project + +# List all settings +$ argocd admin settings list + +# Get the current settings +$ argocd admin settings get + +# Update settings +$ argocd admin settings update --repository.resync --value 15 + +# List all applications +$ argocd admin app list + +# Get application details +$ argocd admin app get my-app + +# Sync an application +$ argocd admin app sync my-app + +# Pause an application +$ argocd admin app pause my-app + +# Resume an application +$ argocd admin app resume my-app + +# List all repositories +$ argocd admin repo list + +# Add a repository +$ argocd admin repo add https://github.com/argoproj/my-repo.git + +# Remove a repository +$ argocd admin repo remove https://github.com/argoproj/my-repo.git + +# Import an application from a YAML file +$ argocd admin app import -f my-app.yaml + +# Export an application to a YAML file +$ argocd admin app export my-app -o my-exported-app.yaml + +# Access the Argo CD web UI +$ argocd admin dashboard + +# List notifications +$ argocd admin notification list + +# Get notification details +$ argocd admin notification get my-notification + +# Create a new notification +$ argocd admin notification create my-notification -f notification-config.yaml + +# Update a notification +$ argocd admin notification update my-notification -f updated-notification-config.yaml + +# Delete a notification +$ argocd admin notification delete my-notification + +# Reset the initial admin password +$ argocd admin initial-password reset +`, } command.AddCommand(NewClusterCommand(clientOpts, pathOpts)) diff --git a/docs/user-guide/commands/argocd_admin.md b/docs/user-guide/commands/argocd_admin.md index 7a3ff2fde6e89..7966e5a3cb9b1 100644 --- a/docs/user-guide/commands/argocd_admin.md +++ b/docs/user-guide/commands/argocd_admin.md @@ -8,6 +8,92 @@ Contains a set of commands useful for Argo CD administrators and requires direct argocd admin [flags] ``` +### Examples + +``` +# List all clusters +$ argocd admin cluster list + +# Add a new cluster +$ argocd admin cluster add my-cluster --name my-cluster --in-cluster-context + +# Remove a cluster +argocd admin cluster remove my-cluster + +# List all projects +$ argocd admin project list + +# Create a new project +$argocd admin project create my-project --src-namespace my-source-namespace --dest-namespace my-dest-namespace + +# Update a project +$ argocd admin project update my-project --src-namespace my-updated-source-namespace --dest-namespace my-updated-dest-namespace + +# Delete a project +$ argocd admin project delete my-project + +# List all settings +$ argocd admin settings list + +# Get the current settings +$ argocd admin settings get + +# Update settings +$ argocd admin settings update --repository.resync --value 15 + +# List all applications +$ argocd admin app list + +# Get application details +$ argocd admin app get my-app + +# Sync an application +$ argocd admin app sync my-app + +# Pause an application +$ argocd admin app pause my-app + +# Resume an application +$ argocd admin app resume my-app + +# List all repositories +$ argocd admin repo list + +# Add a repository +$ argocd admin repo add https://github.com/argoproj/my-repo.git + +# Remove a repository +$ argocd admin repo remove https://github.com/argoproj/my-repo.git + +# Import an application from a YAML file +$ argocd admin app import -f my-app.yaml + +# Export an application to a YAML file +$ argocd admin app export my-app -o my-exported-app.yaml + +# Access the Argo CD web UI +$ argocd admin dashboard + +# List notifications +$ argocd admin notification list + +# Get notification details +$ argocd admin notification get my-notification + +# Create a new notification +$ argocd admin notification create my-notification -f notification-config.yaml + +# Update a notification +$ argocd admin notification update my-notification -f updated-notification-config.yaml + +# Delete a notification +$ argocd admin notification delete my-notification + +# Reset the initial admin password +$ argocd admin initial-password reset + +``` + ### Options ``` From 570c24e38e058041e86e7683f23bd7a86bf3cc3f Mon Sep 17 00:00:00 2001 From: Shyukri Shyukriev Date: Thu, 2 Nov 2023 17:21:56 +0200 Subject: [PATCH 080/269] chore: Upgrade Redis to redis:7.0.14 (#16164) Fixes https://github.com/argoproj/argo-cd/issues/15448 Signed-off-by: Shyukri Shyukriev Co-authored-by: Shyukri Shyukriev --- .github/workflows/ci-build.yaml | 2 +- manifests/base/redis/argocd-redis-deployment.yaml | 2 +- manifests/core-install.yaml | 2 +- manifests/ha/base/redis-ha/chart/upstream.yaml | 8 ++++---- manifests/ha/base/redis-ha/chart/values.yaml | 2 +- manifests/ha/install.yaml | 8 ++++---- manifests/ha/namespace-install.yaml | 8 ++++---- manifests/install.yaml | 2 +- manifests/namespace-install.yaml | 2 +- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index adffe526da728..afdfa61822344 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -429,7 +429,7 @@ jobs: run: | docker pull ghcr.io/dexidp/dex:v2.37.0 docker pull argoproj/argo-cd-ci-builder:v1.0.0 - docker pull redis:7.0.11-alpine + docker pull redis:7.0.14-alpine - name: Create target directory for binaries in the build-process run: | mkdir -p dist diff --git a/manifests/base/redis/argocd-redis-deployment.yaml b/manifests/base/redis/argocd-redis-deployment.yaml index 8d649e3995ebc..6fc776785185f 100644 --- a/manifests/base/redis/argocd-redis-deployment.yaml +++ b/manifests/base/redis/argocd-redis-deployment.yaml @@ -23,7 +23,7 @@ spec: serviceAccountName: argocd-redis containers: - name: redis - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: Always args: - "--save" diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 86e636e12ef59..69514971c03e9 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -20843,7 +20843,7 @@ spec: - "" - --appendonly - "no" - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: Always name: redis ports: diff --git a/manifests/ha/base/redis-ha/chart/upstream.yaml b/manifests/ha/base/redis-ha/chart/upstream.yaml index 80e3bfa21dcdf..1d0e4b3c247f8 100644 --- a/manifests/ha/base/redis-ha/chart/upstream.yaml +++ b/manifests/ha/base/redis-ha/chart/upstream.yaml @@ -1207,7 +1207,7 @@ spec: automountServiceAccountToken: false initContainers: - name: config-init - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent resources: {} @@ -1241,7 +1241,7 @@ spec: containers: - name: redis - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent command: - redis-server @@ -1298,7 +1298,7 @@ spec: - /bin/sh - /readonly-config/trigger-failover-if-master.sh - name: sentinel - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent command: - redis-sentinel @@ -1349,7 +1349,7 @@ spec: {} - name: split-brain-fix - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent command: - sh diff --git a/manifests/ha/base/redis-ha/chart/values.yaml b/manifests/ha/base/redis-ha/chart/values.yaml index e2788777e980d..5606daac34bb3 100644 --- a/manifests/ha/base/redis-ha/chart/values.yaml +++ b/manifests/ha/base/redis-ha/chart/values.yaml @@ -20,7 +20,7 @@ redis-ha: metrics: enabled: true image: - tag: 7.0.11-alpine + tag: 7.0.14-alpine containerSecurityContext: null sentinel: bind: "0.0.0.0" diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index cd532b40b13ad..8576a7d651f67 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -23211,7 +23211,7 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -23265,7 +23265,7 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -23318,7 +23318,7 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -23348,7 +23348,7 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 524ec8ace3e6c..4b33a7ceb867e 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2866,7 +2866,7 @@ spec: - /data/conf/redis.conf command: - redis-server - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent lifecycle: preStop: @@ -2920,7 +2920,7 @@ spec: - /data/conf/sentinel.conf command: - redis-sentinel - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent lifecycle: {} livenessProbe: @@ -2973,7 +2973,7 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent name: split-brain-fix resources: {} @@ -3003,7 +3003,7 @@ spec: value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4 - name: SENTINEL_ID_2 value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: IfNotPresent name: config-init securityContext: diff --git a/manifests/install.yaml b/manifests/install.yaml index 211cdf31d92de..45d1864c55691 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21376,7 +21376,7 @@ spec: - "" - --appendonly - "no" - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: Always name: redis ports: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index cfdf7756ff134..89cb5ed4ff5ed 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1031,7 +1031,7 @@ spec: - "" - --appendonly - "no" - image: redis:7.0.11-alpine + image: redis:7.0.14-alpine imagePullPolicy: Always name: redis ports: From 162c2d3001f52325dd722c4e7a0683f93b08c743 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:49:10 -0400 Subject: [PATCH 081/269] chore: add SECURITY-INSIGHTS.yml (#16135) automation Update SECURITY-INSIGHTS.yml Update SECURITY-INSIGHTS.yml Update SECURITY-INSIGHTS.yml Update SECURITY-INSIGHTS.yml add snyk as security tester reorganize Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .github/workflows/release.yaml | 6 + SECURITY-INSIGHTS.yml | 128 ++++++++++++++++++ .../release-process-and-cadence.md | 18 +++ 3 files changed, 152 insertions(+) create mode 100644 SECURITY-INSIGHTS.yml diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9448b98e5c631..ae5174659cf40 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -265,11 +265,13 @@ jobs: set -xue SOURCE_TAG=${{ github.ref_name }} VERSION_REF="${SOURCE_TAG#*v}" + COMMIT_HASH=$(git rev-parse HEAD) if echo "$VERSION_REF" | grep -E -- '^[0-9]+\.[0-9]+\.0-rc1';then VERSION=$(awk 'BEGIN {FS=OFS="."} {$2++; print}' <<< "${VERSION_REF%-rc1}") echo "Updating VERSION to: $VERSION" echo "UPDATE_VERSION=true" >> $GITHUB_ENV echo "NEW_VERSION=$VERSION" >> $GITHUB_ENV + echo "COMMIT_HASH=$COMMIT_HASH" >> $GITHUB_ENV else echo "Not updating VERSION" echo "UPDATE_VERSION=false" >> $GITHUB_ENV @@ -278,6 +280,10 @@ jobs: - name: Update VERSION on master branch run: | echo ${{ env.NEW_VERSION }} > VERSION + # Replace the 'project-release: vX.X.X-rcX' line in SECURITY-INSIGHTS.yml + sed -i "s/project-release: v.*$/project-release: v${{ env.NEW_VERSION }}/" SECURITY-INSIGHTS.yml + # Update the 'commit-hash: XXXXXXX' line in SECURITY-INSIGHTS.yml + sed -i "s/commit-hash: .*/commit-hash: ${{ env.NEW_VERSION }}/" SECURITY-INSIGHTS.yml if: ${{ env.UPDATE_VERSION == 'true' }} - name: Create PR to update VERSION on master branch diff --git a/SECURITY-INSIGHTS.yml b/SECURITY-INSIGHTS.yml new file mode 100644 index 0000000000000..8ac4bc36b04ae --- /dev/null +++ b/SECURITY-INSIGHTS.yml @@ -0,0 +1,128 @@ +header: + schema-version: 1.0.0 + expiration-date: '2024-10-31T00:00:00.000Z' # One year from initial release. + last-updated: '2023-10-27' + last-reviewed: '2023-10-27' + commit-hash: b71277c6beb949d0199d647a582bc25822b88838 + project-url: https://github.com/argoproj/argo-cd + project-release: v2.9.0-rc3 + changelog: https://github.com/argoproj/argo-cd/releases + license: https://github.com/argoproj/argo-cd/blob/master/LICENSE +project-lifecycle: + status: active + roadmap: https://github.com/orgs/argoproj/projects/25 + bug-fixes-only: false + core-maintainers: + - https://github.com/argoproj/argoproj/blob/master/MAINTAINERS.md + release-cycle: https://argo-cd.readthedocs.io/en/stable/developer-guide/release-process-and-cadence/ + release-process: https://argo-cd.readthedocs.io/en/stable/developer-guide/release-process-and-cadence/#release-process +contribution-policy: + accepts-pull-requests: true + accepts-automated-pull-requests: true + automated-tools-list: + - automated-tool: dependabot + action: allowed + path: + - / + - automated-tool: snyk-report + action: allowed + path: + - docs/snyk + comment: | + This tool runs Snyk and generates a report of vulnerabilities in the project's dependencies. The report is + placed in the project's documentation. The workflow is defined here: + https://github.com/argoproj/argo-cd/blob/master/.github/workflows/update-snyk.yaml + contributing-policy: https://argo-cd.readthedocs.io/en/stable/developer-guide/code-contributions/ + code-of-conduct: https://github.com/cncf/foundation/blob/master/code-of-conduct.md +documentation: + - https://argo-cd.readthedocs.io/ +distribution-points: + - https://github.com/argoproj/argo-cd/releases + - https://quay.io/repository/argoproj/argocd +security-artifacts: + threat-model: + threat-model-created: true + evidence-url: + - https://github.com/argoproj/argoproj/blob/master/docs/argo_threat_model.pdf + - https://github.com/argoproj/argoproj/blob/master/docs/end_user_threat_model.pdf + self-assessment: + self-assessment-created: false + comment: | + An extensive self-assessment was performed for CNCF graduation. Because the self-assessment process was evolving + at the time, no standardized document has been published. +security-testing: + - tool-type: sca + tool-name: Dependabot + tool-version: "2" + tool-url: https://github.com/dependabot + integration: + ad-hoc: false + ci: false + before-release: false + tool-rulesets: + - https://github.com/argoproj/argo-cd/blob/master/.github/dependabot.yml + - tool-type: sca + tool-name: Snyk + tool-version: latest + tool-url: https://snyk.io/ + integration: + ad-hoc: true + ci: true + before-release: false + - tool-type: sast + tool-name: CodeQL + tool-version: latest + tool-url: https://codeql.github.com/ + integration: + ad-hoc: false + ci: true + before-release: false + comment: | + We use the default configuration with the latest version. +security-assessments: + - auditor-name: Trail of Bits + auditor-url: https://trailofbits.com + auditor-report: https://github.com/argoproj/argoproj/blob/master/docs/argo_security_final_report.pdf + report-year: 2021 + - auditor-name: Ada Logics + auditor-url: https://adalogics.com + auditor-report: https://github.com/argoproj/argoproj/blob/master/docs/argo_security_audit_2022.pdf + report-year: 2022 + - auditor-name: Ada Logics + auditor-url: https://adalogics.com + auditor-report: https://github.com/argoproj/argoproj/blob/master/docs/audit_fuzzer_adalogics_2022.pdf + report-year: 2022 + comment: | + Part of the audit was performed by Ada Logics, focussed on fuzzing. + - auditor-name: Chainguard + auditor-url: https://chainguard.dev + auditor-report: https://github.com/argoproj/argoproj/blob/master/docs/software_supply_chain_slsa_assessment_chainguard_2023.pdf + report-year: 2023 + comment: | + Confirmed the project's release process as achieving SLSA (v0.1) level 3. +security-contacts: + - type: email + value: cncf-argo-security@lists.cncf.io + primary: true +vulnerability-reporting: + accepts-vulnerability-reports: true + email-contact: cncf-argo-security@lists.cncf.io + security-policy: https://github.com/argoproj/argo-cd/security/policy + bug-bounty-available: true + bug-bounty-url: https://hackerone.com/ibb/policy_scopes + out-scope: + - vulnerable and outdated components # See https://github.com/argoproj/argo-cd/blob/master/SECURITY.md#a-word-about-security-scanners + - security logging and monitoring failures +dependencies: + third-party-packages: true + dependencies-lists: + - https://github.com/argoproj/argo-cd/blob/master/go.mod + - https://github.com/argoproj/argo-cd/blob/master/Dockerfile + - https://github.com/argoproj/argo-cd/blob/master/ui/package.json + sbom: + - sbom-file: https://github.com/argoproj/argo-cd/releases # Every release's assets include SBOMs. + sbom-format: SPDX + dependencies-lifecycle: + policy-url: https://argo-cd.readthedocs.io/en/stable/developer-guide/release-process-and-cadence/#dependencies-lifecycle-policy + env-dependencies-policy: + policy-url: https://argo-cd.readthedocs.io/en/stable/developer-guide/release-process-and-cadence/#dependencies-lifecycle-policy diff --git a/docs/developer-guide/release-process-and-cadence.md b/docs/developer-guide/release-process-and-cadence.md index 051de617f0776..337d5bafc3528 100644 --- a/docs/developer-guide/release-process-and-cadence.md +++ b/docs/developer-guide/release-process-and-cadence.md @@ -78,3 +78,21 @@ The feature PR must include: If these criteria are not met by the RC date, the feature will be ineligible for inclusion in the RC series or GA for that minor release. It will have to wait for the next minor release. + +### Security Patch Policy + +CVEs in Argo CD code will be patched for all [supported versions](../operator-manual/installation.md#supported-versions). + +### Dependencies Lifecycle Policy + +Dependencies are evaluated before being introduced to ensure they: + +1) are actively maintained +2) are maintained by trustworthy maintainers + +These evaluations vary from dependency to dependencies. + +Dependencies are also scheduled for removal if the project has been deprecated or if the project is no longer maintained. + +CVEs in dependencies will be patched for all supported versions if the CVE is applicable and is assessed by Snyk to be +of high or critical severity. Automation generates a [new Snyk scan weekly](../snyk). From be2a01c231e09b9056f115ef10f22f34f0290d9e Mon Sep 17 00:00:00 2001 From: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Date: Thu, 2 Nov 2023 21:21:16 +0530 Subject: [PATCH 082/269] feat: grace period for repo errors to prevent aggressive unknown sync state (#16085) * feat: added grace period for repo errors to prevent aggressive sync state unknowns Signed-off-by: Soumya Ghosh Dastidar * feat: updated docs Signed-off-by: Soumya Ghosh Dastidar * fix: e2e test Signed-off-by: Soumya Ghosh Dastidar * feat: resolved review comments Signed-off-by: Soumya Ghosh Dastidar * feat: update unit test Signed-off-by: Soumya Ghosh Dastidar * fix: codegen Signed-off-by: Soumya Ghosh Dastidar --------- Signed-off-by: Soumya Ghosh Dastidar Signed-off-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> --- .../commands/argocd_application_controller.go | 3 + cmd/argocd/commands/admin/app.go | 7 +- controller/appcontroller.go | 10 +- controller/appcontroller_test.go | 113 ++++++------ controller/state.go | 38 +++- controller/state_test.go | 166 ++++++++++++------ controller/sync.go | 9 +- controller/sync_test.go | 10 +- .../operator-manual/argocd-cmd-params-cm.yaml | 2 + .../argocd-application-controller.md | 1 + ...cd-application-controller-statefulset.yaml | 6 + manifests/core-install.yaml | 6 + manifests/ha/install.yaml | 6 + manifests/ha/namespace-install.yaml | 6 + manifests/install.yaml | 6 + manifests/namespace-install.yaml | 6 + 16 files changed, 269 insertions(+), 126 deletions(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 391751b0d95d1..4f7e587e36564 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -50,6 +50,7 @@ func NewCommand() *cobra.Command { clientConfig clientcmd.ClientConfig appResyncPeriod int64 appHardResyncPeriod int64 + repoErrorGracePeriod int64 repoServerAddress string repoServerTimeoutSeconds int selfHealTimeoutSeconds int @@ -154,6 +155,7 @@ func NewCommand() *cobra.Command { resyncDuration, hardResyncDuration, time.Duration(selfHealTimeoutSeconds)*time.Second, + time.Duration(repoErrorGracePeriod)*time.Second, metricsPort, metricsCacheExpiration, metricsAplicationLabels, @@ -188,6 +190,7 @@ func NewCommand() *cobra.Command { clientConfig = cli.AddKubectlFlagsToCmd(&command) command.Flags().Int64Var(&appResyncPeriod, "app-resync", int64(env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_TIMEOUT", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Time period in seconds for application resync.") command.Flags().Int64Var(&appHardResyncPeriod, "app-hard-resync", int64(env.ParseDurationFromEnv("ARGOCD_HARD_RECONCILIATION_TIMEOUT", defaultAppHardResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Time period in seconds for application hard resync.") + command.Flags().Int64Var(&repoErrorGracePeriod, "repo-error-grace-period-seconds", int64(env.ParseDurationFromEnv("ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Grace period in seconds for ignoring consecutive errors while communicating with repo server.") command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address.") command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") command.Flags().IntVar(&statusProcessors, "status-processors", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS", 20, 0, math.MaxInt32), "Number of application status processors") diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index a4f4557858a22..10e4effe8797a 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -384,7 +384,7 @@ func reconcileApplications( ) appStateManager := controller.NewAppStateManager( - argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false) + argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false, 0) appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector}) if err != nil { @@ -419,7 +419,10 @@ func reconcileApplications( sources = append(sources, app.Spec.GetSource()) revisions = append(revisions, app.Spec.GetSource().TargetRevision) - res := appStateManager.CompareAppState(&app, proj, revisions, sources, false, false, nil, false) + res, err := appStateManager.CompareAppState(&app, proj, revisions, sources, false, false, nil, false) + if err != nil { + return nil, err + } items = append(items, appReconcileResult{ Name: app.Name, Conditions: app.Status.Conditions, diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 3582d907e5f5b..964bcc1aa0dec 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -143,6 +143,7 @@ func NewApplicationController( appResyncPeriod time.Duration, appHardResyncPeriod time.Duration, selfHealTimeout time.Duration, + repoErrorGracePeriod time.Duration, metricsPort int, metricsCacheExpiration time.Duration, metricsApplicationLabels []string, @@ -259,7 +260,7 @@ func NewApplicationController( } } stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterFilter, argo.NewResourceTracking()) - appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth) + appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod) ctrl.appInformer = appInformer ctrl.appLister = appLister ctrl.projInformer = projInformer @@ -1512,10 +1513,15 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo } now := metav1.Now() - compareResult := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, + compareResult, err := ctrl.appStateManager.CompareAppState(app, project, revisions, sources, refreshType == appv1.RefreshTypeHard, comparisonLevel == CompareWithLatestForceResolve, localManifests, hasMultipleSources) + if goerrors.Is(err, CompareStateRepoError) { + logCtx.Warnf("Ignoring temporary failed attempt to compare app state against repo: %v", err) + return // short circuit if git error is encountered + } + for k, v := range compareResult.timings { logCtx = logCtx.WithField(k, v.Milliseconds()) } diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index a47114f5c2527..9c2933feeb6df 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -59,7 +59,7 @@ type fakeData struct { applicationNamespaces []string } -func newFakeController(data *fakeData) *ApplicationController { +func newFakeController(data *fakeData, repoErr error) *ApplicationController { var clust corev1.Secret err := yaml.Unmarshal([]byte(fakeCluster), &clust) if err != nil { @@ -71,10 +71,18 @@ func newFakeController(data *fakeData) *ApplicationController { if len(data.manifestResponses) > 0 { for _, response := range data.manifestResponses { - mockRepoClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(response, nil).Once() + if repoErr != nil { + mockRepoClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(response, repoErr).Once() + } else { + mockRepoClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(response, nil).Once() + } } } else { - mockRepoClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(data.manifestResponse, nil) + if repoErr != nil { + mockRepoClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(data.manifestResponse, repoErr).Once() + } else { + mockRepoClient.On("GenerateManifest", mock.Anything, mock.Anything).Return(data.manifestResponse, nil).Once() + } } mockRepoClientset := mockrepoclient.Clientset{RepoServerServiceClient: &mockRepoClient} @@ -116,6 +124,7 @@ func newFakeController(data *fakeData) *ApplicationController { time.Minute, time.Hour, time.Minute, + time.Second*10, common.DefaultPortArgoCDMetrics, data.metricsCacheExpiration, []string{}, @@ -364,7 +373,7 @@ func newFakeCM() map[string]interface{} { func TestAutoSync(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -381,7 +390,7 @@ func TestAutoSync(t *testing.T) { func TestAutoSyncNotAllowEmpty(t *testing.T) { app := newFakeApp() app.Spec.SyncPolicy.Automated.Prune = true - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -394,7 +403,7 @@ func TestAutoSyncAllowEmpty(t *testing.T) { app := newFakeApp() app.Spec.SyncPolicy.Automated.Prune = true app.Spec.SyncPolicy.Automated.AllowEmpty = true - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -408,7 +417,7 @@ func TestSkipAutoSync(t *testing.T) { // Set current to 'aaaaa', desired to 'aaaa' and mark system OutOfSync t.Run("PreviouslySyncedToRevision", func(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @@ -423,7 +432,7 @@ func TestSkipAutoSync(t *testing.T) { // Verify we skip when we are already Synced (even if revision is different) t.Run("AlreadyInSyncedState", func(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeSynced, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -439,7 +448,7 @@ func TestSkipAutoSync(t *testing.T) { t.Run("AutoSyncIsDisabled", func(t *testing.T) { app := newFakeApp() app.Spec.SyncPolicy = nil - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -456,7 +465,7 @@ func TestSkipAutoSync(t *testing.T) { app := newFakeApp() now := metav1.Now() app.DeletionTimestamp = &now - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -482,7 +491,7 @@ func TestSkipAutoSync(t *testing.T) { Source: *app.Spec.Source.DeepCopy(), }, } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -496,7 +505,7 @@ func TestSkipAutoSync(t *testing.T) { t.Run("NeedsToPruneResourcesOnlyButAutomatedPruneDisabled", func(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", @@ -522,7 +531,7 @@ func TestAutoSyncIndicateError(t *testing.T) { }, }, } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @@ -557,7 +566,7 @@ func TestAutoSyncParameterOverrides(t *testing.T) { }, }, } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) syncStatus := v1alpha1.SyncStatus{ Status: v1alpha1.SyncStatusCodeOutOfSync, Revision: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", @@ -614,7 +623,7 @@ func TestFinalizeAppDeletion(t *testing.T) { appObj := kube.MustToUnstructured(&app) ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(appObj): appObj, - }}) + }}, nil) patched := false fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) @@ -664,7 +673,7 @@ func TestFinalizeAppDeletion(t *testing.T) { kube.GetResourceKey(appObj): appObj, kube.GetResourceKey(strayObj): strayObj, }, - }) + }, nil) patched := false fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) @@ -699,7 +708,7 @@ func TestFinalizeAppDeletion(t *testing.T) { appObj := kube.MustToUnstructured(&app) ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(appObj): appObj, - }}) + }}, nil) patched := false fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) defaultReactor := fakeAppCs.ReactionChain[0] @@ -728,7 +737,7 @@ func TestFinalizeAppDeletion(t *testing.T) { appObj := kube.MustToUnstructured(&app) ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(appObj): appObj, - }}) + }}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) defaultReactor := fakeAppCs.ReactionChain[0] @@ -792,7 +801,7 @@ func TestNormalizeApplication(t *testing.T) { { // Verify we normalize the app because project is missing - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) key, _ := cache.MetaNamespaceKeyFunc(app) ctrl.appRefreshQueue.AddRateLimited(key) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) @@ -814,7 +823,7 @@ func TestNormalizeApplication(t *testing.T) { // Verify we don't unnecessarily normalize app when project is set app.Spec.Project = "default" data.apps[0] = app - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) key, _ := cache.MetaNamespaceKeyFunc(app) ctrl.appRefreshQueue.AddRateLimited(key) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) @@ -839,7 +848,7 @@ func TestHandleAppUpdated(t *testing.T) { app.Spec.Destination.Server = v1alpha1.KubernetesInternalAPIServerAddr proj := defaultProj.DeepCopy() proj.Spec.SourceNamespaces = []string{test.FakeArgoCDNamespace} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, proj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, proj}}, nil) ctrl.handleObjectUpdated(map[string]bool{app.InstanceName(ctrl.namespace): true}, kube.GetObjectRef(kube.MustToUnstructured(app))) isRequested, level := ctrl.isRefreshRequested(app.QualifiedName()) @@ -866,7 +875,7 @@ func TestHandleOrphanedResourceUpdated(t *testing.T) { proj := defaultProj.DeepCopy() proj.Spec.OrphanedResources = &v1alpha1.OrphanedResourcesMonitorSettings{} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app1, app2, proj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app1, app2, proj}}, nil) ctrl.handleObjectUpdated(map[string]bool{}, corev1.ObjectReference{UID: "test", Kind: kube.DeploymentKind, Name: "test", Namespace: test.FakeArgoCDNamespace}) @@ -901,7 +910,7 @@ func TestGetResourceTree_HasOrphanedResources(t *testing.T) { kube.NewResourceKey("apps", "Deployment", "default", "deploy1"): {ResourceNode: orphanedDeploy1}, kube.NewResourceKey("apps", "Deployment", "default", "deploy2"): {ResourceNode: orphanedDeploy2}, }, - }) + }, nil) tree, err := ctrl.getResourceTree(app, []*v1alpha1.ResourceDiff{{ Namespace: "default", Name: "nginx-deployment", @@ -917,7 +926,7 @@ func TestGetResourceTree_HasOrphanedResources(t *testing.T) { } func TestSetOperationStateOnDeletedApp(t *testing.T) { - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil patched := false @@ -948,7 +957,7 @@ func TestSetOperationStateLogRetries(t *testing.T) { t.Cleanup(func() { logrus.StandardLogger().ReplaceHooks(logrus.LevelHooks{}) }) - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil patched := false @@ -999,7 +1008,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { app.Status.Sync.ComparedTo.Source = app.Spec.GetSource() } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) t.Run("no need to refresh just reconciled application", func(t *testing.T) { needRefresh, _, _ := ctrl.needRefreshAppStatus(app, 1*time.Hour, 2*time.Hour) @@ -1011,7 +1020,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { assert.False(t, needRefresh) // use a one-off controller so other tests don't have a manual refresh request - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) // refresh app using the 'deepest' requested comparison level ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), nil) @@ -1039,7 +1048,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { app := app.DeepCopy() // use a one-off controller so other tests don't have a manual refresh request - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) needRefresh, _, _ := ctrl.needRefreshAppStatus(app, 1*time.Hour, 2*time.Hour) assert.False(t, needRefresh) @@ -1069,7 +1078,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { } // use a one-off controller so other tests don't have a manual refresh request - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) needRefresh, _, _ := ctrl.needRefreshAppStatus(app, 1*time.Hour, 2*time.Hour) assert.False(t, needRefresh) @@ -1149,7 +1158,7 @@ func TestNeedRefreshAppStatus(t *testing.T) { } func TestUpdatedManagedNamespaceMetadata(t *testing.T) { - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) app := newFakeApp() app.Spec.SyncPolicy.ManagedNamespaceMetadata = &v1alpha1.ManagedNamespaceMetadata{ Labels: map[string]string{ @@ -1173,7 +1182,7 @@ func TestUpdatedManagedNamespaceMetadata(t *testing.T) { } func TestUnchangedManagedNamespaceMetadata(t *testing.T) { - ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{}}, nil) app := newFakeApp() app.Spec.SyncPolicy.ManagedNamespaceMetadata = &v1alpha1.ManagedNamespaceMetadata{ Labels: map[string]string{ @@ -1216,7 +1225,7 @@ func TestRefreshAppConditions(t *testing.T) { t.Run("NoErrorConditions", func(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}, nil) _, hasErrors := ctrl.refreshAppConditions(app) assert.False(t, hasErrors) @@ -1227,7 +1236,7 @@ func TestRefreshAppConditions(t *testing.T) { app := newFakeApp() app.Status.SetConditions([]v1alpha1.ApplicationCondition{{Type: v1alpha1.ApplicationConditionExcludedResourceWarning}}, nil) - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}, nil) _, hasErrors := ctrl.refreshAppConditions(app) assert.False(t, hasErrors) @@ -1240,7 +1249,7 @@ func TestRefreshAppConditions(t *testing.T) { app.Spec.Project = "wrong project" app.Status.SetConditions([]v1alpha1.ApplicationCondition{{Type: v1alpha1.ApplicationConditionInvalidSpecError, Message: "old message"}}, nil) - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}}, nil) _, hasErrors := ctrl.refreshAppConditions(app) assert.True(t, hasErrors) @@ -1264,7 +1273,7 @@ func TestUpdateReconciledAt(t *testing.T) { Revision: "abc123", }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - }) + }, nil) key, _ := cache.MetaNamespaceKeyFunc(app) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) fakeAppCs.ReactionChain = nil @@ -1322,7 +1331,7 @@ func TestProjectErrorToCondition(t *testing.T) { Revision: "abc123", }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), - }) + }, nil) key, _ := cache.MetaNamespaceKeyFunc(app) ctrl.appRefreshQueue.AddRateLimited(key) ctrl.requestAppRefresh(app.Name, CompareWithRecent.Pointer(), nil) @@ -1341,7 +1350,7 @@ func TestProjectErrorToCondition(t *testing.T) { func TestFinalizeProjectDeletion_HasApplications(t *testing.T) { app := newFakeApp() proj := &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace}} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, proj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, proj}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) patched := false @@ -1357,7 +1366,7 @@ func TestFinalizeProjectDeletion_HasApplications(t *testing.T) { func TestFinalizeProjectDeletion_DoesNotHaveApplications(t *testing.T) { proj := &v1alpha1.AppProject{ObjectMeta: metav1.ObjectMeta{Name: "default", Namespace: test.FakeArgoCDNamespace}} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{&defaultProj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{&defaultProj}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) receivedPatch := map[string]interface{}{} @@ -1383,7 +1392,7 @@ func TestProcessRequestedAppOperation_FailedNoRetries(t *testing.T) { app.Operation = &v1alpha1.Operation{ Sync: &v1alpha1.SyncOperation{}, } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { @@ -1408,7 +1417,7 @@ func TestProcessRequestedAppOperation_InvalidDestination(t *testing.T) { proj := defaultProj proj.Name = "test-project" proj.Spec.SourceNamespaces = []string{test.FakeArgoCDNamespace} - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &proj}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &proj}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) receivedPatch := map[string]interface{}{} func() { @@ -1437,7 +1446,7 @@ func TestProcessRequestedAppOperation_FailedHasRetries(t *testing.T) { Sync: &v1alpha1.SyncOperation{}, Retry: v1alpha1.RetryStrategy{Limit: 1}, } - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { @@ -1480,7 +1489,7 @@ func TestProcessRequestedAppOperation_RunningPreviouslyFailed(t *testing.T) { Revision: "abc123", }, } - ctrl := newFakeController(data) + ctrl := newFakeController(data, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { @@ -1513,7 +1522,7 @@ func TestProcessRequestedAppOperation_HasRetriesTerminated(t *testing.T) { Revision: "abc123", }, } - ctrl := newFakeController(data) + ctrl := newFakeController(data, nil) fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) receivedPatch := map[string]interface{}{} fakeAppCs.PrependReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { @@ -1540,7 +1549,7 @@ func TestGetAppHosts(t *testing.T) { Revision: "abc123", }, } - ctrl := newFakeController(data) + ctrl := newFakeController(data, nil) mockStateCache := &mockstatecache.LiveStateCache{} mockStateCache.On("IterateResources", mock.Anything, mock.MatchedBy(func(callback func(res *clustercache.Resource, info *statecache.ResourceInfo)) bool { // node resource @@ -1590,15 +1599,15 @@ func TestGetAppHosts(t *testing.T) { func TestMetricsExpiration(t *testing.T) { app := newFakeApp() // Check expiration is disabled by default - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) assert.False(t, ctrl.metricsServer.HasExpiration()) // Check expiration is enabled if set - ctrl = newFakeController(&fakeData{apps: []runtime.Object{app}, metricsCacheExpiration: 10 * time.Second}) + ctrl = newFakeController(&fakeData{apps: []runtime.Object{app}, metricsCacheExpiration: 10 * time.Second}, nil) assert.True(t, ctrl.metricsServer.HasExpiration()) } func TestToAppKey(t *testing.T) { - ctrl := newFakeController(&fakeData{}) + ctrl := newFakeController(&fakeData{}, nil) tests := []struct { name string input string @@ -1618,7 +1627,7 @@ func TestToAppKey(t *testing.T) { func Test_canProcessApp(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) ctrl.applicationNamespaces = []string{"good"} t.Run("without cluster filter, good namespace", func(t *testing.T) { app.Namespace = "good" @@ -1651,7 +1660,7 @@ func Test_canProcessAppSkipReconcileAnnotation(t *testing.T) { appSkipReconcileFalse.Annotations = map[string]string{common.AnnotationKeyAppSkipReconcile: "false"} appSkipReconcileTrue := newFakeApp() appSkipReconcileTrue.Annotations = map[string]string{common.AnnotationKeyAppSkipReconcile: "true"} - ctrl := newFakeController(&fakeData{}) + ctrl := newFakeController(&fakeData{}, nil) tests := []struct { name string input interface{} @@ -1672,7 +1681,7 @@ func Test_canProcessAppSkipReconcileAnnotation(t *testing.T) { func Test_syncDeleteOption(t *testing.T) { app := newFakeApp() - ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}) + ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) cm := newFakeCM() t.Run("without delete option object is deleted", func(t *testing.T) { cmObj := kube.MustToUnstructured(&cm) @@ -1699,7 +1708,7 @@ func TestAddControllerNamespace(t *testing.T) { ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app, &defaultProj}, manifestResponse: &apiclient.ManifestResponse{}, - }) + }, nil) ctrl.processAppRefreshQueueItem() @@ -1718,7 +1727,7 @@ func TestAddControllerNamespace(t *testing.T) { apps: []runtime.Object{app, &proj}, manifestResponse: &apiclient.ManifestResponse{}, applicationNamespaces: []string{appNamespace}, - }) + }, nil) ctrl.processAppRefreshQueueItem() diff --git a/controller/state.go b/controller/state.go index 2704545add445..15da3d2e624ed 100644 --- a/controller/state.go +++ b/controller/state.go @@ -3,12 +3,15 @@ package controller import ( "context" "encoding/json" + "errors" "fmt" - v1 "k8s.io/api/core/v1" "reflect" "strings" + goSync "sync" "time" + v1 "k8s.io/api/core/v1" + "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/health" "github.com/argoproj/gitops-engine/pkg/sync" @@ -40,6 +43,10 @@ import ( "github.com/argoproj/argo-cd/v2/util/stats" ) +var ( + CompareStateRepoError = errors.New("failed to get repo objects") +) + type resourceInfoProviderStub struct { } @@ -62,7 +69,7 @@ type managedResource struct { // AppStateManager defines methods which allow to compare application spec and actual application state. type AppStateManager interface { - CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool) *comparisonResult + CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool) (*comparisonResult, error) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) } @@ -105,10 +112,11 @@ type appStateManager struct { statusRefreshTimeout time.Duration resourceTracking argo.ResourceTracking persistResourceHealth bool + repoErrorCache goSync.Map + repoErrorGracePeriod time.Duration } func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) { - ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) if err != nil { @@ -345,7 +353,7 @@ func isManagedNamespace(ns *unstructured.Unstructured, app *v1alpha1.Application // CompareAppState compares application git state to the live app state, using the specified // revision and supplied source. If revision or overrides are empty, then compares against // revision and overrides in the app spec. -func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string, hasMultipleSources bool) *comparisonResult { +func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localManifests []string, hasMultipleSources bool) (*comparisonResult, error) { ts := stats.NewTimingStats() appLabelKey, resourceOverrides, resFilter, err := m.getComparisonSettings() @@ -361,7 +369,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 Revisions: revisions, }, healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown}, - } + }, nil } else { return &comparisonResult{ syncStatus: &v1alpha1.SyncStatus{ @@ -370,7 +378,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 Revision: revisions[0], }, healthStatus: &v1alpha1.HealthStatus{Status: health.HealthStatusUnknown}, - } + }, nil } } @@ -408,7 +416,21 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 targetObjs = make([]*unstructured.Unstructured, 0) msg := fmt.Sprintf("Failed to load target state: %s", err.Error()) conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionComparisonError, Message: msg, LastTransitionTime: &now}) + if firstSeen, ok := m.repoErrorCache.Load(app.Name); ok { + if time.Since(firstSeen.(time.Time)) <= m.repoErrorGracePeriod && !noRevisionCache { + // if first seen is less than grace period and it's not a Level 3 comparison, + // ignore error and short circuit + logCtx.Debugf("Ignoring repo error %v, already encountered error in grace period", err.Error()) + return nil, CompareStateRepoError + } + } else if !noRevisionCache { + logCtx.Debugf("Ignoring repo error %v, new occurrence", err.Error()) + m.repoErrorCache.Store(app.Name, time.Now()) + return nil, CompareStateRepoError + } failedToLoadObjs = true + } else { + m.repoErrorCache.Delete(app.Name) } } else { // Prevent applying local manifests for now when signature verification is enabled @@ -776,7 +798,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 }) ts.AddCheckpoint("health_ms") compRes.timings = ts.Timings() - return &compRes + return &compRes, nil } func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, revisions []string, sources []v1alpha1.ApplicationSource, hasMultipleSources bool, startedAt metav1.Time) error { @@ -832,6 +854,7 @@ func NewAppStateManager( statusRefreshTimeout time.Duration, resourceTracking argo.ResourceTracking, persistResourceHealth bool, + repoErrorGracePeriod time.Duration, ) AppStateManager { return &appStateManager{ liveStateCache: liveStateCache, @@ -847,6 +870,7 @@ func NewAppStateManager( statusRefreshTimeout: statusRefreshTimeout, resourceTracking: resourceTracking, persistResourceHealth: persistResourceHealth, + repoErrorGracePeriod: repoErrorGracePeriod, } } diff --git a/controller/state_test.go b/controller/state_test.go index dcb48e87fce9b..9d2df1f239185 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -2,6 +2,7 @@ package controller import ( "encoding/json" + "fmt" "os" "testing" "time" @@ -37,12 +38,13 @@ func TestCompareAppStateEmpty(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -51,6 +53,31 @@ func TestCompareAppStateEmpty(t *testing.T) { assert.Len(t, app.Status.Conditions, 0) } +// TestCompareAppStateRepoError tests the case when CompareAppState notices a repo error +func TestCompareAppStateRepoError(t *testing.T) { + app := newFakeApp() + ctrl := newFakeController(&fakeData{manifestResponses: make([]*apiclient.ManifestResponse, 3)}, fmt.Errorf("test repo error")) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, compRes) + assert.EqualError(t, err, CompareStateRepoError.Error()) + + // expect to still get compare state error to as inside grace period + compRes, err = ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, compRes) + assert.EqualError(t, err, CompareStateRepoError.Error()) + + time.Sleep(10 * time.Second) + // expect to not get error as outside of grace period, but status should be unknown + compRes, err = ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.NotNil(t, compRes) + assert.Nil(t, err) + assert.Equal(t, compRes.syncStatus.Status, argoappv1.SyncStatusCodeUnknown) +} + // TestCompareAppStateNamespaceMetadataDiffers tests comparison when managed namespace metadata differs func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { app := newFakeApp() @@ -75,12 +102,13 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -122,12 +150,13 @@ func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -149,12 +178,13 @@ func TestCompareAppStateMissing(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -180,12 +210,13 @@ func TestCompareAppStateExtra(t *testing.T) { key: pod, }, } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) assert.Equal(t, 1, len(compRes.resources)) @@ -210,12 +241,13 @@ func TestCompareAppStateHook(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, 0, len(compRes.resources)) @@ -241,12 +273,13 @@ func TestCompareAppStateSkipHook(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) assert.Equal(t, 1, len(compRes.resources)) @@ -270,13 +303,14 @@ func TestCompareAppStateCompareOptionIgnoreExtraneous(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -303,12 +337,13 @@ func TestCompareAppStateExtraHook(t *testing.T) { key: pod, }, } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -331,12 +366,13 @@ func TestAppRevisionsSingleSource(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) app := newFakeApp() revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, app.Spec.HasMultipleSources()) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, app.Spec.HasMultipleSources()) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.NotEmpty(t, compRes.syncStatus.Revision) @@ -370,12 +406,13 @@ func TestAppRevisionsMultiSource(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) app := newFakeMultiSourceApp() revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, app.Spec.HasMultipleSources()) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, app.Spec.GetSources(), false, false, nil, app.Spec.HasMultipleSources()) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Empty(t, compRes.syncStatus.Revision) @@ -417,12 +454,13 @@ func TestCompareAppStateDuplicatedNamespacedResources(t *testing.T) { kube.GetResourceKey(obj3): obj3, }, } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, 1, len(app.Status.Conditions)) @@ -457,8 +495,9 @@ func TestCompareAppStateManagedNamespaceMetadataWithLiveNsDoesNotGetPruned(t *te kube.GetResourceKey(ns): ns, }, } - ctrl := newFakeController(&data) - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, []string{}, app.Spec.Sources, false, false, nil, false) + ctrl := newFakeController(&data, nil) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, []string{}, app.Spec.Sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.Equal(t, 0, len(app.Status.Conditions)) @@ -512,13 +551,14 @@ func TestSetHealth(t *testing.T) { managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(deployment): deployment, }, - }) + }, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) } @@ -548,13 +588,14 @@ func TestSetHealthSelfReferencedApp(t *testing.T) { kube.GetResourceKey(deployment): deployment, kube.GetResourceKey(unstructuredApp): unstructuredApp, }, - }) + }, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.Equal(t, health.HealthStatusHealthy, compRes.healthStatus.Status) } @@ -574,7 +615,7 @@ func TestSetManagedResourcesWithOrphanedResources(t *testing.T) { AppName: "", }, }, - }) + }, nil) tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) @@ -603,7 +644,7 @@ func TestSetManagedResourcesWithResourcesOfAnotherApp(t *testing.T) { AppName: "app2", }, }, - }) + }, nil) tree, err := ctrl.setAppManagedResources(app1, &comparisonResult{managedResources: make([]managedResource, 0)}) @@ -622,13 +663,14 @@ func TestReturnUnknownComparisonStateOnSettingLoadError(t *testing.T) { configMapData: map[string]string{ "resource.customizations": "invalid setting", }, - }) + }, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.Equal(t, health.HealthStatusUnknown, compRes.healthStatus.Status) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) @@ -655,7 +697,7 @@ func TestSetManagedResourcesKnownOrphanedResourceExceptions(t *testing.T) { ResourceNode: argoappv1.ResourceNode{ResourceRef: argoappv1.ResourceRef{Kind: kube.ServiceAccountKind, Name: "kubernetes", Namespace: app.Namespace}}, }, }, - }) + }, nil) tree, err := ctrl.setAppManagedResources(app, &comparisonResult{managedResources: make([]managedResource, 0)}) @@ -668,7 +710,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { app := newFakeApp() ctrl := newFakeController(&fakeData{ apps: []runtime.Object{app}, - }) + }, nil) manager := ctrl.appStateManager.(*appStateManager) setRevisionHistoryLimit := func(value int) { i := int64(value) @@ -763,12 +805,13 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -789,12 +832,13 @@ func TestSignedResponseNoSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -820,12 +864,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -846,12 +891,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -872,12 +918,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -898,12 +945,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -925,14 +973,15 @@ func TestSignedResponseSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) testProj := signedProj testProj.Spec.SignatureKeys[0].KeyID = "4AEE18F83AFDEB24" sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &testProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &testProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -956,12 +1005,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { } // it doesn't matter for our test whether local manifests are valid localManifests := []string{"foobar"} - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeUnknown, compRes.syncStatus.Status) @@ -985,12 +1035,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1014,12 +1065,13 @@ func TestSignedResponseSignatureRequired(t *testing.T) { } // it doesn't matter for our test whether local manifests are valid localManifests := []string{""} - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "abc123") - compRes := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &signedProj, revisions, sources, false, false, localManifests, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeSynced, compRes.syncStatus.Status) @@ -1154,7 +1206,7 @@ func TestIsLiveResourceManaged(t *testing.T) { kube.GetResourceKey(unmanagedObjWrongGroup): unmanagedObjWrongGroup, kube.GetResourceKey(unmanagedObjWrongNamespace): unmanagedObjWrongNamespace, }, - }) + }, nil) manager := ctrl.appStateManager.(*appStateManager) appName := "guestbook" diff --git a/controller/sync.go b/controller/sync.go index 783183c17fc7c..2b925b7782b9e 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -3,6 +3,7 @@ package controller import ( "context" "encoding/json" + goerrors "errors" "fmt" "os" "strconv" @@ -152,7 +153,13 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha revisions = []string{revision} } - compareResult := m.CompareAppState(app, proj, revisions, sources, false, true, syncOp.Manifests, app.Spec.HasMultipleSources()) + // ignore error if CompareStateRepoError, this shouldn't happen as noRevisionCache is true + compareResult, err := m.CompareAppState(app, proj, revisions, sources, false, true, syncOp.Manifests, app.Spec.HasMultipleSources()) + if err != nil && !goerrors.Is(err, CompareStateRepoError) { + state.Phase = common.OperationError + state.Message = err.Error() + return + } // We now have a concrete commit SHA. Save this in the sync result revision so that we remember // what we should be syncing to when resuming operations. diff --git a/controller/sync_test.go b/controller/sync_test.go index da68e5d9a3dfe..309f846ca6460 100644 --- a/controller/sync_test.go +++ b/controller/sync_test.go @@ -41,7 +41,7 @@ func TestPersistRevisionHistory(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) // Sync with source unspecified opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{ @@ -87,7 +87,7 @@ func TestPersistManagedNamespaceMetadataState(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) // Sync with source unspecified opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{ @@ -118,7 +118,7 @@ func TestPersistRevisionHistoryRollback(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) // Sync with source specified source := v1alpha1.ApplicationSource{ @@ -172,7 +172,7 @@ func TestSyncComparisonError(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) // Sync with source unspecified opState := &v1alpha1.OperationState{Operation: v1alpha1.Operation{ @@ -217,7 +217,7 @@ func TestAppStateManager_SyncAppState(t *testing.T) { }, managedLiveObjs: make(map[kube.ResourceKey]*unstructured.Unstructured), } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) return &fixture{ project: project, diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index f9f8b3fc14d52..11661232f4ab5 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -58,6 +58,8 @@ data: controller.sharding.algorithm: legacy # Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit. controller.kubectl.parallelism.limit: "20" + # Grace period in seconds for ignoring consecutive errors while communicating with repo server. + controller.repo.error.grace.period.seconds: "180" ## Server properties # Listen on given address for incoming connections (default "0.0.0.0") diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 99e4c42df28db..e03cf7fc51536 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -55,6 +55,7 @@ argocd-application-controller [flags] --redis-insecure-skip-tls-verify Skip Redis server certificate validation. --redis-use-tls Use TLS when connecting to Redis. --redisdb int Redis database. + --repo-error-grace-period-seconds int Grace period in seconds for ignoring consecutive errors while communicating with repo server. (default 180) --repo-server string Repo server address. (default "argocd-repo-server:8081") --repo-server-plaintext Disable TLS on connections to repo server --repo-server-strict-tls Whether to use strict validation of the TLS cert presented by the repo server diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index 33f02100a947a..0b7a230881c8e 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -35,6 +35,12 @@ spec: name: argocd-cm key: timeout.hard.reconciliation optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.error.grace.period.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: configMapKeyRef: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 69514971c03e9..bd196b10ca374 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21211,6 +21211,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: configMapKeyRef: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 8576a7d651f67..522347b1854ea 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -23014,6 +23014,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: configMapKeyRef: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 4b33a7ceb867e..471aac5912c04 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2669,6 +2669,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: configMapKeyRef: diff --git a/manifests/install.yaml b/manifests/install.yaml index 45d1864c55691..86f45d765f90a 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -22058,6 +22058,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: configMapKeyRef: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 89cb5ed4ff5ed..5641d06dbe56b 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1713,6 +1713,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + key: controller.repo.error.grace.period.seconds + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: configMapKeyRef: From aced025e6081f8650ab91fd0d19ec9d945e46fdd Mon Sep 17 00:00:00 2001 From: Pavel Date: Fri, 3 Nov 2023 01:07:50 +0800 Subject: [PATCH 083/269] feat: add retry logic for k8s client #7692 (#16154) * add retry logic for k8s client Signed-off-by: Pavel Aborilov * add docs for retry logic and envs to manifests Signed-off-by: Pavel Aborilov --------- Signed-off-by: Pavel Aborilov Signed-off-by: Pavel --- .../operator-manual/argocd-cmd-params-cm.yaml | 8 ++ docs/operator-manual/high_availability.md | 37 +++++++- ...ocd-application-controller-deployment.yaml | 14 ++- ...cd-application-controller-statefulset.yaml | 14 ++- .../base/server/argocd-server-deployment.yaml | 12 +++ manifests/core-install.yaml | 12 +++ manifests/ha/install.yaml | 24 +++++ manifests/ha/namespace-install.yaml | 24 +++++ manifests/install.yaml | 24 +++++ manifests/namespace-install.yaml | 24 +++++ pkg/apis/application/v1alpha1/types.go | 10 ++- util/http/http.go | 87 ++++++++++++++++++- 12 files changed, 281 insertions(+), 9 deletions(-) diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index 11661232f4ab5..bb55c6fb213f3 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -58,6 +58,10 @@ data: controller.sharding.algorithm: legacy # Number of allowed concurrent kubectl fork/execs. Any value less than 1 means no limit. controller.kubectl.parallelism.limit: "20" + # The maximum number of retries for each request + controller.k8sclient.retry.max: "0" + # The initial backoff delay on the first retry attempt in ms. Subsequent retries will double this backoff time up to a maximum threshold + controller.k8sclient.retry.base.backoff: "100" # Grace period in seconds for ignoring consecutive errors while communicating with repo server. controller.repo.error.grace.period.seconds: "180" @@ -74,6 +78,10 @@ data: server.rootpath: "" # Directory path that contains additional static assets server.staticassets: "/shared/app" + # The maximum number of retries for each request + server.k8sclient.retry.max: "0" + # The initial backoff delay on the first retry attempt in ms. Subsequent retries will double this backoff time up to a maximum threshold + server.k8sclient.retry.base.backoff: "100" # Set the logging format. One of: text|json (default "text") server.log.format: "text" diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index db4cb0a6e077e..7de532d9632c3 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -295,4 +295,39 @@ backoff = time.Since(lastRequeueTime) >= WORKQUEUE_FAILURE_COOLDOWN_NS ? ``` backoff = WORKQUEUE_BASE_DELAY_NS -``` \ No newline at end of file +``` + +## HTTP Request Retry Strategy + +In scenarios where network instability or transient server errors occur, the retry strategy ensures the robustness of HTTP communication by automatically resending failed requests. It uses a combination of maximum retries and backoff intervals to prevent overwhelming the server or thrashing the network. + +### Configuring Retries + +The retry logic can be fine-tuned with the following environment variables: + +* `ARGOCD_K8SCLIENT_RETRY_MAX` - The maximum number of retries for each request. The request will be dropped after this count is reached. Defaults to 0 (no retries). +* `ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF` - The initial backoff delay on the first retry attempt in ms. Subsequent retries will double this backoff time up to a maximum threshold. Defaults to 100ms. + +### Backoff Strategy + +The backoff strategy employed is a simple exponential backoff without jitter. The backoff time increases exponentially with each retry attempt until a maximum backoff duration is reached. + +The formula for calculating the backoff time is: + +``` +backoff = min(retryWaitMax, baseRetryBackoff * (2 ^ retryAttempt)) +``` +Where `retryAttempt` starts at 0 and increments by 1 for each subsequent retry. + +### Maximum Wait Time + +There is a cap on the backoff time to prevent excessive wait times between retries. This cap is defined by: + +`retryWaitMax` - The maximum duration to wait before retrying. This ensures that retries happen within a reasonable timeframe. Defaults to 10 seconds. + +### Non-Retriable Conditions + +Not all HTTP responses are eligible for retries. The following conditions will not trigger a retry: + +* Responses with a status code indicating client errors (4xx) except for 429 Too Many Requests. +* Responses with the status code 501 Not Implemented. diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 14cb1a317bab3..9b618d96367dc 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -160,6 +160,18 @@ spec: name: argocd-cmd-params-cm key: controller.heatbeat.time optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.max + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.base.backoff + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -215,4 +227,4 @@ spec: - key: tls.key path: tls.key - key: ca.crt - path: ca.crt \ No newline at end of file + path: ca.crt diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index 0b7a230881c8e..3c576a421a25c 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -161,6 +161,18 @@ spec: name: argocd-cmd-params-cm key: controller.kubectl.parallelism.limit optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.max + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.base.backoff + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller @@ -216,4 +228,4 @@ spec: - key: tls.key path: tls.key - key: ca.crt - path: ca.crt \ No newline at end of file + path: ca.crt diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index 66c6ed384b1d2..b09891d26e529 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -227,6 +227,18 @@ spec: name: argocd-cmd-params-cm key: server.enable.proxy.extension optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.k8sclient.retry.max + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.k8sclient.retry.base.backoff + optional: true volumeMounts: - name: ssh-known-hosts mountPath: /app/config/ssh diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index bd196b10ca374..a0943c86e2f57 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21337,6 +21337,18 @@ spec: key: controller.kubectl.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 522347b1854ea..d975ce383bebc 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -22888,6 +22888,18 @@ spec: key: server.enable.proxy.extension name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -23140,6 +23152,18 @@ spec: key: controller.kubectl.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 471aac5912c04..33ada40e37004 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2543,6 +2543,18 @@ spec: key: server.enable.proxy.extension name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -2795,6 +2807,18 @@ spec: key: controller.kubectl.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/install.yaml b/manifests/install.yaml index 86f45d765f90a..27109b5141f86 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21932,6 +21932,18 @@ spec: key: server.enable.proxy.extension name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -22184,6 +22196,18 @@ spec: key: controller.kubectl.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 5641d06dbe56b..9e6f98030d89b 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1587,6 +1587,18 @@ spec: key: server.enable.proxy.extension name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: server.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: @@ -1839,6 +1851,18 @@ spec: key: controller.kubectl.parallelism.limit name: argocd-cmd-params-cm optional: true + - name: ARGOCD_K8SCLIENT_RETRY_MAX + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.max + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF + valueFrom: + configMapKeyRef: + key: controller.k8sclient.retry.base.backoff + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index c2aa7f2d10bdb..e18fcd1cdf057 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -35,11 +35,11 @@ import ( "k8s.io/client-go/tools/clientcmd/api" "sigs.k8s.io/yaml" - "github.com/argoproj/argo-cd/v2/util/env" - "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/util/collections" + "github.com/argoproj/argo-cd/v2/util/env" "github.com/argoproj/argo-cd/v2/util/helm" + utilhttp "github.com/argoproj/argo-cd/v2/util/http" "github.com/argoproj/argo-cd/v2/util/security" ) @@ -2892,6 +2892,12 @@ func SetK8SConfigDefaults(config *rest.Config) error { config.Timeout = K8sServerSideTimeout config.Transport = tr + maxRetries := env.ParseInt64FromEnv(utilhttp.EnvRetryMax, 0, 1, math.MaxInt64) + if maxRetries > 0 { + backoffDurationMS := env.ParseInt64FromEnv(utilhttp.EnvRetryBaseBackoff, 100, 1, math.MaxInt64) + backoffDuration := time.Duration(backoffDurationMS) * time.Millisecond + config.WrapTransport = utilhttp.WithRetry(maxRetries, backoffDuration) + } return nil } diff --git a/util/http/http.go b/util/http/http.go index 2572e739f009d..fcf8447e1e2f6 100644 --- a/util/http/http.go +++ b/util/http/http.go @@ -1,21 +1,32 @@ package http import ( + "bytes" "fmt" + "io" "math" "net/http" "net/http/httputil" "strconv" "strings" + "time" - "github.com/argoproj/argo-cd/v2/util/env" + log "github.com/sirupsen/logrus" + "k8s.io/client-go/transport" "github.com/argoproj/argo-cd/v2/common" - - log "github.com/sirupsen/logrus" + "github.com/argoproj/argo-cd/v2/util/env" ) -const maxCookieLength = 4093 +const ( + maxCookieLength = 4093 + + // limit size of the resp to 512KB + respReadLimit = int64(524288) + retryWaitMax = time.Duration(10) * time.Second + EnvRetryMax = "ARGOCD_K8SCLIENT_RETRY_MAX" + EnvRetryBaseBackoff = "ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF" +) // max number of chunks a cookie can be broken into. To be compatible with // widest range of browsers, you shouldn't create more than 30 cookies per domain @@ -160,3 +171,71 @@ func (rt *TransportWithHeader) RoundTrip(r *http.Request) (*http.Response, error } return rt.RoundTripper.RoundTrip(r) } + +func WithRetry(maxRetries int64, baseRetryBackoff time.Duration) transport.WrapperFunc { + return func(rt http.RoundTripper) http.RoundTripper { + return &retryTransport{ + inner: rt, + maxRetries: maxRetries, + backoff: baseRetryBackoff, + } + } +} + +type retryTransport struct { + inner http.RoundTripper + maxRetries int64 + backoff time.Duration +} + +func isRetriable(resp *http.Response) bool { + if resp == nil { + return false + } + if resp.StatusCode == http.StatusTooManyRequests { + return true + } + if resp.StatusCode == 0 || (resp.StatusCode >= 500 && resp.StatusCode != http.StatusNotImplemented) { + return true + } + return false +} + +func (t *retryTransport) RoundTrip(req *http.Request) (*http.Response, error) { + var resp *http.Response + var err error + backoff := t.backoff + var bodyBytes []byte + if req.Body != nil { + bodyBytes, _ = io.ReadAll(req.Body) + } + for i := 0; i <= int(t.maxRetries); i++ { + req.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) + resp, err = t.inner.RoundTrip(req) + if i < int(t.maxRetries) && (err != nil || isRetriable(resp)) { + if resp != nil && resp.Body != nil { + drainBody(resp.Body) + } + if backoff > retryWaitMax { + backoff = retryWaitMax + } + select { + case <-time.After(backoff): + case <-req.Context().Done(): + return nil, req.Context().Err() + } + backoff *= 2 + continue + } + break + } + return resp, err +} + +func drainBody(body io.ReadCloser) { + defer body.Close() + _, err := io.Copy(io.Discard, io.LimitReader(body, respReadLimit)) + if err != nil { + log.Warnf("error reading response body: %s", err.Error()) + } +} From 4ce5bb85467154e86e9db2cb6bf320e870b5eaf4 Mon Sep 17 00:00:00 2001 From: Jeremy Chabernaud Date: Fri, 3 Nov 2023 16:21:50 +0100 Subject: [PATCH 084/269] docs: add Axians ACSP to users (#16226) Signed-off-by: djerfy --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 85fe16196ce9b..657f2b8270449 100644 --- a/USERS.md +++ b/USERS.md @@ -26,6 +26,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Arctiq Inc.](https://www.arctiq.ca) 1. [ARZ Allgemeines Rechenzentrum GmbH](https://www.arz.at/) 1. [Autodesk](https://www.autodesk.com) +1. [Axians ACSP](https://www.axians.fr) 1. [Axual B.V.](https://axual.com) 1. [Back Market](https://www.backmarket.com) 1. [Baloise](https://www.baloise.com) From a01a4b910f063dbe4e6aa515392d0939486219d2 Mon Sep 17 00:00:00 2001 From: pasha-codefresh Date: Fri, 3 Nov 2023 19:04:29 +0200 Subject: [PATCH 085/269] chore: update gitops engine version (#16232) * chore: update gitops engine version Signed-off-by: pashakostohrys * chore: update gitops engine version Signed-off-by: pashakostohrys --------- Signed-off-by: pashakostohrys --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2dc71e929b0e9..e03d1709e3220 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 - github.com/argoproj/gitops-engine v0.7.1-0.20231013183858-f15cf615b814 + github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 diff --git a/go.sum b/go.sum index fcf4a561a7511..08da01826154c 100644 --- a/go.sum +++ b/go.sum @@ -695,8 +695,8 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20231013183858-f15cf615b814 h1:oTaLRbCwjnGtScIX2ZRdIEDsiDxonwh9/BbUxdXrjYc= -github.com/argoproj/gitops-engine v0.7.1-0.20231013183858-f15cf615b814/go.mod h1:1TchqKw9XmYYZluyEHa1dTJQoZgbV6PhabB/e8Wf3KY= +github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 h1:vnXMrNkBFC0H0KBkH1Jno31OVgJQR4KSd0ypEcfzQRA= +github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48/go.mod h1:1TchqKw9XmYYZluyEHa1dTJQoZgbV6PhabB/e8Wf3KY= github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf h1:4wliaBwd6iKvT/5huDTJntaYtTSdwPLs00SOQwDSK6A= github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf/go.mod h1:TuK0BNKo34DIUOyCCGOB9ij+smGCxeCgt9ZB+0fMWno= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= From 740df9a13e7a82ca98ccd7577e0fe6ab32b33bd7 Mon Sep 17 00:00:00 2001 From: Kazakov Stepan Date: Sat, 4 Nov 2023 01:11:32 +0300 Subject: [PATCH 086/269] fix(ui): summary: fix sync options block layout (#16152) Signed-off-by: Kazakov Stepan --- .../components/application-summary/application-summary.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/applications/components/application-summary/application-summary.tsx b/ui/src/app/applications/components/application-summary/application-summary.tsx index 9072f650f5026..5e8fa2db22ba1 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -271,7 +271,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { { title: 'SYNC OPTIONS', view: ( -
    +
    {((app.spec.syncPolicy || {}).syncOptions || []).map(opt => opt.endsWith('=true') || opt.endsWith('=false') ? (
    From 0b59bf800cfc53f0b05460fef3340dffb63797ea Mon Sep 17 00:00:00 2001 From: Alexey Vazhnov Date: Sun, 5 Nov 2023 20:01:36 +0100 Subject: [PATCH 087/269] Documentation "Annotations and Labels used by Argo CD": fix internal link to `../faq.md#why-is-my-app-out-of-sync-even-after-syncing` (#16236) The broken link is visible in https://argo-cd.readthedocs.io/en/stable/user-guide/annotations-and-labels/#labels Signed-off-by: Alexey Vazhnov --- docs/user-guide/annotations-and-labels.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/user-guide/annotations-and-labels.md b/docs/user-guide/annotations-and-labels.md index 4e3a997b393d4..032824c8708f3 100644 --- a/docs/user-guide/annotations-and-labels.md +++ b/docs/user-guide/annotations-and-labels.md @@ -20,7 +20,7 @@ ## Labels -| Label key | Target resource(es) | Possible values | Description | -|--------------------------------|---------------------|---------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------| -| argocd.argoproj.io/instance | Application | any | Recommended tracking label to [avoid conflicts with other tools which use `app.kubernetes.io/instance`](../faq.md#why-is-my-app-out-of-sync-even-after-syncing. | -| argocd.argoproj.io/secret-type | Secret | `cluster`, `repository`, `repo-creds` | Identifies certain types of Secrets used by Argo CD. See the [Declarative Setup docs](../operator-manual/declarative-setup.md) for details. | +| Label key | Target resource(es) | Possible values | Description | +|--------------------------------|---------------------|---------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| argocd.argoproj.io/instance | Application | any | Recommended tracking label to [avoid conflicts with other tools which use `app.kubernetes.io/instance`](../faq.md#why-is-my-app-out-of-sync-even-after-syncing). | +| argocd.argoproj.io/secret-type | Secret | `cluster`, `repository`, `repo-creds` | Identifies certain types of Secrets used by Argo CD. See the [Declarative Setup docs](../operator-manual/declarative-setup.md) for details. | From 3c9a1ec9dd8699473a3f806ba9f732efadd2f9a8 Mon Sep 17 00:00:00 2001 From: Geoffrey MUSELLI Date: Sun, 5 Nov 2023 19:57:28 -0500 Subject: [PATCH 088/269] fix(appset): Fix name conflict in appset controller (#16207) (#16222) * fix(16207): Fix name conflict in appset controller Signed-off-by: gmuselli * fix(16207): e2e Signed-off-by: gmuselli * Update test/e2e/fixture/applicationsets/utils/fixture.go Signed-off-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --------- Signed-off-by: gmuselli Signed-off-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- .github/workflows/ci-build.yaml | 2 +- Makefile | 5 +- .../controllers/applicationset_controller.go | 2 +- test/e2e/applicationset_test.go | 195 +++++++++++++++++- test/e2e/cluster_generator_test.go | 8 +- test/e2e/clusterdecisiongenerator_e2e_test.go | 8 +- test/e2e/fixture/applicationsets/actions.go | 43 ++-- .../fixture/applicationsets/consequences.go | 8 +- test/e2e/fixture/applicationsets/context.go | 7 +- .../fixture/applicationsets/utils/fixture.go | 110 +++++----- 10 files changed, 307 insertions(+), 81 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index afdfa61822344..3a596a9552d70 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -374,7 +374,7 @@ jobs: ARGOCD_E2E_K3S: "true" ARGOCD_IN_CI: "true" ARGOCD_E2E_APISERVER_PORT: "8088" - ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external" + ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external,argocd-e2e-external-2" ARGOCD_SERVER: "127.0.0.1:8088" GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} diff --git a/Makefile b/Makefile index 4d245b9bf15b5..d4df041fa58e1 100644 --- a/Makefile +++ b/Makefile @@ -438,6 +438,7 @@ start-e2e: test-tools-image start-e2e-local: mod-vendor-local dep-ui-local cli-local kubectl create ns argocd-e2e || true kubectl create ns argocd-e2e-external || true + kubectl create ns argocd-e2e-external-2 || true kubectl config set-context --current --namespace=argocd-e2e kustomize build test/manifests/base | kubectl apply -f - kubectl apply -f https://raw.githubusercontent.com/open-cluster-management/api/a6845f2ebcb186ec26b832f60c988537a58f3859/cluster/v1alpha1/0000_04_clusters.open-cluster-management.io_placementdecisions.crd.yaml @@ -458,8 +459,8 @@ start-e2e-local: mod-vendor-local dep-ui-local cli-local ARGOCD_ZJWT_FEATURE_FLAG=always \ ARGOCD_IN_CI=$(ARGOCD_IN_CI) \ BIN_MODE=$(ARGOCD_BIN_MODE) \ - ARGOCD_APPLICATION_NAMESPACES=argocd-e2e-external \ - ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES=argocd-e2e-external \ + ARGOCD_APPLICATION_NAMESPACES=argocd-e2e-external,argocd-e2e-external-2 \ + ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACES=argocd-e2e-external,argocd-e2e-external-2 \ ARGOCD_APPLICATIONSET_CONTROLLER_ALLOWED_SCM_PROVIDERS=http://127.0.0.1:8341,http://127.0.0.1:8342,http://127.0.0.1:8343,http://127.0.0.1:8344 \ ARGOCD_E2E_TEST=true \ goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START} diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 385d476752aef..be73c81ca0c3f 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -734,7 +734,7 @@ func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, logCtx * func (r *ApplicationSetReconciler) getCurrentApplications(_ context.Context, applicationSet argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) { // TODO: Should this use the context param? var current argov1alpha1.ApplicationList - err := r.Client.List(context.Background(), ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}) + err := r.Client.List(context.Background(), ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}, client.InNamespace(applicationSet.Namespace)) if err != nil { return nil, fmt.Errorf("error retrieving applications: %w", err) diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index f56f9f552e9f6..2fef0ace55583 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -53,6 +53,8 @@ var ( func TestSimpleListGeneratorExternalNamespace(t *testing.T) { + var externalNamespace = string(utils.ArgoCDExternalNamespace) + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", @@ -60,7 +62,7 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { }, ObjectMeta: metav1.ObjectMeta{ Name: "my-cluster-guestbook", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, Spec: argov1alpha1.ApplicationSpec{ @@ -82,10 +84,10 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { Given(t). // Create a ListGenerator-based ApplicationSet When(). - SwitchToExternalNamespace(). - CreateNamespace(utils.ArgoCDExternalNamespace).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + CreateNamespace(externalNamespace).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ Name: "simple-list-generator-external", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, }, Spec: v1alpha1.ApplicationSetSpec{ GoTemplate: true, @@ -151,6 +153,191 @@ func TestSimpleListGeneratorExternalNamespace(t *testing.T) { } +func TestSimpleListGeneratorExternalNamespaceNoConflict(t *testing.T) { + + var externalNamespace = string(utils.ArgoCDExternalNamespace) + var externalNamespace2 = string(utils.ArgoCDExternalNamespace2) + + expectedApp := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: externalNamespace, + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + + expectedAppExternalNamespace2 := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: externalNamespace2, + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + } + + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application + + Given(t). + // Create a ListGenerator-based ApplicationSet + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + CreateNamespace(externalNamespace2).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + Name: "simple-list-generator-external", + Namespace: externalNamespace2, + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "{{.url}}", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + CreateNamespace(externalNamespace).Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + Name: "simple-list-generator-external", + Namespace: externalNamespace, + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "{{.url}}", + Namespace: "guestbook", + }, + }, + }, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{"cluster": "my-cluster","url": "https://kubernetes.default.svc"}`), + }}, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + Then(). + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + expectedAppNewNamespace = expectedApp.DeepCopy() + expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2" + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + Then(). + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Annotations = map[string]string{"annotation-key": "annotation-value"} + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{ + "label-key": "label-value", + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Annotations = map[string]string{"annotation-key": "annotation-value"} + appset.Spec.Template.Labels = map[string]string{ + "label-key": "label-value", + } + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("simple-list-generator-external", ExpectedConditions)). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + Then(). + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})). + When(). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace2). + Then(). + Expect(ApplicationsExist([]argov1alpha1.Application{expectedAppExternalNamespace2})). + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{expectedAppExternalNamespace2})) +} + func TestSimpleListGenerator(t *testing.T) { expectedApp := argov1alpha1.Application{ diff --git a/test/e2e/cluster_generator_test.go b/test/e2e/cluster_generator_test.go index 7cac40aa569fb..1d5699e23503d 100644 --- a/test/e2e/cluster_generator_test.go +++ b/test/e2e/cluster_generator_test.go @@ -18,6 +18,8 @@ import ( func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { + var externalNamespace = string(utils.ArgoCDExternalNamespace) + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", @@ -25,7 +27,7 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { }, ObjectMeta: metav1.ObjectMeta{ Name: "cluster1-guestbook", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, Spec: argov1alpha1.ApplicationSpec{ @@ -49,8 +51,8 @@ func TestSimpleClusterGeneratorExternalNamespace(t *testing.T) { // Create a ClusterGenerator-based ApplicationSet When(). CreateClusterSecret("my-secret", "cluster1", "https://kubernetes.default.svc"). - SwitchToExternalNamespace(). - CreateNamespace(utils.ArgoCDExternalNamespace). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). + CreateNamespace(externalNamespace). Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ Name: "simple-cluster-generator", }, diff --git a/test/e2e/clusterdecisiongenerator_e2e_test.go b/test/e2e/clusterdecisiongenerator_e2e_test.go index 97d1327fe0331..5f0d6ff6ae3c7 100644 --- a/test/e2e/clusterdecisiongenerator_e2e_test.go +++ b/test/e2e/clusterdecisiongenerator_e2e_test.go @@ -19,6 +19,8 @@ var tenSec = int64(10) func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { + var externalNamespace = string(utils.ArgoCDExternalNamespace) + expectedApp := argov1alpha1.Application{ TypeMeta: metav1.TypeMeta{ Kind: "Application", @@ -26,7 +28,7 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { }, ObjectMeta: metav1.ObjectMeta{ Name: "cluster1-guestbook", - Namespace: utils.ArgoCDExternalNamespace, + Namespace: externalNamespace, Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, }, Spec: argov1alpha1.ApplicationSpec{ @@ -61,8 +63,8 @@ func TestSimpleClusterDecisionResourceGeneratorExternalNamespace(t *testing.T) { CreatePlacementDecisionConfigMap("my-configmap"). CreatePlacementDecision("my-placementdecision"). StatusUpdatePlacementDecision("my-placementdecision", clusterList). - CreateNamespace(utils.ArgoCDExternalNamespace). - SwitchToExternalNamespace(). + CreateNamespace(externalNamespace). + SwitchToExternalNamespace(utils.ArgoCDExternalNamespace). Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ Name: "simple-cluster-generator", }, diff --git a/test/e2e/fixture/applicationsets/actions.go b/test/e2e/fixture/applicationsets/actions.go index 78878bcc24cbc..0b167c2b1a734 100644 --- a/test/e2e/fixture/applicationsets/actions.go +++ b/test/e2e/fixture/applicationsets/actions.go @@ -64,14 +64,14 @@ func (a *Actions) Then() *Consequences { return &Consequences{a.context, a} } -func (a *Actions) SwitchToExternalNamespace() *Actions { - a.context.useExternalNamespace = true - log.Infof("switched to external namespace: %s", utils.ArgoCDExternalNamespace) +func (a *Actions) SwitchToExternalNamespace(namespace utils.ExternalNamespace) *Actions { + a.context.switchToNamespace = namespace + log.Infof("switched to external namespace: %s", namespace) return a } func (a *Actions) SwitchToArgoCDNamespace() *Actions { - a.context.useExternalNamespace = false + a.context.switchToNamespace = "" log.Infof("switched to argocd namespace: %s", utils.ArgoCDNamespace) return a } @@ -216,8 +216,13 @@ func (a *Actions) Create(appSet v1alpha1.ApplicationSet) *Actions { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + return a + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } @@ -390,8 +395,13 @@ func (a *Actions) Delete() *Actions { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + return a + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } @@ -413,8 +423,12 @@ func (a *Actions) get() (*v1alpha1.ApplicationSet, error) { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + return nil, fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } @@ -460,8 +474,13 @@ func (a *Actions) Update(toUpdate func(*v1alpha1.ApplicationSet)) *Actions { var appSetClientSet dynamic.ResourceInterface - if a.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if a.context.switchToNamespace != "" { + externalAppSetClientset, found := fixtureClient.ExternalAppSetClientsets[utils.ExternalNamespace(a.context.switchToNamespace)] + if !found { + a.lastOutput, a.lastError = "", fmt.Errorf("No external clientset found for %s", a.context.switchToNamespace) + return a + } + appSetClientSet = externalAppSetClientset } else { appSetClientSet = fixtureClient.AppSetClientset } diff --git a/test/e2e/fixture/applicationsets/consequences.go b/test/e2e/fixture/applicationsets/consequences.go index 2672b58fe9317..db614f3cf3075 100644 --- a/test/e2e/fixture/applicationsets/consequences.go +++ b/test/e2e/fixture/applicationsets/consequences.go @@ -77,8 +77,8 @@ func (c *Consequences) app(name string) *v1alpha1.Application { func (c *Consequences) apps() []v1alpha1.Application { var namespace string - if c.context.useExternalNamespace { - namespace = utils.ArgoCDExternalNamespace + if c.context.switchToNamespace != "" { + namespace = string(c.context.switchToNamespace) } else { namespace = fixture.TestNamespace() } @@ -100,8 +100,8 @@ func (c *Consequences) applicationSet(applicationSetName string) *v1alpha1.Appli var appSetClientSet dynamic.ResourceInterface - if c.context.useExternalNamespace { - appSetClientSet = fixtureClient.ExternalAppSetClientset + if c.context.switchToNamespace != "" { + appSetClientSet = fixtureClient.ExternalAppSetClientsets[c.context.switchToNamespace] } else { appSetClientSet = fixtureClient.AppSetClientset } diff --git a/test/e2e/fixture/applicationsets/context.go b/test/e2e/fixture/applicationsets/context.go index d2a0479a62aee..c10b2c99bfe5f 100644 --- a/test/e2e/fixture/applicationsets/context.go +++ b/test/e2e/fixture/applicationsets/context.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" ) @@ -12,9 +13,9 @@ type Context struct { t *testing.T // name is the ApplicationSet's name, created by a Create action - name string - namespace string - useExternalNamespace bool + name string + namespace string + switchToNamespace utils.ExternalNamespace } func Given(t *testing.T) *Context { diff --git a/test/e2e/fixture/applicationsets/utils/fixture.go b/test/e2e/fixture/applicationsets/utils/fixture.go index b81a8875498a0..0074fe76bf5c8 100644 --- a/test/e2e/fixture/applicationsets/utils/fixture.go +++ b/test/e2e/fixture/applicationsets/utils/fixture.go @@ -25,15 +25,21 @@ import ( "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + "github.com/argoproj/argo-cd/v2/util/errors" ) +type ExternalNamespace string + const ( // ArgoCDNamespace is the namespace into which Argo CD and ApplicationSet controller are deployed, // and in which Application resources should be created. ArgoCDNamespace = "argocd-e2e" // ArgoCDExternalNamespace is an external namespace to test additional namespaces - ArgoCDExternalNamespace = "argocd-e2e-external" + ArgoCDExternalNamespace ExternalNamespace = "argocd-e2e-external" + + // ArgoCDExternalNamespace2 is an external namespace to test additional namespaces + ArgoCDExternalNamespace2 ExternalNamespace = "argocd-e2e-external-2" // ApplicationsResourcesNamespace is the namespace into which temporary resources (such as Deployments/Pods/etc) // can be deployed, such as using it as the target namespace in an Application resource. @@ -54,11 +60,11 @@ var ( // E2EFixtureK8sClient contains Kubernetes clients initialized from local k8s configuration type E2EFixtureK8sClient struct { - KubeClientset kubernetes.Interface - DynamicClientset dynamic.Interface - AppClientset appclientset.Interface - AppSetClientset dynamic.ResourceInterface - ExternalAppSetClientset dynamic.ResourceInterface + KubeClientset kubernetes.Interface + DynamicClientset dynamic.Interface + AppClientset appclientset.Interface + AppSetClientset dynamic.ResourceInterface + ExternalAppSetClientsets map[ExternalNamespace]dynamic.ResourceInterface } func GetEnvWithDefault(envName, defaultValue string) string { @@ -91,7 +97,11 @@ func GetE2EFixtureK8sClient() *E2EFixtureK8sClient { } internalClientVars.AppSetClientset = internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(TestNamespace()) - internalClientVars.ExternalAppSetClientset = internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(ArgoCDExternalNamespace) + internalClientVars.ExternalAppSetClientsets = map[ExternalNamespace]dynamic.ResourceInterface{ + ArgoCDExternalNamespace: internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(string(ArgoCDExternalNamespace)), + ArgoCDExternalNamespace2: internalClientVars.DynamicClientset.Resource(v1alpha1.SchemeGroupVersion.WithResource("applicationsets")).Namespace(string(ArgoCDExternalNamespace2)), + } + }) return internalClientVars } @@ -112,9 +122,15 @@ func EnsureCleanState(t *testing.T) { } // Delete the argocd-e2e-external namespace, if it exists - err2 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), ArgoCDExternalNamespace, v1.DeleteOptions{PropagationPolicy: &policy}) + err2 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace), v1.DeleteOptions{PropagationPolicy: &policy}) if err2 != nil && !strings.Contains(err2.Error(), "not found") { // 'not found' error is expected - CheckError(err) + CheckError(err2) + } + + // Delete the argocd-e2e-external namespace, if it exists + err3 := fixtureClient.KubeClientset.CoreV1().Namespaces().Delete(context.Background(), string(ArgoCDExternalNamespace2), v1.DeleteOptions{PropagationPolicy: &policy}) + if err3 != nil && !strings.Contains(err3.Error(), "not found") { // 'not found' error is expected + CheckError(err3) } // delete resources @@ -177,6 +193,15 @@ func EnsureCleanState(t *testing.T) { func waitForExpectedClusterState() error { fixtureClient := GetE2EFixtureK8sClient() + + SetProjectSpec(fixtureClient, "default", v1alpha1.AppProjectSpec{ + OrphanedResources: nil, + SourceRepos: []string{"*"}, + Destinations: []v1alpha1.ApplicationDestination{{Namespace: "*", Server: "*"}}, + ClusterResourceWhitelist: []v1.GroupKind{{Group: "*", Kind: "*"}}, + SourceNamespaces: []string{string(ArgoCDExternalNamespace), string(ArgoCDExternalNamespace2)}, + }) + // Wait up to 60 seconds for all the ApplicationSets to delete if err := waitForSuccess(func() error { list, err := fixtureClient.AppSetClientset.List(context.Background(), v1.ListOptions{}) @@ -210,56 +235,45 @@ func waitForExpectedClusterState() error { } // Wait up to 120 seconds for namespace to not exist - if err := waitForSuccess(func() error { - _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), ApplicationsResourcesNamespace, v1.GetOptions{}) - - msg := "" - - if err == nil { - msg = fmt.Sprintf("namespace '%s' still exists, after delete", ApplicationsResourcesNamespace) - } - - if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { - // Success is an error containing 'applicationset-e2e' not found. - return nil - } - - if msg == "" { - msg = err.Error() + for _, namespace := range []string{string(ApplicationsResourcesNamespace), string(ArgoCDExternalNamespace), string(ArgoCDExternalNamespace2)} { + // Wait up to 120 seconds for namespace to not exist + if err := waitForSuccess(func() error { + return cleanUpNamespace(fixtureClient, namespace) + }, time.Now().Add(120*time.Second)); err != nil { + return err } - - return fmt.Errorf(msg) - - }, time.Now().Add(120*time.Second)); err != nil { - return err } - // Wait up to 120 seconds for namespace to not exist - if err := waitForSuccess(func() error { - _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), ArgoCDExternalNamespace, v1.GetOptions{}) + return nil +} - msg := "" +func SetProjectSpec(fixtureClient *E2EFixtureK8sClient, project string, spec v1alpha1.AppProjectSpec) { + proj, err := fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, v1.GetOptions{}) + errors.CheckError(err) + proj.Spec = spec + _, err = fixtureClient.AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Update(context.Background(), proj, v1.UpdateOptions{}) + errors.CheckError(err) +} - if err == nil { - msg = fmt.Sprintf("namespace '%s' still exists, after delete", ArgoCDExternalNamespace) - } +func cleanUpNamespace(fixtureClient *E2EFixtureK8sClient, namespace string) error { + _, err := fixtureClient.KubeClientset.CoreV1().Namespaces().Get(context.Background(), namespace, v1.GetOptions{}) - if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { - // Success is an error containing 'applicationset-e2e' not found. - return nil - } + msg := "" - if msg == "" { - msg = err.Error() - } + if err == nil { + msg = fmt.Sprintf("namespace '%s' still exists, after delete", namespace) + } - return fmt.Errorf(msg) + if msg == "" && err != nil && strings.Contains(err.Error(), "not found") { + // Success is an error containing 'applicationset-e2e' not found. + return nil + } - }, time.Now().Add(120*time.Second)); err != nil { - return err + if msg == "" { + msg = err.Error() } - return nil + return fmt.Errorf(msg) } // waitForSuccess waits for the condition to return a non-error value. From 58da6a33abdcfed8c1a665efcf7359fa47452b39 Mon Sep 17 00:00:00 2001 From: pasha-codefresh Date: Mon, 6 Nov 2023 17:57:32 +0200 Subject: [PATCH 089/269] feat: Support for Kustomize Components (#16230) * feat: support components in kustomize Signed-off-by: pashakostohrys * feat: support components in kustomize Signed-off-by: pashakostohrys * feat: support components in kustomize Signed-off-by: pashakostohrys * feat: support components in kustomize Signed-off-by: pashakostohrys * fix: typo in kustomization word Signed-off-by: pashakostohrys * fix: typo in kustomization word Signed-off-by: pashakostohrys * fix: typo in kustomization word Signed-off-by: pashakostohrys * fix: typo in kustomization word Signed-off-by: pashakostohrys --------- Signed-off-by: pashakostohrys --- assets/swagger.json | 7 + docs/user-guide/kustomize.md | 1 + manifests/core-install.yaml | 268 ++++ manifests/crds/application-crd.yaml | 76 + manifests/crds/applicationset-crd.yaml | 192 +++ manifests/ha/install.yaml | 268 ++++ manifests/install.yaml | 268 ++++ pkg/apis/api-rules/violation_exceptions.list | 1 + pkg/apis/application/v1alpha1/generated.pb.go | 1417 +++++++++-------- pkg/apis/application/v1alpha1/generated.proto | 3 + .../application/v1alpha1/openapi_generated.go | 15 + pkg/apis/application/v1alpha1/types.go | 8 +- .../v1alpha1/zz_generated.deepcopy.go | 5 + util/kustomize/kustomize.go | 86 +- util/kustomize/kustomize_test.go | 22 + .../components/deployment.yaml | 21 + .../components/kustomization.yaml | 4 + .../kustomization.yaml | 5 + 18 files changed, 1948 insertions(+), 719 deletions(-) create mode 100644 util/kustomize/testdata/kustomization_yaml_components/components/deployment.yaml create mode 100644 util/kustomize/testdata/kustomization_yaml_components/components/kustomization.yaml create mode 100644 util/kustomize/testdata/kustomization_yaml_components/kustomization.yaml diff --git a/assets/swagger.json b/assets/swagger.json index 7fc9142edcaff..b7f0cdefabe1c 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -6395,6 +6395,13 @@ "type": "string" } }, + "components": { + "type": "array", + "title": "Components specifies a list of kustomize components to add to the kustomization before building", + "items": { + "type": "string" + } + }, "forceCommonAnnotations": { "type": "boolean", "title": "ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize apps" diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index 7007ac17675da..e97b457666958 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -13,6 +13,7 @@ The following configuration options are available for Kustomize: * `forceCommonAnnotations` is a boolean value which defines if it's allowed to override existing annotations * `commonAnnotationsEnvsubst` is a boolean value which enables env variables substition in annotation values * `patches` is a list of Kustomize patches that supports inline updates +* `components` is a list of Kustomize components To use Kustomize with an overlay, point your path to the overlay. diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index a0943c86e2f57..2469f171351fe 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -320,6 +320,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for @@ -648,6 +654,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -1093,6 +1105,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize apps @@ -1411,6 +1429,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize @@ -1882,6 +1906,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2214,6 +2244,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2690,6 +2726,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3039,6 +3082,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3503,6 +3553,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -3845,6 +3901,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4331,6 +4394,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4673,6 +4742,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -5108,6 +5184,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5318,6 +5398,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5687,6 +5771,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5897,6 +5985,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6270,6 +6362,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6480,6 +6576,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6833,6 +6933,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7043,6 +7147,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7420,6 +7528,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7630,6 +7742,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7999,6 +8115,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8209,6 +8329,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8582,6 +8706,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8792,6 +8920,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9145,6 +9277,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9355,6 +9491,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9718,6 +9858,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9928,6 +10072,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10471,6 +10619,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10681,6 +10833,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11219,6 +11375,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11429,6 +11589,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11796,6 +11960,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12006,6 +12174,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12383,6 +12555,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12593,6 +12769,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12962,6 +13142,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13172,6 +13356,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13545,6 +13733,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13755,6 +13947,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14108,6 +14304,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14318,6 +14518,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14681,6 +14885,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14891,6 +15099,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -15434,6 +15646,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -15644,6 +15860,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16182,6 +16402,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16392,6 +16616,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16763,6 +16991,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16973,6 +17205,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -17333,6 +17569,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -17543,6 +17783,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18086,6 +18330,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18296,6 +18544,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18834,6 +19086,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19044,6 +19300,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19486,6 +19746,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19696,6 +19960,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index f1833e22a95da..962543f80eb97 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -319,6 +319,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for @@ -647,6 +653,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -1092,6 +1104,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize apps @@ -1410,6 +1428,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize @@ -1881,6 +1905,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2213,6 +2243,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2689,6 +2725,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3038,6 +3081,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3502,6 +3552,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -3844,6 +3900,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4330,6 +4393,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4672,6 +4741,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index 9348368951811..c324134df927b 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -244,6 +244,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -454,6 +458,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -823,6 +831,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -1033,6 +1045,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -1406,6 +1422,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -1616,6 +1636,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -1969,6 +1993,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -2179,6 +2207,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -2556,6 +2588,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -2766,6 +2802,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -3135,6 +3175,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -3345,6 +3389,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -3718,6 +3766,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -3928,6 +3980,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -4281,6 +4337,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -4491,6 +4551,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -4854,6 +4918,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5064,6 +5132,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5607,6 +5679,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5817,6 +5893,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6355,6 +6435,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6565,6 +6649,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6932,6 +7020,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7142,6 +7234,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7519,6 +7615,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7729,6 +7829,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8098,6 +8202,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8308,6 +8416,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8681,6 +8793,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8891,6 +9007,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9244,6 +9364,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9454,6 +9578,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9817,6 +9945,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10027,6 +10159,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10570,6 +10706,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10780,6 +10920,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11318,6 +11462,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11528,6 +11676,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11899,6 +12051,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12109,6 +12265,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12469,6 +12629,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12679,6 +12843,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13222,6 +13390,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13432,6 +13604,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13970,6 +14146,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14180,6 +14360,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14622,6 +14806,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14832,6 +15020,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index d975ce383bebc..0f637cd786dc2 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -320,6 +320,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for @@ -648,6 +654,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -1093,6 +1105,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize apps @@ -1411,6 +1429,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize @@ -1882,6 +1906,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2214,6 +2244,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2690,6 +2726,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3039,6 +3082,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3503,6 +3553,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -3845,6 +3901,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4331,6 +4394,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4673,6 +4742,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -5108,6 +5184,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5318,6 +5398,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5687,6 +5771,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5897,6 +5985,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6270,6 +6362,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6480,6 +6576,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6833,6 +6933,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7043,6 +7147,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7420,6 +7528,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7630,6 +7742,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7999,6 +8115,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8209,6 +8329,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8582,6 +8706,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8792,6 +8920,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9145,6 +9277,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9355,6 +9491,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9718,6 +9858,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9928,6 +10072,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10471,6 +10619,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10681,6 +10833,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11219,6 +11375,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11429,6 +11589,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11796,6 +11960,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12006,6 +12174,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12383,6 +12555,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12593,6 +12769,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12962,6 +13142,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13172,6 +13356,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13545,6 +13733,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13755,6 +13947,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14108,6 +14304,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14318,6 +14518,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14681,6 +14885,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14891,6 +15099,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -15434,6 +15646,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -15644,6 +15860,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16182,6 +16402,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16392,6 +16616,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16763,6 +16991,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16973,6 +17205,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -17333,6 +17569,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -17543,6 +17783,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18086,6 +18330,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18296,6 +18544,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18834,6 +19086,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19044,6 +19300,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19486,6 +19746,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19696,6 +19960,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: diff --git a/manifests/install.yaml b/manifests/install.yaml index 27109b5141f86..cb4cda559caf0 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -320,6 +320,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for @@ -648,6 +654,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -1093,6 +1105,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize apps @@ -1411,6 +1429,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize components + to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources for Kustomize @@ -1882,6 +1906,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2214,6 +2244,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -2690,6 +2726,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3039,6 +3082,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of + kustomize components to add to the kustomization + before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations @@ -3503,6 +3553,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -3845,6 +3901,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4331,6 +4394,12 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -4673,6 +4742,13 @@ spec: description: CommonLabels is a list of additional labels to add to rendered manifests type: object + components: + description: Components specifies a list of kustomize + components to add to the kustomization before + building + items: + type: string + type: array forceCommonAnnotations: description: ForceCommonAnnotations specifies whether to force applying common annotations to resources @@ -5108,6 +5184,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5318,6 +5398,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5687,6 +5771,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -5897,6 +5985,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6270,6 +6362,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6480,6 +6576,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -6833,6 +6933,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7043,6 +7147,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7420,6 +7528,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7630,6 +7742,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -7999,6 +8115,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8209,6 +8329,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8582,6 +8706,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -8792,6 +8920,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9145,6 +9277,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9355,6 +9491,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9718,6 +9858,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -9928,6 +10072,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10471,6 +10619,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -10681,6 +10833,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11219,6 +11375,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11429,6 +11589,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -11796,6 +11960,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12006,6 +12174,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12383,6 +12555,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12593,6 +12769,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -12962,6 +13142,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13172,6 +13356,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13545,6 +13733,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -13755,6 +13947,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14108,6 +14304,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14318,6 +14518,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14681,6 +14885,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -14891,6 +15099,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -15434,6 +15646,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -15644,6 +15860,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16182,6 +16402,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16392,6 +16616,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16763,6 +16991,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -16973,6 +17205,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -17333,6 +17569,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -17543,6 +17783,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18086,6 +18330,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18296,6 +18544,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -18834,6 +19086,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19044,6 +19300,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19486,6 +19746,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: @@ -19696,6 +19960,10 @@ spec: additionalProperties: type: string type: object + components: + items: + type: string + type: array forceCommonAnnotations: type: boolean forceCommonLabels: diff --git a/pkg/apis/api-rules/violation_exceptions.list b/pkg/apis/api-rules/violation_exceptions.list index a4f9a79767ac9..2b0f2e90d00a9 100644 --- a/pkg/apis/api-rules/violation_exceptions.list +++ b/pkg/apis/api-rules/violation_exceptions.list @@ -25,6 +25,7 @@ API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/ap API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,ExtVars API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,Libs API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceJsonnet,TLAs +API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSourceKustomize,Components API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationSpec,Info API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,Conditions API rule violation: list_type_missing,github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1,ApplicationStatus,Resources diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 91e8f8d42963b..777ef9fa49bcc 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4448,692 +4448,693 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 10945 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x6f, 0x70, 0x1c, 0xc9, - 0x75, 0x18, 0xae, 0xd9, 0x3f, 0xc0, 0xee, 0x03, 0x08, 0x92, 0x4d, 0xf2, 0x0e, 0xa4, 0xee, 0x0e, - 0xf4, 0xdc, 0xcf, 0xa7, 0xf3, 0x4f, 0x77, 0x80, 0x8f, 0xba, 0x53, 0x2e, 0x3a, 0x5b, 0x32, 0xfe, - 0x90, 0x20, 0x48, 0x80, 0xc0, 0x35, 0x40, 0x52, 0x3a, 0xf9, 0x74, 0x1a, 0xec, 0x36, 0x16, 0x43, - 0xcc, 0xce, 0xcc, 0xcd, 0xcc, 0x82, 0xc0, 0x59, 0x92, 0x25, 0x4b, 0xb6, 0x95, 0xe8, 0xcf, 0x29, - 0x52, 0x52, 0x3e, 0x27, 0x91, 0x23, 0x5b, 0x4e, 0x2a, 0xae, 0x44, 0x15, 0x27, 0xf9, 0x10, 0x27, - 0x4e, 0xca, 0x65, 0x3b, 0x95, 0x52, 0x4a, 0x49, 0xd9, 0x95, 0x72, 0x59, 0x4e, 0x62, 0x23, 0x12, - 0x52, 0xae, 0xa4, 0x52, 0x15, 0x57, 0x39, 0xf1, 0x07, 0x87, 0xc9, 0x87, 0x54, 0xff, 0xef, 0x99, - 0x9d, 0x05, 0x16, 0xc0, 0x80, 0xa4, 0x94, 0xfb, 0xb6, 0xdb, 0xef, 0xcd, 0x7b, 0x3d, 0x3d, 0xdd, - 0xef, 0xbd, 0x7e, 0xfd, 0xde, 0x6b, 0x98, 0x6f, 0xb9, 0xc9, 0x7a, 0x67, 0x75, 0xbc, 0x11, 0xb4, - 0x27, 0x9c, 0xa8, 0x15, 0x84, 0x51, 0x70, 0x87, 0xfd, 0x78, 0xb6, 0xd1, 0x9c, 0xd8, 0xbc, 0x34, - 0x11, 0x6e, 0xb4, 0x26, 0x9c, 0xd0, 0x8d, 0x27, 0x9c, 0x30, 0xf4, 0xdc, 0x86, 0x93, 0xb8, 0x81, - 0x3f, 0xb1, 0xf9, 0x9c, 0xe3, 0x85, 0xeb, 0xce, 0x73, 0x13, 0x2d, 0xe2, 0x93, 0xc8, 0x49, 0x48, - 0x73, 0x3c, 0x8c, 0x82, 0x24, 0x40, 0x3f, 0xa2, 0xa9, 0x8d, 0x4b, 0x6a, 0xec, 0xc7, 0x6b, 0x8d, - 0xe6, 0xf8, 0xe6, 0xa5, 0xf1, 0x70, 0xa3, 0x35, 0x4e, 0xa9, 0x8d, 0x1b, 0xd4, 0xc6, 0x25, 0xb5, - 0x0b, 0xcf, 0x1a, 0x7d, 0x69, 0x05, 0xad, 0x60, 0x82, 0x11, 0x5d, 0xed, 0xac, 0xb1, 0x7f, 0xec, - 0x0f, 0xfb, 0xc5, 0x99, 0x5d, 0xb0, 0x37, 0x5e, 0x8c, 0xc7, 0xdd, 0x80, 0x76, 0x6f, 0xa2, 0x11, - 0x44, 0x64, 0x62, 0xb3, 0xab, 0x43, 0x17, 0xae, 0x6a, 0x1c, 0xb2, 0x95, 0x10, 0x3f, 0x76, 0x03, - 0x3f, 0x7e, 0x96, 0x76, 0x81, 0x44, 0x9b, 0x24, 0x32, 0x5f, 0xcf, 0x40, 0xc8, 0xa3, 0xf4, 0xbc, - 0xa6, 0xd4, 0x76, 0x1a, 0xeb, 0xae, 0x4f, 0xa2, 0x6d, 0xfd, 0x78, 0x9b, 0x24, 0x4e, 0xde, 0x53, - 0x13, 0xbd, 0x9e, 0x8a, 0x3a, 0x7e, 0xe2, 0xb6, 0x49, 0xd7, 0x03, 0xef, 0xdd, 0xef, 0x81, 0xb8, - 0xb1, 0x4e, 0xda, 0x4e, 0xd7, 0x73, 0xef, 0xe9, 0xf5, 0x5c, 0x27, 0x71, 0xbd, 0x09, 0xd7, 0x4f, - 0xe2, 0x24, 0xca, 0x3e, 0x64, 0xbf, 0x0e, 0x27, 0x26, 0x6f, 0x2f, 0x4f, 0x76, 0x92, 0xf5, 0xe9, - 0xc0, 0x5f, 0x73, 0x5b, 0xe8, 0x05, 0x18, 0x6a, 0x78, 0x9d, 0x38, 0x21, 0xd1, 0x0d, 0xa7, 0x4d, - 0x46, 0xad, 0x8b, 0xd6, 0xd3, 0xf5, 0xa9, 0x33, 0xdf, 0xdc, 0x19, 0x7b, 0xc7, 0xee, 0xce, 0xd8, - 0xd0, 0xb4, 0x06, 0x61, 0x13, 0x0f, 0xfd, 0x10, 0x0c, 0x46, 0x81, 0x47, 0x26, 0xf1, 0x8d, 0xd1, - 0x12, 0x7b, 0xe4, 0xa4, 0x78, 0x64, 0x10, 0xf3, 0x66, 0x2c, 0xe1, 0xf6, 0xef, 0x97, 0x00, 0x26, - 0xc3, 0x70, 0x29, 0x0a, 0xee, 0x90, 0x46, 0x82, 0x3e, 0x0a, 0x35, 0x3a, 0x74, 0x4d, 0x27, 0x71, - 0x18, 0xb7, 0xa1, 0x4b, 0x3f, 0x3c, 0xce, 0xdf, 0x64, 0xdc, 0x7c, 0x13, 0x3d, 0x71, 0x28, 0xf6, - 0xf8, 0xe6, 0x73, 0xe3, 0x8b, 0xab, 0xf4, 0xf9, 0x05, 0x92, 0x38, 0x53, 0x48, 0x30, 0x03, 0xdd, - 0x86, 0x15, 0x55, 0xe4, 0x43, 0x25, 0x0e, 0x49, 0x83, 0x75, 0x6c, 0xe8, 0xd2, 0xfc, 0xf8, 0x51, - 0x66, 0xe8, 0xb8, 0xee, 0xf9, 0x72, 0x48, 0x1a, 0x53, 0xc3, 0x82, 0x73, 0x85, 0xfe, 0xc3, 0x8c, - 0x0f, 0xda, 0x84, 0x81, 0x38, 0x71, 0x92, 0x4e, 0x3c, 0x5a, 0x66, 0x1c, 0x6f, 0x14, 0xc6, 0x91, - 0x51, 0x9d, 0x1a, 0x11, 0x3c, 0x07, 0xf8, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x64, 0xc1, 0x88, 0x46, - 0x9e, 0x77, 0xe3, 0x04, 0xfd, 0x78, 0xd7, 0xe0, 0x8e, 0xf7, 0x37, 0xb8, 0xf4, 0x69, 0x36, 0xb4, - 0xa7, 0x04, 0xb3, 0x9a, 0x6c, 0x31, 0x06, 0xb6, 0x0d, 0x55, 0x37, 0x21, 0xed, 0x78, 0xb4, 0x74, - 0xb1, 0xfc, 0xf4, 0xd0, 0xa5, 0xab, 0x45, 0xbd, 0xe7, 0xd4, 0x09, 0xc1, 0xb4, 0x3a, 0x47, 0xc9, - 0x63, 0xce, 0xc5, 0xfe, 0x95, 0x61, 0xf3, 0xfd, 0xe8, 0x80, 0xa3, 0xe7, 0x60, 0x28, 0x0e, 0x3a, - 0x51, 0x83, 0x60, 0x12, 0x06, 0xf1, 0xa8, 0x75, 0xb1, 0x4c, 0xa7, 0x1e, 0x9d, 0xa9, 0xcb, 0xba, - 0x19, 0x9b, 0x38, 0xe8, 0x8b, 0x16, 0x0c, 0x37, 0x49, 0x9c, 0xb8, 0x3e, 0xe3, 0x2f, 0x3b, 0xbf, - 0x72, 0xe4, 0xce, 0xcb, 0xc6, 0x19, 0x4d, 0x7c, 0xea, 0xac, 0x78, 0x91, 0x61, 0xa3, 0x31, 0xc6, - 0x29, 0xfe, 0x74, 0xc5, 0x35, 0x49, 0xdc, 0x88, 0xdc, 0x90, 0xfe, 0x67, 0x73, 0xc6, 0x58, 0x71, - 0x33, 0x1a, 0x84, 0x4d, 0x3c, 0xe4, 0x43, 0x95, 0xae, 0xa8, 0x78, 0xb4, 0xc2, 0xfa, 0x3f, 0x77, - 0xb4, 0xfe, 0x8b, 0x41, 0xa5, 0x8b, 0x55, 0x8f, 0x3e, 0xfd, 0x17, 0x63, 0xce, 0x06, 0x7d, 0xc1, - 0x82, 0x51, 0xb1, 0xe2, 0x31, 0xe1, 0x03, 0x7a, 0x7b, 0xdd, 0x4d, 0x88, 0xe7, 0xc6, 0xc9, 0x68, - 0x95, 0xf5, 0x61, 0xa2, 0xbf, 0xb9, 0x35, 0x1b, 0x05, 0x9d, 0xf0, 0xba, 0xeb, 0x37, 0xa7, 0x2e, - 0x0a, 0x4e, 0xa3, 0xd3, 0x3d, 0x08, 0xe3, 0x9e, 0x2c, 0xd1, 0x57, 0x2c, 0xb8, 0xe0, 0x3b, 0x6d, - 0x12, 0x87, 0x0e, 0xfd, 0xb4, 0x1c, 0x3c, 0xe5, 0x39, 0x8d, 0x0d, 0xd6, 0xa3, 0x81, 0xc3, 0xf5, - 0xc8, 0x16, 0x3d, 0xba, 0x70, 0xa3, 0x27, 0x69, 0xbc, 0x07, 0x5b, 0xf4, 0x75, 0x0b, 0x4e, 0x07, - 0x51, 0xb8, 0xee, 0xf8, 0xa4, 0x29, 0xa1, 0xf1, 0xe8, 0x20, 0x5b, 0x7a, 0x1f, 0x39, 0xda, 0x27, - 0x5a, 0xcc, 0x92, 0x5d, 0x08, 0x7c, 0x37, 0x09, 0xa2, 0x65, 0x92, 0x24, 0xae, 0xdf, 0x8a, 0xa7, - 0xce, 0xed, 0xee, 0x8c, 0x9d, 0xee, 0xc2, 0xc2, 0xdd, 0xfd, 0x41, 0x3f, 0x01, 0x43, 0xf1, 0xb6, - 0xdf, 0xb8, 0xed, 0xfa, 0xcd, 0xe0, 0x6e, 0x3c, 0x5a, 0x2b, 0x62, 0xf9, 0x2e, 0x2b, 0x82, 0x62, - 0x01, 0x6a, 0x06, 0xd8, 0xe4, 0x96, 0xff, 0xe1, 0xf4, 0x54, 0xaa, 0x17, 0xfd, 0xe1, 0xf4, 0x64, - 0xda, 0x83, 0x2d, 0xfa, 0x59, 0x0b, 0x4e, 0xc4, 0x6e, 0xcb, 0x77, 0x92, 0x4e, 0x44, 0xae, 0x93, - 0xed, 0x78, 0x14, 0x58, 0x47, 0xae, 0x1d, 0x71, 0x54, 0x0c, 0x92, 0x53, 0xe7, 0x44, 0x1f, 0x4f, - 0x98, 0xad, 0x31, 0x4e, 0xf3, 0xcd, 0x5b, 0x68, 0x7a, 0x5a, 0x0f, 0x15, 0xbb, 0xd0, 0xf4, 0xa4, - 0xee, 0xc9, 0x12, 0xfd, 0x18, 0x9c, 0xe2, 0x4d, 0x6a, 0x64, 0xe3, 0xd1, 0x61, 0x26, 0x68, 0xcf, - 0xee, 0xee, 0x8c, 0x9d, 0x5a, 0xce, 0xc0, 0x70, 0x17, 0x36, 0x7a, 0x1d, 0xc6, 0x42, 0x12, 0xb5, - 0xdd, 0x64, 0xd1, 0xf7, 0xb6, 0xa5, 0xf8, 0x6e, 0x04, 0x21, 0x69, 0x8a, 0xee, 0xc4, 0xa3, 0x27, - 0x2e, 0x5a, 0x4f, 0xd7, 0xa6, 0xde, 0x25, 0xba, 0x39, 0xb6, 0xb4, 0x37, 0x3a, 0xde, 0x8f, 0x9e, - 0xfd, 0xaf, 0x4b, 0x70, 0x2a, 0xab, 0x38, 0xd1, 0xdf, 0xb1, 0xe0, 0xe4, 0x9d, 0xbb, 0xc9, 0x4a, - 0xb0, 0x41, 0xfc, 0x78, 0x6a, 0x9b, 0x8a, 0x37, 0xa6, 0x32, 0x86, 0x2e, 0x35, 0x8a, 0x55, 0xd1, - 0xe3, 0xd7, 0xd2, 0x5c, 0x2e, 0xfb, 0x49, 0xb4, 0x3d, 0xf5, 0xa8, 0x78, 0xbb, 0x93, 0xd7, 0x6e, - 0xaf, 0x98, 0x50, 0x9c, 0xed, 0xd4, 0x85, 0xcf, 0x59, 0x70, 0x36, 0x8f, 0x04, 0x3a, 0x05, 0xe5, - 0x0d, 0xb2, 0xcd, 0xad, 0x32, 0x4c, 0x7f, 0xa2, 0x57, 0xa1, 0xba, 0xe9, 0x78, 0x1d, 0x22, 0xac, - 0x9b, 0xd9, 0xa3, 0xbd, 0x88, 0xea, 0x19, 0xe6, 0x54, 0xdf, 0x57, 0x7a, 0xd1, 0xb2, 0x7f, 0xa7, - 0x0c, 0x43, 0x86, 0x7e, 0xbb, 0x0f, 0x16, 0x5b, 0x90, 0xb2, 0xd8, 0x16, 0x0a, 0x53, 0xcd, 0x3d, - 0x4d, 0xb6, 0xbb, 0x19, 0x93, 0x6d, 0xb1, 0x38, 0x96, 0x7b, 0xda, 0x6c, 0x28, 0x81, 0x7a, 0x10, - 0x52, 0x8b, 0x9c, 0xaa, 0xfe, 0x4a, 0x11, 0x9f, 0x70, 0x51, 0x92, 0x9b, 0x3a, 0xb1, 0xbb, 0x33, - 0x56, 0x57, 0x7f, 0xb1, 0x66, 0x64, 0x7f, 0xdb, 0x82, 0xb3, 0x46, 0x1f, 0xa7, 0x03, 0xbf, 0xe9, - 0xb2, 0x4f, 0x7b, 0x11, 0x2a, 0xc9, 0x76, 0x28, 0xcd, 0x7e, 0x35, 0x52, 0x2b, 0xdb, 0x21, 0xc1, - 0x0c, 0x42, 0x0d, 0xfd, 0x36, 0x89, 0x63, 0xa7, 0x45, 0xb2, 0x86, 0xfe, 0x02, 0x6f, 0xc6, 0x12, - 0x8e, 0x22, 0x40, 0x9e, 0x13, 0x27, 0x2b, 0x91, 0xe3, 0xc7, 0x8c, 0xfc, 0x8a, 0xdb, 0x26, 0x62, - 0x80, 0xff, 0xff, 0xfe, 0x66, 0x0c, 0x7d, 0x62, 0xea, 0x91, 0xdd, 0x9d, 0x31, 0x34, 0xdf, 0x45, - 0x09, 0xe7, 0x50, 0xb7, 0xbf, 0x62, 0xc1, 0x23, 0xf9, 0xb6, 0x18, 0x7a, 0x0a, 0x06, 0xf8, 0x96, - 0x4f, 0xbc, 0x9d, 0xfe, 0x24, 0xac, 0x15, 0x0b, 0x28, 0x9a, 0x80, 0xba, 0xd2, 0x13, 0xe2, 0x1d, - 0x4f, 0x0b, 0xd4, 0xba, 0x56, 0x2e, 0x1a, 0x87, 0x0e, 0x1a, 0xfd, 0x23, 0x2c, 0x37, 0x35, 0x68, - 0x6c, 0x93, 0xc4, 0x20, 0xf6, 0x7f, 0xb2, 0xe0, 0xa4, 0xd1, 0xab, 0xfb, 0x60, 0x9a, 0xfb, 0x69, - 0xd3, 0x7c, 0xae, 0xb0, 0xf9, 0xdc, 0xc3, 0x36, 0xff, 0x82, 0x05, 0x17, 0x0c, 0xac, 0x05, 0x27, - 0x69, 0xac, 0x5f, 0xde, 0x0a, 0x23, 0x12, 0xd3, 0xed, 0x34, 0x7a, 0xdc, 0x90, 0x5b, 0x53, 0x43, - 0x82, 0x42, 0xf9, 0x3a, 0xd9, 0xe6, 0x42, 0xec, 0x19, 0xa8, 0xf1, 0xc9, 0x19, 0x44, 0x62, 0xc4, - 0xd5, 0xbb, 0x2d, 0x8a, 0x76, 0xac, 0x30, 0x90, 0x0d, 0x03, 0x4c, 0x38, 0xd1, 0xc5, 0x4a, 0xd5, - 0x10, 0xd0, 0x8f, 0x78, 0x8b, 0xb5, 0x60, 0x01, 0xb1, 0xe3, 0x54, 0x77, 0x96, 0x22, 0xc2, 0x3e, - 0x6e, 0xf3, 0x8a, 0x4b, 0xbc, 0x66, 0x4c, 0xb7, 0x0d, 0x8e, 0xef, 0x07, 0x89, 0xd8, 0x01, 0x18, - 0xdb, 0x86, 0x49, 0xdd, 0x8c, 0x4d, 0x1c, 0xca, 0xd4, 0x73, 0x56, 0x89, 0xc7, 0x47, 0x54, 0x30, - 0x9d, 0x67, 0x2d, 0x58, 0x40, 0xec, 0xdd, 0x12, 0xdb, 0xa0, 0xa8, 0xa5, 0x4f, 0xee, 0xc7, 0xee, - 0x36, 0x4a, 0xc9, 0xca, 0xa5, 0xe2, 0x04, 0x17, 0xe9, 0xbd, 0xc3, 0x7d, 0x23, 0x23, 0x2e, 0x71, - 0xa1, 0x5c, 0xf7, 0xde, 0xe5, 0xfe, 0x66, 0x09, 0xc6, 0xd2, 0x0f, 0x74, 0x49, 0x5b, 0xba, 0xa5, - 0x32, 0x18, 0x65, 0x9d, 0x18, 0x06, 0x3e, 0x36, 0xf1, 0x7a, 0x08, 0xac, 0xd2, 0x71, 0x0a, 0x2c, - 0x53, 0x9e, 0x96, 0xf7, 0x91, 0xa7, 0x4f, 0xa9, 0x51, 0xaf, 0x64, 0x04, 0x58, 0x5a, 0xa7, 0x5c, - 0x84, 0x4a, 0x9c, 0x90, 0x70, 0xb4, 0x9a, 0x96, 0x47, 0xcb, 0x09, 0x09, 0x31, 0x83, 0xd8, 0xff, - 0xad, 0x04, 0x8f, 0xa6, 0xc7, 0x50, 0xab, 0x80, 0x0f, 0xa4, 0x54, 0xc0, 0xbb, 0x4d, 0x15, 0x70, - 0x6f, 0x67, 0xec, 0x9d, 0x3d, 0x1e, 0xfb, 0x9e, 0xd1, 0x10, 0x68, 0x36, 0x33, 0x8a, 0x13, 0xe9, - 0x51, 0xbc, 0xb7, 0x33, 0xf6, 0x78, 0x8f, 0x77, 0xcc, 0x0c, 0xf3, 0x53, 0x30, 0x10, 0x11, 0x27, - 0x0e, 0x7c, 0x31, 0xd0, 0xea, 0x73, 0x60, 0xd6, 0x8a, 0x05, 0xd4, 0xfe, 0x77, 0xf5, 0xec, 0x60, - 0xcf, 0x72, 0x27, 0x5c, 0x10, 0x21, 0x17, 0x2a, 0xcc, 0xac, 0xe7, 0xa2, 0xe1, 0xfa, 0xd1, 0x96, - 0x11, 0x55, 0x03, 0x8a, 0xf4, 0x54, 0x8d, 0x7e, 0x35, 0xda, 0x84, 0x19, 0x0b, 0xb4, 0x05, 0xb5, - 0x86, 0xb4, 0xb6, 0x4b, 0x45, 0xf8, 0xa5, 0x84, 0xad, 0xad, 0x39, 0x0e, 0x53, 0x79, 0xad, 0x4c, - 0x74, 0xc5, 0x0d, 0x11, 0x28, 0xb7, 0xdc, 0x44, 0x7c, 0xd6, 0x23, 0xee, 0xa7, 0x66, 0x5d, 0xe3, - 0x15, 0x07, 0xa9, 0x12, 0x99, 0x75, 0x13, 0x4c, 0xe9, 0xa3, 0x9f, 0xb6, 0x60, 0x28, 0x6e, 0xb4, - 0x97, 0xa2, 0x60, 0xd3, 0x6d, 0x92, 0x48, 0x58, 0x53, 0x47, 0x14, 0x4d, 0xcb, 0xd3, 0x0b, 0x92, - 0xa0, 0xe6, 0xcb, 0xf7, 0xb7, 0x1a, 0x82, 0x4d, 0xbe, 0x74, 0x97, 0xf1, 0xa8, 0x78, 0xf7, 0x19, - 0xd2, 0x70, 0xa9, 0xfe, 0x93, 0x9b, 0x2a, 0x36, 0x53, 0x8e, 0x6c, 0x5d, 0xce, 0x74, 0x1a, 0x1b, - 0x74, 0xbd, 0xe9, 0x0e, 0xbd, 0x73, 0x77, 0x67, 0xec, 0xd1, 0xe9, 0x7c, 0x9e, 0xb8, 0x57, 0x67, - 0xd8, 0x80, 0x85, 0x1d, 0xcf, 0xc3, 0xe4, 0xf5, 0x0e, 0x61, 0x2e, 0x93, 0x02, 0x06, 0x6c, 0x49, + // 10964 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, + 0x75, 0x18, 0xae, 0xd9, 0x0f, 0x60, 0xf7, 0xe1, 0x83, 0x64, 0x93, 0xbc, 0x03, 0xa9, 0xbb, 0x03, + 0x3d, 0xf7, 0xf3, 0xe9, 0xfc, 0xd3, 0x1d, 0xe0, 0xa3, 0xee, 0x94, 0x8b, 0xce, 0x96, 0x8c, 0x0f, + 0x12, 0x04, 0x09, 0x10, 0xb8, 0x06, 0x48, 0x4a, 0x27, 0x9f, 0x4e, 0x83, 0xdd, 0xc6, 0x62, 0x88, + 0xd9, 0x99, 0xb9, 0x99, 0x59, 0x10, 0x38, 0x4b, 0xb2, 0x64, 0xc9, 0xb6, 0x12, 0x7d, 0x9c, 0x22, + 0x25, 0xe5, 0x73, 0x12, 0x39, 0xb2, 0xe5, 0xa4, 0xec, 0x4a, 0x54, 0x71, 0x92, 0x3f, 0xe2, 0xc4, + 0x49, 0xb9, 0x6c, 0xa7, 0x52, 0x4a, 0x29, 0x29, 0xbb, 0x52, 0x2e, 0xcb, 0x49, 0x6c, 0x44, 0x62, + 0xca, 0x95, 0x54, 0xaa, 0xe2, 0x2a, 0x27, 0xfe, 0x23, 0x61, 0xf2, 0x47, 0xaa, 0xbf, 0x7b, 0x66, + 0x67, 0x81, 0x05, 0x30, 0x20, 0x29, 0xe5, 0xfe, 0xdb, 0xed, 0xf7, 0xe6, 0xbd, 0x9e, 0x9e, 0xee, + 0xf7, 0x5e, 0xbf, 0x7e, 0xef, 0x35, 0x2c, 0xb4, 0xdc, 0x64, 0xa3, 0xb3, 0x36, 0xd1, 0x08, 0xda, + 0x93, 0x4e, 0xd4, 0x0a, 0xc2, 0x28, 0xb8, 0xcd, 0x7e, 0x3c, 0xdb, 0x68, 0x4e, 0x6e, 0x5d, 0x9c, + 0x0c, 0x37, 0x5b, 0x93, 0x4e, 0xe8, 0xc6, 0x93, 0x4e, 0x18, 0x7a, 0x6e, 0xc3, 0x49, 0xdc, 0xc0, + 0x9f, 0xdc, 0x7a, 0xce, 0xf1, 0xc2, 0x0d, 0xe7, 0xb9, 0xc9, 0x16, 0xf1, 0x49, 0xe4, 0x24, 0xa4, + 0x39, 0x11, 0x46, 0x41, 0x12, 0xa0, 0x1f, 0xd1, 0xd4, 0x26, 0x24, 0x35, 0xf6, 0xe3, 0xb5, 0x46, + 0x73, 0x62, 0xeb, 0xe2, 0x44, 0xb8, 0xd9, 0x9a, 0xa0, 0xd4, 0x26, 0x0c, 0x6a, 0x13, 0x92, 0xda, + 0xf9, 0x67, 0x8d, 0xbe, 0xb4, 0x82, 0x56, 0x30, 0xc9, 0x88, 0xae, 0x75, 0xd6, 0xd9, 0x3f, 0xf6, + 0x87, 0xfd, 0xe2, 0xcc, 0xce, 0xdb, 0x9b, 0x2f, 0xc6, 0x13, 0x6e, 0x40, 0xbb, 0x37, 0xd9, 0x08, + 0x22, 0x32, 0xb9, 0xd5, 0xd5, 0xa1, 0xf3, 0x57, 0x34, 0x0e, 0xd9, 0x4e, 0x88, 0x1f, 0xbb, 0x81, + 0x1f, 0x3f, 0x4b, 0xbb, 0x40, 0xa2, 0x2d, 0x12, 0x99, 0xaf, 0x67, 0x20, 0xe4, 0x51, 0x7a, 0x5e, + 0x53, 0x6a, 0x3b, 0x8d, 0x0d, 0xd7, 0x27, 0xd1, 0x8e, 0x7e, 0xbc, 0x4d, 0x12, 0x27, 0xef, 0xa9, + 0xc9, 0x5e, 0x4f, 0x45, 0x1d, 0x3f, 0x71, 0xdb, 0xa4, 0xeb, 0x81, 0xf7, 0xee, 0xf7, 0x40, 0xdc, + 0xd8, 0x20, 0x6d, 0xa7, 0xeb, 0xb9, 0xf7, 0xf4, 0x7a, 0xae, 0x93, 0xb8, 0xde, 0xa4, 0xeb, 0x27, + 0x71, 0x12, 0x65, 0x1f, 0xb2, 0x5f, 0x87, 0x91, 0xa9, 0x5b, 0x2b, 0x53, 0x9d, 0x64, 0x63, 0x26, + 0xf0, 0xd7, 0xdd, 0x16, 0x7a, 0x01, 0x86, 0x1a, 0x5e, 0x27, 0x4e, 0x48, 0x74, 0xdd, 0x69, 0x93, + 0x31, 0xeb, 0x82, 0xf5, 0x74, 0x7d, 0xfa, 0xf4, 0x37, 0x77, 0xc7, 0xdf, 0x71, 0x77, 0x77, 0x7c, + 0x68, 0x46, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x08, 0x06, 0xa3, 0xc0, 0x23, 0x53, 0xf8, 0xfa, 0x58, + 0x89, 0x3d, 0x72, 0x42, 0x3c, 0x32, 0x88, 0x79, 0x33, 0x96, 0x70, 0xfb, 0x0f, 0x4a, 0x00, 0x53, + 0x61, 0xb8, 0x1c, 0x05, 0xb7, 0x49, 0x23, 0x41, 0x1f, 0x85, 0x1a, 0x1d, 0xba, 0xa6, 0x93, 0x38, + 0x8c, 0xdb, 0xd0, 0xc5, 0x1f, 0x9e, 0xe0, 0x6f, 0x32, 0x61, 0xbe, 0x89, 0x9e, 0x38, 0x14, 0x7b, + 0x62, 0xeb, 0xb9, 0x89, 0xa5, 0x35, 0xfa, 0xfc, 0x22, 0x49, 0x9c, 0x69, 0x24, 0x98, 0x81, 0x6e, + 0xc3, 0x8a, 0x2a, 0xf2, 0xa1, 0x12, 0x87, 0xa4, 0xc1, 0x3a, 0x36, 0x74, 0x71, 0x61, 0xe2, 0x28, + 0x33, 0x74, 0x42, 0xf7, 0x7c, 0x25, 0x24, 0x8d, 0xe9, 0x61, 0xc1, 0xb9, 0x42, 0xff, 0x61, 0xc6, + 0x07, 0x6d, 0xc1, 0x40, 0x9c, 0x38, 0x49, 0x27, 0x1e, 0x2b, 0x33, 0x8e, 0xd7, 0x0b, 0xe3, 0xc8, + 0xa8, 0x4e, 0x8f, 0x0a, 0x9e, 0x03, 0xfc, 0x3f, 0x16, 0xdc, 0xec, 0x3f, 0xb6, 0x60, 0x54, 0x23, + 0x2f, 0xb8, 0x71, 0x82, 0x7e, 0xbc, 0x6b, 0x70, 0x27, 0xfa, 0x1b, 0x5c, 0xfa, 0x34, 0x1b, 0xda, + 0x93, 0x82, 0x59, 0x4d, 0xb6, 0x18, 0x03, 0xdb, 0x86, 0xaa, 0x9b, 0x90, 0x76, 0x3c, 0x56, 0xba, + 0x50, 0x7e, 0x7a, 0xe8, 0xe2, 0x95, 0xa2, 0xde, 0x73, 0x7a, 0x44, 0x30, 0xad, 0xce, 0x53, 0xf2, + 0x98, 0x73, 0xb1, 0x7f, 0x75, 0xd8, 0x7c, 0x3f, 0x3a, 0xe0, 0xe8, 0x39, 0x18, 0x8a, 0x83, 0x4e, + 0xd4, 0x20, 0x98, 0x84, 0x41, 0x3c, 0x66, 0x5d, 0x28, 0xd3, 0xa9, 0x47, 0x67, 0xea, 0x8a, 0x6e, + 0xc6, 0x26, 0x0e, 0xfa, 0xa2, 0x05, 0xc3, 0x4d, 0x12, 0x27, 0xae, 0xcf, 0xf8, 0xcb, 0xce, 0xaf, + 0x1e, 0xb9, 0xf3, 0xb2, 0x71, 0x56, 0x13, 0x9f, 0x3e, 0x23, 0x5e, 0x64, 0xd8, 0x68, 0x8c, 0x71, + 0x8a, 0x3f, 0x5d, 0x71, 0x4d, 0x12, 0x37, 0x22, 0x37, 0xa4, 0xff, 0xd9, 0x9c, 0x31, 0x56, 0xdc, + 0xac, 0x06, 0x61, 0x13, 0x0f, 0xf9, 0x50, 0xa5, 0x2b, 0x2a, 0x1e, 0xab, 0xb0, 0xfe, 0xcf, 0x1f, + 0xad, 0xff, 0x62, 0x50, 0xe9, 0x62, 0xd5, 0xa3, 0x4f, 0xff, 0xc5, 0x98, 0xb3, 0x41, 0x5f, 0xb0, + 0x60, 0x4c, 0xac, 0x78, 0x4c, 0xf8, 0x80, 0xde, 0xda, 0x70, 0x13, 0xe2, 0xb9, 0x71, 0x32, 0x56, + 0x65, 0x7d, 0x98, 0xec, 0x6f, 0x6e, 0xcd, 0x45, 0x41, 0x27, 0xbc, 0xe6, 0xfa, 0xcd, 0xe9, 0x0b, + 0x82, 0xd3, 0xd8, 0x4c, 0x0f, 0xc2, 0xb8, 0x27, 0x4b, 0xf4, 0x15, 0x0b, 0xce, 0xfb, 0x4e, 0x9b, + 0xc4, 0xa1, 0x43, 0x3f, 0x2d, 0x07, 0x4f, 0x7b, 0x4e, 0x63, 0x93, 0xf5, 0x68, 0xe0, 0x70, 0x3d, + 0xb2, 0x45, 0x8f, 0xce, 0x5f, 0xef, 0x49, 0x1a, 0xef, 0xc1, 0x16, 0x7d, 0xdd, 0x82, 0x53, 0x41, + 0x14, 0x6e, 0x38, 0x3e, 0x69, 0x4a, 0x68, 0x3c, 0x36, 0xc8, 0x96, 0xde, 0x47, 0x8e, 0xf6, 0x89, + 0x96, 0xb2, 0x64, 0x17, 0x03, 0xdf, 0x4d, 0x82, 0x68, 0x85, 0x24, 0x89, 0xeb, 0xb7, 0xe2, 0xe9, + 0xb3, 0x77, 0x77, 0xc7, 0x4f, 0x75, 0x61, 0xe1, 0xee, 0xfe, 0xa0, 0x9f, 0x80, 0xa1, 0x78, 0xc7, + 0x6f, 0xdc, 0x72, 0xfd, 0x66, 0x70, 0x27, 0x1e, 0xab, 0x15, 0xb1, 0x7c, 0x57, 0x14, 0x41, 0xb1, + 0x00, 0x35, 0x03, 0x6c, 0x72, 0xcb, 0xff, 0x70, 0x7a, 0x2a, 0xd5, 0x8b, 0xfe, 0x70, 0x7a, 0x32, + 0xed, 0xc1, 0x16, 0xfd, 0xac, 0x05, 0x23, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x91, 0x6b, 0x64, + 0x27, 0x1e, 0x03, 0xd6, 0x91, 0xab, 0x47, 0x1c, 0x15, 0x83, 0xe4, 0xf4, 0x59, 0xd1, 0xc7, 0x11, + 0xb3, 0x35, 0xc6, 0x69, 0xbe, 0x79, 0x0b, 0x4d, 0x4f, 0xeb, 0xa1, 0x62, 0x17, 0x9a, 0x9e, 0xd4, + 0x3d, 0x59, 0xa2, 0x1f, 0x83, 0x93, 0xbc, 0x49, 0x8d, 0x6c, 0x3c, 0x36, 0xcc, 0x04, 0xed, 0x99, + 0xbb, 0xbb, 0xe3, 0x27, 0x57, 0x32, 0x30, 0xdc, 0x85, 0x8d, 0x5e, 0x87, 0xf1, 0x90, 0x44, 0x6d, + 0x37, 0x59, 0xf2, 0xbd, 0x1d, 0x29, 0xbe, 0x1b, 0x41, 0x48, 0x9a, 0xa2, 0x3b, 0xf1, 0xd8, 0xc8, + 0x05, 0xeb, 0xe9, 0xda, 0xf4, 0xbb, 0x44, 0x37, 0xc7, 0x97, 0xf7, 0x46, 0xc7, 0xfb, 0xd1, 0xb3, + 0xff, 0x55, 0x09, 0x4e, 0x66, 0x15, 0x27, 0xfa, 0x3b, 0x16, 0x9c, 0xb8, 0x7d, 0x27, 0x59, 0x0d, + 0x36, 0x89, 0x1f, 0x4f, 0xef, 0x50, 0xf1, 0xc6, 0x54, 0xc6, 0xd0, 0xc5, 0x46, 0xb1, 0x2a, 0x7a, + 0xe2, 0x6a, 0x9a, 0xcb, 0x25, 0x3f, 0x89, 0x76, 0xa6, 0x1f, 0x15, 0x6f, 0x77, 0xe2, 0xea, 0xad, + 0x55, 0x13, 0x8a, 0xb3, 0x9d, 0x3a, 0xff, 0x39, 0x0b, 0xce, 0xe4, 0x91, 0x40, 0x27, 0xa1, 0xbc, + 0x49, 0x76, 0xb8, 0x55, 0x86, 0xe9, 0x4f, 0xf4, 0x2a, 0x54, 0xb7, 0x1c, 0xaf, 0x43, 0x84, 0x75, + 0x33, 0x77, 0xb4, 0x17, 0x51, 0x3d, 0xc3, 0x9c, 0xea, 0xfb, 0x4a, 0x2f, 0x5a, 0xf6, 0xef, 0x96, + 0x61, 0xc8, 0xd0, 0x6f, 0xf7, 0xc1, 0x62, 0x0b, 0x52, 0x16, 0xdb, 0x62, 0x61, 0xaa, 0xb9, 0xa7, + 0xc9, 0x76, 0x27, 0x63, 0xb2, 0x2d, 0x15, 0xc7, 0x72, 0x4f, 0x9b, 0x0d, 0x25, 0x50, 0x0f, 0x42, + 0x6a, 0x91, 0x53, 0xd5, 0x5f, 0x29, 0xe2, 0x13, 0x2e, 0x49, 0x72, 0xd3, 0x23, 0x77, 0x77, 0xc7, + 0xeb, 0xea, 0x2f, 0xd6, 0x8c, 0xec, 0x6f, 0x5b, 0x70, 0xc6, 0xe8, 0xe3, 0x4c, 0xe0, 0x37, 0x5d, + 0xf6, 0x69, 0x2f, 0x40, 0x25, 0xd9, 0x09, 0xa5, 0xd9, 0xaf, 0x46, 0x6a, 0x75, 0x27, 0x24, 0x98, + 0x41, 0xa8, 0xa1, 0xdf, 0x26, 0x71, 0xec, 0xb4, 0x48, 0xd6, 0xd0, 0x5f, 0xe4, 0xcd, 0x58, 0xc2, + 0x51, 0x04, 0xc8, 0x73, 0xe2, 0x64, 0x35, 0x72, 0xfc, 0x98, 0x91, 0x5f, 0x75, 0xdb, 0x44, 0x0c, + 0xf0, 0xff, 0xdf, 0xdf, 0x8c, 0xa1, 0x4f, 0x4c, 0x3f, 0x72, 0x77, 0x77, 0x1c, 0x2d, 0x74, 0x51, + 0xc2, 0x39, 0xd4, 0xed, 0xaf, 0x58, 0xf0, 0x48, 0xbe, 0x2d, 0x86, 0x9e, 0x82, 0x01, 0xbe, 0xe5, + 0x13, 0x6f, 0xa7, 0x3f, 0x09, 0x6b, 0xc5, 0x02, 0x8a, 0x26, 0xa1, 0xae, 0xf4, 0x84, 0x78, 0xc7, + 0x53, 0x02, 0xb5, 0xae, 0x95, 0x8b, 0xc6, 0xa1, 0x83, 0x46, 0xff, 0x08, 0xcb, 0x4d, 0x0d, 0x1a, + 0xdb, 0x24, 0x31, 0x88, 0xfd, 0x1f, 0x2d, 0x38, 0x61, 0xf4, 0xea, 0x3e, 0x98, 0xe6, 0x7e, 0xda, + 0x34, 0x9f, 0x2f, 0x6c, 0x3e, 0xf7, 0xb0, 0xcd, 0xbf, 0x60, 0xc1, 0x79, 0x03, 0x6b, 0xd1, 0x49, + 0x1a, 0x1b, 0x97, 0xb6, 0xc3, 0x88, 0xc4, 0x74, 0x3b, 0x8d, 0x1e, 0x37, 0xe4, 0xd6, 0xf4, 0x90, + 0xa0, 0x50, 0xbe, 0x46, 0x76, 0xb8, 0x10, 0x7b, 0x06, 0x6a, 0x7c, 0x72, 0x06, 0x91, 0x18, 0x71, + 0xf5, 0x6e, 0x4b, 0xa2, 0x1d, 0x2b, 0x0c, 0x64, 0xc3, 0x00, 0x13, 0x4e, 0x74, 0xb1, 0x52, 0x35, + 0x04, 0xf4, 0x23, 0xde, 0x64, 0x2d, 0x58, 0x40, 0xec, 0x38, 0xd5, 0x9d, 0xe5, 0x88, 0xb0, 0x8f, + 0xdb, 0xbc, 0xec, 0x12, 0xaf, 0x19, 0xd3, 0x6d, 0x83, 0xe3, 0xfb, 0x41, 0x22, 0x76, 0x00, 0xc6, + 0xb6, 0x61, 0x4a, 0x37, 0x63, 0x13, 0x87, 0x32, 0xf5, 0x9c, 0x35, 0xe2, 0xf1, 0x11, 0x15, 0x4c, + 0x17, 0x58, 0x0b, 0x16, 0x10, 0xfb, 0x6e, 0x89, 0x6d, 0x50, 0xd4, 0xd2, 0x27, 0xf7, 0x63, 0x77, + 0x1b, 0xa5, 0x64, 0xe5, 0x72, 0x71, 0x82, 0x8b, 0xf4, 0xde, 0xe1, 0xbe, 0x91, 0x11, 0x97, 0xb8, + 0x50, 0xae, 0x7b, 0xef, 0x72, 0x7f, 0xab, 0x04, 0xe3, 0xe9, 0x07, 0xba, 0xa4, 0x2d, 0xdd, 0x52, + 0x19, 0x8c, 0xb2, 0x4e, 0x0c, 0x03, 0x1f, 0x9b, 0x78, 0x3d, 0x04, 0x56, 0xe9, 0x38, 0x05, 0x96, + 0x29, 0x4f, 0xcb, 0xfb, 0xc8, 0xd3, 0xa7, 0xd4, 0xa8, 0x57, 0x32, 0x02, 0x2c, 0xad, 0x53, 0x2e, + 0x40, 0x25, 0x4e, 0x48, 0x38, 0x56, 0x4d, 0xcb, 0xa3, 0x95, 0x84, 0x84, 0x98, 0x41, 0xec, 0xff, + 0x5a, 0x82, 0x47, 0xd3, 0x63, 0xa8, 0x55, 0xc0, 0x07, 0x52, 0x2a, 0xe0, 0xdd, 0xa6, 0x0a, 0xb8, + 0xb7, 0x3b, 0xfe, 0xce, 0x1e, 0x8f, 0x7d, 0xcf, 0x68, 0x08, 0x34, 0x97, 0x19, 0xc5, 0xc9, 0xf4, + 0x28, 0xde, 0xdb, 0x1d, 0x7f, 0xbc, 0xc7, 0x3b, 0x66, 0x86, 0xf9, 0x29, 0x18, 0x88, 0x88, 0x13, + 0x07, 0xbe, 0x18, 0x68, 0xf5, 0x39, 0x30, 0x6b, 0xc5, 0x02, 0x6a, 0xff, 0xdb, 0x7a, 0x76, 0xb0, + 0xe7, 0xb8, 0x13, 0x2e, 0x88, 0x90, 0x0b, 0x15, 0x66, 0xd6, 0x73, 0xd1, 0x70, 0xed, 0x68, 0xcb, + 0x88, 0xaa, 0x01, 0x45, 0x7a, 0xba, 0x46, 0xbf, 0x1a, 0x6d, 0xc2, 0x8c, 0x05, 0xda, 0x86, 0x5a, + 0x43, 0x5a, 0xdb, 0xa5, 0x22, 0xfc, 0x52, 0xc2, 0xd6, 0xd6, 0x1c, 0x87, 0xa9, 0xbc, 0x56, 0x26, + 0xba, 0xe2, 0x86, 0x08, 0x94, 0x5b, 0x6e, 0x22, 0x3e, 0xeb, 0x11, 0xf7, 0x53, 0x73, 0xae, 0xf1, + 0x8a, 0x83, 0x54, 0x89, 0xcc, 0xb9, 0x09, 0xa6, 0xf4, 0xd1, 0x4f, 0x5b, 0x30, 0x14, 0x37, 0xda, + 0xcb, 0x51, 0xb0, 0xe5, 0x36, 0x49, 0x24, 0xac, 0xa9, 0x23, 0x8a, 0xa6, 0x95, 0x99, 0x45, 0x49, + 0x50, 0xf3, 0xe5, 0xfb, 0x5b, 0x0d, 0xc1, 0x26, 0x5f, 0xba, 0xcb, 0x78, 0x54, 0xbc, 0xfb, 0x2c, + 0x69, 0xb8, 0x54, 0xff, 0xc9, 0x4d, 0x15, 0x9b, 0x29, 0x47, 0xb6, 0x2e, 0x67, 0x3b, 0x8d, 0x4d, + 0xba, 0xde, 0x74, 0x87, 0xde, 0x79, 0x77, 0x77, 0xfc, 0xd1, 0x99, 0x7c, 0x9e, 0xb8, 0x57, 0x67, + 0xd8, 0x80, 0x85, 0x1d, 0xcf, 0xc3, 0xe4, 0xf5, 0x0e, 0x61, 0x2e, 0x93, 0x02, 0x06, 0x6c, 0x59, 0x13, 0xcc, 0x0c, 0x98, 0x01, 0xc1, 0x26, 0x5f, 0xf4, 0x3a, 0x0c, 0xb4, 0x9d, 0x24, 0x72, 0xb7, - 0x84, 0x9f, 0xe4, 0x88, 0xf6, 0xfe, 0x02, 0xa3, 0xa5, 0x99, 0x33, 0x4d, 0xcd, 0x1b, 0xb1, 0x60, - 0x84, 0xda, 0x50, 0x6d, 0x93, 0xa8, 0x45, 0x46, 0x6b, 0x45, 0xf8, 0x84, 0x17, 0x28, 0x29, 0xcd, + 0x85, 0x9f, 0xe4, 0x88, 0xf6, 0xfe, 0x22, 0xa3, 0xa5, 0x99, 0x33, 0x4d, 0xcd, 0x1b, 0xb1, 0x60, + 0x84, 0xda, 0x50, 0x6d, 0x93, 0xa8, 0x45, 0xc6, 0x6a, 0x45, 0xf8, 0x84, 0x17, 0x29, 0x29, 0xcd, 0xb0, 0x4e, 0xad, 0x23, 0xd6, 0x86, 0x39, 0x17, 0xf4, 0x2a, 0xd4, 0x62, 0xe2, 0x91, 0x06, 0xb5, - 0x6f, 0xea, 0x8c, 0xe3, 0x7b, 0xfa, 0xb4, 0xf5, 0xa8, 0x61, 0xb1, 0x2c, 0x1e, 0xe5, 0x0b, 0x4c, - 0xfe, 0xc3, 0x8a, 0x24, 0x1d, 0xc0, 0xd0, 0xeb, 0xb4, 0x5c, 0x7f, 0x14, 0x8a, 0x18, 0xc0, 0x25, - 0x46, 0x2b, 0x33, 0x80, 0xbc, 0x11, 0x0b, 0x46, 0xf6, 0x1f, 0x5b, 0x80, 0xd2, 0x42, 0xed, 0x3e, - 0x18, 0xb5, 0xaf, 0xa7, 0x8d, 0xda, 0xf9, 0x22, 0xad, 0x8e, 0x1e, 0x76, 0xed, 0xaf, 0xd7, 0x21, - 0xa3, 0x0e, 0x6e, 0x90, 0x38, 0x21, 0xcd, 0xb7, 0x45, 0xf8, 0xdb, 0x22, 0xfc, 0x6d, 0x11, 0xae, - 0x44, 0xf8, 0x6a, 0x46, 0x84, 0xbf, 0xdf, 0x58, 0xf5, 0xfa, 0x50, 0xf5, 0x35, 0x75, 0xea, 0x6a, - 0xf6, 0xc0, 0x40, 0xa0, 0x92, 0xe0, 0xda, 0xf2, 0xe2, 0x8d, 0x5c, 0x99, 0xfd, 0x5a, 0x5a, 0x66, - 0x1f, 0x95, 0xc5, 0xff, 0x0b, 0x52, 0xfa, 0x5f, 0x59, 0xf0, 0xae, 0xb4, 0xf4, 0x92, 0x33, 0x67, - 0xae, 0xe5, 0x07, 0x11, 0x99, 0x71, 0xd7, 0xd6, 0x48, 0x44, 0xfc, 0x06, 0x89, 0x95, 0x17, 0xc3, - 0xea, 0xe5, 0xc5, 0x40, 0xcf, 0xc3, 0xf0, 0x9d, 0x38, 0xf0, 0x97, 0x02, 0xd7, 0x17, 0x22, 0x88, - 0x6e, 0x84, 0x4f, 0xed, 0xee, 0x8c, 0x0d, 0xd3, 0x11, 0x95, 0xed, 0x38, 0x85, 0x85, 0xa6, 0xe1, - 0xf4, 0x9d, 0xd7, 0x97, 0x9c, 0xc4, 0x70, 0x07, 0xc8, 0x8d, 0x3b, 0x3b, 0xb0, 0xb8, 0xf6, 0x72, - 0x06, 0x88, 0xbb, 0xf1, 0xed, 0xbf, 0x51, 0x82, 0xf3, 0x99, 0x17, 0x09, 0x3c, 0x2f, 0xe8, 0x24, - 0x74, 0x53, 0x83, 0x7e, 0xc1, 0x82, 0x53, 0xed, 0xb4, 0xc7, 0x21, 0x16, 0x8e, 0xdd, 0x0f, 0x16, - 0xa6, 0x23, 0x32, 0x2e, 0x8d, 0xa9, 0x51, 0x31, 0x42, 0xa7, 0x32, 0x80, 0x18, 0x77, 0xf5, 0x05, - 0xbd, 0x0a, 0xf5, 0xb6, 0xb3, 0x75, 0x33, 0x6c, 0x3a, 0x89, 0xdc, 0x4f, 0xf6, 0x76, 0x03, 0x74, - 0x12, 0xd7, 0x1b, 0xe7, 0xc7, 0xf5, 0xe3, 0x73, 0x7e, 0xb2, 0x18, 0x2d, 0x27, 0x91, 0xeb, 0xb7, - 0xb8, 0x3b, 0x6f, 0x41, 0x92, 0xc1, 0x9a, 0xa2, 0xfd, 0x55, 0x2b, 0xab, 0xa4, 0xd4, 0xe8, 0x44, - 0x4e, 0x42, 0x5a, 0xdb, 0xe8, 0x63, 0x50, 0xa5, 0x1b, 0x3f, 0x39, 0x2a, 0xb7, 0x8b, 0xd4, 0x9c, - 0xc6, 0x97, 0xd0, 0x4a, 0x94, 0xfe, 0x8b, 0x31, 0x67, 0x6a, 0xff, 0x71, 0x2d, 0x6b, 0x2c, 0xb0, - 0xc3, 0xdb, 0x4b, 0x00, 0xad, 0x60, 0x85, 0xb4, 0x43, 0x8f, 0x0e, 0x8b, 0xc5, 0x4e, 0x00, 0x94, - 0xaf, 0x63, 0x56, 0x41, 0xb0, 0x81, 0x85, 0xfe, 0x92, 0x05, 0xd0, 0x92, 0x73, 0x5e, 0x1a, 0x02, - 0x37, 0x8b, 0x7c, 0x1d, 0xbd, 0xa2, 0x74, 0x5f, 0x14, 0x43, 0x6c, 0x30, 0x47, 0x3f, 0x65, 0x41, - 0x2d, 0x91, 0xdd, 0xe7, 0xaa, 0x71, 0xa5, 0xc8, 0x9e, 0xc8, 0x97, 0xd6, 0x36, 0x91, 0x1a, 0x12, - 0xc5, 0x17, 0xfd, 0x8c, 0x05, 0x10, 0x6f, 0xfb, 0x8d, 0xa5, 0xc0, 0x73, 0x1b, 0xdb, 0x42, 0x63, - 0xde, 0x2a, 0xd4, 0x1f, 0xa3, 0xa8, 0x4f, 0x8d, 0xd0, 0xd1, 0xd0, 0xff, 0xb1, 0xc1, 0x19, 0x7d, - 0x02, 0x6a, 0xb1, 0x98, 0x6e, 0x42, 0x47, 0xae, 0x14, 0xeb, 0x15, 0xe2, 0xb4, 0x85, 0x78, 0x15, - 0xff, 0xb0, 0xe2, 0x89, 0x7e, 0xce, 0x82, 0x93, 0x61, 0xda, 0xcf, 0x27, 0xd4, 0x61, 0x71, 0x32, - 0x20, 0xe3, 0x47, 0x9c, 0x3a, 0xb3, 0xbb, 0x33, 0x76, 0x32, 0xd3, 0x88, 0xb3, 0xbd, 0xa0, 0x12, - 0x50, 0xcf, 0xe0, 0xc5, 0x90, 0xfb, 0x1c, 0x07, 0xb5, 0x04, 0x9c, 0xcd, 0x02, 0x71, 0x37, 0x3e, - 0x5a, 0x82, 0xb3, 0xb4, 0x77, 0xdb, 0xdc, 0xfc, 0x94, 0xea, 0x25, 0x66, 0xca, 0xb0, 0x36, 0xf5, - 0x98, 0x98, 0x21, 0xcc, 0xab, 0x9f, 0xc5, 0xc1, 0xb9, 0x4f, 0xa2, 0xdf, 0xb1, 0xe0, 0x31, 0x97, - 0xa9, 0x01, 0xd3, 0x61, 0xae, 0x35, 0x82, 0x38, 0x89, 0x25, 0x85, 0xca, 0x8a, 0x5e, 0xea, 0x67, - 0xea, 0xff, 0x13, 0x6f, 0xf0, 0xd8, 0xdc, 0x1e, 0x5d, 0xc2, 0x7b, 0x76, 0xd8, 0xfe, 0x56, 0x29, - 0x75, 0xac, 0xa1, 0x7c, 0x89, 0x4c, 0x6a, 0x34, 0xa4, 0x1b, 0x47, 0x0a, 0xc1, 0x42, 0xa5, 0x86, - 0x72, 0x12, 0x69, 0xa9, 0xa1, 0x9a, 0x62, 0x6c, 0x30, 0xa7, 0xb6, 0xe5, 0x69, 0x27, 0xeb, 0xb1, - 0x14, 0x82, 0xec, 0xd5, 0x22, 0xbb, 0xd4, 0x7d, 0x08, 0x75, 0x5e, 0x74, 0xed, 0x74, 0x17, 0x08, - 0x77, 0x77, 0xc9, 0xfe, 0x56, 0xfa, 0x28, 0xc5, 0x58, 0x83, 0x7d, 0x1c, 0x13, 0x7d, 0xd1, 0x82, - 0xa1, 0x28, 0xf0, 0x3c, 0xd7, 0x6f, 0x51, 0x79, 0x21, 0x94, 0xde, 0x87, 0x8f, 0x45, 0xef, 0x08, - 0xc1, 0xc0, 0x2c, 0x54, 0xac, 0x79, 0x62, 0xb3, 0x03, 0xf6, 0x1f, 0x59, 0x30, 0xda, 0x4b, 0xae, - 0x21, 0x02, 0xef, 0x94, 0x8b, 0x56, 0x05, 0x49, 0x2c, 0xfa, 0x33, 0xc4, 0x23, 0xca, 0x7f, 0x5c, - 0x9b, 0x7a, 0x52, 0xbc, 0xe6, 0x3b, 0x97, 0x7a, 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x57, 0xe0, 0x94, - 0xf1, 0x5e, 0xb1, 0x1a, 0x98, 0xfa, 0xd4, 0x38, 0x35, 0x24, 0x26, 0x33, 0xb0, 0x7b, 0x3b, 0x63, - 0x8f, 0x64, 0xdb, 0x84, 0xe0, 0xed, 0xa2, 0x63, 0xff, 0x72, 0x29, 0xfb, 0xb5, 0x94, 0xce, 0x7c, - 0xcb, 0xea, 0xda, 0x95, 0x7f, 0xf0, 0x38, 0xf4, 0x14, 0xdb, 0xbf, 0xab, 0x38, 0x8c, 0xde, 0x38, - 0x0f, 0xf0, 0xa0, 0xd7, 0xfe, 0x37, 0x15, 0xd8, 0xa3, 0x67, 0x7d, 0x18, 0xc1, 0x07, 0x3e, 0x1d, - 0xfc, 0xbc, 0xa5, 0x4e, 0x8e, 0xca, 0x6c, 0x91, 0x37, 0x8f, 0x6b, 0xec, 0xf9, 0x3e, 0x24, 0xe6, - 0xc1, 0x06, 0xca, 0x1b, 0x9d, 0x3e, 0xa3, 0x42, 0x5f, 0xb3, 0xd2, 0x67, 0x5f, 0x3c, 0x7a, 0xcc, - 0x3d, 0xb6, 0x3e, 0x19, 0x07, 0x6a, 0xbc, 0x63, 0xfa, 0x18, 0xa6, 0xd7, 0x51, 0xdb, 0x38, 0xc0, - 0x9a, 0xeb, 0x3b, 0x9e, 0xfb, 0x06, 0xdd, 0x65, 0x54, 0x99, 0xa2, 0x64, 0x96, 0xc7, 0x15, 0xd5, - 0x8a, 0x0d, 0x8c, 0x0b, 0x7f, 0x11, 0x86, 0x8c, 0x37, 0xcf, 0x89, 0x91, 0x38, 0x6b, 0xc6, 0x48, - 0xd4, 0x8d, 0xd0, 0x86, 0x0b, 0xef, 0x87, 0x53, 0xd9, 0x0e, 0x1e, 0xe4, 0x79, 0xfb, 0xcf, 0x07, - 0xb3, 0x87, 0x51, 0x2b, 0x24, 0x6a, 0xd3, 0xae, 0xbd, 0xed, 0x20, 0x7a, 0xdb, 0x41, 0xf4, 0xb6, - 0x83, 0xc8, 0xf4, 0xf1, 0x0b, 0xe7, 0xc7, 0xe0, 0x7d, 0x72, 0x7e, 0xa4, 0xdc, 0x39, 0xb5, 0xc2, - 0xdd, 0x39, 0xf6, 0x6e, 0x15, 0x52, 0x76, 0x14, 0x1f, 0xef, 0x1f, 0x82, 0xc1, 0x88, 0x84, 0xc1, - 0x4d, 0x3c, 0x2f, 0x74, 0x88, 0x8e, 0x83, 0xe7, 0xcd, 0x58, 0xc2, 0xa9, 0xae, 0x09, 0x9d, 0x64, - 0x5d, 0x28, 0x11, 0xa5, 0x6b, 0x96, 0x9c, 0x64, 0x1d, 0x33, 0x08, 0x7a, 0x3f, 0x8c, 0x24, 0x4e, - 0xd4, 0xa2, 0x66, 0xf3, 0x26, 0xfb, 0xac, 0xe2, 0xc8, 0xf2, 0x11, 0x81, 0x3b, 0xb2, 0x92, 0x82, - 0xe2, 0x0c, 0x36, 0x7a, 0x1d, 0x2a, 0xeb, 0xc4, 0x6b, 0x8b, 0x21, 0x5f, 0x2e, 0x4e, 0xc6, 0xb3, - 0x77, 0xbd, 0x4a, 0xbc, 0x36, 0x97, 0x40, 0xf4, 0x17, 0x66, 0xac, 0xe8, 0x7c, 0xab, 0x6f, 0x74, - 0xe2, 0x24, 0x68, 0xbb, 0x6f, 0x48, 0x4f, 0xdd, 0x07, 0x0b, 0x66, 0x7c, 0x5d, 0xd2, 0xe7, 0x2e, - 0x11, 0xf5, 0x17, 0x6b, 0xce, 0xac, 0x1f, 0x4d, 0x37, 0x62, 0x9f, 0x6a, 0x5b, 0x38, 0xdc, 0x8a, - 0xee, 0xc7, 0x8c, 0xa4, 0xcf, 0xfb, 0xa1, 0xfe, 0x62, 0xcd, 0x19, 0x6d, 0xab, 0x79, 0x3f, 0xc4, - 0xfa, 0x70, 0xb3, 0xe0, 0x3e, 0xf0, 0x39, 0x9f, 0x3b, 0xff, 0x9f, 0x84, 0x6a, 0x63, 0xdd, 0x89, - 0x92, 0xd1, 0x61, 0x36, 0x69, 0x94, 0x6b, 0x66, 0x9a, 0x36, 0x62, 0x0e, 0x43, 0x8f, 0x43, 0x39, - 0x22, 0x6b, 0x2c, 0xfc, 0xd2, 0x08, 0xcc, 0xc1, 0x64, 0x0d, 0xd3, 0x76, 0xfb, 0x17, 0x4b, 0x69, - 0x73, 0x29, 0xfd, 0xde, 0x7c, 0xb6, 0x37, 0x3a, 0x51, 0x2c, 0xdd, 0x37, 0xc6, 0x6c, 0x67, 0xcd, - 0x58, 0xc2, 0xd1, 0xa7, 0x2c, 0x18, 0xbc, 0x13, 0x07, 0xbe, 0x4f, 0x12, 0xa1, 0x9a, 0x6e, 0x15, - 0x3c, 0x14, 0xd7, 0x38, 0x75, 0xdd, 0x07, 0xd1, 0x80, 0x25, 0x5f, 0xda, 0x5d, 0xb2, 0xd5, 0xf0, - 0x3a, 0xcd, 0xae, 0x58, 0x8b, 0xcb, 0xbc, 0x19, 0x4b, 0x38, 0x45, 0x75, 0x7d, 0x8e, 0x5a, 0x49, - 0xa3, 0xce, 0xf9, 0x02, 0x55, 0xc0, 0xed, 0xbf, 0x36, 0x00, 0xe7, 0x72, 0x17, 0x07, 0x35, 0x64, - 0x98, 0xa9, 0x70, 0xc5, 0xf5, 0x88, 0x8c, 0x32, 0x62, 0x86, 0xcc, 0x2d, 0xd5, 0x8a, 0x0d, 0x0c, - 0xf4, 0x93, 0x00, 0xa1, 0x13, 0x39, 0x6d, 0xa2, 0xdc, 0xab, 0x47, 0xb6, 0x17, 0x68, 0x3f, 0x96, - 0x24, 0x4d, 0xbd, 0x37, 0x55, 0x4d, 0x31, 0x36, 0x58, 0xa2, 0x17, 0x60, 0x28, 0x22, 0x1e, 0x71, - 0x62, 0x16, 0xbd, 0x9b, 0x4d, 0x45, 0xc0, 0x1a, 0x84, 0x4d, 0x3c, 0xf4, 0x94, 0x0a, 0xc8, 0xca, - 0x04, 0xa6, 0xa4, 0x83, 0xb2, 0xd0, 0x9b, 0x16, 0x8c, 0xac, 0xb9, 0x1e, 0xd1, 0xdc, 0x45, 0xe2, - 0xc0, 0xe2, 0xd1, 0x5f, 0xf2, 0x8a, 0x49, 0x57, 0x4b, 0xc8, 0x54, 0x73, 0x8c, 0x33, 0xec, 0xe9, - 0x67, 0xde, 0x24, 0x11, 0x13, 0xad, 0x03, 0xe9, 0xcf, 0x7c, 0x8b, 0x37, 0x63, 0x09, 0x47, 0x93, - 0x70, 0x32, 0x74, 0xe2, 0x78, 0x3a, 0x22, 0x4d, 0xe2, 0x27, 0xae, 0xe3, 0xf1, 0xb0, 0xfe, 0x9a, - 0x0e, 0xeb, 0x5d, 0x4a, 0x83, 0x71, 0x16, 0x1f, 0x7d, 0x08, 0x1e, 0xe5, 0xfe, 0x8b, 0x05, 0x37, - 0x8e, 0x5d, 0xbf, 0xa5, 0xa7, 0x81, 0x70, 0xe3, 0x8c, 0x09, 0x52, 0x8f, 0xce, 0xe5, 0xa3, 0xe1, - 0x5e, 0xcf, 0xa3, 0x67, 0xa0, 0x16, 0x6f, 0xb8, 0xe1, 0x74, 0xd4, 0x8c, 0xd9, 0xd9, 0x45, 0x4d, - 0x3b, 0x0d, 0x97, 0x45, 0x3b, 0x56, 0x18, 0xa8, 0x01, 0xc3, 0xfc, 0x93, 0xf0, 0x88, 0x32, 0x21, - 0x1f, 0x9f, 0xed, 0xa9, 0x1e, 0x45, 0xe6, 0xd9, 0x38, 0x76, 0xee, 0x5e, 0x96, 0x27, 0x29, 0xdc, - 0xf1, 0x7f, 0xcb, 0x20, 0x83, 0x53, 0x44, 0xed, 0x9f, 0x2f, 0xa5, 0x77, 0xdc, 0xe6, 0x22, 0x45, - 0x31, 0x5d, 0x8a, 0xc9, 0x2d, 0x27, 0x92, 0xde, 0x98, 0x23, 0x66, 0x1f, 0x08, 0xba, 0xb7, 0x9c, - 0xc8, 0x5c, 0xd4, 0x8c, 0x01, 0x96, 0x9c, 0xd0, 0x1d, 0xa8, 0x24, 0x9e, 0x53, 0x50, 0xba, 0x92, - 0xc1, 0x51, 0x3b, 0x40, 0xe6, 0x27, 0x63, 0xcc, 0x78, 0xa0, 0xc7, 0xa8, 0xd5, 0xbf, 0x2a, 0x4f, - 0x3a, 0x84, 0xa1, 0xbe, 0x1a, 0x63, 0xd6, 0x6a, 0xff, 0x79, 0x3d, 0x47, 0xae, 0x2a, 0x45, 0x86, - 0x2e, 0x01, 0xd0, 0x0d, 0xe4, 0x52, 0x44, 0xd6, 0xdc, 0x2d, 0x61, 0x48, 0xa8, 0xb5, 0x7b, 0x43, - 0x41, 0xb0, 0x81, 0x25, 0x9f, 0x59, 0xee, 0xac, 0xd1, 0x67, 0x4a, 0xdd, 0xcf, 0x70, 0x08, 0x36, - 0xb0, 0xd0, 0xf3, 0x30, 0xe0, 0xb6, 0x9d, 0x96, 0x8a, 0xa4, 0x7c, 0x8c, 0x2e, 0xda, 0x39, 0xd6, - 0x72, 0x6f, 0x67, 0x6c, 0x44, 0x75, 0x88, 0x35, 0x61, 0x81, 0x8b, 0x7e, 0xd9, 0x82, 0xe1, 0x46, - 0xd0, 0x6e, 0x07, 0x3e, 0xdf, 0x76, 0x89, 0x3d, 0xe4, 0x9d, 0xe3, 0x52, 0xf3, 0xe3, 0xd3, 0x06, - 0x33, 0xbe, 0x89, 0x54, 0x79, 0x55, 0x26, 0x08, 0xa7, 0x7a, 0x65, 0xae, 0xed, 0xea, 0x3e, 0x6b, - 0xfb, 0xd7, 0x2c, 0x38, 0xcd, 0x9f, 0x35, 0x76, 0x83, 0x22, 0x85, 0x28, 0x38, 0xe6, 0xd7, 0xea, - 0xda, 0x20, 0x2b, 0x2f, 0x5d, 0x17, 0x1c, 0x77, 0x77, 0x12, 0xcd, 0xc2, 0xe9, 0xb5, 0x20, 0x6a, - 0x10, 0x73, 0x20, 0x84, 0x60, 0x52, 0x84, 0xae, 0x64, 0x11, 0x70, 0xf7, 0x33, 0xe8, 0x16, 0x3c, - 0x62, 0x34, 0x9a, 0xe3, 0xc0, 0x65, 0xd3, 0x13, 0x82, 0xda, 0x23, 0x57, 0x72, 0xb1, 0x70, 0x8f, - 0xa7, 0xd3, 0x0e, 0x93, 0x7a, 0x1f, 0x0e, 0x93, 0xd7, 0xe0, 0x7c, 0xa3, 0x7b, 0x64, 0x36, 0xe3, - 0xce, 0x6a, 0xcc, 0x25, 0x55, 0x6d, 0xea, 0x07, 0x04, 0x81, 0xf3, 0xd3, 0xbd, 0x10, 0x71, 0x6f, - 0x1a, 0xe8, 0x63, 0x50, 0x8b, 0x08, 0xfb, 0x2a, 0xb1, 0xc8, 0xa7, 0x39, 0xe2, 0x2e, 0x59, 0x5b, - 0xa0, 0x9c, 0xac, 0x96, 0xbd, 0xa2, 0x21, 0xc6, 0x8a, 0x23, 0xba, 0x0b, 0x83, 0xa1, 0x93, 0x34, - 0xd6, 0x45, 0x16, 0xcd, 0x91, 0xc3, 0x58, 0x14, 0xf3, 0x25, 0x4a, 0x55, 0x4f, 0xf2, 0x25, 0xce, - 0x04, 0x4b, 0x6e, 0x17, 0x3e, 0x00, 0xa7, 0xbb, 0x16, 0xd2, 0x81, 0x9c, 0x25, 0x33, 0xf0, 0x48, - 0xfe, 0x94, 0x3d, 0x90, 0xcb, 0xe4, 0x1f, 0x67, 0x62, 0x4f, 0x0d, 0x33, 0xb6, 0x0f, 0xf7, 0x9b, - 0x03, 0x65, 0xe2, 0x6f, 0x0a, 0x09, 0x7e, 0xe5, 0x68, 0x23, 0x77, 0xd9, 0xdf, 0xe4, 0x2b, 0x8e, - 0xf9, 0x18, 0x2e, 0xfb, 0x9b, 0x98, 0xd2, 0x46, 0x5f, 0xb6, 0x52, 0x66, 0x18, 0x77, 0xda, 0x7d, - 0xe4, 0x58, 0xec, 0xf6, 0xbe, 0x2d, 0x33, 0xfb, 0xdf, 0x96, 0xe0, 0xe2, 0x7e, 0x44, 0xfa, 0x18, - 0xbe, 0x27, 0x61, 0x20, 0x66, 0xa7, 0xc9, 0x42, 0x24, 0x0e, 0xd1, 0x99, 0xc2, 0xcf, 0x97, 0x5f, - 0xc3, 0x02, 0x84, 0x3c, 0x28, 0xb7, 0x9d, 0x50, 0xf8, 0x72, 0xe6, 0x8e, 0x9a, 0x8d, 0x42, 0xff, - 0x3b, 0xde, 0x82, 0x13, 0x72, 0x0f, 0x81, 0xd1, 0x80, 0x29, 0x1b, 0x94, 0x40, 0xd5, 0x89, 0x22, - 0x47, 0x1e, 0x5d, 0x5e, 0x2f, 0x86, 0xdf, 0x24, 0x25, 0x39, 0x75, 0x7a, 0x77, 0x67, 0xec, 0x44, - 0xaa, 0x09, 0x73, 0x66, 0xf6, 0xe7, 0x07, 0x53, 0x19, 0x19, 0xec, 0x3c, 0x3a, 0x86, 0x01, 0xe1, - 0xc2, 0xb1, 0x8a, 0x4e, 0x02, 0xe2, 0x29, 0x75, 0x6c, 0x97, 0x26, 0x12, 0x93, 0x05, 0x2b, 0xf4, - 0x39, 0x8b, 0xa5, 0xff, 0xca, 0x2c, 0x15, 0xb1, 0x37, 0x3a, 0x9e, 0x6c, 0x64, 0x33, 0xa9, 0x58, - 0x36, 0x62, 0x93, 0x3b, 0xd5, 0x99, 0x21, 0x4f, 0x64, 0xcb, 0xee, 0x90, 0x64, 0x82, 0xb0, 0x84, - 0xa3, 0xad, 0x9c, 0x73, 0xe7, 0x02, 0x52, 0x48, 0xfb, 0x38, 0x69, 0xfe, 0x9a, 0x05, 0xa7, 0xdd, - 0xec, 0x01, 0xa2, 0xd8, 0x49, 0x1c, 0x31, 0xb2, 0xa1, 0xf7, 0xf9, 0xa4, 0x52, 0xa6, 0x5d, 0x20, - 0xdc, 0xdd, 0x19, 0xd4, 0x84, 0x8a, 0xeb, 0xaf, 0x05, 0xc2, 0x84, 0x98, 0x3a, 0x5a, 0xa7, 0xe6, - 0xfc, 0xb5, 0x40, 0xaf, 0x66, 0xfa, 0x0f, 0x33, 0xea, 0x68, 0x1e, 0xce, 0x46, 0xc2, 0xd7, 0x73, - 0xd5, 0x8d, 0xe9, 0x8e, 0x7c, 0xde, 0x6d, 0xbb, 0x09, 0x53, 0xff, 0xe5, 0xa9, 0xd1, 0xdd, 0x9d, - 0xb1, 0xb3, 0x38, 0x07, 0x8e, 0x73, 0x9f, 0x42, 0x6f, 0xc0, 0xa0, 0xcc, 0x57, 0xae, 0x15, 0xb1, - 0x2b, 0xeb, 0x9e, 0xff, 0x6a, 0x32, 0x2d, 0x8b, 0xd4, 0x64, 0xc9, 0xd0, 0x7e, 0x73, 0x08, 0xba, - 0x0f, 0x25, 0xd1, 0xc7, 0xa1, 0x1e, 0xa9, 0x1c, 0x6a, 0xab, 0x08, 0x65, 0x29, 0xbf, 0xaf, 0x38, - 0x10, 0x55, 0x86, 0x88, 0xce, 0x96, 0xd6, 0x1c, 0xe9, 0x76, 0x21, 0xd6, 0x67, 0x97, 0x05, 0xcc, - 0x6d, 0xc1, 0x55, 0x9f, 0x4b, 0x6d, 0xfb, 0x0d, 0xcc, 0x78, 0xa0, 0x08, 0x06, 0xd6, 0x89, 0xe3, - 0x25, 0xeb, 0xc5, 0xb8, 0xd0, 0xaf, 0x32, 0x5a, 0xd9, 0x4c, 0x1a, 0xde, 0x8a, 0x05, 0x27, 0xb4, - 0x05, 0x83, 0xeb, 0x7c, 0x02, 0x08, 0x0b, 0x7e, 0xe1, 0xa8, 0x83, 0x9b, 0x9a, 0x55, 0xfa, 0x73, - 0x8b, 0x06, 0x2c, 0xd9, 0xb1, 0xa0, 0x15, 0xe3, 0x3c, 0x9e, 0x2f, 0xdd, 0xe2, 0x92, 0x88, 0xfa, - 0x3f, 0x8c, 0xff, 0x28, 0x0c, 0x47, 0xa4, 0x11, 0xf8, 0x0d, 0xd7, 0x23, 0xcd, 0x49, 0xe9, 0x1e, - 0x3f, 0x48, 0xea, 0x09, 0xdb, 0x05, 0x63, 0x83, 0x06, 0x4e, 0x51, 0x44, 0x9f, 0xb5, 0x60, 0x44, - 0x25, 0x5e, 0xd2, 0x0f, 0x42, 0x84, 0x3b, 0x76, 0xbe, 0xa0, 0x34, 0x4f, 0x46, 0x73, 0x0a, 0xed, - 0xee, 0x8c, 0x8d, 0xa4, 0xdb, 0x70, 0x86, 0x2f, 0x7a, 0x05, 0x20, 0x58, 0xe5, 0x91, 0x29, 0x93, - 0x89, 0xf0, 0xcd, 0x1e, 0xe4, 0x55, 0x47, 0x78, 0x0e, 0x9a, 0xa4, 0x80, 0x0d, 0x6a, 0xe8, 0x3a, - 0x00, 0x5f, 0x36, 0x2b, 0xdb, 0xa1, 0x34, 0xf3, 0x65, 0xee, 0x10, 0x2c, 0x2b, 0xc8, 0xbd, 0x9d, - 0xb1, 0x6e, 0x5f, 0x19, 0x0b, 0x1b, 0x30, 0x1e, 0x47, 0x3f, 0x01, 0x83, 0x71, 0xa7, 0xdd, 0x76, - 0x94, 0xe7, 0xb6, 0xc0, 0xac, 0x36, 0x4e, 0xd7, 0x10, 0x45, 0xbc, 0x01, 0x4b, 0x8e, 0xe8, 0x0e, - 0x15, 0xaa, 0xb1, 0x70, 0xe2, 0xb1, 0x55, 0xc4, 0x6d, 0x82, 0x21, 0xf6, 0x4e, 0xef, 0x95, 0x81, - 0x36, 0x38, 0x07, 0xe7, 0xde, 0xce, 0xd8, 0x23, 0xe9, 0xf6, 0xf9, 0x40, 0xe4, 0x99, 0xe5, 0xd2, - 0x44, 0xd7, 0x64, 0xf9, 0x12, 0xfa, 0xda, 0x32, 0xab, 0xfe, 0x69, 0x5d, 0xbe, 0x84, 0x35, 0xf7, - 0x1e, 0x33, 0xf3, 0x61, 0xb4, 0x00, 0x67, 0x1a, 0x81, 0x9f, 0x44, 0x81, 0xe7, 0xf1, 0x9a, 0x3c, - 0x7c, 0xc7, 0xc5, 0x3d, 0xbb, 0xef, 0x14, 0xdd, 0x3e, 0x33, 0xdd, 0x8d, 0x82, 0xf3, 0x9e, 0xb3, - 0xfd, 0x74, 0xc8, 0x9e, 0x18, 0x9c, 0xe7, 0x61, 0x98, 0x6c, 0x25, 0x24, 0xf2, 0x1d, 0xef, 0x26, - 0x9e, 0x97, 0x3e, 0x4d, 0xb6, 0x06, 0x2e, 0x1b, 0xed, 0x38, 0x85, 0x85, 0x6c, 0xe5, 0x66, 0x30, - 0x72, 0x27, 0xb9, 0x9b, 0x41, 0x3a, 0x15, 0xec, 0xff, 0x55, 0x4a, 0x19, 0x64, 0x2b, 0x11, 0x21, - 0x28, 0x80, 0xaa, 0x1f, 0x34, 0x95, 0xec, 0xbf, 0x56, 0x8c, 0xec, 0xbf, 0x11, 0x34, 0x8d, 0x1a, - 0x27, 0xf4, 0x5f, 0x8c, 0x39, 0x1f, 0x56, 0x04, 0x42, 0x56, 0xcb, 0x60, 0x00, 0xb1, 0xd1, 0x28, - 0x92, 0xb3, 0x2a, 0x02, 0xb1, 0x68, 0x32, 0xc2, 0x69, 0xbe, 0x68, 0x03, 0xaa, 0xeb, 0x41, 0x9c, - 0xc8, 0xed, 0xc7, 0x11, 0x77, 0x3a, 0x57, 0x83, 0x38, 0x61, 0x56, 0x84, 0x7a, 0x6d, 0xda, 0x12, - 0x63, 0xce, 0xc3, 0xfe, 0x2f, 0x56, 0xca, 0x83, 0x7d, 0x9b, 0x85, 0xaf, 0x6e, 0x12, 0x9f, 0x2e, - 0x6b, 0x33, 0xd0, 0xe7, 0x2f, 0x64, 0x92, 0x01, 0xdf, 0xd5, 0xab, 0xe2, 0xd4, 0x5d, 0x4a, 0x61, - 0x9c, 0x91, 0x30, 0x62, 0x82, 0x3e, 0x69, 0xa5, 0xd3, 0x32, 0x4b, 0x45, 0x6c, 0x30, 0xcc, 0xd4, - 0xe4, 0x7d, 0x33, 0x3c, 0xed, 0x2f, 0x5b, 0x30, 0x38, 0xe5, 0x34, 0x36, 0x82, 0xb5, 0x35, 0xf4, - 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0xcc, 0x10, 0x55, 0xdb, 0xf6, 0x19, 0xd1, 0x8e, 0x15, 0x06, 0x9d, - 0xc3, 0x6b, 0x4e, 0x43, 0x26, 0x28, 0x97, 0xf9, 0x1c, 0xbe, 0xc2, 0x5a, 0xb0, 0x80, 0xa0, 0x17, - 0x60, 0xa8, 0xed, 0x6c, 0xc9, 0x87, 0xb3, 0xee, 0xf3, 0x05, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0x2f, - 0x2d, 0x18, 0x9d, 0x72, 0x62, 0xb7, 0x31, 0xd9, 0x49, 0xd6, 0xa7, 0xdc, 0x64, 0xb5, 0xd3, 0xd8, - 0x20, 0x09, 0xcf, 0x4a, 0xa7, 0xbd, 0xec, 0xc4, 0x74, 0x29, 0xa9, 0x7d, 0x9d, 0xea, 0xe5, 0x4d, - 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, 0x27, 0x8e, 0xef, 0x06, 0x51, 0x13, 0x93, 0xb5, - 0x62, 0x6a, 0x42, 0x2c, 0x93, 0x46, 0x44, 0x12, 0x4c, 0xd6, 0xc4, 0x11, 0xaf, 0xa6, 0x8f, 0x4d, - 0x66, 0xf6, 0x17, 0x2d, 0x38, 0x3f, 0x45, 0x9c, 0x88, 0x44, 0xac, 0x84, 0x84, 0x7a, 0x91, 0x69, - 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, 0x33, 0xed, 0x96, 0x55, 0x6c, 0xb7, 0xd8, 0x09, - 0xed, 0x8a, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, 0x5b, 0x30, 0xcc, 0x0e, 0xbb, 0x66, 0x48, 0xe2, - 0xb8, 0x5e, 0x57, 0xa5, 0x25, 0xab, 0xcf, 0x4a, 0x4b, 0x17, 0xa1, 0xb2, 0x1e, 0xb4, 0x49, 0xf6, - 0xa0, 0xf6, 0x6a, 0x40, 0xb7, 0xd5, 0x14, 0x82, 0x9e, 0xa3, 0x1f, 0xde, 0xf5, 0x13, 0x87, 0x2e, - 0x01, 0xe9, 0x4c, 0x3d, 0xc9, 0x3f, 0xba, 0x6a, 0xc6, 0x26, 0x8e, 0xfd, 0x9b, 0x75, 0x18, 0x14, - 0xa7, 0xf9, 0x7d, 0x57, 0x26, 0x90, 0xfb, 0xfb, 0x52, 0xcf, 0xfd, 0x7d, 0x0c, 0x03, 0x0d, 0x56, - 0xc7, 0x4d, 0x98, 0x91, 0xd7, 0x0b, 0x09, 0xff, 0xe0, 0xa5, 0xe1, 0x74, 0xb7, 0xf8, 0x7f, 0x2c, - 0x58, 0xa1, 0x2f, 0x59, 0x70, 0xb2, 0x11, 0xf8, 0x3e, 0x69, 0x68, 0x1b, 0xa7, 0x52, 0xc4, 0x29, - 0xff, 0x74, 0x9a, 0xa8, 0x3e, 0x69, 0xc9, 0x00, 0x70, 0x96, 0x3d, 0x7a, 0x09, 0x4e, 0xf0, 0x31, - 0xbb, 0x95, 0xf2, 0x00, 0xeb, 0x02, 0x3c, 0x26, 0x10, 0xa7, 0x71, 0xd1, 0x38, 0xf7, 0xa4, 0x8b, - 0x52, 0x37, 0x03, 0xfa, 0xd8, 0xce, 0x28, 0x72, 0x63, 0x60, 0xa0, 0x08, 0x50, 0x44, 0xd6, 0x22, - 0x12, 0xaf, 0x8b, 0x68, 0x07, 0x66, 0x5f, 0x0d, 0x1e, 0x2e, 0x8b, 0x19, 0x77, 0x51, 0xc2, 0x39, - 0xd4, 0xd1, 0x86, 0xd8, 0x60, 0xd6, 0x8a, 0x90, 0xa1, 0xe2, 0x33, 0xf7, 0xdc, 0x67, 0x8e, 0x41, - 0x35, 0x5e, 0x77, 0xa2, 0x26, 0xb3, 0xeb, 0xca, 0x3c, 0x73, 0x66, 0x99, 0x36, 0x60, 0xde, 0x8e, - 0x66, 0xe0, 0x54, 0xa6, 0x7c, 0x50, 0x2c, 0x3c, 0xb5, 0x2a, 0x4b, 0x22, 0x53, 0x78, 0x28, 0xc6, - 0x5d, 0x4f, 0x98, 0xce, 0x87, 0xa1, 0x7d, 0x9c, 0x0f, 0xdb, 0x2a, 0xa6, 0x8e, 0xfb, 0x50, 0x5f, - 0x2e, 0x64, 0x00, 0xfa, 0x0a, 0xa0, 0xfb, 0x42, 0x26, 0x80, 0xee, 0x04, 0xeb, 0xc0, 0xad, 0x62, - 0x3a, 0x70, 0xf0, 0x68, 0xb9, 0x07, 0x19, 0xfd, 0xf6, 0x67, 0x16, 0xc8, 0xef, 0x3a, 0xed, 0x34, - 0xd6, 0x09, 0x9d, 0x32, 0xe8, 0xfd, 0x30, 0xa2, 0xb6, 0xd0, 0xd3, 0x41, 0xc7, 0xe7, 0x81, 0x6f, - 0x65, 0x7d, 0x24, 0x8b, 0x53, 0x50, 0x9c, 0xc1, 0x46, 0x13, 0x50, 0xa7, 0xe3, 0xc4, 0x1f, 0xe5, - 0xba, 0x56, 0x6d, 0xd3, 0x27, 0x97, 0xe6, 0xc4, 0x53, 0x1a, 0x07, 0x05, 0x70, 0xda, 0x73, 0xe2, - 0x84, 0xf5, 0x80, 0xee, 0xa8, 0x0f, 0x59, 0x43, 0x80, 0x85, 0xe2, 0xcf, 0x67, 0x09, 0xe1, 0x6e, - 0xda, 0xf6, 0xb7, 0x2b, 0x70, 0x22, 0x25, 0x19, 0x0f, 0xa8, 0xa4, 0x9f, 0x81, 0x9a, 0xd4, 0x9b, - 0xd9, 0x6a, 0x27, 0x4a, 0xb9, 0x2a, 0x0c, 0xaa, 0xb4, 0x56, 0xb5, 0x56, 0xcd, 0x1a, 0x15, 0x86, - 0xc2, 0xc5, 0x26, 0x1e, 0x13, 0xca, 0x89, 0x17, 0x4f, 0x7b, 0x2e, 0xf1, 0x13, 0xde, 0xcd, 0x62, - 0x84, 0xf2, 0xca, 0xfc, 0xb2, 0x49, 0x54, 0x0b, 0xe5, 0x0c, 0x00, 0x67, 0xd9, 0xa3, 0xcf, 0x58, - 0x70, 0xc2, 0xb9, 0x1b, 0xeb, 0x62, 0xa3, 0x22, 0x54, 0xee, 0x88, 0x4a, 0x2a, 0x55, 0xbf, 0x94, - 0xbb, 0x7c, 0x53, 0x4d, 0x38, 0xcd, 0x14, 0xbd, 0x65, 0x01, 0x22, 0x5b, 0xa4, 0x21, 0x83, 0xf9, - 0x44, 0x5f, 0x06, 0x8a, 0xd8, 0x69, 0x5e, 0xee, 0xa2, 0xcb, 0xa5, 0x7a, 0x77, 0x3b, 0xce, 0xe9, - 0x83, 0xfd, 0xcf, 0xca, 0x6a, 0x41, 0xe9, 0xf8, 0x51, 0xc7, 0x88, 0x63, 0xb3, 0x0e, 0x1f, 0xc7, - 0xa6, 0xe3, 0x01, 0xba, 0x53, 0x13, 0x53, 0x99, 0x4c, 0xa5, 0x07, 0x94, 0xc9, 0xf4, 0x53, 0x56, - 0xaa, 0xae, 0xcf, 0xd0, 0xa5, 0x57, 0x8a, 0x8d, 0x5d, 0x1d, 0xe7, 0xb1, 0x0a, 0x19, 0xe9, 0x9e, - 0x0e, 0x51, 0xa1, 0xd2, 0xd4, 0x40, 0x3b, 0x90, 0x34, 0xfc, 0x0f, 0x65, 0x18, 0x32, 0x34, 0x69, - 0xae, 0x59, 0x64, 0x3d, 0x64, 0x66, 0x51, 0xe9, 0x00, 0x66, 0xd1, 0x4f, 0x42, 0xbd, 0x21, 0xa5, - 0x7c, 0x31, 0x95, 0x6d, 0xb3, 0xba, 0x43, 0x0b, 0x7a, 0xd5, 0x84, 0x35, 0x4f, 0x34, 0x9b, 0x4a, - 0x9c, 0x11, 0x1a, 0xa2, 0xc2, 0x34, 0x44, 0x5e, 0x66, 0x8b, 0xd0, 0x14, 0xdd, 0xcf, 0xb0, 0xf2, - 0x4f, 0xa1, 0x2b, 0xde, 0x4b, 0x46, 0x98, 0xf3, 0xf2, 0x4f, 0x4b, 0x73, 0xb2, 0x19, 0x9b, 0x38, - 0xf6, 0xb7, 0x2d, 0xf5, 0x71, 0xef, 0x43, 0xa1, 0x83, 0x3b, 0xe9, 0x42, 0x07, 0x97, 0x0b, 0x19, - 0xe6, 0x1e, 0x15, 0x0e, 0x6e, 0xc0, 0xe0, 0x74, 0xd0, 0x6e, 0x3b, 0x7e, 0x13, 0xfd, 0x20, 0x0c, - 0x36, 0xf8, 0x4f, 0xe1, 0xd8, 0x61, 0xc7, 0x83, 0x02, 0x8a, 0x25, 0x0c, 0x3d, 0x06, 0x15, 0x27, - 0x6a, 0x49, 0x67, 0x0e, 0x0b, 0x6d, 0x99, 0x8c, 0x5a, 0x31, 0x66, 0xad, 0xf6, 0x3f, 0xaa, 0x00, - 0x4c, 0x07, 0xed, 0xd0, 0x89, 0x48, 0x73, 0x25, 0x60, 0x95, 0xf5, 0x8e, 0xf5, 0x50, 0x4d, 0x6f, - 0x96, 0x1e, 0xe6, 0x83, 0x35, 0xe3, 0x70, 0xa5, 0x7c, 0x9f, 0x0f, 0x57, 0x7a, 0x9c, 0x97, 0x55, - 0x1e, 0xa2, 0xf3, 0x32, 0xfb, 0xf3, 0x16, 0x20, 0x3a, 0x69, 0x02, 0x9f, 0xf8, 0x89, 0x3e, 0xd0, - 0x9e, 0x80, 0x7a, 0x43, 0xb6, 0x0a, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, 0xa7, 0x8f, 0x1d, - 0xf2, 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb1, 0x4c, 0xea, 0x0b, 0x71, 0x6e, 0xff, 0x56, 0x09, - 0x1e, 0xe1, 0x2a, 0x79, 0xc1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, 0xa2, 0xd0, 0xa0, - 0x5b, 0x33, 0x57, 0x46, 0xb9, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0x9c, 0xef, 0x26, - 0x98, 0x11, 0x47, 0x31, 0xd4, 0x64, 0x29, 0x77, 0x21, 0x8b, 0x0b, 0x62, 0xa4, 0xc4, 0x92, 0xd0, - 0x9b, 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x06, 0x26, 0x61, 0xc0, 0xe4, 0xae, 0x11, - 0x64, 0x38, 0x2f, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xcb, 0x82, 0xac, 0x46, 0x32, 0x4a, 0x98, 0x59, - 0x7b, 0x96, 0x30, 0x3b, 0x40, 0x0d, 0xb1, 0x1f, 0x87, 0x21, 0x27, 0xa1, 0x46, 0x04, 0xdf, 0x76, - 0x97, 0x0f, 0x77, 0xac, 0xb1, 0x10, 0x34, 0xdd, 0x35, 0x97, 0x6d, 0xb7, 0x4d, 0x72, 0xf6, 0xff, - 0xa8, 0xc0, 0xe9, 0xae, 0x5c, 0x0c, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, 0xa5, 0x43, 0xab, - 0x6e, 0x06, 0xa5, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe0, 0x4c, 0x44, 0x37, 0xfa, - 0x1d, 0x32, 0xb9, 0x96, 0x90, 0x68, 0x99, 0x34, 0x02, 0xbf, 0xc9, 0x0b, 0xed, 0x95, 0xa7, 0x1e, - 0xdd, 0xdd, 0x19, 0x3b, 0x83, 0xbb, 0xc1, 0x38, 0xef, 0x19, 0x14, 0xc2, 0x09, 0xcf, 0xb4, 0x01, - 0xc5, 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, 0x6d, 0x48, 0x56, - 0x1f, 0x90, 0x21, 0xf9, 0x69, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x17, 0x9c, 0x8b, 0x73, 0xdc, - 0x96, 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, 0x48, 0xb4, 0x7b, - 0x25, 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, 0xeb, 0xa3, 0x2d, - 0x1e, 0x97, 0xc5, 0x75, 0xdb, 0x87, 0x8a, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, 0xa2, 0xa0, 0xc2, - 0xb5, 0x2e, 0x01, 0x68, 0x43, 0x4d, 0x04, 0xa0, 0xab, 0x63, 0x5f, 0x6d, 0xcf, 0x61, 0x03, 0x8b, - 0xee, 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xea, 0xfa, 0x89, 0x70, 0x0e, 0x2a, 0x25, 0x3e, - 0xa7, 0x41, 0xd8, 0xc4, 0xbb, 0xf0, 0x5e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0xae, 0xc3, 0xf9, 0x59, - 0x37, 0x51, 0x69, 0x13, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x01, 0x59, 0x3d, 0xd3, 0x80, 0x8c, - 0xb4, 0x85, 0x52, 0x3a, 0xcb, 0x22, 0x9b, 0xb6, 0x60, 0xbf, 0x08, 0x67, 0x67, 0xdd, 0xe4, 0x8a, - 0xeb, 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x63, 0x00, 0x86, 0xcd, 0xc4, 0xbb, 0x83, 0x64, 0x32, 0x7d, - 0x91, 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xfb, 0xc8, 0x59, 0x80, 0xf9, 0x23, 0x66, - 0x58, 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x42, 0x75, 0x8d, 0x85, 0xd5, 0x97, 0x8b, 0x88, - 0x2c, 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x60, 0x3e, 0xe7, 0x47, 0x35, 0x64, 0x94, 0xce, 0xd5, - 0x32, 0x42, 0x41, 0x45, 0x96, 0x96, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, 0xf5, 0x29, 0xc1, - 0x3b, 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0x91, 0x48, 0xd6, 0x99, 0xfd, 0x26, 0x62, 0xd7, 0x07, 0xd9, - 0x20, 0x18, 0x29, 0x12, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x4f, 0x28, 0xd1, 0x5d, 0x2b, 0xc2, 0xaf, - 0x6a, 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2f, 0xc1, 0xc8, 0xac, 0xdf, 0x59, 0x9a, 0x5d, 0xea, - 0xac, 0x7a, 0x6e, 0xe3, 0x3a, 0xd9, 0xa6, 0xa2, 0x79, 0x83, 0x6c, 0xcf, 0xcd, 0x88, 0x15, 0xa4, - 0xe6, 0xcc, 0x75, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x35, 0xd7, 0x6f, 0x91, 0x28, 0x8c, 0x5c, - 0xe1, 0xf2, 0x34, 0x84, 0xd1, 0x15, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf5, 0x49, 0x94, - 0x35, 0x64, 0x17, 0x69, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, 0x93, 0x51, 0x21, - 0xad, 0xd0, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x55, 0x16, 0xb8, 0x91, 0x09, 0x94, 0x5f, - 0xe6, 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x06, 0xd9, 0x9e, 0xa1, 0xbb, 0xde, 0x4c, 0xbe, 0xcc, 0x75, - 0xde, 0x8c, 0x25, 0x9c, 0x55, 0x08, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x85, 0xc0, 0x74, 0xf7, 0x7b, - 0xec, 0x9f, 0x7f, 0xc9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, 0x62, 0x57, 0x81, - 0xd9, 0x1f, 0xcd, 0xbb, 0x71, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, 0x96, 0xeb, 0x13, - 0x76, 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0xd3, 0x41, 0x93, 0x1c, 0xc2, 0x48, 0xb6, 0x6f, - 0xc3, 0xe9, 0xae, 0x24, 0xa9, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x54, 0x6d, 0x0c, 0x43, 0x94, 0xb0, - 0xac, 0x52, 0x33, 0x0d, 0xa7, 0xf9, 0x42, 0xa2, 0x9c, 0x96, 0x1b, 0xeb, 0xa4, 0xad, 0x12, 0xdf, - 0x98, 0x7f, 0xfd, 0x56, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x2f, 0x58, 0x70, 0x22, 0x95, 0xb7, 0x56, - 0x90, 0x11, 0xc4, 0x56, 0x5a, 0xc0, 0xa2, 0xff, 0x58, 0x08, 0x74, 0x99, 0x29, 0x53, 0xbd, 0xd2, - 0x34, 0x08, 0x9b, 0x78, 0xf6, 0x97, 0x4b, 0x50, 0x93, 0x11, 0x14, 0x7d, 0x74, 0xe5, 0x73, 0x16, - 0x9c, 0x50, 0x67, 0x1a, 0xcc, 0x59, 0x56, 0x2a, 0x22, 0xc9, 0x80, 0xf6, 0x40, 0x6d, 0xb7, 0xfd, - 0xb5, 0x40, 0x5b, 0xe4, 0xd8, 0x64, 0x86, 0xd3, 0xbc, 0xd1, 0x2d, 0x80, 0x78, 0x3b, 0x4e, 0x48, - 0xdb, 0x70, 0xdb, 0xd9, 0xc6, 0x8a, 0x1b, 0x6f, 0x04, 0x11, 0xa1, 0xeb, 0xeb, 0x46, 0xd0, 0x24, - 0xcb, 0x0a, 0x53, 0x9b, 0x50, 0xba, 0x0d, 0x1b, 0x94, 0xec, 0x7f, 0x50, 0x82, 0x53, 0xd9, 0x2e, - 0xa1, 0x0f, 0xc3, 0xb0, 0xe4, 0x6e, 0xdc, 0x1e, 0x26, 0xc3, 0x46, 0x86, 0xb1, 0x01, 0xbb, 0xb7, - 0x33, 0x36, 0xd6, 0x7d, 0x7b, 0xdb, 0xb8, 0x89, 0x82, 0x53, 0xc4, 0xf8, 0xc1, 0x92, 0x38, 0x01, - 0x9d, 0xda, 0x9e, 0x0c, 0x43, 0x71, 0x3a, 0x64, 0x1c, 0x2c, 0x99, 0x50, 0x9c, 0xc1, 0x46, 0x4b, - 0x70, 0xd6, 0x68, 0xb9, 0x41, 0xdc, 0xd6, 0xfa, 0x6a, 0x10, 0xc9, 0x9d, 0xd5, 0x63, 0x3a, 0xb0, - 0xab, 0x1b, 0x07, 0xe7, 0x3e, 0x49, 0xb5, 0x7d, 0xc3, 0x09, 0x9d, 0x86, 0x9b, 0x6c, 0x0b, 0x3f, - 0xa4, 0x92, 0x4d, 0xd3, 0xa2, 0x1d, 0x2b, 0x0c, 0x7b, 0x01, 0x2a, 0x7d, 0xce, 0xa0, 0xbe, 0x2c, - 0xfa, 0x97, 0xa1, 0x46, 0xc9, 0x49, 0xf3, 0xae, 0x08, 0x92, 0x01, 0xd4, 0xe4, 0x05, 0x20, 0xc8, - 0x86, 0xb2, 0xeb, 0xc8, 0xb3, 0x3b, 0xf5, 0x5a, 0x73, 0x71, 0xdc, 0x61, 0x9b, 0x64, 0x0a, 0x44, - 0x4f, 0x42, 0x99, 0x6c, 0x85, 0xd9, 0x43, 0xba, 0xcb, 0x5b, 0xa1, 0x1b, 0x91, 0x98, 0x22, 0x91, - 0xad, 0x10, 0x5d, 0x80, 0x92, 0xdb, 0x14, 0x4a, 0x0a, 0x04, 0x4e, 0x69, 0x6e, 0x06, 0x97, 0xdc, - 0xa6, 0xbd, 0x05, 0x75, 0x75, 0xe3, 0x08, 0xda, 0x90, 0xb2, 0xdb, 0x2a, 0x22, 0xe4, 0x49, 0xd2, - 0xed, 0x21, 0xb5, 0x3b, 0x00, 0x3a, 0x81, 0xaf, 0x28, 0xf9, 0x72, 0x11, 0x2a, 0x8d, 0x40, 0x24, - 0x17, 0xd7, 0x34, 0x19, 0x26, 0xb4, 0x19, 0xc4, 0xbe, 0x0d, 0x23, 0xd7, 0xfd, 0xe0, 0x2e, 0x2b, - 0x97, 0xce, 0xaa, 0x83, 0x51, 0xc2, 0x6b, 0xf4, 0x47, 0xd6, 0x44, 0x60, 0x50, 0xcc, 0x61, 0xaa, - 0xde, 0x52, 0xa9, 0x57, 0xbd, 0x25, 0xfb, 0x93, 0x16, 0x0c, 0xab, 0x4c, 0xa0, 0xd9, 0xcd, 0x0d, - 0x4a, 0xb7, 0x15, 0x05, 0x9d, 0x30, 0x4b, 0x97, 0xdd, 0x09, 0x84, 0x39, 0xcc, 0x4c, 0x91, 0x2b, - 0xed, 0x93, 0x22, 0x77, 0x11, 0x2a, 0x1b, 0xae, 0xdf, 0xcc, 0x5e, 0x72, 0x71, 0xdd, 0xf5, 0x9b, - 0x98, 0x41, 0x68, 0x17, 0x4e, 0xa9, 0x2e, 0x48, 0x85, 0xf0, 0x22, 0x0c, 0xaf, 0x76, 0x5c, 0xaf, - 0x29, 0xcb, 0x9e, 0x65, 0x3c, 0x25, 0x53, 0x06, 0x0c, 0xa7, 0x30, 0xe9, 0xbe, 0x6e, 0xd5, 0xf5, - 0x9d, 0x68, 0x7b, 0x49, 0x6b, 0x20, 0x25, 0x94, 0xa6, 0x14, 0x04, 0x1b, 0x58, 0xf6, 0x9b, 0x65, - 0x18, 0x49, 0xe7, 0x43, 0xf5, 0xb1, 0xbd, 0x7a, 0x12, 0xaa, 0x2c, 0x45, 0x2a, 0xfb, 0x69, 0xd9, - 0xf3, 0x98, 0xc3, 0x50, 0x0c, 0x03, 0xbc, 0xb8, 0x42, 0x31, 0x17, 0xc4, 0xa8, 0x4e, 0x2a, 0xff, - 0x0a, 0x8b, 0x27, 0x13, 0xf5, 0x1c, 0x04, 0x2b, 0xf4, 0x19, 0x0b, 0x06, 0x83, 0xd0, 0xac, 0xd3, - 0xf3, 0xa1, 0x22, 0x73, 0xc5, 0x44, 0xb2, 0x8c, 0xb0, 0x88, 0xd5, 0xa7, 0x97, 0x9f, 0x43, 0xb2, - 0xbe, 0xf0, 0x3e, 0x18, 0x36, 0x31, 0xf7, 0x33, 0x8a, 0x6b, 0xa6, 0x51, 0xfc, 0x39, 0x73, 0x52, - 0x88, 0x6c, 0xb8, 0x3e, 0x96, 0xdb, 0x4d, 0xa8, 0x36, 0x54, 0x00, 0xc0, 0xa1, 0x8a, 0x65, 0xaa, - 0x6a, 0x07, 0xec, 0x10, 0x88, 0x53, 0xb3, 0xbf, 0x6d, 0x19, 0xf3, 0x03, 0x93, 0x78, 0xae, 0x89, - 0x22, 0x28, 0xb7, 0x36, 0x37, 0x84, 0x29, 0x7a, 0xad, 0xa0, 0xe1, 0x9d, 0xdd, 0xdc, 0xd0, 0x73, - 0xdc, 0x6c, 0xc5, 0x94, 0x59, 0x1f, 0x4e, 0xc0, 0x54, 0xd2, 0x64, 0x79, 0xff, 0xa4, 0x49, 0xfb, - 0xad, 0x12, 0x9c, 0xee, 0x9a, 0x54, 0xe8, 0x0d, 0xa8, 0x46, 0xf4, 0x2d, 0xc5, 0xeb, 0xcd, 0x17, - 0x96, 0xe6, 0x18, 0xcf, 0x35, 0xb5, 0xde, 0x4d, 0xb7, 0x63, 0xce, 0x12, 0x5d, 0x03, 0xa4, 0xc3, - 0x54, 0x94, 0x07, 0x92, 0xbf, 0xf2, 0x05, 0xf1, 0x28, 0x9a, 0xec, 0xc2, 0xc0, 0x39, 0x4f, 0xa1, - 0x97, 0xb2, 0x8e, 0xcc, 0x72, 0xfa, 0xdc, 0x72, 0x2f, 0x9f, 0xa4, 0xfd, 0xcf, 0x4b, 0x70, 0x22, - 0x55, 0x36, 0x09, 0x79, 0x50, 0x23, 0x1e, 0x73, 0xea, 0x4b, 0x65, 0x73, 0xd4, 0x62, 0xc2, 0x4a, - 0x41, 0x5e, 0x16, 0x74, 0xb1, 0xe2, 0xf0, 0x70, 0x1c, 0xae, 0xbf, 0x08, 0xc3, 0xb2, 0x43, 0x1f, - 0x72, 0xda, 0x9e, 0x18, 0x40, 0x35, 0x47, 0x2f, 0x1b, 0x30, 0x9c, 0xc2, 0xb4, 0x7f, 0xbb, 0x0c, - 0xa3, 0xfc, 0x14, 0xa4, 0xa9, 0x66, 0xde, 0x82, 0xdc, 0x6f, 0xfd, 0x65, 0x5d, 0xdc, 0x8c, 0x0f, - 0xe4, 0xea, 0x51, 0x6b, 0xf7, 0xe7, 0x33, 0xea, 0x2b, 0x32, 0xeb, 0x17, 0x32, 0x91, 0x59, 0xdc, - 0xec, 0x6e, 0x1d, 0x53, 0x8f, 0xbe, 0xb7, 0x42, 0xb5, 0xfe, 0x6e, 0x09, 0x4e, 0x66, 0x2e, 0x46, - 0x40, 0x6f, 0xa6, 0x6b, 0xe9, 0x5a, 0x45, 0xf8, 0xca, 0xf7, 0xac, 0x95, 0x7f, 0xb0, 0x8a, 0xba, - 0x0f, 0x68, 0xa9, 0xd8, 0xbf, 0x57, 0x82, 0x91, 0xf4, 0x8d, 0x0e, 0x0f, 0xe1, 0x48, 0xbd, 0x1b, - 0xea, 0xac, 0x68, 0x39, 0xbb, 0xa9, 0x92, 0xbb, 0xe4, 0x79, 0x7d, 0x68, 0xd9, 0x88, 0x35, 0xfc, - 0xa1, 0x28, 0x54, 0x6c, 0xff, 0x3d, 0x0b, 0xce, 0xf1, 0xb7, 0xcc, 0xce, 0xc3, 0xbf, 0x92, 0x37, - 0xba, 0xaf, 0x16, 0xdb, 0xc1, 0x4c, 0x51, 0xbe, 0xfd, 0xc6, 0x97, 0xdd, 0x90, 0x27, 0x7a, 0x9b, - 0x9e, 0x0a, 0x0f, 0x61, 0x67, 0x0f, 0x34, 0x19, 0xec, 0xdf, 0x2b, 0x83, 0xbe, 0x14, 0x10, 0xb9, - 0x22, 0xc7, 0xb1, 0x90, 0xe2, 0x84, 0xcb, 0xdb, 0x7e, 0x43, 0x5f, 0x3f, 0x58, 0xcb, 0xa4, 0x38, - 0xfe, 0xac, 0x05, 0x43, 0xae, 0xef, 0x26, 0xae, 0xc3, 0xb6, 0xd1, 0xc5, 0x5c, 0x58, 0xa6, 0xd8, - 0xcd, 0x71, 0xca, 0x41, 0x64, 0x9e, 0xe3, 0x28, 0x66, 0xd8, 0xe4, 0x8c, 0x3e, 0x2a, 0x82, 0xa7, - 0xcb, 0x85, 0x65, 0xe7, 0xd6, 0x32, 0x11, 0xd3, 0x21, 0x35, 0xbc, 0x92, 0xa8, 0xa0, 0xa4, 0x76, - 0x4c, 0x49, 0xa9, 0x3a, 0xb7, 0xfa, 0x7a, 0x66, 0xda, 0x8c, 0x39, 0x23, 0x3b, 0x06, 0xd4, 0x3d, - 0x16, 0x07, 0x0c, 0x4c, 0x9d, 0x80, 0xba, 0xd3, 0x49, 0x82, 0x36, 0x1d, 0x26, 0x71, 0xd4, 0xa4, - 0x43, 0x6f, 0x25, 0x00, 0x6b, 0x1c, 0xfb, 0xcd, 0x2a, 0x64, 0x92, 0x0e, 0xd1, 0x96, 0x79, 0xa1, - 0xa5, 0x55, 0xec, 0x85, 0x96, 0xaa, 0x33, 0x79, 0x97, 0x5a, 0xa2, 0x16, 0x54, 0xc3, 0x75, 0x27, - 0x96, 0x66, 0xf5, 0xcb, 0x6a, 0x1f, 0x47, 0x1b, 0xef, 0xed, 0x8c, 0xfd, 0x58, 0x7f, 0x5e, 0x57, - 0x3a, 0x57, 0x27, 0x78, 0xf1, 0x10, 0xcd, 0x9a, 0xd1, 0xc0, 0x9c, 0xfe, 0x41, 0xae, 0x6c, 0xfb, - 0x94, 0xa8, 0xce, 0x8e, 0x49, 0xdc, 0xf1, 0x12, 0x31, 0x1b, 0x5e, 0x2e, 0x70, 0x95, 0x71, 0xc2, - 0x3a, 0x5d, 0x9e, 0xff, 0xc7, 0x06, 0x53, 0xf4, 0x61, 0xa8, 0xc7, 0x89, 0x13, 0x25, 0x87, 0x4c, - 0x70, 0x55, 0x83, 0xbe, 0x2c, 0x89, 0x60, 0x4d, 0x0f, 0xbd, 0xc2, 0x6a, 0xb5, 0xba, 0xf1, 0xfa, - 0x21, 0x73, 0x1e, 0x64, 0x5d, 0x57, 0x41, 0x01, 0x1b, 0xd4, 0xd0, 0x25, 0x00, 0x36, 0xb7, 0x79, - 0xa0, 0x5f, 0x8d, 0x79, 0x99, 0x94, 0x28, 0xc4, 0x0a, 0x82, 0x0d, 0x2c, 0xfb, 0x87, 0x21, 0x5d, - 0xef, 0x01, 0x8d, 0xc9, 0xf2, 0x12, 0xdc, 0x0b, 0xcd, 0x72, 0x17, 0x52, 0x95, 0x20, 0x7e, 0xcd, - 0x02, 0xb3, 0x28, 0x05, 0x7a, 0x9d, 0x57, 0xbf, 0xb0, 0x8a, 0x38, 0x39, 0x34, 0xe8, 0x8e, 0x2f, - 0x38, 0x61, 0xe6, 0x08, 0x5b, 0x96, 0xc0, 0xb8, 0xf0, 0x5e, 0xa8, 0x49, 0xe8, 0x81, 0x8c, 0xba, - 0x4f, 0xc0, 0x99, 0xec, 0x75, 0xdf, 0xe2, 0xd4, 0x69, 0x7f, 0xd7, 0x8f, 0xf4, 0xe7, 0x94, 0x7a, - 0xf9, 0x73, 0xfa, 0xb8, 0xd6, 0xf4, 0xd7, 0x2d, 0xb8, 0xb8, 0xdf, 0xad, 0xe4, 0xe8, 0x31, 0xa8, - 0xdc, 0x75, 0x22, 0x59, 0x44, 0x9b, 0x09, 0xca, 0xdb, 0x4e, 0xe4, 0x63, 0xd6, 0x8a, 0xb6, 0x61, - 0x80, 0x47, 0x83, 0x09, 0x6b, 0xfd, 0xe5, 0x62, 0xef, 0x48, 0xbf, 0x4e, 0x8c, 0xed, 0x02, 0x8f, - 0x44, 0xc3, 0x82, 0xa1, 0xfd, 0x1d, 0x0b, 0xd0, 0xe2, 0x26, 0x89, 0x22, 0xb7, 0x69, 0xc4, 0xaf, - 0xb1, 0x5b, 0x4e, 0x8c, 0xdb, 0x4c, 0xcc, 0x14, 0xd7, 0xcc, 0x2d, 0x27, 0xc6, 0xbf, 0xfc, 0x5b, - 0x4e, 0x4a, 0x07, 0xbb, 0xe5, 0x04, 0x2d, 0xc2, 0xb9, 0x36, 0xdf, 0x6e, 0xf0, 0x9b, 0x03, 0xf8, - 0xde, 0x43, 0x25, 0x94, 0x9d, 0xdf, 0xdd, 0x19, 0x3b, 0xb7, 0x90, 0x87, 0x80, 0xf3, 0x9f, 0xb3, - 0xdf, 0x0b, 0x88, 0x87, 0xad, 0x4d, 0xe7, 0xc5, 0x20, 0xf5, 0x74, 0xbf, 0xd8, 0x5f, 0xad, 0xc2, - 0xc9, 0x4c, 0x89, 0x55, 0xba, 0xd5, 0xeb, 0x0e, 0x7a, 0x3a, 0xb2, 0xfe, 0xee, 0xee, 0x5e, 0x5f, - 0x61, 0x54, 0x3e, 0x54, 0x5d, 0x3f, 0xec, 0x24, 0xc5, 0xe4, 0x90, 0xf2, 0x4e, 0xcc, 0x51, 0x82, - 0x86, 0xbb, 0x98, 0xfe, 0xc5, 0x9c, 0x4d, 0x91, 0x41, 0x59, 0x29, 0x63, 0xbc, 0xf2, 0x80, 0xdc, - 0x01, 0x9f, 0xd2, 0x21, 0x52, 0xd5, 0x22, 0x1c, 0x8b, 0x99, 0xc9, 0x72, 0xdc, 0x47, 0xed, 0xbf, - 0x5a, 0x82, 0x21, 0xe3, 0xa3, 0xa1, 0x5f, 0x4c, 0x97, 0x6c, 0xb2, 0x8a, 0x7b, 0x25, 0x46, 0x7f, - 0x5c, 0x17, 0x65, 0xe2, 0xaf, 0xf4, 0x54, 0x77, 0xb5, 0xa6, 0x7b, 0x3b, 0x63, 0xa7, 0x32, 0xf5, - 0x98, 0x52, 0x15, 0x9c, 0x2e, 0x7c, 0x1c, 0x4e, 0x66, 0xc8, 0xe4, 0xbc, 0xf2, 0x4a, 0xfa, 0x36, - 0xf7, 0x23, 0xba, 0xa5, 0xcc, 0x21, 0xfb, 0x06, 0x1d, 0x32, 0x91, 0x46, 0x17, 0x78, 0xa4, 0x0f, - 0x1f, 0x6c, 0x26, 0x5b, 0xb6, 0xd4, 0x67, 0xb6, 0xec, 0xd3, 0x50, 0x0b, 0x03, 0xcf, 0x6d, 0xb8, - 0xaa, 0xaa, 0x20, 0xcb, 0xcf, 0x5d, 0x12, 0x6d, 0x58, 0x41, 0xd1, 0x5d, 0xa8, 0xab, 0x8b, 0xef, - 0x85, 0x7f, 0xbb, 0xa8, 0x43, 0x1f, 0x65, 0xb4, 0xe8, 0x0b, 0xed, 0x35, 0x2f, 0x64, 0xc3, 0x00, - 0x53, 0x82, 0x32, 0xf4, 0x9f, 0xf9, 0xde, 0x99, 0x76, 0x8c, 0xb1, 0x80, 0xd8, 0x5f, 0xaf, 0xc3, - 0xd9, 0xbc, 0x3a, 0xd7, 0xe8, 0x63, 0x30, 0xc0, 0xfb, 0x58, 0xcc, 0x55, 0x0a, 0x79, 0x3c, 0x66, - 0x19, 0x41, 0xd1, 0x2d, 0xf6, 0x1b, 0x0b, 0x9e, 0x82, 0xbb, 0xe7, 0xac, 0x8a, 0x19, 0x72, 0x3c, - 0xdc, 0xe7, 0x1d, 0xcd, 0x7d, 0xde, 0xe1, 0xdc, 0x3d, 0x67, 0x15, 0x6d, 0x41, 0xb5, 0xe5, 0x26, - 0xc4, 0x11, 0x4e, 0x84, 0xdb, 0xc7, 0xc2, 0x9c, 0x38, 0xdc, 0x4a, 0x63, 0x3f, 0x31, 0x67, 0x88, - 0xbe, 0x66, 0xc1, 0xc9, 0xd5, 0x74, 0x6a, 0xbc, 0x10, 0x9e, 0xce, 0x31, 0xd4, 0x32, 0x4f, 0x33, - 0xe2, 0xd7, 0xfc, 0x64, 0x1a, 0x71, 0xb6, 0x3b, 0xe8, 0xd3, 0x16, 0x0c, 0xae, 0xb9, 0x9e, 0x51, - 0xd6, 0xf6, 0x18, 0x3e, 0xce, 0x15, 0xc6, 0x40, 0xef, 0x38, 0xf8, 0xff, 0x18, 0x4b, 0xce, 0xbd, - 0x34, 0xd5, 0xc0, 0x51, 0x35, 0xd5, 0xe0, 0x03, 0xd2, 0x54, 0x9f, 0xb5, 0xa0, 0xae, 0x46, 0x5a, - 0xa4, 0x3b, 0x7f, 0xf8, 0x18, 0x3f, 0x39, 0xf7, 0x9c, 0xa8, 0xbf, 0x58, 0x33, 0x47, 0x5f, 0xb2, - 0x60, 0xc8, 0x79, 0xa3, 0x13, 0x91, 0x26, 0xd9, 0x0c, 0xc2, 0x58, 0xdc, 0x11, 0xf8, 0x6a, 0xf1, - 0x9d, 0x99, 0xa4, 0x4c, 0x66, 0xc8, 0xe6, 0x62, 0x18, 0x8b, 0xb4, 0x24, 0xdd, 0x80, 0xcd, 0x2e, - 0xd8, 0x3b, 0x25, 0x18, 0xdb, 0x87, 0x02, 0x7a, 0x11, 0x86, 0x83, 0xa8, 0xe5, 0xf8, 0xee, 0x1b, - 0x66, 0xad, 0x0b, 0x65, 0x65, 0x2d, 0x1a, 0x30, 0x9c, 0xc2, 0x34, 0x13, 0xb2, 0x4b, 0xfb, 0x24, - 0x64, 0x5f, 0x84, 0x4a, 0x44, 0xc2, 0x20, 0xbb, 0x59, 0x60, 0x29, 0x01, 0x0c, 0x82, 0x1e, 0x87, - 0xb2, 0x13, 0xba, 0x22, 0x10, 0x4d, 0xed, 0x81, 0x26, 0x97, 0xe6, 0x30, 0x6d, 0x4f, 0xd5, 0x87, - 0xa8, 0xde, 0x97, 0xfa, 0x10, 0xc6, 0x95, 0xfe, 0x03, 0x3d, 0xaf, 0xf4, 0x7f, 0xab, 0x0c, 0x8f, - 0xef, 0x39, 0x5f, 0x74, 0x1c, 0x9e, 0xb5, 0x47, 0x1c, 0x9e, 0x1c, 0x9e, 0xd2, 0x7e, 0xc3, 0x53, - 0xee, 0x31, 0x3c, 0x9f, 0xa6, 0xcb, 0x40, 0xd6, 0x08, 0x29, 0xe6, 0x96, 0xb7, 0x5e, 0x25, 0x47, - 0xc4, 0x0a, 0x90, 0x50, 0xac, 0xf9, 0xd2, 0x3d, 0x40, 0x2a, 0x19, 0xb9, 0x5a, 0x84, 0x1a, 0xe8, - 0x59, 0x33, 0x84, 0xcf, 0xfd, 0x5e, 0x19, 0xce, 0xf6, 0xcf, 0x95, 0xe0, 0xc9, 0x3e, 0xa4, 0xb7, - 0x39, 0x8b, 0xad, 0x3e, 0x67, 0xf1, 0xf7, 0xf6, 0x67, 0xb2, 0xff, 0xaa, 0x05, 0x17, 0x7a, 0x2b, - 0x0f, 0xf4, 0x1c, 0x0c, 0xad, 0x46, 0x8e, 0xdf, 0x58, 0x67, 0x37, 0x57, 0xca, 0x41, 0x61, 0x63, - 0xad, 0x9b, 0xb1, 0x89, 0x43, 0xb7, 0xb7, 0x3c, 0x26, 0xc1, 0xc0, 0x90, 0xc9, 0xa3, 0x74, 0x7b, - 0xbb, 0x92, 0x05, 0xe2, 0x6e, 0x7c, 0xfb, 0x4f, 0x4b, 0xf9, 0xdd, 0xe2, 0x46, 0xc6, 0x41, 0xbe, - 0x93, 0xf8, 0x0a, 0xa5, 0x3e, 0x64, 0x49, 0xf9, 0x7e, 0xcb, 0x92, 0x4a, 0x2f, 0x59, 0x82, 0x66, - 0xe0, 0x94, 0x71, 0x25, 0x0a, 0x4f, 0x08, 0xe6, 0x01, 0xb7, 0xaa, 0x4a, 0xc6, 0x52, 0x06, 0x8e, - 0xbb, 0x9e, 0x40, 0xcf, 0x40, 0xcd, 0xf5, 0x63, 0xd2, 0xe8, 0x44, 0x3c, 0xd0, 0xdb, 0x48, 0xc2, - 0x9a, 0x13, 0xed, 0x58, 0x61, 0xd8, 0xbf, 0x54, 0x82, 0xf3, 0x3d, 0xed, 0xac, 0xfb, 0x24, 0xbb, - 0xcc, 0xcf, 0x51, 0xb9, 0x3f, 0x9f, 0xc3, 0x1c, 0xa4, 0xea, 0xbe, 0x83, 0xf4, 0xfb, 0xbd, 0x27, - 0x26, 0xb5, 0xb9, 0xbf, 0x6f, 0x47, 0xe9, 0x25, 0x38, 0xe1, 0x84, 0x21, 0xc7, 0x63, 0xf1, 0x9a, - 0x99, 0x2a, 0x39, 0x93, 0x26, 0x10, 0xa7, 0x71, 0xfb, 0xd2, 0x9e, 0x7f, 0x68, 0x41, 0x1d, 0x93, - 0x35, 0x2e, 0x1d, 0xd0, 0x1d, 0x31, 0x44, 0x56, 0x11, 0xf5, 0x34, 0xe9, 0xc0, 0xc6, 0x2e, 0xab, - 0x33, 0x99, 0x37, 0xd8, 0xdd, 0x57, 0xe7, 0x94, 0x0e, 0x74, 0x75, 0x8e, 0xba, 0x3c, 0xa5, 0xdc, - 0xfb, 0xf2, 0x14, 0xfb, 0x1b, 0x83, 0xf4, 0xf5, 0xc2, 0x60, 0x3a, 0x22, 0xcd, 0x98, 0x7e, 0xdf, - 0x4e, 0xe4, 0x89, 0x49, 0xa2, 0xbe, 0xef, 0x4d, 0x3c, 0x8f, 0x69, 0x7b, 0xea, 0x28, 0xa6, 0x74, - 0xa0, 0x1a, 0x21, 0xe5, 0x7d, 0x6b, 0x84, 0xbc, 0x04, 0x27, 0xe2, 0x78, 0x7d, 0x29, 0x72, 0x37, - 0x9d, 0x84, 0x5c, 0x27, 0xdb, 0xc2, 0xca, 0xd2, 0x79, 0xfd, 0xcb, 0x57, 0x35, 0x10, 0xa7, 0x71, - 0xd1, 0x2c, 0x9c, 0xd6, 0x95, 0x3a, 0x48, 0x94, 0xb0, 0xe8, 0x7e, 0x3e, 0x13, 0x54, 0x12, 0xaf, - 0xae, 0xed, 0x21, 0x10, 0x70, 0xf7, 0x33, 0x54, 0xbe, 0xa5, 0x1a, 0x69, 0x47, 0x06, 0xd2, 0xf2, - 0x2d, 0x45, 0x87, 0xf6, 0xa5, 0xeb, 0x09, 0xb4, 0x00, 0x67, 0xf8, 0xc4, 0x98, 0x0c, 0x43, 0xe3, - 0x8d, 0x06, 0xd3, 0x75, 0x0c, 0x67, 0xbb, 0x51, 0x70, 0xde, 0x73, 0xe8, 0x05, 0x18, 0x52, 0xcd, - 0x73, 0x33, 0xe2, 0x14, 0x41, 0x79, 0x31, 0x14, 0x99, 0xb9, 0x26, 0x36, 0xf1, 0xd0, 0x87, 0xe0, - 0x51, 0xfd, 0x97, 0xa7, 0x80, 0xf1, 0xa3, 0xb5, 0x19, 0x51, 0x04, 0x49, 0x5d, 0xd5, 0x31, 0x9b, - 0x8b, 0xd6, 0xc4, 0xbd, 0x9e, 0x47, 0xab, 0x70, 0x41, 0x81, 0x2e, 0xfb, 0x09, 0xcb, 0xe7, 0x88, - 0xc9, 0x94, 0x13, 0x93, 0x9b, 0x91, 0xc7, 0xca, 0x26, 0xd5, 0xf5, 0x2d, 0x8a, 0xb3, 0x6e, 0x72, - 0x35, 0x0f, 0x13, 0xcf, 0xe3, 0x3d, 0xa8, 0xa0, 0x09, 0xa8, 0x13, 0xdf, 0x59, 0xf5, 0xc8, 0xe2, - 0xf4, 0x1c, 0x2b, 0xa6, 0x64, 0x9c, 0xe4, 0x5d, 0x96, 0x00, 0xac, 0x71, 0x54, 0x84, 0xe9, 0x70, - 0xcf, 0x1b, 0x3d, 0x97, 0xe0, 0x6c, 0xab, 0x11, 0x52, 0xdb, 0xc3, 0x6d, 0x90, 0xc9, 0x06, 0x0b, - 0xa8, 0xa3, 0x1f, 0x86, 0x17, 0x98, 0x54, 0xe1, 0xd3, 0xb3, 0xd3, 0x4b, 0x5d, 0x38, 0x38, 0xf7, - 0x49, 0x16, 0x78, 0x19, 0x05, 0x5b, 0xdb, 0xa3, 0x67, 0x32, 0x81, 0x97, 0xb4, 0x11, 0x73, 0x18, - 0xba, 0x06, 0x88, 0xc5, 0xe2, 0x5f, 0x4d, 0x92, 0x50, 0x19, 0x3b, 0xa3, 0x67, 0xd9, 0x2b, 0xa9, - 0x30, 0xb2, 0x2b, 0x5d, 0x18, 0x38, 0xe7, 0x29, 0xfb, 0x3f, 0x5a, 0x70, 0x42, 0xad, 0xd7, 0xfb, - 0x90, 0x8d, 0xe2, 0xa5, 0xb3, 0x51, 0x66, 0x8f, 0x2e, 0xf1, 0x58, 0xcf, 0x7b, 0x84, 0x34, 0xff, - 0xf4, 0x10, 0x80, 0x96, 0x8a, 0x4a, 0x21, 0x59, 0x3d, 0x15, 0xd2, 0x43, 0x2b, 0x91, 0xf2, 0x2a, - 0xa7, 0x54, 0x1f, 0x6c, 0xe5, 0x94, 0x65, 0x38, 0x27, 0xcd, 0x05, 0x7e, 0x56, 0x74, 0x35, 0x88, - 0x95, 0x80, 0xab, 0x4d, 0x3d, 0x2e, 0x08, 0x9d, 0x9b, 0xcb, 0x43, 0xc2, 0xf9, 0xcf, 0xa6, 0xac, - 0x94, 0xc1, 0xfd, 0xac, 0x14, 0xbd, 0xa6, 0xe7, 0xd7, 0xe4, 0x9d, 0x1c, 0x99, 0x35, 0x3d, 0x7f, - 0x65, 0x19, 0x6b, 0x9c, 0x7c, 0xc1, 0x5e, 0x2f, 0x48, 0xb0, 0xc3, 0x81, 0x05, 0xbb, 0x14, 0x31, - 0x43, 0x3d, 0x45, 0x8c, 0xf4, 0x49, 0x0f, 0xf7, 0xf4, 0x49, 0xbf, 0x1f, 0x46, 0x5c, 0x7f, 0x9d, - 0x44, 0x6e, 0x42, 0x9a, 0x6c, 0x2d, 0x30, 0xf1, 0x53, 0xd3, 0x6a, 0x7d, 0x2e, 0x05, 0xc5, 0x19, - 0xec, 0xb4, 0x5c, 0x1c, 0xe9, 0x43, 0x2e, 0xf6, 0xd0, 0x46, 0x27, 0x8b, 0xd1, 0x46, 0xa7, 0x8e, - 0xae, 0x8d, 0x4e, 0x1f, 0xab, 0x36, 0x42, 0x85, 0x68, 0xa3, 0xbe, 0x04, 0xbd, 0xb1, 0xfd, 0x3b, - 0xbb, 0xcf, 0xf6, 0xaf, 0x97, 0x2a, 0x3a, 0x77, 0x68, 0x55, 0x94, 0xaf, 0x65, 0x1e, 0x39, 0x94, - 0x96, 0xf9, 0x6c, 0x09, 0xce, 0x69, 0x39, 0x4c, 0x67, 0xbf, 0xbb, 0x46, 0x25, 0x11, 0xbb, 0xd6, - 0x89, 0x9f, 0xdb, 0x18, 0xc9, 0x51, 0x3a, 0xcf, 0x4a, 0x41, 0xb0, 0x81, 0xc5, 0x72, 0x8c, 0x48, - 0xc4, 0xca, 0xe8, 0x66, 0x85, 0xf4, 0xb4, 0x68, 0xc7, 0x0a, 0x83, 0xce, 0x2f, 0xfa, 0x5b, 0xe4, - 0x6d, 0x66, 0x8b, 0xc5, 0x4d, 0x6b, 0x10, 0x36, 0xf1, 0xd0, 0xd3, 0x9c, 0x09, 0x13, 0x10, 0x54, - 0x50, 0x0f, 0x8b, 0x7b, 0x5e, 0xa5, 0x4c, 0x50, 0x50, 0xd9, 0x1d, 0x96, 0x4c, 0x56, 0xed, 0xee, - 0x0e, 0x0b, 0x81, 0x52, 0x18, 0xf6, 0xff, 0xb4, 0xe0, 0x7c, 0xee, 0x50, 0xdc, 0x07, 0xe5, 0xbb, - 0x95, 0x56, 0xbe, 0xcb, 0x45, 0x6d, 0x37, 0x8c, 0xb7, 0xe8, 0xa1, 0x88, 0xff, 0xbd, 0x05, 0x23, - 0x1a, 0xff, 0x3e, 0xbc, 0xaa, 0x9b, 0x7e, 0xd5, 0xe2, 0x76, 0x56, 0xf5, 0xae, 0x77, 0xfb, 0xed, - 0x12, 0xa8, 0x02, 0x8e, 0x93, 0x0d, 0x59, 0x1e, 0x77, 0x9f, 0x93, 0xc4, 0x6d, 0x18, 0x60, 0x07, - 0xa1, 0x71, 0x31, 0x41, 0x1e, 0x69, 0xfe, 0xec, 0x50, 0x55, 0x1f, 0x32, 0xb3, 0xbf, 0x31, 0x16, - 0x0c, 0x59, 0x91, 0x67, 0x37, 0xa6, 0xd2, 0xbc, 0x29, 0xd2, 0xb2, 0x74, 0x91, 0x67, 0xd1, 0x8e, - 0x15, 0x06, 0x55, 0x0f, 0x6e, 0x23, 0xf0, 0xa7, 0x3d, 0x27, 0x96, 0x77, 0x19, 0x2a, 0xf5, 0x30, - 0x27, 0x01, 0x58, 0xe3, 0xb0, 0x33, 0x52, 0x37, 0x0e, 0x3d, 0x67, 0xdb, 0xd8, 0x3f, 0x1b, 0xf5, - 0x09, 0x14, 0x08, 0x9b, 0x78, 0x76, 0x1b, 0x46, 0xd3, 0x2f, 0x31, 0x43, 0xd6, 0x58, 0x80, 0x62, - 0x5f, 0xc3, 0x39, 0x01, 0x75, 0x87, 0x3d, 0x35, 0xdf, 0x71, 0xb2, 0x57, 0x90, 0x4f, 0x4a, 0x00, - 0xd6, 0x38, 0xf6, 0xaf, 0x58, 0x70, 0x26, 0x67, 0xd0, 0x0a, 0x4c, 0x7b, 0x4b, 0xb4, 0xb4, 0xc9, - 0x53, 0xec, 0x3f, 0x04, 0x83, 0x4d, 0xb2, 0xe6, 0xc8, 0x10, 0x38, 0x43, 0xb6, 0xcf, 0xf0, 0x66, - 0x2c, 0xe1, 0xf6, 0x7f, 0xb7, 0xe0, 0x64, 0xba, 0xaf, 0x31, 0x4b, 0x25, 0xe1, 0xc3, 0xe4, 0xc6, - 0x8d, 0x60, 0x93, 0x44, 0xdb, 0xf4, 0xcd, 0xad, 0x4c, 0x2a, 0x49, 0x17, 0x06, 0xce, 0x79, 0x8a, - 0x95, 0x6f, 0x6d, 0xaa, 0xd1, 0x96, 0x33, 0xf2, 0x56, 0x91, 0x33, 0x52, 0x7f, 0x4c, 0xf3, 0xb8, - 0x5c, 0xb1, 0xc4, 0x26, 0x7f, 0xfb, 0x3b, 0x15, 0x50, 0x79, 0xb1, 0x2c, 0xfe, 0xa8, 0xa0, 0xe8, - 0xad, 0x83, 0x66, 0x10, 0xa9, 0xc9, 0x50, 0xd9, 0x2b, 0x20, 0x80, 0x7b, 0x49, 0x4c, 0xd7, 0xa5, - 0x7a, 0xc3, 0x15, 0x0d, 0xc2, 0x26, 0x1e, 0xed, 0x89, 0xe7, 0x6e, 0x12, 0xfe, 0xd0, 0x40, 0xba, - 0x27, 0xf3, 0x12, 0x80, 0x35, 0x0e, 0xed, 0x49, 0xd3, 0x5d, 0x5b, 0x13, 0x5b, 0x7e, 0xd5, 0x13, - 0x3a, 0x3a, 0x98, 0x41, 0x78, 0x45, 0xee, 0x60, 0x43, 0x58, 0xc1, 0x46, 0x45, 0xee, 0x60, 0x03, - 0x33, 0x08, 0xb5, 0xdb, 0xfc, 0x20, 0x6a, 0xb3, 0x2b, 0xe2, 0x9b, 0x8a, 0x8b, 0xb0, 0x7e, 0x95, - 0xdd, 0x76, 0xa3, 0x1b, 0x05, 0xe7, 0x3d, 0x47, 0x67, 0x60, 0x18, 0x91, 0xa6, 0xdb, 0x48, 0x4c, - 0x6a, 0x90, 0x9e, 0x81, 0x4b, 0x5d, 0x18, 0x38, 0xe7, 0x29, 0x34, 0x09, 0x27, 0x65, 0x5e, 0xb3, - 0xac, 0x5a, 0x33, 0x94, 0xae, 0x92, 0x81, 0xd3, 0x60, 0x9c, 0xc5, 0xa7, 0x52, 0xad, 0x2d, 0x0a, - 0x56, 0x31, 0x63, 0xd9, 0x90, 0x6a, 0xb2, 0x90, 0x15, 0x56, 0x18, 0xf6, 0xa7, 0xca, 0x54, 0x0b, - 0xf7, 0x28, 0xd4, 0x76, 0xdf, 0xa2, 0x05, 0xd3, 0x33, 0xb2, 0xd2, 0xc7, 0x8c, 0x7c, 0x1e, 0x86, - 0xef, 0xc4, 0x81, 0xaf, 0x22, 0xf1, 0xaa, 0x3d, 0x23, 0xf1, 0x0c, 0xac, 0xfc, 0x48, 0xbc, 0x81, - 0xa2, 0x22, 0xf1, 0x06, 0x0f, 0x19, 0x89, 0xf7, 0xad, 0x2a, 0xa8, 0xab, 0x41, 0x6e, 0x90, 0xe4, - 0x6e, 0x10, 0x6d, 0xb8, 0x7e, 0x8b, 0xe5, 0x83, 0x7f, 0xcd, 0x82, 0x61, 0xbe, 0x5e, 0xe6, 0xcd, - 0x4c, 0xaa, 0xb5, 0x82, 0xee, 0x9c, 0x48, 0x31, 0x1b, 0x5f, 0x31, 0x18, 0x65, 0xae, 0xd2, 0x34, - 0x41, 0x38, 0xd5, 0x23, 0xf4, 0x71, 0x00, 0xe9, 0x1f, 0x5d, 0x93, 0x22, 0x73, 0xae, 0x98, 0xfe, - 0x61, 0xb2, 0xa6, 0x6d, 0xe0, 0x15, 0xc5, 0x04, 0x1b, 0x0c, 0xd1, 0x67, 0x75, 0x96, 0x19, 0x0f, - 0xd9, 0xff, 0xe8, 0xb1, 0x8c, 0x4d, 0x3f, 0x39, 0x66, 0x18, 0x06, 0x5d, 0xbf, 0x45, 0xe7, 0x89, - 0x88, 0x58, 0x7a, 0x57, 0x5e, 0x2d, 0x85, 0xf9, 0xc0, 0x69, 0x4e, 0x39, 0x9e, 0xe3, 0x37, 0x48, - 0x34, 0xc7, 0xd1, 0xcd, 0x0b, 0xa4, 0x59, 0x03, 0x96, 0x84, 0xba, 0x2e, 0x55, 0xa9, 0xf6, 0x73, - 0xa9, 0xca, 0x85, 0x0f, 0xc0, 0xe9, 0xae, 0x8f, 0x79, 0xa0, 0x94, 0xb2, 0xc3, 0x67, 0xa3, 0xd9, - 0xff, 0x62, 0x40, 0x2b, 0xad, 0x1b, 0x41, 0x93, 0x5f, 0xed, 0x11, 0xe9, 0x2f, 0x2a, 0x6c, 0xdc, - 0x02, 0xa7, 0x88, 0x71, 0x09, 0xb5, 0x6a, 0xc4, 0x26, 0x4b, 0x3a, 0x47, 0x43, 0x27, 0x22, 0xfe, - 0x71, 0xcf, 0xd1, 0x25, 0xc5, 0x04, 0x1b, 0x0c, 0xd1, 0x7a, 0x2a, 0xa7, 0xe4, 0xca, 0xd1, 0x73, - 0x4a, 0x58, 0x95, 0xa9, 0xbc, 0x6a, 0xfc, 0x5f, 0xb2, 0x60, 0xc4, 0x4f, 0xcd, 0xdc, 0x62, 0xc2, - 0x48, 0xf3, 0x57, 0x05, 0xbf, 0x59, 0x2a, 0xdd, 0x86, 0x33, 0xfc, 0xf3, 0x54, 0x5a, 0xf5, 0x80, - 0x2a, 0x4d, 0xdf, 0x11, 0x34, 0xd0, 0xeb, 0x8e, 0x20, 0xe4, 0xab, 0x4b, 0xd2, 0x06, 0x0b, 0xbf, - 0x24, 0x0d, 0x72, 0x2e, 0x48, 0xbb, 0x0d, 0xf5, 0x46, 0x44, 0x9c, 0xe4, 0x90, 0xf7, 0x65, 0xb1, - 0x03, 0xfa, 0x69, 0x49, 0x00, 0x6b, 0x5a, 0xf6, 0xff, 0xae, 0xc0, 0x29, 0x39, 0x22, 0x32, 0x04, - 0x9d, 0xea, 0x47, 0xce, 0x57, 0x1b, 0xb7, 0x4a, 0x3f, 0x5e, 0x95, 0x00, 0xac, 0x71, 0xa8, 0x3d, - 0xd6, 0x89, 0xc9, 0x62, 0x48, 0xfc, 0x79, 0x77, 0x35, 0x16, 0xe7, 0x9c, 0x6a, 0xa1, 0xdc, 0xd4, - 0x20, 0x6c, 0xe2, 0x51, 0x63, 0x9c, 0xdb, 0xc5, 0x71, 0x36, 0x7d, 0x45, 0xd8, 0xdb, 0x58, 0xc2, - 0xd1, 0xcf, 0xe7, 0x56, 0x8e, 0x2d, 0x26, 0x71, 0xab, 0x2b, 0xf2, 0xfe, 0x80, 0x57, 0x2c, 0xfe, - 0x6d, 0x0b, 0xce, 0xf1, 0x56, 0x39, 0x92, 0x37, 0xc3, 0xa6, 0x93, 0x90, 0xb8, 0x98, 0x4a, 0xee, - 0x39, 0xfd, 0xd3, 0x4e, 0xde, 0x3c, 0xb6, 0x38, 0xbf, 0x37, 0xe8, 0x4d, 0x0b, 0x4e, 0x6e, 0xa4, - 0x6a, 0x7e, 0x48, 0xd5, 0x71, 0xd4, 0x74, 0xfc, 0x14, 0x51, 0xbd, 0xd4, 0xd2, 0xed, 0x31, 0xce, - 0x72, 0xb7, 0xff, 0xd4, 0x02, 0x53, 0x8c, 0xde, 0xff, 0x52, 0x21, 0x07, 0x37, 0x05, 0xa5, 0x75, - 0x59, 0xed, 0x69, 0x5d, 0x3e, 0x0e, 0xe5, 0x8e, 0xdb, 0x14, 0xfb, 0x0b, 0x7d, 0xfa, 0x3a, 0x37, - 0x83, 0x69, 0xbb, 0xfd, 0x4f, 0xab, 0xda, 0x6f, 0x21, 0xf2, 0xa2, 0xbe, 0x2f, 0x5e, 0x7b, 0x4d, - 0x15, 0x1b, 0xe3, 0x6f, 0x7e, 0xa3, 0xab, 0xd8, 0xd8, 0x8f, 0x1c, 0x3c, 0xed, 0x8d, 0x0f, 0x50, - 0xaf, 0x5a, 0x63, 0x83, 0xfb, 0xe4, 0xbc, 0xdd, 0x81, 0x1a, 0xdd, 0x82, 0x31, 0x07, 0x64, 0x2d, - 0xd5, 0xa9, 0xda, 0x55, 0xd1, 0x7e, 0x6f, 0x67, 0xec, 0x7d, 0x07, 0xef, 0x96, 0x7c, 0x1a, 0x2b, - 0xfa, 0x28, 0x86, 0x3a, 0xfd, 0xcd, 0xd2, 0xf3, 0xc4, 0xe6, 0xee, 0xa6, 0x92, 0x99, 0x12, 0x50, - 0x48, 0xee, 0x9f, 0xe6, 0x83, 0x7c, 0xa8, 0xb3, 0xdb, 0x68, 0x19, 0x53, 0xbe, 0x07, 0x5c, 0x52, - 0x49, 0x72, 0x12, 0x70, 0x6f, 0x67, 0xec, 0xa5, 0x83, 0x33, 0x55, 0x8f, 0x63, 0xcd, 0xc2, 0xfe, - 0x72, 0x45, 0xcf, 0x5d, 0x51, 0x63, 0xee, 0xfb, 0x62, 0xee, 0xbe, 0x98, 0x99, 0xbb, 0x17, 0xbb, - 0xe6, 0xee, 0x88, 0xbe, 0x35, 0x35, 0x35, 0x1b, 0xef, 0xb7, 0x21, 0xb0, 0xbf, 0xbf, 0x81, 0x59, - 0x40, 0xaf, 0x77, 0xdc, 0x88, 0xc4, 0x4b, 0x51, 0xc7, 0x77, 0xfd, 0x16, 0x9b, 0x8e, 0x35, 0xd3, - 0x02, 0x4a, 0x81, 0x71, 0x16, 0x9f, 0x6e, 0xea, 0xe9, 0x37, 0xbf, 0xed, 0x6c, 0xf2, 0x59, 0x65, - 0x94, 0xdd, 0x5a, 0x16, 0xed, 0x58, 0x61, 0xd8, 0xdf, 0x60, 0x67, 0xd9, 0x46, 0x5e, 0x30, 0x9d, - 0x13, 0x1e, 0xbb, 0xfe, 0x97, 0xd7, 0xec, 0x52, 0x73, 0x82, 0xdf, 0xf9, 0xcb, 0x61, 0xe8, 0x2e, - 0x0c, 0xae, 0xf2, 0xfb, 0xef, 0x8a, 0xa9, 0x4f, 0x2e, 0x2e, 0xd3, 0x63, 0xb7, 0x9c, 0xc8, 0x9b, - 0xf5, 0xee, 0xe9, 0x9f, 0x58, 0x72, 0xb3, 0xbf, 0x59, 0x81, 0x93, 0x99, 0x0b, 0x62, 0x53, 0xd5, - 0x52, 0x4b, 0xfb, 0x56, 0x4b, 0xfd, 0x08, 0x40, 0x93, 0x84, 0x5e, 0xb0, 0xcd, 0xcc, 0xb1, 0xca, - 0x81, 0xcd, 0x31, 0x65, 0xc1, 0xcf, 0x28, 0x2a, 0xd8, 0xa0, 0x28, 0x0a, 0x95, 0xf1, 0xe2, 0xab, - 0x99, 0x42, 0x65, 0xc6, 0x2d, 0x06, 0x03, 0xf7, 0xf7, 0x16, 0x03, 0x17, 0x4e, 0xf2, 0x2e, 0xaa, - 0xec, 0xdb, 0x43, 0x24, 0xd9, 0xb2, 0xfc, 0x85, 0x99, 0x34, 0x19, 0x9c, 0xa5, 0xfb, 0x20, 0xef, - 0x7f, 0x46, 0xef, 0x86, 0xba, 0xfc, 0xce, 0xf1, 0x68, 0x5d, 0x57, 0x30, 0x90, 0xd3, 0x80, 0xdd, - 0xcb, 0x2c, 0x7e, 0xda, 0x5f, 0x2c, 0x51, 0xeb, 0x99, 0xff, 0x53, 0x95, 0x68, 0x9e, 0x82, 0x01, - 0xa7, 0x93, 0xac, 0x07, 0x5d, 0x77, 0xe8, 0x4d, 0xb2, 0x56, 0x2c, 0xa0, 0x68, 0x1e, 0x2a, 0x4d, - 0x5d, 0x5d, 0xe4, 0x20, 0xa3, 0xa8, 0x1d, 0x91, 0x4e, 0x42, 0x30, 0xa3, 0x82, 0x1e, 0x83, 0x4a, - 0xe2, 0xb4, 0x64, 0xa2, 0x13, 0x4b, 0x6e, 0x5d, 0x71, 0x5a, 0x31, 0x66, 0xad, 0xa6, 0xd2, 0xac, - 0xec, 0xa3, 0x34, 0x5f, 0x82, 0x13, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x11, 0xe3, 0x70, 0x4d, - 0xc7, 0x4b, 0x98, 0x40, 0x9c, 0xc6, 0xb5, 0x7f, 0x63, 0x18, 0xce, 0x2e, 0x4f, 0x2f, 0xc8, 0x9a, - 0xd9, 0xc7, 0x96, 0xab, 0x94, 0xc7, 0xe3, 0xfe, 0xe5, 0x2a, 0xf5, 0xe0, 0xee, 0x19, 0xb9, 0x4a, - 0x9e, 0x91, 0xab, 0x94, 0x4e, 0x1c, 0x29, 0x17, 0x91, 0x38, 0x92, 0xd7, 0x83, 0x7e, 0x12, 0x47, - 0x8e, 0x2d, 0x79, 0x69, 0xcf, 0x0e, 0x1d, 0x28, 0x79, 0x49, 0x65, 0x76, 0x15, 0x12, 0xd2, 0xdf, - 0xe3, 0x53, 0xe5, 0x66, 0x76, 0xa9, 0xac, 0x1a, 0x9e, 0xae, 0x22, 0x04, 0xec, 0xab, 0xc5, 0x77, - 0xa0, 0x8f, 0xac, 0x1a, 0x91, 0x31, 0x63, 0x66, 0x72, 0x0d, 0x16, 0x91, 0xc9, 0x95, 0xd7, 0x9d, - 0x7d, 0x33, 0xb9, 0x5e, 0x82, 0x13, 0x0d, 0x2f, 0xf0, 0xc9, 0x52, 0x14, 0x24, 0x41, 0x23, 0xf0, - 0x84, 0x31, 0xad, 0x44, 0xc2, 0xb4, 0x09, 0xc4, 0x69, 0xdc, 0x5e, 0x69, 0x60, 0xf5, 0xa3, 0xa6, - 0x81, 0xc1, 0x03, 0x4a, 0x03, 0xfb, 0x19, 0x9d, 0xb0, 0x3c, 0xc4, 0xbe, 0xc8, 0x47, 0x8a, 0xff, - 0x22, 0xfd, 0x64, 0x2d, 0xa3, 0xb7, 0xf8, 0x25, 0x76, 0xd4, 0x1c, 0x9d, 0x0e, 0xda, 0xd4, 0xdc, - 0x1a, 0x66, 0x43, 0xf2, 0xda, 0x31, 0x4c, 0xd8, 0xdb, 0xcb, 0x9a, 0x8d, 0xba, 0xd8, 0x4e, 0x37, - 0xe1, 0x74, 0x47, 0x8e, 0x92, 0x50, 0xfd, 0xd5, 0x12, 0xfc, 0xc0, 0xbe, 0x5d, 0x40, 0x77, 0x01, - 0x12, 0xa7, 0x25, 0x26, 0xaa, 0x38, 0xa6, 0x38, 0x62, 0x50, 0xe3, 0x8a, 0xa4, 0xc7, 0x2b, 0x81, - 0xa8, 0xbf, 0xec, 0x00, 0x40, 0xfe, 0x66, 0xb1, 0x8c, 0x81, 0xd7, 0x55, 0x30, 0x11, 0x07, 0x1e, - 0xc1, 0x0c, 0x42, 0xd5, 0x7f, 0x44, 0x5a, 0xfa, 0xd6, 0x65, 0xf5, 0xf9, 0x30, 0x6b, 0xc5, 0x02, - 0x8a, 0x5e, 0x80, 0x21, 0xc7, 0xf3, 0x78, 0x56, 0x0a, 0x89, 0xc5, 0x2d, 0x36, 0xba, 0x72, 0x9b, - 0x06, 0x61, 0x13, 0xcf, 0xfe, 0x93, 0x12, 0x8c, 0xed, 0x23, 0x53, 0xba, 0xf2, 0xec, 0xaa, 0x7d, - 0xe7, 0xd9, 0x89, 0xcc, 0x80, 0x81, 0x1e, 0x99, 0x01, 0x2f, 0xc0, 0x50, 0x42, 0x9c, 0xb6, 0x08, - 0x83, 0x12, 0xfb, 0x6f, 0x7d, 0xee, 0xaa, 0x41, 0xd8, 0xc4, 0xa3, 0x52, 0x6c, 0xc4, 0x69, 0x34, - 0x48, 0x1c, 0xcb, 0xd0, 0x7f, 0xe1, 0xc3, 0x2c, 0x2c, 0xaf, 0x80, 0xb9, 0x86, 0x27, 0x53, 0x2c, - 0x70, 0x86, 0x65, 0x76, 0xc0, 0xeb, 0x7d, 0x0e, 0xf8, 0xd7, 0x4b, 0xf0, 0xf8, 0x9e, 0xda, 0xad, - 0xef, 0xac, 0x8c, 0x4e, 0x4c, 0xa2, 0xec, 0xc4, 0xb9, 0x19, 0x93, 0x08, 0x33, 0x08, 0x1f, 0xa5, - 0x30, 0x34, 0x6e, 0xb5, 0x2e, 0x3a, 0x65, 0x88, 0x8f, 0x52, 0x8a, 0x05, 0xce, 0xb0, 0x3c, 0xec, - 0xb4, 0xfc, 0xfb, 0x25, 0x78, 0xb2, 0x0f, 0x1b, 0xa0, 0xc0, 0xd4, 0xaa, 0x74, 0x82, 0x5b, 0xf9, - 0x01, 0xe5, 0x21, 0x1e, 0x72, 0xb8, 0xbe, 0x51, 0x82, 0x0b, 0xbd, 0x55, 0x31, 0xfa, 0x51, 0xba, - 0x87, 0x97, 0xb1, 0x4f, 0x66, 0x6e, 0xdc, 0x19, 0xbe, 0x7f, 0x4f, 0x81, 0x70, 0x16, 0x17, 0x8d, - 0x03, 0x84, 0x4e, 0xb2, 0x1e, 0x5f, 0xde, 0x72, 0xe3, 0x44, 0xd4, 0x7e, 0x19, 0xe1, 0x27, 0x46, - 0xb2, 0x15, 0x1b, 0x18, 0x94, 0x1d, 0xfb, 0x37, 0x13, 0xdc, 0x08, 0x12, 0xfe, 0x10, 0xdf, 0x46, - 0x9c, 0x91, 0x37, 0x65, 0x18, 0x20, 0x9c, 0xc5, 0xa5, 0xec, 0xd8, 0x99, 0x24, 0xef, 0x28, 0xdf, - 0x5f, 0x30, 0x76, 0xf3, 0xaa, 0x15, 0x1b, 0x18, 0xd9, 0xac, 0xbf, 0xea, 0xfe, 0x59, 0x7f, 0xf6, - 0x3f, 0x29, 0xc1, 0xf9, 0x9e, 0xa6, 0x5c, 0x7f, 0x0b, 0xf0, 0xe1, 0xcb, 0xd4, 0x3b, 0xdc, 0xdc, - 0x39, 0x60, 0x46, 0xd9, 0x1f, 0xf6, 0x98, 0x69, 0x22, 0xa3, 0xec, 0xf0, 0x29, 0xd9, 0x0f, 0xdf, - 0x78, 0x76, 0x25, 0x91, 0x55, 0x0e, 0x90, 0x44, 0x96, 0xf9, 0x18, 0xd5, 0x3e, 0x17, 0xf2, 0x9f, - 0x95, 0x7b, 0x0e, 0x2f, 0xdd, 0xfa, 0xf5, 0xe5, 0x1d, 0x9d, 0x81, 0x53, 0xae, 0xcf, 0x6e, 0x4d, - 0x5a, 0xee, 0xac, 0x8a, 0x72, 0x20, 0xa5, 0xf4, 0x9d, 0xe5, 0x73, 0x19, 0x38, 0xee, 0x7a, 0xe2, - 0x21, 0x4c, 0xea, 0x3b, 0xdc, 0x90, 0x1e, 0x2c, 0xad, 0x14, 0x2d, 0xc2, 0x39, 0x39, 0x14, 0xeb, - 0x4e, 0x44, 0x9a, 0x42, 0x8d, 0xc4, 0x22, 0x8d, 0xe1, 0x3c, 0x4f, 0x85, 0xc8, 0x41, 0xc0, 0xf9, - 0xcf, 0xb1, 0x8b, 0x6a, 0x82, 0xd0, 0x6d, 0x88, 0x4d, 0x8e, 0xbe, 0xa8, 0x86, 0x36, 0x62, 0x0e, - 0xb3, 0x3f, 0x02, 0x75, 0xf5, 0xfe, 0x3c, 0x98, 0x5a, 0x4d, 0xba, 0xae, 0x60, 0x6a, 0x35, 0xe3, - 0x0c, 0x2c, 0xfa, 0xb5, 0xa8, 0x49, 0x9c, 0x59, 0x3d, 0xd7, 0xc9, 0x36, 0xb3, 0x8f, 0xed, 0xf7, - 0xc0, 0xb0, 0xf2, 0xb3, 0xf4, 0x7b, 0x7d, 0x8f, 0xfd, 0xe5, 0x01, 0x38, 0x91, 0x2a, 0xc9, 0x97, - 0x72, 0x6b, 0x5a, 0xfb, 0xba, 0x35, 0x59, 0x70, 0x7c, 0xc7, 0x97, 0x77, 0x7b, 0x19, 0xc1, 0xf1, - 0x1d, 0x9f, 0x60, 0x0e, 0xa3, 0xe6, 0x6d, 0x33, 0xda, 0xc6, 0x1d, 0x5f, 0x04, 0xb1, 0x2a, 0xf3, - 0x76, 0x86, 0xb5, 0x62, 0x01, 0x45, 0x9f, 0xb4, 0x60, 0x38, 0x66, 0x3e, 0x73, 0xee, 0x14, 0x16, - 0x93, 0xee, 0xda, 0xd1, 0x2b, 0x0e, 0xaa, 0xf2, 0x93, 0x2c, 0x2e, 0xc5, 0x6c, 0xc1, 0x29, 0x8e, - 0xe8, 0x33, 0x16, 0xd4, 0xd5, 0x15, 0x24, 0xe2, 0x02, 0xbe, 0xe5, 0x62, 0x2b, 0x1e, 0x72, 0x6f, - 0xa2, 0x3a, 0x7e, 0x50, 0xa5, 0xe7, 0xb0, 0x66, 0x8c, 0x62, 0xe5, 0xb1, 0x1d, 0x3c, 0x1e, 0x8f, - 0x2d, 0xe4, 0x78, 0x6b, 0xdf, 0x0d, 0xf5, 0xb6, 0xe3, 0xbb, 0x6b, 0x24, 0x4e, 0xb8, 0x13, 0x55, - 0x16, 0x62, 0x95, 0x8d, 0x58, 0xc3, 0xa9, 0x42, 0x8e, 0xd9, 0x8b, 0x25, 0x86, 0xd7, 0x93, 0x29, - 0xe4, 0x65, 0xdd, 0x8c, 0x4d, 0x1c, 0xd3, 0x45, 0x0b, 0x0f, 0xd4, 0x45, 0x3b, 0xb4, 0x8f, 0x8b, - 0xf6, 0x1f, 0x5a, 0x70, 0x2e, 0xf7, 0xab, 0x3d, 0xbc, 0xe1, 0x86, 0xf6, 0x57, 0xaa, 0x70, 0x26, - 0xa7, 0xb6, 0x26, 0xda, 0x36, 0xe7, 0xb3, 0x55, 0xc4, 0xc9, 0x7d, 0xfa, 0x20, 0x5a, 0x0e, 0x63, - 0xce, 0x24, 0x3e, 0xd8, 0x01, 0x89, 0x3e, 0xa4, 0x28, 0xdf, 0xdf, 0x43, 0x0a, 0x63, 0x5a, 0x56, - 0x1e, 0xe8, 0xb4, 0xac, 0xee, 0x3d, 0x2d, 0xd1, 0xaf, 0x5a, 0x30, 0xda, 0xee, 0x51, 0xd0, 0x5d, - 0x38, 0x1e, 0x6f, 0x1d, 0x4f, 0xb9, 0xf8, 0xa9, 0xc7, 0x76, 0x77, 0xc6, 0x7a, 0xd6, 0xd1, 0xc7, - 0x3d, 0x7b, 0x65, 0x7f, 0xa7, 0x0c, 0xac, 0xb0, 0x2b, 0xab, 0x9f, 0xb6, 0x8d, 0x3e, 0x61, 0x96, - 0xe8, 0xb5, 0x8a, 0x2a, 0x27, 0xcb, 0x89, 0xab, 0x12, 0xbf, 0x7c, 0x04, 0xf3, 0x2a, 0xfe, 0x66, - 0x85, 0x56, 0xa9, 0x0f, 0xa1, 0xe5, 0xc9, 0x5a, 0xc8, 0xe5, 0xe2, 0x6b, 0x21, 0xd7, 0xb3, 0x75, - 0x90, 0xf7, 0xfe, 0xc4, 0x95, 0x87, 0xf2, 0x13, 0xff, 0x4d, 0x8b, 0x0b, 0x9e, 0xcc, 0x57, 0xd0, - 0x96, 0x81, 0xb5, 0x87, 0x65, 0xf0, 0x0c, 0xd4, 0x62, 0xe2, 0xad, 0x5d, 0x25, 0x8e, 0x27, 0x2c, - 0x08, 0x7d, 0x6a, 0x2c, 0xda, 0xb1, 0xc2, 0x60, 0x97, 0xa5, 0x7a, 0x5e, 0x70, 0xf7, 0x72, 0x3b, - 0x4c, 0xb6, 0x85, 0x2d, 0xa1, 0x2f, 0x4b, 0x55, 0x10, 0x6c, 0x60, 0xd9, 0x7f, 0xab, 0xc4, 0x67, - 0xa0, 0x08, 0x3d, 0x78, 0x31, 0x73, 0xbd, 0x5d, 0xff, 0xa7, 0xf6, 0x1f, 0x03, 0x68, 0xa8, 0x8b, - 0xe1, 0xc5, 0x99, 0xd0, 0xd5, 0x23, 0xdf, 0x5a, 0x2d, 0xe8, 0xe9, 0xd7, 0xd0, 0x6d, 0xd8, 0xe0, - 0x97, 0x92, 0xa5, 0xe5, 0x7d, 0x65, 0x69, 0x4a, 0xac, 0x54, 0xf6, 0xd1, 0x76, 0x7f, 0x62, 0x41, - 0xca, 0x22, 0x42, 0x21, 0x54, 0x69, 0x77, 0xb7, 0x8b, 0xb9, 0xf3, 0xde, 0x24, 0x4d, 0x45, 0xa3, - 0x98, 0xf6, 0xec, 0x27, 0xe6, 0x8c, 0x90, 0x27, 0x22, 0x14, 0xf8, 0xa8, 0xde, 0x28, 0x8e, 0xe1, - 0xd5, 0x20, 0xd8, 0xe0, 0x07, 0x9b, 0x3a, 0xda, 0xc1, 0x7e, 0x11, 0x4e, 0x77, 0x75, 0x8a, 0xdd, - 0x64, 0x15, 0xc8, 0x8b, 0xfe, 0x8d, 0xe9, 0xca, 0xd2, 0x26, 0x31, 0x87, 0xd9, 0xdf, 0xb0, 0xe0, - 0x54, 0x96, 0x3c, 0x7a, 0xcb, 0x82, 0xd3, 0x71, 0x96, 0xde, 0x71, 0x8d, 0x9d, 0x8a, 0x32, 0xec, - 0x02, 0xe1, 0xee, 0x4e, 0xd8, 0xff, 0x47, 0x4c, 0xfe, 0xdb, 0xae, 0xdf, 0x0c, 0xee, 0x2a, 0xc3, - 0xc4, 0xea, 0x69, 0x98, 0xd0, 0xf5, 0xd8, 0x58, 0x27, 0xcd, 0x8e, 0xd7, 0x95, 0xaf, 0xb9, 0x2c, - 0xda, 0xb1, 0xc2, 0x60, 0xe9, 0x69, 0x1d, 0x51, 0x2c, 0x3d, 0x33, 0x29, 0x67, 0x44, 0x3b, 0x56, - 0x18, 0xe8, 0x79, 0x18, 0x36, 0x5e, 0x52, 0xce, 0x4b, 0x66, 0x90, 0x1b, 0x2a, 0x33, 0xc6, 0x29, - 0x2c, 0x34, 0x0e, 0xa0, 0x8c, 0x1c, 0xa9, 0x22, 0x99, 0xa3, 0x48, 0x49, 0xa2, 0x18, 0x1b, 0x18, - 0x2c, 0x19, 0xd4, 0xeb, 0xc4, 0xcc, 0xc7, 0x3f, 0xa0, 0x0b, 0x78, 0x4e, 0x8b, 0x36, 0xac, 0xa0, - 0x54, 0x9a, 0xb4, 0x1d, 0xbf, 0xe3, 0x78, 0x74, 0x84, 0xc4, 0xd6, 0x4f, 0x2d, 0xc3, 0x05, 0x05, - 0xc1, 0x06, 0x16, 0x7d, 0xe3, 0xc4, 0x6d, 0x93, 0x57, 0x02, 0x5f, 0x46, 0x87, 0xe9, 0x63, 0x1f, - 0xd1, 0x8e, 0x15, 0x86, 0xfd, 0x5f, 0x2d, 0x38, 0xa9, 0x53, 0xcb, 0xf9, 0x9d, 0xd5, 0xe6, 0x4e, - 0xd5, 0xda, 0x77, 0xa7, 0x9a, 0xce, 0xb9, 0x2d, 0xf5, 0x95, 0x73, 0x6b, 0xa6, 0xc3, 0x96, 0xf7, - 0x4c, 0x87, 0xfd, 0x41, 0x7d, 0x1f, 0x2a, 0xcf, 0x9b, 0x1d, 0xca, 0xbb, 0x0b, 0x15, 0xd9, 0x30, - 0xd0, 0x70, 0x54, 0x5d, 0x95, 0x61, 0xbe, 0x77, 0x98, 0x9e, 0x64, 0x48, 0x02, 0x62, 0x2f, 0x42, - 0x5d, 0x9d, 0x7e, 0xc8, 0x8d, 0xaa, 0x95, 0xbf, 0x51, 0xed, 0x2b, 0x2d, 0x6f, 0x6a, 0xf5, 0x9b, - 0xdf, 0x7d, 0xe2, 0x1d, 0xbf, 0xfb, 0xdd, 0x27, 0xde, 0xf1, 0x07, 0xdf, 0x7d, 0xe2, 0x1d, 0x9f, - 0xdc, 0x7d, 0xc2, 0xfa, 0xe6, 0xee, 0x13, 0xd6, 0xef, 0xee, 0x3e, 0x61, 0xfd, 0xc1, 0xee, 0x13, - 0xd6, 0x77, 0x76, 0x9f, 0xb0, 0xbe, 0xf4, 0x9f, 0x9f, 0x78, 0xc7, 0x2b, 0xb9, 0xe1, 0x81, 0xf4, - 0xc7, 0xb3, 0x8d, 0xe6, 0xc4, 0xe6, 0x25, 0x16, 0xa1, 0x46, 0x97, 0xd7, 0x84, 0x31, 0xa7, 0x26, - 0xe4, 0xf2, 0xfa, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa1, 0x4f, 0x88, 0x2f, 0x3c, 0xe0, 0x00, - 0x00, + 0x6f, 0xea, 0x8c, 0xe3, 0x7b, 0xfa, 0xb4, 0xf5, 0xa8, 0x61, 0xb1, 0x22, 0x1e, 0xe5, 0x0b, 0x4c, + 0xfe, 0xc3, 0x8a, 0x24, 0x1d, 0xc0, 0xd0, 0xeb, 0xb4, 0x5c, 0x7f, 0x0c, 0x8a, 0x18, 0xc0, 0x65, + 0x46, 0x2b, 0x33, 0x80, 0xbc, 0x11, 0x0b, 0x46, 0xf6, 0x9f, 0x58, 0x80, 0xd2, 0x42, 0xed, 0x3e, + 0x18, 0xb5, 0xaf, 0xa7, 0x8d, 0xda, 0x85, 0x22, 0xad, 0x8e, 0x1e, 0x76, 0xed, 0x6f, 0xd4, 0x21, + 0xa3, 0x0e, 0xae, 0x93, 0x38, 0x21, 0xcd, 0xb7, 0x45, 0xf8, 0xdb, 0x22, 0xfc, 0x6d, 0x11, 0xae, + 0x44, 0xf8, 0x5a, 0x46, 0x84, 0xbf, 0xdf, 0x58, 0xf5, 0xfa, 0x50, 0xf5, 0x35, 0x75, 0xea, 0x6a, + 0xf6, 0xc0, 0x40, 0xa0, 0x92, 0xe0, 0xea, 0xca, 0xd2, 0xf5, 0x5c, 0x99, 0xfd, 0x5a, 0x5a, 0x66, + 0x1f, 0x95, 0xc5, 0xff, 0x0b, 0x52, 0xfa, 0x5f, 0x5a, 0xf0, 0xae, 0xb4, 0xf4, 0x92, 0x33, 0x67, + 0xbe, 0xe5, 0x07, 0x11, 0x99, 0x75, 0xd7, 0xd7, 0x49, 0x44, 0xfc, 0x06, 0x89, 0x95, 0x17, 0xc3, + 0xea, 0xe5, 0xc5, 0x40, 0xcf, 0xc3, 0xf0, 0xed, 0x38, 0xf0, 0x97, 0x03, 0xd7, 0x17, 0x22, 0x88, + 0x6e, 0x84, 0x4f, 0xde, 0xdd, 0x1d, 0x1f, 0xa6, 0x23, 0x2a, 0xdb, 0x71, 0x0a, 0x0b, 0xcd, 0xc0, + 0xa9, 0xdb, 0xaf, 0x2f, 0x3b, 0x89, 0xe1, 0x0e, 0x90, 0x1b, 0x77, 0x76, 0x60, 0x71, 0xf5, 0xe5, + 0x0c, 0x10, 0x77, 0xe3, 0xdb, 0x7f, 0xa3, 0x04, 0xe7, 0x32, 0x2f, 0x12, 0x78, 0x5e, 0xd0, 0x49, + 0xe8, 0xa6, 0x06, 0xfd, 0x82, 0x05, 0x27, 0xdb, 0x69, 0x8f, 0x43, 0x2c, 0x1c, 0xbb, 0x1f, 0x2c, + 0x4c, 0x47, 0x64, 0x5c, 0x1a, 0xd3, 0x63, 0x62, 0x84, 0x4e, 0x66, 0x00, 0x31, 0xee, 0xea, 0x0b, + 0x7a, 0x15, 0xea, 0x6d, 0x67, 0xfb, 0x46, 0xd8, 0x74, 0x12, 0xb9, 0x9f, 0xec, 0xed, 0x06, 0xe8, + 0x24, 0xae, 0x37, 0xc1, 0x8f, 0xeb, 0x27, 0xe6, 0xfd, 0x64, 0x29, 0x5a, 0x49, 0x22, 0xd7, 0x6f, + 0x71, 0x77, 0xde, 0xa2, 0x24, 0x83, 0x35, 0x45, 0xfb, 0xab, 0x56, 0x56, 0x49, 0xa9, 0xd1, 0x89, + 0x9c, 0x84, 0xb4, 0x76, 0xd0, 0xc7, 0xa0, 0x4a, 0x37, 0x7e, 0x72, 0x54, 0x6e, 0x15, 0xa9, 0x39, + 0x8d, 0x2f, 0xa1, 0x95, 0x28, 0xfd, 0x17, 0x63, 0xce, 0xd4, 0xfe, 0x93, 0x5a, 0xd6, 0x58, 0x60, + 0x87, 0xb7, 0x17, 0x01, 0x5a, 0xc1, 0x2a, 0x69, 0x87, 0x1e, 0x1d, 0x16, 0x8b, 0x9d, 0x00, 0x28, + 0x5f, 0xc7, 0x9c, 0x82, 0x60, 0x03, 0x0b, 0xfd, 0x25, 0x0b, 0xa0, 0x25, 0xe7, 0xbc, 0x34, 0x04, + 0x6e, 0x14, 0xf9, 0x3a, 0x7a, 0x45, 0xe9, 0xbe, 0x28, 0x86, 0xd8, 0x60, 0x8e, 0x7e, 0xca, 0x82, + 0x5a, 0x22, 0xbb, 0xcf, 0x55, 0xe3, 0x6a, 0x91, 0x3d, 0x91, 0x2f, 0xad, 0x6d, 0x22, 0x35, 0x24, + 0x8a, 0x2f, 0xfa, 0x19, 0x0b, 0x20, 0xde, 0xf1, 0x1b, 0xcb, 0x81, 0xe7, 0x36, 0x76, 0x84, 0xc6, + 0xbc, 0x59, 0xa8, 0x3f, 0x46, 0x51, 0x9f, 0x1e, 0xa5, 0xa3, 0xa1, 0xff, 0x63, 0x83, 0x33, 0xfa, + 0x04, 0xd4, 0x62, 0x31, 0xdd, 0x84, 0x8e, 0x5c, 0x2d, 0xd6, 0x2b, 0xc4, 0x69, 0x0b, 0xf1, 0x2a, + 0xfe, 0x61, 0xc5, 0x13, 0xfd, 0x9c, 0x05, 0x27, 0xc2, 0xb4, 0x9f, 0x4f, 0xa8, 0xc3, 0xe2, 0x64, + 0x40, 0xc6, 0x8f, 0x38, 0x7d, 0xfa, 0xee, 0xee, 0xf8, 0x89, 0x4c, 0x23, 0xce, 0xf6, 0x82, 0x4a, + 0x40, 0x3d, 0x83, 0x97, 0x42, 0xee, 0x73, 0x1c, 0xd4, 0x12, 0x70, 0x2e, 0x0b, 0xc4, 0xdd, 0xf8, + 0x68, 0x19, 0xce, 0xd0, 0xde, 0xed, 0x70, 0xf3, 0x53, 0xaa, 0x97, 0x98, 0x29, 0xc3, 0xda, 0xf4, + 0x63, 0x62, 0x86, 0x30, 0xaf, 0x7e, 0x16, 0x07, 0xe7, 0x3e, 0x89, 0x7e, 0xd7, 0x82, 0xc7, 0x5c, + 0xa6, 0x06, 0x4c, 0x87, 0xb9, 0xd6, 0x08, 0xe2, 0x24, 0x96, 0x14, 0x2a, 0x2b, 0x7a, 0xa9, 0x9f, + 0xe9, 0xff, 0x4f, 0xbc, 0xc1, 0x63, 0xf3, 0x7b, 0x74, 0x09, 0xef, 0xd9, 0x61, 0xfb, 0x5b, 0xa5, + 0xd4, 0xb1, 0x86, 0xf2, 0x25, 0x32, 0xa9, 0xd1, 0x90, 0x6e, 0x1c, 0x29, 0x04, 0x0b, 0x95, 0x1a, + 0xca, 0x49, 0xa4, 0xa5, 0x86, 0x6a, 0x8a, 0xb1, 0xc1, 0x9c, 0xda, 0x96, 0xa7, 0x9c, 0xac, 0xc7, + 0x52, 0x08, 0xb2, 0x57, 0x8b, 0xec, 0x52, 0xf7, 0x21, 0xd4, 0x39, 0xd1, 0xb5, 0x53, 0x5d, 0x20, + 0xdc, 0xdd, 0x25, 0xfb, 0x5b, 0xe9, 0xa3, 0x14, 0x63, 0x0d, 0xf6, 0x71, 0x4c, 0xf4, 0x45, 0x0b, + 0x86, 0xa2, 0xc0, 0xf3, 0x5c, 0xbf, 0x45, 0xe5, 0x85, 0x50, 0x7a, 0x1f, 0x3e, 0x16, 0xbd, 0x23, + 0x04, 0x03, 0xb3, 0x50, 0xb1, 0xe6, 0x89, 0xcd, 0x0e, 0xd8, 0x7f, 0x6c, 0xc1, 0x58, 0x2f, 0xb9, + 0x86, 0x08, 0xbc, 0x53, 0x2e, 0x5a, 0x15, 0x24, 0xb1, 0xe4, 0xcf, 0x12, 0x8f, 0x28, 0xff, 0x71, + 0x6d, 0xfa, 0x49, 0xf1, 0x9a, 0xef, 0x5c, 0xee, 0x8d, 0x8a, 0xf7, 0xa2, 0x83, 0x5e, 0x81, 0x93, + 0xc6, 0x7b, 0xc5, 0x6a, 0x60, 0xea, 0xd3, 0x13, 0xd4, 0x90, 0x98, 0xca, 0xc0, 0xee, 0xed, 0x8e, + 0x3f, 0x92, 0x6d, 0x13, 0x82, 0xb7, 0x8b, 0x8e, 0xfd, 0xcb, 0xa5, 0xec, 0xd7, 0x52, 0x3a, 0xf3, + 0x2d, 0xab, 0x6b, 0x57, 0xfe, 0xc1, 0xe3, 0xd0, 0x53, 0x6c, 0xff, 0xae, 0xe2, 0x30, 0x7a, 0xe3, + 0x3c, 0xc0, 0x83, 0x5e, 0xfb, 0x5f, 0x57, 0x60, 0x8f, 0x9e, 0xf5, 0x61, 0x04, 0x1f, 0xf8, 0x74, + 0xf0, 0xf3, 0x96, 0x3a, 0x39, 0x2a, 0xb3, 0x45, 0xde, 0x3c, 0xae, 0xb1, 0xe7, 0xfb, 0x90, 0x98, + 0x07, 0x1b, 0x28, 0x6f, 0x74, 0xfa, 0x8c, 0x0a, 0x7d, 0xcd, 0x4a, 0x9f, 0x7d, 0xf1, 0xe8, 0x31, + 0xf7, 0xd8, 0xfa, 0x64, 0x1c, 0xa8, 0xf1, 0x8e, 0xe9, 0x63, 0x98, 0x5e, 0x47, 0x6d, 0x13, 0x00, + 0xeb, 0xae, 0xef, 0x78, 0xee, 0x1b, 0x74, 0x97, 0x51, 0x65, 0x8a, 0x92, 0x59, 0x1e, 0x97, 0x55, + 0x2b, 0x36, 0x30, 0xce, 0xff, 0x45, 0x18, 0x32, 0xde, 0x3c, 0x27, 0x46, 0xe2, 0x8c, 0x19, 0x23, + 0x51, 0x37, 0x42, 0x1b, 0xce, 0xbf, 0x1f, 0x4e, 0x66, 0x3b, 0x78, 0x90, 0xe7, 0xed, 0xff, 0x39, + 0x98, 0x3d, 0x8c, 0x5a, 0x25, 0x51, 0x9b, 0x76, 0xed, 0x6d, 0x07, 0xd1, 0xdb, 0x0e, 0xa2, 0xb7, + 0x1d, 0x44, 0xa6, 0x8f, 0x5f, 0x38, 0x3f, 0x06, 0xef, 0x93, 0xf3, 0x23, 0xe5, 0xce, 0xa9, 0x15, + 0xee, 0xce, 0xb1, 0xef, 0x56, 0x21, 0x65, 0x47, 0xf1, 0xf1, 0xfe, 0x21, 0x18, 0x8c, 0x48, 0x18, + 0xdc, 0xc0, 0x0b, 0x42, 0x87, 0xe8, 0x38, 0x78, 0xde, 0x8c, 0x25, 0x9c, 0xea, 0x9a, 0xd0, 0x49, + 0x36, 0x84, 0x12, 0x51, 0xba, 0x66, 0xd9, 0x49, 0x36, 0x30, 0x83, 0xa0, 0xf7, 0xc3, 0x68, 0xe2, + 0x44, 0x2d, 0x6a, 0x36, 0x6f, 0xb1, 0xcf, 0x2a, 0x8e, 0x2c, 0x1f, 0x11, 0xb8, 0xa3, 0xab, 0x29, + 0x28, 0xce, 0x60, 0xa3, 0xd7, 0xa1, 0xb2, 0x41, 0xbc, 0xb6, 0x18, 0xf2, 0x95, 0xe2, 0x64, 0x3c, + 0x7b, 0xd7, 0x2b, 0xc4, 0x6b, 0x73, 0x09, 0x44, 0x7f, 0x61, 0xc6, 0x8a, 0xce, 0xb7, 0xfa, 0x66, + 0x27, 0x4e, 0x82, 0xb6, 0xfb, 0x86, 0xf4, 0xd4, 0x7d, 0xb0, 0x60, 0xc6, 0xd7, 0x24, 0x7d, 0xee, + 0x12, 0x51, 0x7f, 0xb1, 0xe6, 0xcc, 0xfa, 0xd1, 0x74, 0x23, 0xf6, 0xa9, 0x76, 0x84, 0xc3, 0xad, + 0xe8, 0x7e, 0xcc, 0x4a, 0xfa, 0xbc, 0x1f, 0xea, 0x2f, 0xd6, 0x9c, 0xd1, 0x8e, 0x9a, 0xf7, 0x43, + 0xac, 0x0f, 0x37, 0x0a, 0xee, 0x03, 0x9f, 0xf3, 0xb9, 0xf3, 0xff, 0x49, 0xa8, 0x36, 0x36, 0x9c, + 0x28, 0x19, 0x1b, 0x66, 0x93, 0x46, 0xb9, 0x66, 0x66, 0x68, 0x23, 0xe6, 0x30, 0xf4, 0x38, 0x94, + 0x23, 0xb2, 0xce, 0xc2, 0x2f, 0x8d, 0xc0, 0x1c, 0x4c, 0xd6, 0x31, 0x6d, 0xb7, 0x7f, 0xb1, 0x94, + 0x36, 0x97, 0xd2, 0xef, 0xcd, 0x67, 0x7b, 0xa3, 0x13, 0xc5, 0xd2, 0x7d, 0x63, 0xcc, 0x76, 0xd6, + 0x8c, 0x25, 0x1c, 0x7d, 0xca, 0x82, 0xc1, 0xdb, 0x71, 0xe0, 0xfb, 0x24, 0x11, 0xaa, 0xe9, 0x66, + 0xc1, 0x43, 0x71, 0x95, 0x53, 0xd7, 0x7d, 0x10, 0x0d, 0x58, 0xf2, 0xa5, 0xdd, 0x25, 0xdb, 0x0d, + 0xaf, 0xd3, 0xec, 0x8a, 0xb5, 0xb8, 0xc4, 0x9b, 0xb1, 0x84, 0x53, 0x54, 0xd7, 0xe7, 0xa8, 0x95, + 0x34, 0xea, 0xbc, 0x2f, 0x50, 0x05, 0xdc, 0xfe, 0x6b, 0x03, 0x70, 0x36, 0x77, 0x71, 0x50, 0x43, + 0x86, 0x99, 0x0a, 0x97, 0x5d, 0x8f, 0xc8, 0x28, 0x23, 0x66, 0xc8, 0xdc, 0x54, 0xad, 0xd8, 0xc0, + 0x40, 0x3f, 0x09, 0x10, 0x3a, 0x91, 0xd3, 0x26, 0xca, 0xbd, 0x7a, 0x64, 0x7b, 0x81, 0xf6, 0x63, + 0x59, 0xd2, 0xd4, 0x7b, 0x53, 0xd5, 0x14, 0x63, 0x83, 0x25, 0x7a, 0x01, 0x86, 0x22, 0xe2, 0x11, + 0x27, 0x66, 0xd1, 0xbb, 0xd9, 0x54, 0x04, 0xac, 0x41, 0xd8, 0xc4, 0x43, 0x4f, 0xa9, 0x80, 0xac, + 0x4c, 0x60, 0x4a, 0x3a, 0x28, 0x0b, 0xbd, 0x69, 0xc1, 0xe8, 0xba, 0xeb, 0x11, 0xcd, 0x5d, 0x24, + 0x0e, 0x2c, 0x1d, 0xfd, 0x25, 0x2f, 0x9b, 0x74, 0xb5, 0x84, 0x4c, 0x35, 0xc7, 0x38, 0xc3, 0x9e, + 0x7e, 0xe6, 0x2d, 0x12, 0x31, 0xd1, 0x3a, 0x90, 0xfe, 0xcc, 0x37, 0x79, 0x33, 0x96, 0x70, 0x34, + 0x05, 0x27, 0x42, 0x27, 0x8e, 0x67, 0x22, 0xd2, 0x24, 0x7e, 0xe2, 0x3a, 0x1e, 0x0f, 0xeb, 0xaf, + 0xe9, 0xb0, 0xde, 0xe5, 0x34, 0x18, 0x67, 0xf1, 0xd1, 0x87, 0xe0, 0x51, 0xee, 0xbf, 0x58, 0x74, + 0xe3, 0xd8, 0xf5, 0x5b, 0x7a, 0x1a, 0x08, 0x37, 0xce, 0xb8, 0x20, 0xf5, 0xe8, 0x7c, 0x3e, 0x1a, + 0xee, 0xf5, 0x3c, 0x7a, 0x06, 0x6a, 0xf1, 0xa6, 0x1b, 0xce, 0x44, 0xcd, 0x98, 0x9d, 0x5d, 0xd4, + 0xb4, 0xd3, 0x70, 0x45, 0xb4, 0x63, 0x85, 0x81, 0x1a, 0x30, 0xcc, 0x3f, 0x09, 0x8f, 0x28, 0x13, + 0xf2, 0xf1, 0xd9, 0x9e, 0xea, 0x51, 0x64, 0x9e, 0x4d, 0x60, 0xe7, 0xce, 0x25, 0x79, 0x92, 0xc2, + 0x1d, 0xff, 0x37, 0x0d, 0x32, 0x38, 0x45, 0xd4, 0xfe, 0xf9, 0x52, 0x7a, 0xc7, 0x6d, 0x2e, 0x52, + 0x14, 0xd3, 0xa5, 0x98, 0xdc, 0x74, 0x22, 0xe9, 0x8d, 0x39, 0x62, 0xf6, 0x81, 0xa0, 0x7b, 0xd3, + 0x89, 0xcc, 0x45, 0xcd, 0x18, 0x60, 0xc9, 0x09, 0xdd, 0x86, 0x4a, 0xe2, 0x39, 0x05, 0xa5, 0x2b, + 0x19, 0x1c, 0xb5, 0x03, 0x64, 0x61, 0x2a, 0xc6, 0x8c, 0x07, 0x7a, 0x8c, 0x5a, 0xfd, 0x6b, 0xf2, + 0xa4, 0x43, 0x18, 0xea, 0x6b, 0x31, 0x66, 0xad, 0xf6, 0xaf, 0x40, 0x8e, 0x5c, 0x55, 0x8a, 0x0c, + 0x5d, 0x04, 0xa0, 0x1b, 0xc8, 0xe5, 0x88, 0xac, 0xbb, 0xdb, 0xc2, 0x90, 0x50, 0x6b, 0xf7, 0xba, + 0x82, 0x60, 0x03, 0x4b, 0x3e, 0xb3, 0xd2, 0x59, 0xa7, 0xcf, 0x94, 0xba, 0x9f, 0xe1, 0x10, 0x6c, + 0x60, 0xa1, 0xe7, 0x61, 0xc0, 0x6d, 0x3b, 0x2d, 0x15, 0x49, 0xf9, 0x18, 0x5d, 0xb4, 0xf3, 0xac, + 0xe5, 0xde, 0xee, 0xf8, 0xa8, 0xea, 0x10, 0x6b, 0xc2, 0x02, 0x17, 0xfd, 0xb2, 0x05, 0xc3, 0x8d, + 0xa0, 0xdd, 0x0e, 0x7c, 0xbe, 0xed, 0x12, 0x7b, 0xc8, 0xdb, 0xc7, 0xa5, 0xe6, 0x27, 0x66, 0x0c, + 0x66, 0x7c, 0x13, 0xa9, 0xf2, 0xaa, 0x4c, 0x10, 0x4e, 0xf5, 0xca, 0x5c, 0xdb, 0xd5, 0x7d, 0xd6, + 0xf6, 0xaf, 0x5b, 0x70, 0x8a, 0x3f, 0x6b, 0xec, 0x06, 0x45, 0x0a, 0x51, 0x70, 0xcc, 0xaf, 0xd5, + 0xb5, 0x41, 0x56, 0x5e, 0xba, 0x2e, 0x38, 0xee, 0xee, 0x24, 0x9a, 0x83, 0x53, 0xeb, 0x41, 0xd4, + 0x20, 0xe6, 0x40, 0x08, 0xc1, 0xa4, 0x08, 0x5d, 0xce, 0x22, 0xe0, 0xee, 0x67, 0xd0, 0x4d, 0x78, + 0xc4, 0x68, 0x34, 0xc7, 0x81, 0xcb, 0xa6, 0x27, 0x04, 0xb5, 0x47, 0x2e, 0xe7, 0x62, 0xe1, 0x1e, + 0x4f, 0xa7, 0x1d, 0x26, 0xf5, 0x3e, 0x1c, 0x26, 0xaf, 0xc1, 0xb9, 0x46, 0xf7, 0xc8, 0x6c, 0xc5, + 0x9d, 0xb5, 0x98, 0x4b, 0xaa, 0xda, 0xf4, 0x0f, 0x08, 0x02, 0xe7, 0x66, 0x7a, 0x21, 0xe2, 0xde, + 0x34, 0xd0, 0xc7, 0xa0, 0x16, 0x11, 0xf6, 0x55, 0x62, 0x91, 0x4f, 0x73, 0xc4, 0x5d, 0xb2, 0xb6, + 0x40, 0x39, 0x59, 0x2d, 0x7b, 0x45, 0x43, 0x8c, 0x15, 0x47, 0x74, 0x07, 0x06, 0x43, 0x27, 0x69, + 0x6c, 0x88, 0x2c, 0x9a, 0x23, 0x87, 0xb1, 0x28, 0xe6, 0xcb, 0x94, 0xaa, 0x9e, 0xe4, 0xcb, 0x9c, + 0x09, 0x96, 0xdc, 0xa8, 0x35, 0xd2, 0x08, 0xda, 0x61, 0xe0, 0x13, 0x3f, 0x89, 0xc7, 0x46, 0xb4, + 0x35, 0x32, 0xa3, 0x5a, 0xb1, 0x81, 0x71, 0xfe, 0x03, 0x70, 0xaa, 0x6b, 0xe1, 0x1d, 0xc8, 0xb9, + 0x32, 0x0b, 0x8f, 0xe4, 0x4f, 0xf1, 0x03, 0xb9, 0x58, 0xfe, 0x51, 0x26, 0x56, 0xd5, 0x30, 0x7b, + 0xfb, 0x70, 0xd7, 0x39, 0x50, 0x26, 0xfe, 0x96, 0x90, 0xf8, 0x97, 0x8f, 0x36, 0xd2, 0x97, 0xfc, + 0x2d, 0xbe, 0x42, 0x99, 0x4f, 0xe2, 0x92, 0xbf, 0x85, 0x29, 0x6d, 0xf4, 0x65, 0x2b, 0x65, 0xb6, + 0x71, 0x27, 0xdf, 0x47, 0x8e, 0xc5, 0xce, 0xef, 0xdb, 0x92, 0xb3, 0xff, 0x4d, 0x09, 0x2e, 0xec, + 0x47, 0xa4, 0x8f, 0xe1, 0x7b, 0x12, 0x06, 0x62, 0x76, 0xfa, 0x2c, 0x44, 0xe8, 0x10, 0x9d, 0x59, + 0xfc, 0x3c, 0xfa, 0x35, 0x2c, 0x40, 0xc8, 0x83, 0x72, 0xdb, 0x09, 0x85, 0xef, 0x67, 0xfe, 0xa8, + 0xd9, 0x2b, 0xf4, 0xbf, 0xe3, 0x2d, 0x3a, 0x21, 0xf7, 0x28, 0x18, 0x0d, 0x98, 0xb2, 0x41, 0x09, + 0x54, 0x9d, 0x28, 0x72, 0xe4, 0x51, 0xe7, 0xb5, 0x62, 0xf8, 0x4d, 0x51, 0x92, 0xd3, 0xa7, 0xee, + 0xee, 0x8e, 0x8f, 0xa4, 0x9a, 0x30, 0x67, 0x66, 0x7f, 0x7e, 0x30, 0x95, 0xc1, 0xc1, 0xce, 0xaf, + 0x63, 0x18, 0x10, 0x2e, 0x1f, 0xab, 0xe8, 0xa4, 0x21, 0x9e, 0x82, 0xc7, 0x76, 0x75, 0x22, 0x91, + 0x59, 0xb0, 0x42, 0x9f, 0xb3, 0x58, 0xba, 0xb0, 0xcc, 0x6a, 0x11, 0x7b, 0xa9, 0xe3, 0xc9, 0x5e, + 0x36, 0x93, 0x90, 0x65, 0x23, 0x36, 0xb9, 0x53, 0x1d, 0x1b, 0xf2, 0xc4, 0xb7, 0xec, 0x8e, 0x4a, + 0x26, 0x14, 0x4b, 0x38, 0xda, 0xce, 0x39, 0xa7, 0x2e, 0x20, 0xe5, 0xb4, 0x8f, 0x93, 0xe9, 0xaf, + 0x59, 0x70, 0xca, 0xcd, 0x1e, 0x38, 0x8a, 0x9d, 0xc7, 0x11, 0x23, 0x21, 0x7a, 0x9f, 0x67, 0x2a, + 0xe5, 0xdb, 0x05, 0xc2, 0xdd, 0x9d, 0x41, 0x4d, 0xa8, 0xb8, 0xfe, 0x7a, 0x20, 0x4c, 0x8e, 0xe9, + 0xa3, 0x75, 0x6a, 0xde, 0x5f, 0x0f, 0xf4, 0x6a, 0xa6, 0xff, 0x30, 0xa3, 0x8e, 0x16, 0xe0, 0x4c, + 0x24, 0x7c, 0x43, 0x57, 0xdc, 0x98, 0xee, 0xe0, 0x17, 0xdc, 0xb6, 0x9b, 0x30, 0x73, 0xa1, 0x3c, + 0x3d, 0x76, 0x77, 0x77, 0xfc, 0x0c, 0xce, 0x81, 0xe3, 0xdc, 0xa7, 0xd0, 0x1b, 0x30, 0x28, 0xf3, + 0x9b, 0x6b, 0x45, 0xec, 0xe2, 0xba, 0xe7, 0xbf, 0x9a, 0x4c, 0x2b, 0x22, 0x95, 0x59, 0x32, 0xb4, + 0xdf, 0x1c, 0x82, 0xee, 0x43, 0x4c, 0xf4, 0x71, 0xa8, 0x47, 0x2a, 0xe7, 0xda, 0x2a, 0x42, 0xb9, + 0xca, 0xef, 0x2b, 0x0e, 0x50, 0x95, 0xe1, 0xa2, 0xb3, 0xab, 0x35, 0x47, 0xba, 0xbd, 0x88, 0xf5, + 0x59, 0x67, 0x01, 0x73, 0x5b, 0x70, 0xd5, 0xe7, 0x58, 0x3b, 0x7e, 0x03, 0x33, 0x1e, 0x28, 0x82, + 0x81, 0x0d, 0xe2, 0x78, 0xc9, 0x46, 0x31, 0x2e, 0xf7, 0x2b, 0x8c, 0x56, 0x36, 0xf3, 0x86, 0xb7, + 0x62, 0xc1, 0x09, 0x6d, 0xc3, 0xe0, 0x06, 0x9f, 0x00, 0xc2, 0xe2, 0x5f, 0x3c, 0xea, 0xe0, 0xa6, + 0x66, 0x95, 0xfe, 0xdc, 0xa2, 0x01, 0x4b, 0x76, 0x2c, 0xc8, 0xc5, 0x38, 0xbf, 0xe7, 0x4b, 0xb7, + 0xb8, 0xa4, 0xa3, 0xfe, 0x0f, 0xef, 0x3f, 0x0a, 0xc3, 0x11, 0x69, 0x04, 0x7e, 0xc3, 0xf5, 0x48, + 0x73, 0x4a, 0xba, 0xd3, 0x0f, 0x92, 0xaa, 0xc2, 0x76, 0xcd, 0xd8, 0xa0, 0x81, 0x53, 0x14, 0xd1, + 0x67, 0x2d, 0x18, 0x55, 0x89, 0x9a, 0xf4, 0x83, 0x10, 0xe1, 0xbe, 0x5d, 0x28, 0x28, 0x2d, 0x94, + 0xd1, 0x9c, 0x46, 0x77, 0x77, 0xc7, 0x47, 0xd3, 0x6d, 0x38, 0xc3, 0x17, 0xbd, 0x02, 0x10, 0xac, + 0xf1, 0x48, 0x96, 0xa9, 0x44, 0xf8, 0x72, 0x0f, 0xf2, 0xaa, 0xa3, 0x3c, 0x67, 0x4d, 0x52, 0xc0, + 0x06, 0x35, 0x74, 0x0d, 0x80, 0x2f, 0x9b, 0xd5, 0x9d, 0x50, 0x6e, 0x0b, 0x64, 0xae, 0x11, 0xac, + 0x28, 0xc8, 0xbd, 0xdd, 0xf1, 0x6e, 0xdf, 0x1a, 0x0b, 0x33, 0x30, 0x1e, 0x47, 0x3f, 0x01, 0x83, + 0x71, 0xa7, 0xdd, 0x76, 0x94, 0xa7, 0xb7, 0xc0, 0x2c, 0x38, 0x4e, 0xd7, 0x10, 0x45, 0xbc, 0x01, + 0x4b, 0x8e, 0xe8, 0x36, 0x15, 0xaa, 0xb1, 0x70, 0xfa, 0xb1, 0x55, 0xc4, 0x6d, 0x82, 0x21, 0xf6, + 0x4e, 0xef, 0x95, 0x81, 0x39, 0x38, 0x07, 0xe7, 0xde, 0xee, 0xf8, 0x23, 0xe9, 0xf6, 0x85, 0x40, + 0xe4, 0xa5, 0xe5, 0xd2, 0x44, 0x57, 0x65, 0xb9, 0x13, 0xfa, 0xda, 0x32, 0x0b, 0xff, 0x69, 0x5d, + 0xee, 0x84, 0x35, 0xf7, 0x1e, 0x33, 0xf3, 0x61, 0xb4, 0x08, 0xa7, 0x1b, 0x81, 0x9f, 0x44, 0x81, + 0xe7, 0xf1, 0x1a, 0x3e, 0x7c, 0x87, 0xc6, 0x3d, 0xc1, 0xef, 0x14, 0xdd, 0x3e, 0x3d, 0xd3, 0x8d, + 0x82, 0xf3, 0x9e, 0xb3, 0xfd, 0x74, 0x88, 0x9f, 0x18, 0x9c, 0xe7, 0x61, 0x98, 0x6c, 0x27, 0x24, + 0xf2, 0x1d, 0xef, 0x06, 0x5e, 0x90, 0x3e, 0x50, 0xb6, 0x06, 0x2e, 0x19, 0xed, 0x38, 0x85, 0x85, + 0x6c, 0xe5, 0x96, 0x30, 0x72, 0x2d, 0xb9, 0x5b, 0x42, 0x3a, 0x21, 0xec, 0xff, 0x55, 0x4a, 0x19, + 0x64, 0xab, 0x11, 0x21, 0x28, 0x80, 0xaa, 0x1f, 0x34, 0x95, 0xec, 0xbf, 0x5a, 0x8c, 0xec, 0xbf, + 0x1e, 0x34, 0x8d, 0x9a, 0x28, 0xf4, 0x5f, 0x8c, 0x39, 0x1f, 0x56, 0x34, 0x42, 0x56, 0xd7, 0x60, + 0x00, 0xb1, 0xd1, 0x28, 0x92, 0xb3, 0x2a, 0x1a, 0xb1, 0x64, 0x32, 0xc2, 0x69, 0xbe, 0x68, 0x13, + 0xaa, 0x1b, 0x41, 0x9c, 0xc8, 0xed, 0xc7, 0x11, 0x77, 0x3a, 0x57, 0x82, 0x38, 0x61, 0x56, 0x84, + 0x7a, 0x6d, 0xda, 0x12, 0x63, 0xce, 0xc3, 0xfe, 0xcf, 0x56, 0xca, 0xe3, 0x7d, 0x8b, 0x85, 0xbb, + 0x6e, 0x11, 0x9f, 0x2e, 0x6b, 0x33, 0x30, 0xe8, 0x2f, 0x64, 0x92, 0x07, 0xdf, 0xd5, 0xab, 0x42, + 0xd5, 0x1d, 0x4a, 0x61, 0x82, 0x91, 0x30, 0x62, 0x88, 0x3e, 0x69, 0xa5, 0xd3, 0x38, 0x4b, 0x45, + 0x6c, 0x30, 0xcc, 0x54, 0xe6, 0x7d, 0x33, 0x42, 0xed, 0x2f, 0x5b, 0x30, 0x38, 0xed, 0x34, 0x36, + 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0xcc, 0x28, 0x55, 0xdb, 0xfc, 0x59, 0xd1, + 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x26, 0x34, 0x97, 0xf9, 0x1c, 0xbe, 0xcc, 0x5a, + 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xa8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, 0xf6, 0x45, 0x0d, 0xc2, + 0x26, 0x9e, 0xfd, 0x2f, 0x2c, 0x18, 0x9b, 0x76, 0x62, 0xb7, 0x31, 0xd5, 0x49, 0x36, 0xa6, 0xdd, + 0x64, 0xad, 0xd3, 0xd8, 0x24, 0x09, 0xcf, 0x62, 0xa7, 0xbd, 0xec, 0xc4, 0x74, 0x29, 0xa9, 0x7d, + 0x9d, 0xea, 0xe5, 0x0d, 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, 0x27, 0x8e, 0xef, 0x04, + 0x51, 0x13, 0x93, 0xf5, 0x62, 0x6a, 0x48, 0xac, 0x90, 0x46, 0x44, 0x12, 0x4c, 0xd6, 0xc5, 0x91, + 0xb0, 0xa6, 0x8f, 0x4d, 0x66, 0xf6, 0x17, 0x2d, 0x38, 0x37, 0x4d, 0x9c, 0x88, 0x44, 0xac, 0xe4, + 0x84, 0x7a, 0x91, 0x19, 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, 0x33, 0xed, 0x96, 0x55, + 0x6c, 0xb7, 0xd8, 0x89, 0xee, 0xaa, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, 0x5b, 0x30, 0xcc, 0x0e, + 0xc7, 0x66, 0x49, 0xe2, 0xb8, 0x5e, 0x57, 0x65, 0x26, 0xab, 0xcf, 0xca, 0x4c, 0x17, 0xa0, 0xb2, + 0x11, 0xb4, 0x49, 0xf6, 0x60, 0xf7, 0x4a, 0x40, 0xb7, 0xd5, 0x14, 0x82, 0x9e, 0xa3, 0x1f, 0xde, + 0xf5, 0x13, 0x87, 0x2e, 0x01, 0xe9, 0x7c, 0x3d, 0xc1, 0x3f, 0xba, 0x6a, 0xc6, 0x26, 0x8e, 0xfd, + 0x5b, 0x75, 0x18, 0x14, 0xa7, 0xff, 0x7d, 0x57, 0x32, 0x90, 0xfb, 0xfb, 0x52, 0xcf, 0xfd, 0x7d, + 0x0c, 0x03, 0x0d, 0x56, 0xf7, 0x4d, 0x98, 0x91, 0xd7, 0x0a, 0x09, 0x17, 0xe1, 0xa5, 0xe4, 0x74, + 0xb7, 0xf8, 0x7f, 0x2c, 0x58, 0xa1, 0x2f, 0x59, 0x70, 0xa2, 0x11, 0xf8, 0x3e, 0x69, 0x68, 0x1b, + 0xa7, 0x52, 0x44, 0x54, 0xc0, 0x4c, 0x9a, 0xa8, 0x3e, 0x99, 0xc9, 0x00, 0x70, 0x96, 0x3d, 0x7a, + 0x09, 0x46, 0xf8, 0x98, 0xdd, 0x4c, 0x79, 0x8c, 0x75, 0xc1, 0x1e, 0x13, 0x88, 0xd3, 0xb8, 0x68, + 0x82, 0x7b, 0xde, 0x45, 0x69, 0x9c, 0x01, 0xed, 0x58, 0x33, 0x8a, 0xe2, 0x18, 0x18, 0x28, 0x02, + 0x14, 0x91, 0xf5, 0x88, 0xc4, 0x1b, 0x22, 0x3a, 0x82, 0xd9, 0x57, 0x83, 0x87, 0xcb, 0x7a, 0xc6, + 0x5d, 0x94, 0x70, 0x0e, 0x75, 0xb4, 0x29, 0x36, 0x98, 0xb5, 0x22, 0x64, 0xa8, 0xf8, 0xcc, 0x3d, + 0xf7, 0x99, 0xe3, 0x50, 0x8d, 0x37, 0x9c, 0xa8, 0xc9, 0xec, 0xba, 0x32, 0xcf, 0xb4, 0x59, 0xa1, + 0x0d, 0x98, 0xb7, 0xa3, 0x59, 0x38, 0x99, 0x29, 0x37, 0x14, 0x0b, 0xcf, 0xae, 0xca, 0xaa, 0xc8, + 0x14, 0x2a, 0x8a, 0x71, 0xd7, 0x13, 0xa6, 0xf3, 0x61, 0x68, 0x1f, 0xe7, 0xc3, 0x8e, 0x8a, 0xc1, + 0xe3, 0x3e, 0xd7, 0x97, 0x0b, 0x19, 0x80, 0xbe, 0x02, 0xee, 0xbe, 0x90, 0x09, 0xb8, 0x1b, 0x61, + 0x1d, 0xb8, 0x59, 0x4c, 0x07, 0x0e, 0x1e, 0x5d, 0xf7, 0x20, 0xa3, 0xe5, 0xfe, 0xdc, 0x02, 0xf9, + 0x5d, 0x67, 0x9c, 0xc6, 0x06, 0xa1, 0x53, 0x06, 0xbd, 0x1f, 0x46, 0xd5, 0x16, 0x7a, 0x26, 0xe8, + 0xf8, 0x3c, 0x50, 0xae, 0xac, 0x8f, 0x70, 0x71, 0x0a, 0x8a, 0x33, 0xd8, 0x68, 0x12, 0xea, 0x74, + 0x9c, 0xf8, 0xa3, 0x5c, 0xd7, 0xaa, 0x6d, 0xfa, 0xd4, 0xf2, 0xbc, 0x78, 0x4a, 0xe3, 0xa0, 0x00, + 0x4e, 0x79, 0x4e, 0x9c, 0xb0, 0x1e, 0xd0, 0x1d, 0xf5, 0x21, 0x6b, 0x0e, 0xb0, 0xd0, 0xfd, 0x85, + 0x2c, 0x21, 0xdc, 0x4d, 0xdb, 0xfe, 0x76, 0x05, 0x46, 0x52, 0x92, 0xf1, 0x80, 0x4a, 0xfa, 0x19, + 0xa8, 0x49, 0xbd, 0x99, 0xad, 0x8e, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, 0x6b, 0x4d, 0x6b, 0xd5, + 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, 0x8c, 0xe7, 0x12, 0x3f, + 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, 0xce, 0x00, 0x70, 0x96, + 0x3d, 0xfa, 0x8c, 0x05, 0x23, 0xce, 0x9d, 0x58, 0x17, 0x27, 0x15, 0xa1, 0x75, 0x47, 0x54, 0x52, + 0xa9, 0x7a, 0xa7, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, 0x0b, 0x10, 0xd9, 0x26, + 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x50, 0xc4, 0x4e, 0xf3, 0x52, 0x17, 0x5d, 0x2e, 0xd5, 0xbb, + 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x5a, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, 0x3a, 0x46, 0xdc, 0x9b, + 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0xca, 0x98, 0xca, 0x7c, 0x2a, 0x3d, 0xa0, 0xcc, + 0xa7, 0x9f, 0xb2, 0x52, 0x75, 0x80, 0x86, 0x2e, 0xbe, 0x52, 0x6c, 0xac, 0xeb, 0x04, 0x8f, 0x6d, + 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, 0xe1, 0xbf, 0x2f, 0xc3, + 0x90, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, 0x30, 0x8b, 0x7e, 0x12, + 0xea, 0x0d, 0x29, 0xe5, 0x8b, 0xa9, 0x84, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, 0xab, 0x26, 0xac, 0x79, + 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x15, 0xa6, 0x21, 0xf2, 0x32, 0x61, 0x84, 0xa6, 0xe8, + 0x7e, 0x86, 0x95, 0x8b, 0x0a, 0x5d, 0xf1, 0x5e, 0x32, 0x22, 0x9d, 0x97, 0x8b, 0x5a, 0x9e, 0x97, + 0xcd, 0xd8, 0xc4, 0xb1, 0xbf, 0x6d, 0xa9, 0x8f, 0x7b, 0x1f, 0x0a, 0x23, 0xdc, 0x4e, 0x17, 0x46, + 0xb8, 0x54, 0xc8, 0x30, 0xf7, 0xa8, 0x88, 0x70, 0x1d, 0x06, 0x67, 0x82, 0x76, 0xdb, 0xf1, 0x9b, + 0xe8, 0x07, 0x61, 0xb0, 0xc1, 0x7f, 0x0a, 0xc7, 0x0e, 0x3b, 0x1e, 0x14, 0x50, 0x2c, 0x61, 0xe8, + 0x31, 0xa8, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x54, 0xd4, 0x8a, 0x31, 0x6b, 0xb5, + 0xff, 0x61, 0x05, 0xd8, 0x09, 0xb4, 0x13, 0x91, 0xe6, 0x6a, 0xc0, 0x2a, 0xf1, 0x1d, 0xeb, 0xa1, + 0x9a, 0xde, 0x2c, 0x3d, 0xcc, 0x07, 0x6b, 0xc6, 0xe1, 0x4a, 0xf9, 0x3e, 0x1f, 0xae, 0xf4, 0x38, + 0x2f, 0xab, 0x3c, 0x44, 0xe7, 0x65, 0xf6, 0xe7, 0x2d, 0x40, 0x2a, 0x6c, 0x41, 0x1f, 0x68, 0x4f, + 0x42, 0x5d, 0x05, 0x30, 0x08, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, 0xa7, 0x8f, 0x1d, 0xf2, + 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb4, 0x4c, 0xea, 0x0b, 0x71, 0x6e, 0xff, 0x76, 0x09, 0x1e, + 0xe1, 0x2a, 0x79, 0xd1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, 0xa2, 0xd0, 0xa0, 0x5b, + 0x33, 0x57, 0x46, 0xc5, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0xbc, 0xef, 0x26, 0x98, + 0x11, 0x47, 0x31, 0xd4, 0x64, 0xe9, 0x77, 0x21, 0x8b, 0x0b, 0x62, 0xa4, 0xc4, 0x92, 0xd0, 0x9b, + 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x26, 0x26, 0x61, 0xc0, 0xe4, 0xae, 0x11, 0x94, + 0xb8, 0x20, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xdb, 0x82, 0xac, 0x46, 0x32, 0x4a, 0x9e, 0x59, 0x7b, + 0x96, 0x3c, 0x3b, 0x40, 0xcd, 0xb1, 0x1f, 0x87, 0x21, 0x27, 0xa1, 0x46, 0x04, 0xdf, 0x76, 0x97, + 0x0f, 0x77, 0xac, 0xb1, 0x18, 0x34, 0xdd, 0x75, 0x97, 0x6d, 0xb7, 0x4d, 0x72, 0xf6, 0x7f, 0xaf, + 0xc0, 0xa9, 0xae, 0xdc, 0x0d, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, 0xa5, 0x43, 0xab, 0x6e, + 0x06, 0xb1, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe1, 0x74, 0x44, 0x37, 0xfa, 0x1d, + 0x32, 0xb5, 0x9e, 0x90, 0x68, 0x85, 0x34, 0x02, 0xbf, 0xc9, 0x0b, 0xf3, 0x95, 0xa7, 0x1f, 0xbd, + 0xbb, 0x3b, 0x7e, 0x1a, 0x77, 0x83, 0x71, 0xde, 0x33, 0x28, 0x84, 0x11, 0xcf, 0xb4, 0x01, 0xc5, + 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, 0x6d, 0x48, 0x56, 0x1f, + 0x90, 0x21, 0xf9, 0x69, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x17, 0x9c, 0xbb, 0x73, 0xdc, 0x96, + 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, 0x48, 0xb4, 0x7b, 0x25, + 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, 0xeb, 0xa3, 0x6d, 0x1e, + 0x97, 0xc5, 0x75, 0xdb, 0x87, 0x8a, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, 0xd2, 0xa0, 0xc2, 0xb5, + 0x2e, 0x02, 0x68, 0x43, 0x4d, 0x04, 0xac, 0xab, 0x63, 0x5f, 0x6d, 0xcf, 0x61, 0x03, 0x8b, 0xee, + 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xe2, 0xfa, 0x89, 0x70, 0x0e, 0x2a, 0x25, 0x3e, 0xaf, + 0x41, 0xd8, 0xc4, 0x3b, 0xff, 0x5e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0x6e, 0xc0, 0xb9, 0x39, 0x37, + 0x51, 0x69, 0x16, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x0d, 0x59, 0x3d, 0xd3, 0x86, 0x8c, 0x34, + 0x87, 0x52, 0x3a, 0x2b, 0x23, 0x9b, 0xe6, 0x60, 0xbf, 0x08, 0x67, 0xe6, 0xdc, 0xe4, 0xb2, 0xeb, + 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x73, 0x00, 0x86, 0xcd, 0x44, 0xbd, 0x83, 0x64, 0x3e, 0x7d, 0x91, + 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xeb, 0xc8, 0x59, 0x83, 0xf9, 0x23, 0x66, 0x58, + 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x40, 0x75, 0x9d, 0x85, 0xe1, 0x97, 0x8b, 0x88, 0x2c, + 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x20, 0x3f, 0xe7, 0x47, 0x35, 0x64, 0x94, 0xce, 0xed, 0x32, + 0x42, 0x47, 0x45, 0x56, 0x97, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, 0xf5, 0x29, 0xc1, 0x3b, + 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0xa9, 0x48, 0x36, 0x98, 0xfd, 0x26, 0x62, 0xdd, 0x07, 0xd9, 0x20, + 0x18, 0x29, 0x15, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x4f, 0x28, 0xd1, 0x5d, 0x2b, 0xc2, 0xaf, 0x6a, + 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2f, 0xc1, 0xe8, 0x9c, 0xdf, 0x59, 0x9e, 0x5b, 0xee, 0xac, + 0x79, 0x6e, 0xe3, 0x1a, 0xd9, 0xa1, 0xa2, 0x79, 0x93, 0xec, 0xcc, 0xcf, 0x8a, 0x15, 0xa4, 0xe6, + 0xcc, 0x35, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x75, 0xd7, 0x6f, 0x91, 0x28, 0x8c, 0x5c, 0xe1, + 0xf2, 0x34, 0x84, 0xd1, 0x65, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf1, 0x49, 0x94, 0x35, + 0x64, 0x97, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, 0x93, 0x51, 0x21, 0xad, + 0xd2, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x35, 0x16, 0xb8, 0x91, 0x09, 0xac, 0x5f, 0xe1, + 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x26, 0xd9, 0x99, 0xa5, 0xbb, 0xde, 0x4c, 0x7e, 0xcd, 0x35, 0xde, + 0x8c, 0x25, 0x9c, 0x55, 0x14, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x45, 0xc1, 0x74, 0xf7, 0x7b, 0xec, + 0x9f, 0x7f, 0xc9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, 0x52, 0x57, 0x41, 0xda, + 0x1f, 0xcd, 0xbb, 0xa1, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, 0x96, 0xeb, 0x13, 0x76, + 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0x33, 0x41, 0x93, 0x1c, 0xc2, 0x48, 0xb6, 0x6f, 0xc1, + 0xa9, 0xae, 0xa4, 0xaa, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x5a, 0x6d, 0x0c, 0x43, 0x94, 0xb0, 0xac, + 0x6a, 0x33, 0x03, 0xa7, 0xf8, 0x42, 0xa2, 0x9c, 0x56, 0x1a, 0x1b, 0xa4, 0xad, 0x12, 0xe5, 0x98, + 0x7f, 0xfd, 0x66, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x2f, 0x58, 0x30, 0x92, 0xca, 0x73, 0x2b, 0xc8, + 0x08, 0x62, 0x2b, 0x2d, 0x60, 0xd1, 0x7f, 0x2c, 0x04, 0xba, 0xcc, 0x94, 0xa9, 0x5e, 0x69, 0x1a, + 0x84, 0x4d, 0x3c, 0xfb, 0xcb, 0x25, 0xa8, 0xc9, 0x08, 0x8a, 0x3e, 0xba, 0xf2, 0x39, 0x0b, 0x46, + 0xd4, 0x99, 0x06, 0x73, 0x96, 0x95, 0x8a, 0x48, 0x4a, 0xa0, 0x3d, 0x50, 0xdb, 0x6d, 0x7f, 0x3d, + 0xd0, 0x16, 0x39, 0x36, 0x99, 0xe1, 0x34, 0x6f, 0x74, 0x13, 0x20, 0xde, 0x89, 0x13, 0xd2, 0x36, + 0xdc, 0x76, 0xb6, 0xb1, 0xe2, 0x26, 0x1a, 0x41, 0x44, 0xe8, 0xfa, 0xba, 0x1e, 0x34, 0xc9, 0x8a, + 0xc2, 0xd4, 0x26, 0x94, 0x6e, 0xc3, 0x06, 0x25, 0xfb, 0xef, 0x97, 0xe0, 0x64, 0xb6, 0x4b, 0xe8, + 0xc3, 0x30, 0x2c, 0xb9, 0x1b, 0xb7, 0x8d, 0xc9, 0xb0, 0x91, 0x61, 0x6c, 0xc0, 0xee, 0xed, 0x8e, + 0x8f, 0x77, 0xdf, 0xf6, 0x36, 0x61, 0xa2, 0xe0, 0x14, 0x31, 0x7e, 0xb0, 0x24, 0x4e, 0x40, 0xa7, + 0x77, 0xa6, 0xc2, 0x50, 0x9c, 0x0e, 0x19, 0x07, 0x4b, 0x26, 0x14, 0x67, 0xb0, 0xd1, 0x32, 0x9c, + 0x31, 0x5a, 0xae, 0x13, 0xb7, 0xb5, 0xb1, 0x16, 0x44, 0x72, 0x67, 0xf5, 0x98, 0x0e, 0xec, 0xea, + 0xc6, 0xc1, 0xb9, 0x4f, 0x52, 0x6d, 0xdf, 0x70, 0x42, 0xa7, 0xe1, 0x26, 0x3b, 0xc2, 0x0f, 0xa9, + 0x64, 0xd3, 0x8c, 0x68, 0xc7, 0x0a, 0xc3, 0x5e, 0x84, 0x4a, 0x9f, 0x33, 0xa8, 0x2f, 0x8b, 0xfe, + 0x65, 0xa8, 0x51, 0x72, 0xd2, 0xbc, 0x2b, 0x82, 0x64, 0x00, 0x35, 0x79, 0x61, 0x08, 0xb2, 0xa1, + 0xec, 0x3a, 0xf2, 0xec, 0x4e, 0xbd, 0xd6, 0x7c, 0x1c, 0x77, 0xd8, 0x26, 0x99, 0x02, 0xd1, 0x93, + 0x50, 0x26, 0xdb, 0x61, 0xf6, 0x90, 0xee, 0xd2, 0x76, 0xe8, 0x46, 0x24, 0xa6, 0x48, 0x64, 0x3b, + 0x44, 0xe7, 0xa1, 0xe4, 0x36, 0x85, 0x92, 0x02, 0x81, 0x53, 0x9a, 0x9f, 0xc5, 0x25, 0xb7, 0x69, + 0x6f, 0x43, 0x5d, 0xdd, 0x50, 0x82, 0x36, 0xa5, 0xec, 0xb6, 0x8a, 0x08, 0x79, 0x92, 0x74, 0x7b, + 0x48, 0xed, 0x0e, 0x80, 0x4e, 0xf8, 0x2b, 0x4a, 0xbe, 0x5c, 0x80, 0x4a, 0x23, 0x10, 0xc9, 0xc8, + 0x35, 0x4d, 0x86, 0x09, 0x6d, 0x06, 0xb1, 0x6f, 0xc1, 0xe8, 0x35, 0x3f, 0xb8, 0xc3, 0xca, 0xab, + 0xb3, 0x6a, 0x62, 0x94, 0xf0, 0x3a, 0xfd, 0x91, 0x35, 0x11, 0x18, 0x14, 0x73, 0x98, 0xaa, 0xcf, + 0x54, 0xea, 0x55, 0x9f, 0xc9, 0xfe, 0xa4, 0x05, 0xc3, 0x2a, 0x73, 0x68, 0x6e, 0x6b, 0x93, 0xd2, + 0x6d, 0x45, 0x41, 0x27, 0xcc, 0xd2, 0x65, 0x77, 0x08, 0x61, 0x0e, 0x33, 0x53, 0xea, 0x4a, 0xfb, + 0xa4, 0xd4, 0x5d, 0x80, 0xca, 0xa6, 0xeb, 0x37, 0xb3, 0x97, 0x62, 0x5c, 0x73, 0xfd, 0x26, 0x66, + 0x10, 0xda, 0x85, 0x93, 0xaa, 0x0b, 0x52, 0x21, 0xbc, 0x08, 0xc3, 0x6b, 0x1d, 0xd7, 0x6b, 0xca, + 0x32, 0x69, 0x19, 0x4f, 0xc9, 0xb4, 0x01, 0xc3, 0x29, 0x4c, 0xba, 0xaf, 0x5b, 0x73, 0x7d, 0x27, + 0xda, 0x59, 0xd6, 0x1a, 0x48, 0x09, 0xa5, 0x69, 0x05, 0xc1, 0x06, 0x96, 0xfd, 0x66, 0x19, 0x46, + 0xd3, 0xf9, 0x53, 0x7d, 0x6c, 0xaf, 0x9e, 0x84, 0x2a, 0x4b, 0xa9, 0xca, 0x7e, 0x5a, 0xf6, 0x3c, + 0xe6, 0x30, 0x14, 0xc3, 0x00, 0x2f, 0xc6, 0x50, 0xcc, 0x85, 0x32, 0xaa, 0x93, 0xca, 0xbf, 0xc2, + 0xe2, 0xc9, 0x44, 0xfd, 0x07, 0xc1, 0x0a, 0x7d, 0xc6, 0x82, 0xc1, 0x20, 0x34, 0xeb, 0xfa, 0x7c, + 0xa8, 0xc8, 0xdc, 0x32, 0x91, 0x2c, 0x23, 0x2c, 0x62, 0xf5, 0xe9, 0xe5, 0xe7, 0x90, 0xac, 0xcf, + 0xbf, 0x0f, 0x86, 0x4d, 0xcc, 0xfd, 0x8c, 0xe2, 0x9a, 0x69, 0x14, 0x7f, 0xce, 0x9c, 0x14, 0x22, + 0x7b, 0xae, 0x8f, 0xe5, 0x76, 0x03, 0xaa, 0x0d, 0x15, 0x00, 0x70, 0xa8, 0xe2, 0x9a, 0xaa, 0x3a, + 0x02, 0x3b, 0x04, 0xe2, 0xd4, 0xec, 0x6f, 0x5b, 0xc6, 0xfc, 0xc0, 0x24, 0x9e, 0x6f, 0xa2, 0x08, + 0xca, 0xad, 0xad, 0x4d, 0x61, 0x8a, 0x5e, 0x2d, 0x68, 0x78, 0xe7, 0xb6, 0x36, 0xf5, 0x1c, 0x37, + 0x5b, 0x31, 0x65, 0xd6, 0x87, 0x13, 0x30, 0x95, 0x64, 0x59, 0xde, 0x3f, 0xc9, 0xd2, 0x7e, 0xab, + 0x04, 0xa7, 0xba, 0x26, 0x15, 0x7a, 0x03, 0xaa, 0x11, 0x7d, 0x4b, 0xf1, 0x7a, 0x0b, 0x85, 0xa5, + 0x45, 0xc6, 0xf3, 0x4d, 0xad, 0x77, 0xd3, 0xed, 0x98, 0xb3, 0x44, 0x57, 0x01, 0xe9, 0x30, 0x15, + 0xe5, 0x81, 0xe4, 0xaf, 0x7c, 0x5e, 0x3c, 0x8a, 0xa6, 0xba, 0x30, 0x70, 0xce, 0x53, 0xe8, 0xa5, + 0xac, 0x23, 0xb3, 0x9c, 0x3e, 0xb7, 0xdc, 0xcb, 0x27, 0x69, 0xff, 0xb3, 0x12, 0x8c, 0xa4, 0xca, + 0x2c, 0x21, 0x0f, 0x6a, 0xc4, 0x63, 0x4e, 0x7d, 0xa9, 0x6c, 0x8e, 0x5a, 0x7c, 0x58, 0x29, 0xc8, + 0x4b, 0x82, 0x2e, 0x56, 0x1c, 0x1e, 0x8e, 0xc3, 0xf5, 0x17, 0x61, 0x58, 0x76, 0xe8, 0x43, 0x4e, + 0xdb, 0x13, 0x03, 0xa8, 0xe6, 0xe8, 0x25, 0x03, 0x86, 0x53, 0x98, 0xf6, 0xef, 0x94, 0x61, 0x8c, + 0x9f, 0x82, 0x34, 0xd5, 0xcc, 0x5b, 0x94, 0xfb, 0xad, 0xbf, 0xac, 0x8b, 0xa1, 0xf1, 0x81, 0x5c, + 0x3b, 0x6a, 0xad, 0xff, 0x7c, 0x46, 0x7d, 0x45, 0x66, 0xfd, 0x42, 0x26, 0x32, 0x8b, 0x9b, 0xdd, + 0xad, 0x63, 0xea, 0xd1, 0xf7, 0x56, 0xa8, 0xd6, 0xaf, 0x94, 0xe0, 0x44, 0xe6, 0x22, 0x05, 0xf4, + 0x66, 0xba, 0xf6, 0xae, 0x55, 0x84, 0xaf, 0x7c, 0xcf, 0xda, 0xfa, 0x07, 0xab, 0xc0, 0xfb, 0x80, + 0x96, 0x8a, 0xfd, 0xfb, 0x25, 0x18, 0x4d, 0xdf, 0x00, 0xf1, 0x10, 0x8e, 0xd4, 0xbb, 0xa1, 0xce, + 0x8a, 0x9c, 0xb3, 0x9b, 0x2d, 0xb9, 0x4b, 0x9e, 0xd7, 0x93, 0x96, 0x8d, 0x58, 0xc3, 0x1f, 0x8a, + 0xc2, 0xc6, 0xf6, 0xdf, 0xb5, 0xe0, 0x2c, 0x7f, 0xcb, 0xec, 0x3c, 0xfc, 0x2b, 0x79, 0xa3, 0xfb, + 0x6a, 0xb1, 0x1d, 0xcc, 0x14, 0xf1, 0xdb, 0x6f, 0x7c, 0xd9, 0x8d, 0x7a, 0xa2, 0xb7, 0xe9, 0xa9, + 0xf0, 0x10, 0x76, 0xf6, 0x40, 0x93, 0xc1, 0xfe, 0xfd, 0x32, 0xe8, 0x4b, 0x04, 0x91, 0x2b, 0x72, + 0x1c, 0x0b, 0x29, 0x66, 0xb8, 0xb2, 0xe3, 0x37, 0xf4, 0x75, 0x85, 0xb5, 0x4c, 0x8a, 0xe3, 0xcf, + 0x5a, 0x30, 0xe4, 0xfa, 0x6e, 0xe2, 0x3a, 0x6c, 0x1b, 0x5d, 0xcc, 0x05, 0x67, 0x8a, 0xdd, 0x3c, + 0xa7, 0x1c, 0x44, 0xe6, 0x39, 0x8e, 0x62, 0x86, 0x4d, 0xce, 0xe8, 0xa3, 0x22, 0x78, 0xba, 0x5c, + 0x58, 0x76, 0x6e, 0x2d, 0x13, 0x31, 0x1d, 0x52, 0xc3, 0x2b, 0x89, 0x0a, 0x4a, 0x6a, 0xc7, 0x94, + 0x94, 0xaa, 0x8b, 0xab, 0xaf, 0x73, 0xa6, 0xcd, 0x98, 0x33, 0xb2, 0x63, 0x40, 0xdd, 0x63, 0x71, + 0xc0, 0xc0, 0xd4, 0x49, 0xa8, 0x3b, 0x9d, 0x24, 0x68, 0xd3, 0x61, 0x12, 0x47, 0x4d, 0x3a, 0xf4, + 0x56, 0x02, 0xb0, 0xc6, 0xb1, 0xdf, 0xac, 0x42, 0x26, 0xe9, 0x10, 0x6d, 0x9b, 0x17, 0x60, 0x5a, + 0xc5, 0x5e, 0x80, 0xa9, 0x3a, 0x93, 0x77, 0x09, 0x26, 0x6a, 0x41, 0x35, 0xdc, 0x70, 0x62, 0x69, + 0x56, 0xbf, 0xac, 0xf6, 0x71, 0xb4, 0xf1, 0xde, 0xee, 0xf8, 0x8f, 0xf5, 0xe7, 0x75, 0xa5, 0x73, + 0x75, 0x92, 0x17, 0x1b, 0xd1, 0xac, 0x19, 0x0d, 0xcc, 0xe9, 0x1f, 0xe4, 0x8a, 0xb7, 0x4f, 0x89, + 0x6a, 0xee, 0x98, 0xc4, 0x1d, 0x2f, 0x11, 0xb3, 0xe1, 0xe5, 0x02, 0x57, 0x19, 0x27, 0xac, 0xd3, + 0xe5, 0xf9, 0x7f, 0x6c, 0x30, 0x45, 0x1f, 0x86, 0x7a, 0x9c, 0x38, 0x51, 0x72, 0xc8, 0x04, 0x57, + 0x35, 0xe8, 0x2b, 0x92, 0x08, 0xd6, 0xf4, 0xd0, 0x2b, 0xac, 0xb6, 0xab, 0x1b, 0x6f, 0x1c, 0x32, + 0xe7, 0x41, 0xd6, 0x81, 0x15, 0x14, 0xb0, 0x41, 0x0d, 0x5d, 0x04, 0x60, 0x73, 0x9b, 0x07, 0xfa, + 0xd5, 0x98, 0x97, 0x49, 0x89, 0x42, 0xac, 0x20, 0xd8, 0xc0, 0xb2, 0x7f, 0x18, 0xd2, 0xf5, 0x1e, + 0xd0, 0xb8, 0x2c, 0x2f, 0xc1, 0xbd, 0xd0, 0x2c, 0x77, 0x21, 0x55, 0x09, 0xe2, 0xd7, 0x2d, 0x30, + 0x8b, 0x52, 0xa0, 0xd7, 0x79, 0xf5, 0x0b, 0xab, 0x88, 0x93, 0x43, 0x83, 0xee, 0xc4, 0xa2, 0x13, + 0x66, 0x8e, 0xb0, 0x65, 0x09, 0x8c, 0xf3, 0xef, 0x85, 0x9a, 0x84, 0x1e, 0xc8, 0xa8, 0xfb, 0x04, + 0x9c, 0xce, 0x5e, 0x0f, 0x2e, 0x4e, 0x9d, 0xf6, 0x77, 0xfd, 0x48, 0x7f, 0x4e, 0xa9, 0x97, 0x3f, + 0xa7, 0x8f, 0x6b, 0x50, 0x7f, 0xc3, 0x82, 0x0b, 0xfb, 0xdd, 0x62, 0x8e, 0x1e, 0x83, 0xca, 0x1d, + 0x27, 0x92, 0x45, 0xb7, 0x99, 0xa0, 0xbc, 0xe5, 0x44, 0x3e, 0x66, 0xad, 0x68, 0x07, 0x06, 0x78, + 0x34, 0x98, 0xb0, 0xd6, 0x5f, 0x2e, 0xf6, 0x4e, 0xf5, 0x6b, 0xc4, 0xd8, 0x2e, 0xf0, 0x48, 0x34, + 0x2c, 0x18, 0xda, 0xdf, 0xb1, 0x00, 0x2d, 0x6d, 0x91, 0x28, 0x72, 0x9b, 0x46, 0xfc, 0x1a, 0xbb, + 0x15, 0xc5, 0xb8, 0xfd, 0xc4, 0x4c, 0x71, 0xcd, 0xdc, 0x8a, 0x62, 0xfc, 0xcb, 0xbf, 0x15, 0xa5, + 0x74, 0xb0, 0x5b, 0x51, 0xd0, 0x12, 0x9c, 0x6d, 0xf3, 0xed, 0x06, 0xbf, 0x69, 0x80, 0xef, 0x3d, + 0x54, 0x42, 0xd9, 0xb9, 0xbb, 0xbb, 0xe3, 0x67, 0x17, 0xf3, 0x10, 0x70, 0xfe, 0x73, 0xf6, 0x7b, + 0x01, 0xf1, 0xb0, 0xb5, 0x99, 0xbc, 0x18, 0xa4, 0x9e, 0xee, 0x17, 0xfb, 0xab, 0x55, 0x38, 0x91, + 0x29, 0xc9, 0x4a, 0xb7, 0x7a, 0xdd, 0x41, 0x4f, 0x47, 0xd6, 0xdf, 0xdd, 0xdd, 0xeb, 0x2b, 0x8c, + 0xca, 0x87, 0xaa, 0xeb, 0x87, 0x9d, 0xa4, 0x98, 0x1c, 0x52, 0xde, 0x89, 0x79, 0x4a, 0xd0, 0x70, + 0x17, 0xd3, 0xbf, 0x98, 0xb3, 0x29, 0x32, 0x28, 0x2b, 0x65, 0x8c, 0x57, 0x1e, 0x90, 0x3b, 0xe0, + 0x53, 0x3a, 0x44, 0xaa, 0x5a, 0x84, 0x63, 0x31, 0x33, 0x59, 0x8e, 0xfb, 0xa8, 0xfd, 0xd7, 0x4a, + 0x30, 0x64, 0x7c, 0x34, 0xf4, 0x8b, 0xe9, 0x92, 0x4d, 0x56, 0x71, 0xaf, 0xc4, 0xe8, 0x4f, 0xe8, + 0xa2, 0x4c, 0xfc, 0x95, 0x9e, 0xea, 0xae, 0xd6, 0x74, 0x6f, 0x77, 0xfc, 0x64, 0xa6, 0x1e, 0x53, + 0xaa, 0x82, 0xd3, 0xf9, 0x8f, 0xc3, 0x89, 0x0c, 0x99, 0x9c, 0x57, 0x5e, 0x4d, 0xdf, 0xfe, 0x7e, + 0x44, 0xb7, 0x94, 0x39, 0x64, 0xdf, 0xa0, 0x43, 0x26, 0xd2, 0xe8, 0x02, 0x8f, 0xf4, 0xe1, 0x83, + 0xcd, 0x64, 0xcb, 0x96, 0xfa, 0xcc, 0x96, 0x7d, 0x1a, 0x6a, 0x61, 0xe0, 0xb9, 0x0d, 0x57, 0x55, + 0x21, 0x64, 0xf9, 0xb9, 0xcb, 0xa2, 0x0d, 0x2b, 0x28, 0xba, 0x03, 0x75, 0x75, 0x51, 0xbe, 0xf0, + 0x6f, 0x17, 0x75, 0xe8, 0xa3, 0x8c, 0x16, 0x7d, 0x01, 0xbe, 0xe6, 0x85, 0x6c, 0x18, 0x60, 0x4a, + 0x50, 0x86, 0xfe, 0x33, 0xdf, 0x3b, 0xd3, 0x8e, 0x31, 0x16, 0x10, 0xfb, 0xeb, 0x75, 0x38, 0x93, + 0x57, 0x17, 0x1b, 0x7d, 0x0c, 0x06, 0x78, 0x1f, 0x8b, 0xb9, 0x7a, 0x21, 0x8f, 0xc7, 0x1c, 0x23, + 0x28, 0xba, 0xc5, 0x7e, 0x63, 0xc1, 0x53, 0x70, 0xf7, 0x9c, 0x35, 0x31, 0x43, 0x8e, 0x87, 0xfb, + 0x82, 0xa3, 0xb9, 0x2f, 0x38, 0x9c, 0xbb, 0xe7, 0xac, 0xa1, 0x6d, 0xa8, 0xb6, 0xdc, 0x84, 0x38, + 0xc2, 0x89, 0x70, 0xeb, 0x58, 0x98, 0x13, 0x87, 0x5b, 0x69, 0xec, 0x27, 0xe6, 0x0c, 0xd1, 0xd7, + 0x2c, 0x38, 0xb1, 0x96, 0x4e, 0x8d, 0x17, 0xc2, 0xd3, 0x39, 0x86, 0xda, 0xe7, 0x69, 0x46, 0xfc, + 0x5a, 0xa0, 0x4c, 0x23, 0xce, 0x76, 0x07, 0x7d, 0xda, 0x82, 0xc1, 0x75, 0xd7, 0x33, 0xca, 0xe0, + 0x1e, 0xc3, 0xc7, 0xb9, 0xcc, 0x18, 0xe8, 0x1d, 0x07, 0xff, 0x1f, 0x63, 0xc9, 0xb9, 0x97, 0xa6, + 0x1a, 0x38, 0xaa, 0xa6, 0x1a, 0x7c, 0x40, 0x9a, 0xea, 0xb3, 0x16, 0xd4, 0xd5, 0x48, 0x8b, 0x74, + 0xe7, 0x0f, 0x1f, 0xe3, 0x27, 0xe7, 0x9e, 0x13, 0xf5, 0x17, 0x6b, 0xe6, 0xe8, 0x4b, 0x16, 0x0c, + 0x39, 0x6f, 0x74, 0x22, 0xd2, 0x24, 0x5b, 0x41, 0x18, 0x8b, 0x3b, 0x05, 0x5f, 0x2d, 0xbe, 0x33, + 0x53, 0x94, 0xc9, 0x2c, 0xd9, 0x5a, 0x0a, 0x63, 0x91, 0x96, 0xa4, 0x1b, 0xb0, 0xd9, 0x05, 0x7b, + 0xb7, 0x04, 0xe3, 0xfb, 0x50, 0x40, 0x2f, 0xc2, 0x70, 0x10, 0xb5, 0x1c, 0xdf, 0x7d, 0xc3, 0xac, + 0x75, 0xa1, 0xac, 0xac, 0x25, 0x03, 0x86, 0x53, 0x98, 0x66, 0x42, 0x76, 0x69, 0x9f, 0x84, 0xec, + 0x0b, 0x50, 0x89, 0x48, 0x18, 0x64, 0x37, 0x0b, 0x2c, 0x25, 0x80, 0x41, 0xd0, 0xe3, 0x50, 0x76, + 0x42, 0x57, 0x04, 0xa2, 0xa9, 0x3d, 0xd0, 0xd4, 0xf2, 0x3c, 0xa6, 0xed, 0xa9, 0xfa, 0x10, 0xd5, + 0xfb, 0x52, 0x1f, 0x82, 0xaa, 0x01, 0x71, 0x76, 0x31, 0xa0, 0xd5, 0x40, 0xfa, 0x4c, 0xc1, 0x7e, + 0xab, 0x0c, 0x8f, 0xef, 0x39, 0x5f, 0x74, 0x1c, 0x9e, 0xb5, 0x47, 0x1c, 0x9e, 0x1c, 0x9e, 0xd2, + 0x7e, 0xc3, 0x53, 0xee, 0x31, 0x3c, 0x9f, 0xa6, 0xcb, 0x40, 0xd6, 0x08, 0x29, 0xe6, 0x56, 0xb8, + 0x5e, 0x25, 0x47, 0xc4, 0x0a, 0x90, 0x50, 0xac, 0xf9, 0xd2, 0x3d, 0x40, 0x2a, 0x19, 0xb9, 0x5a, + 0x84, 0x1a, 0xe8, 0x59, 0x33, 0x84, 0xcf, 0xfd, 0x5e, 0x19, 0xce, 0xf6, 0xcf, 0x95, 0xe0, 0xc9, + 0x3e, 0xa4, 0xb7, 0x39, 0x8b, 0xad, 0x3e, 0x67, 0xf1, 0xf7, 0xf6, 0x67, 0xb2, 0xff, 0xaa, 0x05, + 0xe7, 0x7b, 0x2b, 0x0f, 0xf4, 0x1c, 0x0c, 0xad, 0x45, 0x8e, 0xdf, 0xd8, 0x60, 0x37, 0x5d, 0xca, + 0x41, 0x61, 0x63, 0xad, 0x9b, 0xb1, 0x89, 0x43, 0xb7, 0xb7, 0x3c, 0x26, 0xc1, 0xc0, 0x90, 0xc9, + 0xa3, 0x74, 0x7b, 0xbb, 0x9a, 0x05, 0xe2, 0x6e, 0x7c, 0xfb, 0xcf, 0x4a, 0xf9, 0xdd, 0xe2, 0x46, + 0xc6, 0x41, 0xbe, 0x93, 0xf8, 0x0a, 0xa5, 0x3e, 0x64, 0x49, 0xf9, 0x7e, 0xcb, 0x92, 0x4a, 0x2f, + 0x59, 0x82, 0x66, 0xe1, 0xa4, 0x71, 0x85, 0x0a, 0x4f, 0x08, 0xe6, 0x01, 0xb7, 0xaa, 0x4a, 0xc6, + 0x72, 0x06, 0x8e, 0xbb, 0x9e, 0x40, 0xcf, 0x40, 0xcd, 0xf5, 0x63, 0xd2, 0xe8, 0x44, 0x3c, 0xd0, + 0xdb, 0x48, 0xc2, 0x9a, 0x17, 0xed, 0x58, 0x61, 0xd8, 0xbf, 0x54, 0x82, 0x73, 0x3d, 0xed, 0xac, + 0xfb, 0x24, 0xbb, 0xcc, 0xcf, 0x51, 0xb9, 0x3f, 0x9f, 0xc3, 0x1c, 0xa4, 0xea, 0xbe, 0x83, 0xf4, + 0x07, 0xbd, 0x27, 0x26, 0xb5, 0xb9, 0xbf, 0x6f, 0x47, 0xe9, 0x25, 0x18, 0x71, 0xc2, 0x90, 0xe3, + 0xb1, 0x78, 0xcd, 0x4c, 0x95, 0x9c, 0x29, 0x13, 0x88, 0xd3, 0xb8, 0x7d, 0x69, 0xcf, 0x3f, 0xb2, + 0xa0, 0x8e, 0xc9, 0x3a, 0x97, 0x0e, 0xe8, 0xb6, 0x18, 0x22, 0xab, 0x88, 0x7a, 0x9a, 0x74, 0x60, + 0x63, 0x97, 0xd5, 0x99, 0xcc, 0x1b, 0xec, 0xee, 0xab, 0x76, 0x4a, 0x07, 0xba, 0x6a, 0x47, 0x5d, + 0xb6, 0x52, 0xee, 0x7d, 0xd9, 0x8a, 0xfd, 0x8d, 0x41, 0xfa, 0x7a, 0x61, 0x30, 0x13, 0x91, 0x66, + 0x4c, 0xbf, 0x6f, 0x27, 0xf2, 0xc4, 0x24, 0x51, 0xdf, 0xf7, 0x06, 0x5e, 0xc0, 0xb4, 0x3d, 0x75, + 0x14, 0x53, 0x3a, 0x50, 0x8d, 0x90, 0xf2, 0xbe, 0x35, 0x42, 0x5e, 0x82, 0x91, 0x38, 0xde, 0x58, + 0x8e, 0xdc, 0x2d, 0x27, 0x21, 0xd7, 0xc8, 0x8e, 0xb0, 0xb2, 0x74, 0x5e, 0xff, 0xca, 0x15, 0x0d, + 0xc4, 0x69, 0x5c, 0x34, 0x07, 0xa7, 0x74, 0xa5, 0x0e, 0x12, 0x25, 0x2c, 0xba, 0x9f, 0xcf, 0x04, + 0x95, 0xc4, 0xab, 0x6b, 0x7b, 0x08, 0x04, 0xdc, 0xfd, 0x0c, 0x95, 0x6f, 0xa9, 0x46, 0xda, 0x91, + 0x81, 0xb4, 0x7c, 0x4b, 0xd1, 0xa1, 0x7d, 0xe9, 0x7a, 0x02, 0x2d, 0xc2, 0x69, 0x3e, 0x31, 0xa6, + 0xc2, 0xd0, 0x78, 0xa3, 0xc1, 0x74, 0x1d, 0xc3, 0xb9, 0x6e, 0x14, 0x9c, 0xf7, 0x1c, 0x7a, 0x01, + 0x86, 0x54, 0xf3, 0xfc, 0xac, 0x38, 0x45, 0x50, 0x5e, 0x0c, 0x45, 0x66, 0xbe, 0x89, 0x4d, 0x3c, + 0xf4, 0x21, 0x78, 0x54, 0xff, 0xe5, 0x29, 0x60, 0xfc, 0x68, 0x6d, 0x56, 0x14, 0x41, 0x52, 0x57, + 0x7b, 0xcc, 0xe5, 0xa2, 0x35, 0x71, 0xaf, 0xe7, 0xd1, 0x1a, 0x9c, 0x57, 0xa0, 0x4b, 0x7e, 0xc2, + 0xf2, 0x39, 0x62, 0x32, 0xed, 0xc4, 0xe4, 0x46, 0xe4, 0xb1, 0xb2, 0x49, 0x75, 0x7d, 0xeb, 0xe2, + 0x9c, 0x9b, 0x5c, 0xc9, 0xc3, 0xc4, 0x0b, 0x78, 0x0f, 0x2a, 0x68, 0x12, 0xea, 0xc4, 0x77, 0xd6, + 0x3c, 0xb2, 0x34, 0x33, 0xcf, 0x8a, 0x29, 0x19, 0x27, 0x79, 0x97, 0x24, 0x00, 0x6b, 0x1c, 0x15, + 0x61, 0x3a, 0xdc, 0xf3, 0x06, 0xd0, 0x65, 0x38, 0xd3, 0x6a, 0x84, 0xd4, 0xf6, 0x70, 0x1b, 0x64, + 0xaa, 0xc1, 0x02, 0xea, 0xe8, 0x87, 0xe1, 0x05, 0x26, 0x55, 0xf8, 0xf4, 0xdc, 0xcc, 0x72, 0x17, + 0x0e, 0xce, 0x7d, 0x92, 0x05, 0x5e, 0x46, 0xc1, 0xf6, 0xce, 0xd8, 0xe9, 0x4c, 0xe0, 0x25, 0x6d, + 0xc4, 0x1c, 0x86, 0xae, 0x02, 0x62, 0xb1, 0xf8, 0x57, 0x92, 0x24, 0x54, 0xc6, 0xce, 0xd8, 0x19, + 0xf6, 0x4a, 0x2a, 0x8c, 0xec, 0x72, 0x17, 0x06, 0xce, 0x79, 0xca, 0xfe, 0x0f, 0x16, 0x8c, 0xa8, + 0xf5, 0x7a, 0x1f, 0xb2, 0x51, 0xbc, 0x74, 0x36, 0xca, 0xdc, 0xd1, 0x25, 0x1e, 0xeb, 0x79, 0x8f, + 0x90, 0xe6, 0x9f, 0x1e, 0x02, 0xd0, 0x52, 0x51, 0x29, 0x24, 0xab, 0xa7, 0x42, 0x7a, 0x68, 0x25, + 0x52, 0x5e, 0xe5, 0x94, 0xea, 0x83, 0xad, 0x9c, 0xb2, 0x02, 0x67, 0xa5, 0xb9, 0xc0, 0xcf, 0x8a, + 0xae, 0x04, 0xb1, 0x12, 0x70, 0xb5, 0xe9, 0xc7, 0x05, 0xa1, 0xb3, 0xf3, 0x79, 0x48, 0x38, 0xff, + 0xd9, 0x94, 0x95, 0x32, 0xb8, 0x9f, 0x95, 0xa2, 0xd7, 0xf4, 0xc2, 0xba, 0xbc, 0xc3, 0x23, 0xb3, + 0xa6, 0x17, 0x2e, 0xaf, 0x60, 0x8d, 0x93, 0x2f, 0xd8, 0xeb, 0x05, 0x09, 0x76, 0x38, 0xb0, 0x60, + 0x97, 0x22, 0x66, 0xa8, 0xa7, 0x88, 0x91, 0x3e, 0xe9, 0xe1, 0x9e, 0x3e, 0xe9, 0xf7, 0xc3, 0xa8, + 0xeb, 0x6f, 0x90, 0xc8, 0x4d, 0x48, 0x93, 0xad, 0x05, 0x26, 0x7e, 0x6a, 0x5a, 0xad, 0xcf, 0xa7, + 0xa0, 0x38, 0x83, 0x9d, 0x96, 0x8b, 0xa3, 0x7d, 0xc8, 0xc5, 0x1e, 0xda, 0xe8, 0x44, 0x31, 0xda, + 0xe8, 0xe4, 0xd1, 0xb5, 0xd1, 0xa9, 0x63, 0xd5, 0x46, 0xa8, 0x10, 0x6d, 0xd4, 0x97, 0xa0, 0x37, + 0xb6, 0x7f, 0x67, 0xf6, 0xd9, 0xfe, 0xf5, 0x52, 0x45, 0x67, 0x0f, 0xad, 0x8a, 0xf2, 0xb5, 0xcc, + 0x23, 0x87, 0xd2, 0x32, 0x9f, 0x2d, 0xc1, 0x59, 0x2d, 0x87, 0xe9, 0xec, 0x77, 0xd7, 0xa9, 0x24, + 0x62, 0xd7, 0x40, 0xf1, 0x73, 0x1b, 0x23, 0x39, 0x4a, 0xe7, 0x59, 0x29, 0x08, 0x36, 0xb0, 0x58, + 0x8e, 0x11, 0x89, 0x58, 0x19, 0xdd, 0xac, 0x90, 0x9e, 0x11, 0xed, 0x58, 0x61, 0xd0, 0xf9, 0x45, + 0x7f, 0x8b, 0xbc, 0xcd, 0x6c, 0xb1, 0xb8, 0x19, 0x0d, 0xc2, 0x26, 0x1e, 0x7a, 0x9a, 0x33, 0x61, + 0x02, 0x82, 0x0a, 0xea, 0x61, 0x71, 0x2f, 0xac, 0x94, 0x09, 0x0a, 0x2a, 0xbb, 0xc3, 0x92, 0xc9, + 0xaa, 0xdd, 0xdd, 0x61, 0x21, 0x50, 0x0a, 0xc3, 0xfe, 0x1f, 0x16, 0x9c, 0xcb, 0x1d, 0x8a, 0xfb, + 0xa0, 0x7c, 0xb7, 0xd3, 0xca, 0x77, 0xa5, 0xa8, 0xed, 0x86, 0xf1, 0x16, 0x3d, 0x14, 0xf1, 0xbf, + 0xb3, 0x60, 0x54, 0xe3, 0xdf, 0x87, 0x57, 0x75, 0xd3, 0xaf, 0x5a, 0xdc, 0xce, 0xaa, 0xde, 0xf5, + 0x6e, 0xbf, 0x53, 0x02, 0x55, 0xc0, 0x71, 0xaa, 0x21, 0xcb, 0xe3, 0xee, 0x73, 0x92, 0xb8, 0x03, + 0x03, 0xec, 0x20, 0x34, 0x2e, 0x26, 0xc8, 0x23, 0xcd, 0x9f, 0x1d, 0xaa, 0xea, 0x43, 0x66, 0xf6, + 0x37, 0xc6, 0x82, 0x21, 0x2b, 0xf2, 0xec, 0xc6, 0x54, 0x9a, 0x37, 0x45, 0x5a, 0x96, 0x2e, 0xf2, + 0x2c, 0xda, 0xb1, 0xc2, 0xa0, 0xea, 0xc1, 0x6d, 0x04, 0xfe, 0x8c, 0xe7, 0xc4, 0xf2, 0xee, 0x43, + 0xa5, 0x1e, 0xe6, 0x25, 0x00, 0x6b, 0x1c, 0x76, 0x46, 0xea, 0xc6, 0xa1, 0xe7, 0xec, 0x18, 0xfb, + 0x67, 0xa3, 0x3e, 0x81, 0x02, 0x61, 0x13, 0xcf, 0x6e, 0xc3, 0x58, 0xfa, 0x25, 0x66, 0xc9, 0x3a, + 0x0b, 0x50, 0xec, 0x6b, 0x38, 0x27, 0xa1, 0xee, 0xb0, 0xa7, 0x16, 0x3a, 0x4e, 0xf6, 0xca, 0xf2, + 0x29, 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x55, 0x0b, 0x4e, 0xe7, 0x0c, 0x5a, 0x81, 0x69, 0x6f, 0x89, + 0x96, 0x36, 0x79, 0x8a, 0xfd, 0x87, 0x60, 0xb0, 0x49, 0xd6, 0x1d, 0x19, 0x02, 0x67, 0xc8, 0xf6, + 0x59, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0x6f, 0x16, 0x9c, 0x48, 0xf7, 0x35, 0x66, 0xa9, 0x24, 0x7c, + 0x98, 0xdc, 0xb8, 0x11, 0x6c, 0x91, 0x68, 0x87, 0xbe, 0xb9, 0x95, 0x49, 0x25, 0xe9, 0xc2, 0xc0, + 0x39, 0x4f, 0xb1, 0xf2, 0xad, 0x4d, 0x35, 0xda, 0x72, 0x46, 0xde, 0x2c, 0x72, 0x46, 0xea, 0x8f, + 0x69, 0x1e, 0x97, 0x2b, 0x96, 0xd8, 0xe4, 0x6f, 0x7f, 0xa7, 0x02, 0x2a, 0x2f, 0x96, 0xc5, 0x1f, + 0x15, 0x14, 0xbd, 0x75, 0xd0, 0x0c, 0x22, 0x35, 0x19, 0x2a, 0x7b, 0x05, 0x04, 0x70, 0x2f, 0x89, + 0xe9, 0xba, 0x54, 0x6f, 0xb8, 0xaa, 0x41, 0xd8, 0xc4, 0xa3, 0x3d, 0xf1, 0xdc, 0x2d, 0xc2, 0x1f, + 0x1a, 0x48, 0xf7, 0x64, 0x41, 0x02, 0xb0, 0xc6, 0xa1, 0x3d, 0x69, 0xba, 0xeb, 0xeb, 0x62, 0xcb, + 0xaf, 0x7a, 0x42, 0x47, 0x07, 0x33, 0x08, 0xaf, 0xc8, 0x1d, 0x6c, 0x0a, 0x2b, 0xd8, 0xa8, 0xc8, + 0x1d, 0x6c, 0x62, 0x06, 0xa1, 0x76, 0x9b, 0x1f, 0x44, 0x6d, 0x76, 0xa5, 0x7c, 0x53, 0x71, 0x11, + 0xd6, 0xaf, 0xb2, 0xdb, 0xae, 0x77, 0xa3, 0xe0, 0xbc, 0xe7, 0xe8, 0x0c, 0x0c, 0x23, 0xd2, 0x74, + 0x1b, 0x89, 0x49, 0x0d, 0xd2, 0x33, 0x70, 0xb9, 0x0b, 0x03, 0xe7, 0x3c, 0x85, 0xa6, 0xe0, 0x84, + 0xcc, 0x6b, 0x96, 0x55, 0x6b, 0x86, 0xd2, 0x55, 0x32, 0x70, 0x1a, 0x8c, 0xb3, 0xf8, 0x54, 0xaa, + 0xb5, 0x45, 0xc1, 0x2a, 0x66, 0x2c, 0x1b, 0x52, 0x4d, 0x16, 0xb2, 0xc2, 0x0a, 0xc3, 0xfe, 0x54, + 0x99, 0x6a, 0xe1, 0x1e, 0x85, 0xda, 0xee, 0x5b, 0xb4, 0x60, 0x7a, 0x46, 0x56, 0xfa, 0x98, 0x91, + 0xcf, 0xc3, 0xf0, 0xed, 0x38, 0xf0, 0x55, 0x24, 0x5e, 0xb5, 0x67, 0x24, 0x9e, 0x81, 0x95, 0x1f, + 0x89, 0x37, 0x50, 0x54, 0x24, 0xde, 0xe0, 0x21, 0x23, 0xf1, 0xbe, 0x55, 0x05, 0x75, 0x35, 0xc8, + 0x75, 0x92, 0xdc, 0x09, 0xa2, 0x4d, 0xd7, 0x6f, 0xb1, 0x7c, 0xf0, 0xaf, 0x59, 0x30, 0xcc, 0xd7, + 0xcb, 0x82, 0x99, 0x49, 0xb5, 0x5e, 0xd0, 0x9d, 0x13, 0x29, 0x66, 0x13, 0xab, 0x06, 0xa3, 0xcc, + 0xd5, 0x9b, 0x26, 0x08, 0xa7, 0x7a, 0x84, 0x3e, 0x0e, 0x20, 0xfd, 0xa3, 0xeb, 0x52, 0x64, 0xce, + 0x17, 0xd3, 0x3f, 0x4c, 0xd6, 0xb5, 0x0d, 0xbc, 0xaa, 0x98, 0x60, 0x83, 0x21, 0xfa, 0xac, 0xce, + 0x32, 0xe3, 0x21, 0xfb, 0x1f, 0x3d, 0x96, 0xb1, 0xe9, 0x27, 0xc7, 0x0c, 0xc3, 0xa0, 0xeb, 0xb7, + 0xe8, 0x3c, 0x11, 0x11, 0x4b, 0xef, 0xca, 0xab, 0xa5, 0xb0, 0x10, 0x38, 0xcd, 0x69, 0xc7, 0x73, + 0xfc, 0x06, 0x89, 0xe6, 0x39, 0xba, 0x79, 0xe1, 0x34, 0x6b, 0xc0, 0x92, 0x50, 0xd7, 0xa5, 0x2a, + 0xd5, 0x7e, 0x2e, 0x55, 0x39, 0xff, 0x01, 0x38, 0xd5, 0xf5, 0x31, 0x0f, 0x94, 0x52, 0x76, 0xf8, + 0x6c, 0x34, 0xfb, 0x9f, 0x0f, 0x68, 0xa5, 0x75, 0x3d, 0x68, 0xf2, 0xab, 0x3d, 0x22, 0xfd, 0x45, + 0x85, 0x8d, 0x5b, 0xe0, 0x14, 0x31, 0x2e, 0xad, 0x56, 0x8d, 0xd8, 0x64, 0x49, 0xe7, 0x68, 0xe8, + 0x44, 0xc4, 0x3f, 0xee, 0x39, 0xba, 0xac, 0x98, 0x60, 0x83, 0x21, 0xda, 0x48, 0xe5, 0x94, 0x5c, + 0x3e, 0x7a, 0x4e, 0x09, 0xab, 0x32, 0x95, 0x57, 0x8d, 0xff, 0x4b, 0x16, 0x8c, 0xfa, 0xa9, 0x99, + 0x5b, 0x4c, 0x18, 0x69, 0xfe, 0xaa, 0xe0, 0x37, 0x4b, 0xa5, 0xdb, 0x70, 0x86, 0x7f, 0x9e, 0x4a, + 0xab, 0x1e, 0x50, 0xa5, 0xe9, 0x3b, 0x82, 0x06, 0x7a, 0xdd, 0x11, 0x84, 0x7c, 0x75, 0x49, 0xda, + 0x60, 0xe1, 0x97, 0xa4, 0x41, 0xce, 0x05, 0x69, 0xb7, 0xa0, 0xde, 0x88, 0x88, 0x93, 0x1c, 0xf2, + 0xbe, 0x2c, 0x76, 0x40, 0x3f, 0x23, 0x09, 0x60, 0x4d, 0xcb, 0xfe, 0xdf, 0x15, 0x38, 0x29, 0x47, + 0x44, 0x86, 0xa0, 0x53, 0xfd, 0xc8, 0xf9, 0x6a, 0xe3, 0x56, 0xe9, 0xc7, 0x2b, 0x12, 0x80, 0x35, + 0x0e, 0xb5, 0xc7, 0x3a, 0x31, 0x59, 0x0a, 0x89, 0xbf, 0xe0, 0xae, 0xc5, 0xe2, 0x9c, 0x53, 0x2d, + 0x94, 0x1b, 0x1a, 0x84, 0x4d, 0x3c, 0x6a, 0x8c, 0x73, 0xbb, 0x38, 0xce, 0xa6, 0xaf, 0x08, 0x7b, + 0x1b, 0x4b, 0x38, 0xfa, 0xf9, 0xdc, 0xca, 0xb1, 0xc5, 0x24, 0x6e, 0x75, 0x45, 0xde, 0x1f, 0xf0, + 0x8a, 0xc5, 0xbf, 0x6d, 0xc1, 0x59, 0xde, 0x2a, 0x47, 0xf2, 0x46, 0xd8, 0x74, 0x12, 0x12, 0x17, + 0x53, 0xc9, 0x3d, 0xa7, 0x7f, 0xda, 0xc9, 0x9b, 0xc7, 0x16, 0xe7, 0xf7, 0x06, 0xbd, 0x69, 0xc1, + 0x89, 0xcd, 0x54, 0xcd, 0x0f, 0xa9, 0x3a, 0x8e, 0x9a, 0x8e, 0x9f, 0x22, 0xaa, 0x97, 0x5a, 0xba, + 0x3d, 0xc6, 0x59, 0xee, 0xf6, 0x9f, 0x59, 0x60, 0x8a, 0xd1, 0xfb, 0x5f, 0x2a, 0xe4, 0xe0, 0xa6, + 0xa0, 0xb4, 0x2e, 0xab, 0x3d, 0xad, 0xcb, 0xc7, 0xa1, 0xdc, 0x71, 0x9b, 0x62, 0x7f, 0xa1, 0x4f, + 0x5f, 0xe7, 0x67, 0x31, 0x6d, 0xb7, 0xff, 0x49, 0x55, 0xfb, 0x2d, 0x44, 0x5e, 0xd4, 0xf7, 0xc5, + 0x6b, 0xaf, 0xab, 0x62, 0x63, 0xfc, 0xcd, 0xaf, 0x77, 0x15, 0x1b, 0xfb, 0x91, 0x83, 0xa7, 0xbd, + 0xf1, 0x01, 0xea, 0x55, 0x6b, 0x6c, 0x70, 0x9f, 0x9c, 0xb7, 0xdb, 0x50, 0xa3, 0x5b, 0x30, 0xe6, + 0x80, 0xac, 0xa5, 0x3a, 0x55, 0xbb, 0x22, 0xda, 0xef, 0xed, 0x8e, 0xbf, 0xef, 0xe0, 0xdd, 0x92, + 0x4f, 0x63, 0x45, 0x1f, 0xc5, 0x50, 0xa7, 0xbf, 0x59, 0x7a, 0x9e, 0xd8, 0xdc, 0xdd, 0x50, 0x32, + 0x53, 0x02, 0x0a, 0xc9, 0xfd, 0xd3, 0x7c, 0x90, 0x0f, 0x75, 0x76, 0x1b, 0x2d, 0x63, 0xca, 0xf7, + 0x80, 0xcb, 0x2a, 0x49, 0x4e, 0x02, 0xee, 0xed, 0x8e, 0xbf, 0x74, 0x70, 0xa6, 0xea, 0x71, 0xac, + 0x59, 0xd8, 0x5f, 0xae, 0xe8, 0xb9, 0x2b, 0x6a, 0xcc, 0x7d, 0x5f, 0xcc, 0xdd, 0x17, 0x33, 0x73, + 0xf7, 0x42, 0xd7, 0xdc, 0x1d, 0xd5, 0xb7, 0xa6, 0xa6, 0x66, 0xe3, 0xfd, 0x36, 0x04, 0xf6, 0xf7, + 0x37, 0x30, 0x0b, 0xe8, 0xf5, 0x8e, 0x1b, 0x91, 0x78, 0x39, 0xea, 0xf8, 0xae, 0xdf, 0x62, 0xd3, + 0xb1, 0x66, 0x5a, 0x40, 0x29, 0x30, 0xce, 0xe2, 0xd3, 0x4d, 0x3d, 0xfd, 0xe6, 0xb7, 0x9c, 0x2d, + 0x3e, 0xab, 0x8c, 0xb2, 0x5b, 0x2b, 0xa2, 0x1d, 0x2b, 0x0c, 0xfb, 0x1b, 0xec, 0x2c, 0xdb, 0xc8, + 0x0b, 0xa6, 0x73, 0xc2, 0x63, 0xd7, 0xff, 0xf2, 0x9a, 0x5d, 0x6a, 0x4e, 0xf0, 0x3b, 0x7f, 0x39, + 0x0c, 0xdd, 0x81, 0xc1, 0x35, 0x7e, 0xff, 0x5d, 0x31, 0xf5, 0xc9, 0xc5, 0x65, 0x7a, 0xec, 0x96, + 0x13, 0x79, 0xb3, 0xde, 0x3d, 0xfd, 0x13, 0x4b, 0x6e, 0xf6, 0x37, 0x2b, 0x70, 0x22, 0x73, 0x41, + 0x6c, 0xaa, 0x5a, 0x6a, 0x69, 0xdf, 0x6a, 0xa9, 0x1f, 0x01, 0x68, 0x92, 0xd0, 0x0b, 0x76, 0x98, + 0x39, 0x56, 0x39, 0xb0, 0x39, 0xa6, 0x2c, 0xf8, 0x59, 0x45, 0x05, 0x1b, 0x14, 0x45, 0xa1, 0x32, + 0x5e, 0x7c, 0x35, 0x53, 0xa8, 0xcc, 0xb8, 0xc5, 0x60, 0xe0, 0xfe, 0xde, 0x62, 0xe0, 0xc2, 0x09, + 0xde, 0x45, 0x95, 0x7d, 0x7b, 0x88, 0x24, 0x5b, 0x96, 0xbf, 0x30, 0x9b, 0x26, 0x83, 0xb3, 0x74, + 0x1f, 0xe4, 0xfd, 0xcf, 0xe8, 0xdd, 0x50, 0x97, 0xdf, 0x39, 0x1e, 0xab, 0xeb, 0x0a, 0x06, 0x72, + 0x1a, 0xb0, 0x7b, 0x99, 0xc5, 0x4f, 0xfb, 0x8b, 0x25, 0x6a, 0x3d, 0xf3, 0x7f, 0xaa, 0x12, 0xcd, + 0x53, 0x30, 0xe0, 0x74, 0x92, 0x8d, 0xa0, 0xeb, 0x0e, 0xbd, 0x29, 0xd6, 0x8a, 0x05, 0x14, 0x2d, + 0x40, 0xa5, 0xa9, 0xab, 0x8b, 0x1c, 0x64, 0x14, 0xb5, 0x23, 0xd2, 0x49, 0x08, 0x66, 0x54, 0xd0, + 0x63, 0x50, 0x49, 0x9c, 0x96, 0x4c, 0x74, 0x62, 0xc9, 0xad, 0xab, 0x4e, 0x2b, 0xc6, 0xac, 0xd5, + 0x54, 0x9a, 0x95, 0x7d, 0x94, 0xe6, 0x4b, 0x30, 0x12, 0xbb, 0x2d, 0xdf, 0x49, 0x3a, 0x11, 0x31, + 0x0e, 0xd7, 0x74, 0xbc, 0x84, 0x09, 0xc4, 0x69, 0x5c, 0xfb, 0x37, 0x87, 0xe1, 0xcc, 0xca, 0xcc, + 0xa2, 0xac, 0x99, 0x7d, 0x6c, 0xb9, 0x4a, 0x79, 0x3c, 0xee, 0x5f, 0xae, 0x52, 0x0f, 0xee, 0x9e, + 0x91, 0xab, 0xe4, 0x19, 0xb9, 0x4a, 0xe9, 0xc4, 0x91, 0x72, 0x11, 0x89, 0x23, 0x79, 0x3d, 0xe8, + 0x27, 0x71, 0xe4, 0xd8, 0x92, 0x97, 0xf6, 0xec, 0xd0, 0x81, 0x92, 0x97, 0x54, 0x66, 0x57, 0x21, + 0x21, 0xfd, 0x3d, 0x3e, 0x55, 0x6e, 0x66, 0x97, 0xca, 0xaa, 0xe1, 0xe9, 0x2a, 0x42, 0xc0, 0xbe, + 0x5a, 0x7c, 0x07, 0xfa, 0xc8, 0xaa, 0x11, 0x19, 0x33, 0x66, 0x26, 0xd7, 0x60, 0x11, 0x99, 0x5c, + 0x79, 0xdd, 0xd9, 0x37, 0x93, 0xeb, 0x25, 0x18, 0x69, 0x78, 0x81, 0x4f, 0x96, 0xa3, 0x20, 0x09, + 0x1a, 0x81, 0x27, 0x8c, 0x69, 0x25, 0x12, 0x66, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, 0x4a, 0x03, 0xab, + 0x1f, 0x35, 0x0d, 0x0c, 0x1e, 0x50, 0x1a, 0xd8, 0xcf, 0xe8, 0x84, 0xe5, 0x21, 0xf6, 0x45, 0x3e, + 0x52, 0xfc, 0x17, 0xe9, 0x27, 0x6b, 0x19, 0xbd, 0xc5, 0x2f, 0xb1, 0xa3, 0xe6, 0xe8, 0x4c, 0xd0, + 0xa6, 0xe6, 0xd6, 0x30, 0x1b, 0x92, 0xd7, 0x8e, 0x61, 0xc2, 0xde, 0x5a, 0xd1, 0x6c, 0xd4, 0xc5, + 0x76, 0xba, 0x09, 0xa7, 0x3b, 0x72, 0x94, 0x84, 0xea, 0xaf, 0x96, 0xe0, 0x07, 0xf6, 0xed, 0x02, + 0xba, 0x03, 0x90, 0x38, 0x2d, 0x31, 0x51, 0xc5, 0x31, 0xc5, 0x11, 0x83, 0x1a, 0x57, 0x25, 0x3d, + 0x5e, 0x09, 0x44, 0xfd, 0x65, 0x07, 0x00, 0xf2, 0x37, 0x8b, 0x65, 0x0c, 0xbc, 0xae, 0x82, 0x89, + 0x38, 0xf0, 0x08, 0x66, 0x10, 0xaa, 0xfe, 0x23, 0xd2, 0xd2, 0xb7, 0x2e, 0xab, 0xcf, 0x87, 0x59, + 0x2b, 0x16, 0x50, 0xf4, 0x02, 0x0c, 0x39, 0x9e, 0xc7, 0xb3, 0x52, 0x48, 0x2c, 0x6e, 0xb1, 0xd1, + 0x95, 0xdb, 0x34, 0x08, 0x9b, 0x78, 0xf6, 0x9f, 0x96, 0x60, 0x7c, 0x1f, 0x99, 0xd2, 0x95, 0x67, + 0x57, 0xed, 0x3b, 0xcf, 0x4e, 0x64, 0x06, 0x0c, 0xf4, 0xc8, 0x0c, 0x78, 0x01, 0x86, 0x12, 0xe2, + 0xb4, 0x45, 0x18, 0x94, 0xd8, 0x7f, 0xeb, 0x73, 0x57, 0x0d, 0xc2, 0x26, 0x1e, 0x95, 0x62, 0xa3, + 0x4e, 0xa3, 0x41, 0xe2, 0x58, 0x86, 0xfe, 0x0b, 0x1f, 0x66, 0x61, 0x79, 0x05, 0xcc, 0x35, 0x3c, + 0x95, 0x62, 0x81, 0x33, 0x2c, 0xb3, 0x03, 0x5e, 0xef, 0x73, 0xc0, 0xbf, 0x5e, 0x82, 0xc7, 0xf7, + 0xd4, 0x6e, 0x7d, 0x67, 0x65, 0x74, 0x62, 0x12, 0x65, 0x27, 0xce, 0x8d, 0x98, 0x44, 0x98, 0x41, + 0xf8, 0x28, 0x85, 0xa1, 0x71, 0xab, 0x75, 0xd1, 0x29, 0x43, 0x7c, 0x94, 0x52, 0x2c, 0x70, 0x86, + 0xe5, 0x61, 0xa7, 0xe5, 0xdf, 0x2b, 0xc1, 0x93, 0x7d, 0xd8, 0x00, 0x05, 0xa6, 0x56, 0xa5, 0x13, + 0xdc, 0xca, 0x0f, 0x28, 0x0f, 0xf1, 0x90, 0xc3, 0xf5, 0x8d, 0x12, 0x9c, 0xef, 0xad, 0x8a, 0xd1, + 0x8f, 0xd2, 0x3d, 0xbc, 0x8c, 0x7d, 0x32, 0x73, 0xe3, 0x4e, 0xf3, 0xfd, 0x7b, 0x0a, 0x84, 0xb3, + 0xb8, 0x68, 0x02, 0x20, 0x74, 0x92, 0x8d, 0xf8, 0xd2, 0xb6, 0x1b, 0x27, 0xa2, 0xf6, 0xcb, 0x28, + 0x3f, 0x31, 0x92, 0xad, 0xd8, 0xc0, 0xa0, 0xec, 0xd8, 0xbf, 0xd9, 0xe0, 0x7a, 0x90, 0xf0, 0x87, + 0xf8, 0x36, 0xe2, 0xb4, 0xbc, 0x29, 0xc3, 0x00, 0xe1, 0x2c, 0x2e, 0x65, 0xc7, 0xce, 0x24, 0x79, + 0x47, 0xf9, 0xfe, 0x82, 0xb1, 0x5b, 0x50, 0xad, 0xd8, 0xc0, 0xc8, 0x66, 0xfd, 0x55, 0xf7, 0xcf, + 0xfa, 0xb3, 0xff, 0x71, 0x09, 0xce, 0xf5, 0x34, 0xe5, 0xfa, 0x5b, 0x80, 0x0f, 0x5f, 0xa6, 0xde, + 0xe1, 0xe6, 0xce, 0x01, 0x33, 0xca, 0xfe, 0xa8, 0xc7, 0x4c, 0x13, 0x19, 0x65, 0x87, 0x4f, 0xc9, + 0x7e, 0xf8, 0xc6, 0xb3, 0x2b, 0x89, 0xac, 0x72, 0x80, 0x24, 0xb2, 0xcc, 0xc7, 0xa8, 0xf6, 0xb9, + 0x90, 0xff, 0xbc, 0xdc, 0x73, 0x78, 0xe9, 0xd6, 0xaf, 0x2f, 0xef, 0xe8, 0x2c, 0x9c, 0x74, 0x7d, + 0x76, 0x6b, 0xd2, 0x4a, 0x67, 0x4d, 0x94, 0x03, 0x29, 0xa5, 0xef, 0x2c, 0x9f, 0xcf, 0xc0, 0x71, + 0xd7, 0x13, 0x0f, 0x61, 0x52, 0xdf, 0xe1, 0x86, 0xf4, 0x60, 0x69, 0xa5, 0x68, 0x09, 0xce, 0xca, + 0xa1, 0xd8, 0x70, 0x22, 0xd2, 0x14, 0x6a, 0x24, 0x16, 0x69, 0x0c, 0xe7, 0x78, 0x2a, 0x44, 0x0e, + 0x02, 0xce, 0x7f, 0x8e, 0x5d, 0x54, 0x13, 0x84, 0x6e, 0x43, 0x6c, 0x72, 0xf4, 0x45, 0x35, 0xb4, + 0x11, 0x73, 0x98, 0xfd, 0x11, 0xa8, 0xab, 0xf7, 0xe7, 0xc1, 0xd4, 0x6a, 0xd2, 0x75, 0x05, 0x53, + 0xab, 0x19, 0x67, 0x60, 0xd1, 0xaf, 0x45, 0x4d, 0xe2, 0xcc, 0xea, 0xb9, 0x46, 0x76, 0x98, 0x7d, + 0x6c, 0xbf, 0x07, 0x86, 0x95, 0x9f, 0xa5, 0xdf, 0xeb, 0x7b, 0xec, 0x2f, 0x0f, 0xc0, 0x48, 0xaa, + 0x24, 0x5f, 0xca, 0xad, 0x69, 0xed, 0xeb, 0xd6, 0x64, 0xc1, 0xf1, 0x1d, 0x5f, 0xde, 0xed, 0x65, + 0x04, 0xc7, 0x77, 0x7c, 0x82, 0x39, 0x8c, 0x9a, 0xb7, 0xcd, 0x68, 0x07, 0x77, 0x7c, 0x11, 0xc4, + 0xaa, 0xcc, 0xdb, 0x59, 0xd6, 0x8a, 0x05, 0x14, 0x7d, 0xd2, 0x82, 0xe1, 0x98, 0xf9, 0xcc, 0xb9, + 0x53, 0x58, 0x4c, 0xba, 0xab, 0x47, 0xaf, 0x38, 0xa8, 0xca, 0x4f, 0xb2, 0xb8, 0x14, 0xb3, 0x05, + 0xa7, 0x38, 0xa2, 0xcf, 0x58, 0x50, 0x57, 0x57, 0x90, 0x88, 0x0b, 0xf8, 0x56, 0x8a, 0xad, 0x78, + 0xc8, 0xbd, 0x89, 0xea, 0xf8, 0x41, 0x95, 0x9e, 0xc3, 0x9a, 0x31, 0x8a, 0x95, 0xc7, 0x76, 0xf0, + 0x78, 0x3c, 0xb6, 0x90, 0xe3, 0xad, 0x7d, 0x37, 0xd4, 0xdb, 0x8e, 0xef, 0xae, 0x93, 0x38, 0xe1, + 0x4e, 0x54, 0x59, 0x88, 0x55, 0x36, 0x62, 0x0d, 0xa7, 0x0a, 0x39, 0x66, 0x2f, 0x96, 0x18, 0x5e, + 0x4f, 0xa6, 0x90, 0x57, 0x74, 0x33, 0x36, 0x71, 0x4c, 0x17, 0x2d, 0x3c, 0x50, 0x17, 0xed, 0xd0, + 0x3e, 0x2e, 0xda, 0x7f, 0x60, 0xc1, 0xd9, 0xdc, 0xaf, 0xf6, 0xf0, 0x86, 0x1b, 0xda, 0x5f, 0xa9, + 0xc2, 0xe9, 0x9c, 0xda, 0x9a, 0x68, 0xc7, 0x9c, 0xcf, 0x56, 0x11, 0x27, 0xf7, 0xe9, 0x83, 0x68, + 0x39, 0x8c, 0x39, 0x93, 0xf8, 0x60, 0x07, 0x24, 0xfa, 0x90, 0xa2, 0x7c, 0x7f, 0x0f, 0x29, 0x8c, + 0x69, 0x59, 0x79, 0xa0, 0xd3, 0xb2, 0xba, 0xf7, 0xb4, 0x44, 0xbf, 0x66, 0xc1, 0x58, 0xbb, 0x47, + 0x41, 0x77, 0xe1, 0x78, 0xbc, 0x79, 0x3c, 0xe5, 0xe2, 0xa7, 0x1f, 0xbb, 0xbb, 0x3b, 0xde, 0xb3, + 0x8e, 0x3e, 0xee, 0xd9, 0x2b, 0xfb, 0x3b, 0x65, 0x60, 0x85, 0x5d, 0x59, 0xfd, 0xb4, 0x1d, 0xf4, + 0x09, 0xb3, 0x44, 0xaf, 0x55, 0x54, 0x39, 0x59, 0x4e, 0x5c, 0x95, 0xf8, 0xe5, 0x23, 0x98, 0x57, + 0xf1, 0x37, 0x2b, 0xb4, 0x4a, 0x7d, 0x08, 0x2d, 0x4f, 0xd6, 0x42, 0x2e, 0x17, 0x5f, 0x0b, 0xb9, + 0x9e, 0xad, 0x83, 0xbc, 0xf7, 0x27, 0xae, 0x3c, 0x94, 0x9f, 0xf8, 0x6f, 0x5a, 0x5c, 0xf0, 0x64, + 0xbe, 0x82, 0xb6, 0x0c, 0xac, 0x3d, 0x2c, 0x83, 0x67, 0xa0, 0x16, 0x13, 0x6f, 0xfd, 0x0a, 0x71, + 0x3c, 0x61, 0x41, 0xe8, 0x53, 0x63, 0xd1, 0x8e, 0x15, 0x06, 0xbb, 0x2c, 0xd5, 0xf3, 0x82, 0x3b, + 0x97, 0xda, 0x61, 0xb2, 0x23, 0x6c, 0x09, 0x7d, 0x59, 0xaa, 0x82, 0x60, 0x03, 0xcb, 0xfe, 0x5b, + 0x25, 0x3e, 0x03, 0x45, 0xe8, 0xc1, 0x8b, 0x99, 0xeb, 0xed, 0xfa, 0x3f, 0xb5, 0xff, 0x18, 0x40, + 0x43, 0x5d, 0x0c, 0x2f, 0xce, 0x84, 0xae, 0x1c, 0xf9, 0xd6, 0x6a, 0x41, 0x4f, 0xbf, 0x86, 0x6e, + 0xc3, 0x06, 0xbf, 0x94, 0x2c, 0x2d, 0xef, 0x2b, 0x4b, 0x53, 0x62, 0xa5, 0xb2, 0x8f, 0xb6, 0xfb, + 0x53, 0x0b, 0x52, 0x16, 0x11, 0x0a, 0xa1, 0x4a, 0xbb, 0xbb, 0x53, 0xcc, 0x9d, 0xf7, 0x26, 0x69, + 0x2a, 0x1a, 0xc5, 0xb4, 0x67, 0x3f, 0x31, 0x67, 0x84, 0x3c, 0x11, 0xa1, 0xc0, 0x47, 0xf5, 0x7a, + 0x71, 0x0c, 0xaf, 0x04, 0xc1, 0x26, 0x3f, 0xd8, 0xd4, 0xd1, 0x0e, 0xf6, 0x8b, 0x70, 0xaa, 0xab, + 0x53, 0xec, 0x26, 0xab, 0x40, 0x5e, 0xf4, 0x6f, 0x4c, 0x57, 0x96, 0x36, 0x89, 0x39, 0xcc, 0xfe, + 0x86, 0x05, 0x27, 0xb3, 0xe4, 0xd1, 0x5b, 0x16, 0x9c, 0x8a, 0xb3, 0xf4, 0x8e, 0x6b, 0xec, 0x54, + 0x94, 0x61, 0x17, 0x08, 0x77, 0x77, 0xc2, 0xfe, 0x3f, 0x62, 0xf2, 0xdf, 0x72, 0xfd, 0x66, 0x70, + 0x47, 0x19, 0x26, 0x56, 0x4f, 0xc3, 0x84, 0xae, 0xc7, 0xc6, 0x06, 0x69, 0x76, 0xbc, 0xae, 0x7c, + 0xcd, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0x4b, 0x4f, 0xeb, 0x88, 0x62, 0xe9, 0x99, 0x49, 0x39, 0x2b, + 0xda, 0xb1, 0xc2, 0x40, 0xcf, 0xc3, 0xb0, 0xf1, 0x92, 0x72, 0x5e, 0x32, 0x83, 0xdc, 0x50, 0x99, + 0x31, 0x4e, 0x61, 0xa1, 0x09, 0x00, 0x65, 0xe4, 0x48, 0x15, 0xc9, 0x1c, 0x45, 0x4a, 0x12, 0xc5, + 0xd8, 0xc0, 0x60, 0xc9, 0xa0, 0x5e, 0x27, 0x66, 0x3e, 0xfe, 0x01, 0x5d, 0xc0, 0x73, 0x46, 0xb4, + 0x61, 0x05, 0xa5, 0xd2, 0xa4, 0xed, 0xf8, 0x1d, 0xc7, 0xa3, 0x23, 0x24, 0xb6, 0x7e, 0x6a, 0x19, + 0x2e, 0x2a, 0x08, 0x36, 0xb0, 0xe8, 0x1b, 0x27, 0x6e, 0x9b, 0xbc, 0x12, 0xf8, 0x32, 0x3a, 0x4c, + 0x1f, 0xfb, 0x88, 0x76, 0xac, 0x30, 0xec, 0xff, 0x62, 0xc1, 0x09, 0x9d, 0x5a, 0xce, 0xef, 0xac, + 0x36, 0x77, 0xaa, 0xd6, 0xbe, 0x3b, 0xd5, 0x74, 0xce, 0x6d, 0xa9, 0xaf, 0x9c, 0x5b, 0x33, 0x1d, + 0xb6, 0xbc, 0x67, 0x3a, 0xec, 0x0f, 0xea, 0xfb, 0x50, 0x79, 0xde, 0xec, 0x50, 0xde, 0x5d, 0xa8, + 0xc8, 0x86, 0x81, 0x86, 0xa3, 0xea, 0xaa, 0x0c, 0xf3, 0xbd, 0xc3, 0xcc, 0x14, 0x43, 0x12, 0x10, + 0x7b, 0x09, 0xea, 0xea, 0xf4, 0x43, 0x6e, 0x54, 0xad, 0xfc, 0x8d, 0x6a, 0x5f, 0x69, 0x79, 0xd3, + 0x6b, 0xdf, 0xfc, 0xee, 0x13, 0xef, 0xf8, 0xbd, 0xef, 0x3e, 0xf1, 0x8e, 0x3f, 0xfc, 0xee, 0x13, + 0xef, 0xf8, 0xe4, 0xdd, 0x27, 0xac, 0x6f, 0xde, 0x7d, 0xc2, 0xfa, 0xbd, 0xbb, 0x4f, 0x58, 0x7f, + 0x78, 0xf7, 0x09, 0xeb, 0x3b, 0x77, 0x9f, 0xb0, 0xbe, 0xf4, 0x9f, 0x9e, 0x78, 0xc7, 0x2b, 0xb9, + 0xe1, 0x81, 0xf4, 0xc7, 0xb3, 0x8d, 0xe6, 0xe4, 0xd6, 0x45, 0x16, 0xa1, 0x46, 0x97, 0xd7, 0xa4, + 0x31, 0xa7, 0x26, 0xe5, 0xf2, 0xfa, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa7, 0x24, 0x1a, 0xa3, + 0x6c, 0xe0, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -7246,6 +7247,15 @@ func (m *ApplicationSourceKustomize) MarshalToSizedBuffer(dAtA []byte) (int, err _ = i var l int _ = l + if len(m.Components) > 0 { + for iNdEx := len(m.Components) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Components[iNdEx]) + copy(dAtA[i:], m.Components[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Components[iNdEx]))) + i-- + dAtA[i] = 0x6a + } + } if len(m.Patches) > 0 { for iNdEx := len(m.Patches) - 1; iNdEx >= 0; iNdEx-- { { @@ -15146,6 +15156,12 @@ func (m *ApplicationSourceKustomize) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if len(m.Components) > 0 { + for _, s := range m.Components { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -18355,6 +18371,7 @@ func (this *ApplicationSourceKustomize) String() string { `CommonAnnotationsEnvsubst:` + fmt.Sprintf("%v", this.CommonAnnotationsEnvsubst) + `,`, `Replicas:` + repeatedStringForReplicas + `,`, `Patches:` + repeatedStringForPatches + `,`, + `Components:` + fmt.Sprintf("%v", this.Components) + `,`, `}`, }, "") return s @@ -27183,6 +27200,38 @@ func (m *ApplicationSourceKustomize) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Components", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Components = append(m.Components, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index a0e6782be69f9..ac1415786d032 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -521,6 +521,9 @@ message ApplicationSourceKustomize { // Patches is a list of Kustomize patches repeated KustomizePatch patches = 12; + + // Components specifies a list of kustomize components to add to the kustomization before building + repeated string components = 13; } // ApplicationSourcePlugin holds options specific to config management plugins diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 561b361d13d43..5dff99db45d12 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -1957,6 +1957,21 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSourceKustomize(ref common. }, }, }, + "components": { + SchemaProps: spec.SchemaProps{ + Description: "Components specifies a list of kustomize components to add to the kustomization before building", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, }, }, }, diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index e18fcd1cdf057..1957ec59a341e 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -467,6 +467,8 @@ type ApplicationSourceKustomize struct { Replicas KustomizeReplicas `json:"replicas,omitempty" protobuf:"bytes,11,opt,name=replicas"` // Patches is a list of Kustomize patches Patches KustomizePatches `json:"patches,omitempty" protobuf:"bytes,12,opt,name=patches"` + // Components specifies a list of kustomize components to add to the kustomization before building + Components []string `json:"components,omitempty" protobuf:"bytes,13,rep,name=components"` } type KustomizeReplica struct { @@ -556,7 +558,8 @@ func (k *ApplicationSourceKustomize) AllowsConcurrentProcessing() bool { k.NamePrefix == "" && k.Namespace == "" && k.NameSuffix == "" && - len(k.Patches) == 0 + len(k.Patches) == 0 && + len(k.Components) == 0 } // IsZero returns true when the Kustomize options are considered empty @@ -570,7 +573,8 @@ func (k *ApplicationSourceKustomize) IsZero() bool { len(k.Replicas) == 0 && len(k.CommonLabels) == 0 && len(k.CommonAnnotations) == 0 && - len(k.Patches) == 0 + len(k.Patches) == 0 && + len(k.Components) == 0 } // MergeImage merges a new Kustomize image identifier in to a list of images diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 8732d2f484996..48e7e601670be 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -1103,6 +1103,11 @@ func (in *ApplicationSourceKustomize) DeepCopyInto(out *ApplicationSourceKustomi (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make([]string, len(*in)) + copy(*out, *in) + } return } diff --git a/util/kustomize/kustomize.go b/util/kustomize/kustomize.go index b18fcf6c43e93..2487b14b4903b 100644 --- a/util/kustomize/kustomize.go +++ b/util/kustomize/kustomize.go @@ -87,6 +87,40 @@ func mapToEditAddArgs(val map[string]string) []string { func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOptions *v1alpha1.KustomizeOptions, envVars *v1alpha1.Env) ([]*unstructured.Unstructured, []Image, error) { + env := os.Environ() + if envVars != nil { + env = append(env, envVars.Environ()...) + } + + closer, environ, err := k.creds.Environ() + if err != nil { + return nil, nil, err + } + defer func() { _ = closer.Close() }() + + // If we were passed a HTTPS URL, make sure that we also check whether there + // is a custom CA bundle configured for connecting to the server. + if k.repo != "" && git.IsHTTPSURL(k.repo) { + parsedURL, err := url.Parse(k.repo) + if err != nil { + log.Warnf("Could not parse URL %s: %v", k.repo, err) + } else { + caPath, err := certutil.GetCertBundlePathForRepository(parsedURL.Host) + if err != nil { + // Some error while getting CA bundle + log.Warnf("Could not get CA bundle path for %s: %v", parsedURL.Host, err) + } else if caPath == "" { + // No cert configured + log.Debugf("No caCert found for repo %s", parsedURL.Host) + } else { + // Make Git use CA bundle + environ = append(environ, fmt.Sprintf("GIT_SSL_CAINFO=%s", caPath)) + } + } + } + + env = append(env, environ...) + if opts != nil { if opts.NamePrefix != "" { cmd := exec.Command(k.getBinaryPath(), "edit", "set", "nameprefix", "--", opts.NamePrefix) @@ -238,6 +272,25 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp return nil, nil, fmt.Errorf("failed to write kustomization.yaml with updated 'patches' field: %w", err) } } + + if len(opts.Components) > 0 { + // components only supported in kustomize >= v3.7.0 + // https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md + if getSemverSafe().LessThan(semver.MustParse("v3.7.0")) { + return nil, nil, fmt.Errorf("kustomize components require kustomize v3.7.0 and above") + } + + // add components + args := []string{"edit", "add", "component"} + args = append(args, opts.Components...) + cmd := exec.Command(k.getBinaryPath(), args...) + cmd.Dir = k.path + cmd.Env = env + _, err := executil.Run(cmd) + if err != nil { + return nil, nil, err + } + } } var cmd *exec.Cmd @@ -247,40 +300,7 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp } else { cmd = exec.Command(k.getBinaryPath(), "build", k.path) } - - env := os.Environ() - if envVars != nil { - env = append(env, envVars.Environ()...) - } cmd.Env = env - closer, environ, err := k.creds.Environ() - if err != nil { - return nil, nil, err - } - defer func() { _ = closer.Close() }() - - // If we were passed a HTTPS URL, make sure that we also check whether there - // is a custom CA bundle configured for connecting to the server. - if k.repo != "" && git.IsHTTPSURL(k.repo) { - parsedURL, err := url.Parse(k.repo) - if err != nil { - log.Warnf("Could not parse URL %s: %v", k.repo, err) - } else { - caPath, err := certutil.GetCertBundlePathForRepository(parsedURL.Host) - if err != nil { - // Some error while getting CA bundle - log.Warnf("Could not get CA bundle path for %s: %v", parsedURL.Host, err) - } else if caPath == "" { - // No cert configured - log.Debugf("No caCert found for repo %s", parsedURL.Host) - } else { - // Make Git use CA bundle - environ = append(environ, fmt.Sprintf("GIT_SSL_CAINFO=%s", caPath)) - } - } - } - - cmd.Env = append(cmd.Env, environ...) out, err := executil.Run(cmd) if err != nil { return nil, nil, err diff --git a/util/kustomize/kustomize_test.go b/util/kustomize/kustomize_test.go index 573cb87fb602c..a6275cf01ae1b 100644 --- a/util/kustomize/kustomize_test.go +++ b/util/kustomize/kustomize_test.go @@ -23,6 +23,7 @@ const kustomization2b = "Kustomization" const kustomization3 = "force_common" const kustomization4 = "custom_version" const kustomization5 = "kustomization_yaml_patches" +const kustomization6 = "kustomization_yaml_components" func testDataDir(tb testing.TB, testData string) (string, error) { res := tb.TempDir() @@ -352,6 +353,27 @@ func TestKustomizeCustomVersion(t *testing.T) { assert.Equal(t, "ARGOCD_APP_NAME=argo-cd-tests\n", string(content)) } +func TestKustomizeBuildComponents(t *testing.T) { + appPath, err := testDataDir(t, kustomization6) + assert.Nil(t, err) + kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + + kustomizeSource := v1alpha1.ApplicationSourceKustomize{ + Components: []string{"./components"}, + } + objs, _, err := kustomize.Build(&kustomizeSource, nil, nil) + assert.Nil(t, err) + obj := objs[0] + assert.Equal(t, "nginx-deployment", obj.GetName()) + assert.Equal(t, map[string]string{ + "app": "nginx", + }, obj.GetLabels()) + replicas, ok, err := unstructured.NestedInt64(obj.Object, "spec", "replicas") + require.NoError(t, err) + require.True(t, ok) + assert.Equal(t, int64(3), replicas) +} + func TestKustomizeBuildPatches(t *testing.T) { appPath, err := testDataDir(t, kustomization5) assert.Nil(t, err) diff --git a/util/kustomize/testdata/kustomization_yaml_components/components/deployment.yaml b/util/kustomize/testdata/kustomization_yaml_components/components/deployment.yaml new file mode 100644 index 0000000000000..545961bb6094d --- /dev/null +++ b/util/kustomize/testdata/kustomization_yaml_components/components/deployment.yaml @@ -0,0 +1,21 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + labels: + app: nginx +spec: + replicas: 3 + selector: + matchLabels: + app: nginx + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.15.4 + ports: + - containerPort: 80 \ No newline at end of file diff --git a/util/kustomize/testdata/kustomization_yaml_components/components/kustomization.yaml b/util/kustomize/testdata/kustomization_yaml_components/components/kustomization.yaml new file mode 100644 index 0000000000000..4fe48f72bced8 --- /dev/null +++ b/util/kustomize/testdata/kustomization_yaml_components/components/kustomization.yaml @@ -0,0 +1,4 @@ +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +resources: + - ./deployment.yaml \ No newline at end of file diff --git a/util/kustomize/testdata/kustomization_yaml_components/kustomization.yaml b/util/kustomize/testdata/kustomization_yaml_components/kustomization.yaml new file mode 100644 index 0000000000000..c3dec961314f3 --- /dev/null +++ b/util/kustomize/testdata/kustomization_yaml_components/kustomization.yaml @@ -0,0 +1,5 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +components: + - ./components \ No newline at end of file From 4254889a0ca74b352ae42b72346d0247ce4d2472 Mon Sep 17 00:00:00 2001 From: Alex Jones <39532774+AlexMichaelJonesNC@users.noreply.github.com> Date: Tue, 7 Nov 2023 03:37:27 +0000 Subject: [PATCH 090/269] Update USERS.md (#16251) Add Fortra to Official USers Signed-off-by: Alex Jones <39532774+AlexMichaelJonesNC@users.noreply.github.com> Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 657f2b8270449..0f660ebb5f4d6 100644 --- a/USERS.md +++ b/USERS.md @@ -94,6 +94,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Flexport](https://www.flexport.com/) 1. [Flip](https://flip.id) 1. [Fonoa](https://www.fonoa.com/) +1. [Fortra](https://www.fortra.com) 1. [freee](https://corp.freee.co.jp/en/company/) 1. [Freshop, Inc](https://www.freshop.com/) 1. [Future PLC](https://www.futureplc.com/) From d4dc155a8969a19523bef95cc9741af3ea07ecb4 Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Wed, 8 Nov 2023 04:04:07 +0100 Subject: [PATCH 091/269] fix: check for double definition (#15670) * fix: check for double definition As found in #13965 (and as a follow-up to #13999), we also need to define what happens if _both_ managedNamespaceMetadata _and_ an Application manifest are both defined for the same namespace. The idea here is that if that happens, we emit an `ApplicationConditionRepeatedResourceWarning`, and set the sync status to `Unknown`, since it's unclear what is supposed to happen. The user will then have the option of removing one of the two definitions. Signed-off-by: Blake Pettersson * fix: check for double definition A simpler fix - don't add a managed namespace to the targetObjs list if a namespace already exists in the application source. Signed-off-by: Blake Pettersson * test: add test cases This adds a test case showing that an ns manifest will override `managedNamespaceMetadata` without failing horribly (as it currently does on `HEAD`), as well as a "standard" mNMd diff vs live. Signed-off-by: Blake Pettersson --------- Signed-off-by: Blake Pettersson --- controller/state_test.go | 116 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/controller/state_test.go b/controller/state_test.go index 9d2df1f239185..b08cb74f5b6e6 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -117,6 +117,122 @@ func TestCompareAppStateNamespaceMetadataDiffers(t *testing.T) { assert.Len(t, app.Status.Conditions, 0) } +// TestCompareAppStateNamespaceMetadataDiffers tests comparison when managed namespace metadata differs to live and manifest ns +func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { + ns := NewNamespace() + ns.SetName(test.FakeDestNamespace) + ns.SetNamespace(test.FakeDestNamespace) + ns.SetAnnotations(map[string]string{"bar": "bat"}) + + app := newFakeApp() + app.Spec.SyncPolicy.ManagedNamespaceMetadata = &argoappv1.ManagedNamespaceMetadata{ + Labels: map[string]string{ + "foo": "bar", + }, + Annotations: map[string]string{ + "foo": "bar", + }, + } + app.Status.OperationState = &argoappv1.OperationState{ + SyncResult: &argoappv1.SyncOperationResult{}, + } + + liveNs := ns.DeepCopy() + liveNs.SetAnnotations(nil) + + data := fakeData{ + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{toJSON(t, liveNs)}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(ns): ns, + }, + } + ctrl := newFakeController(&data) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.NotNil(t, compRes) + assert.NotNil(t, compRes.syncStatus) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Len(t, compRes.resources, 1) + assert.Len(t, compRes.managedResources, 1) + assert.NotNil(t, compRes.diffResultList) + assert.Len(t, compRes.diffResultList.Diffs, 1) + + result := NewNamespace() + assert.NoError(t, json.Unmarshal(compRes.diffResultList.Diffs[0].PredictedLive, result)) + + labels := result.GetLabels() + delete(labels, "kubernetes.io/metadata.name") + + assert.Equal(t, map[string]string{}, labels) + // Manifests override definitions in managedNamespaceMetadata + assert.Equal(t, map[string]string{"bar": "bat"}, result.GetAnnotations()) + assert.Len(t, app.Status.Conditions, 0) +} + +// TestCompareAppStateNamespaceMetadata tests comparison when managed namespace metadata differs to live +func TestCompareAppStateNamespaceMetadata(t *testing.T) { + ns := NewNamespace() + ns.SetName(test.FakeDestNamespace) + ns.SetNamespace(test.FakeDestNamespace) + ns.SetAnnotations(map[string]string{"bar": "bat"}) + + app := newFakeApp() + app.Spec.SyncPolicy.ManagedNamespaceMetadata = &argoappv1.ManagedNamespaceMetadata{ + Labels: map[string]string{ + "foo": "bar", + }, + Annotations: map[string]string{ + "foo": "bar", + }, + } + app.Status.OperationState = &argoappv1.OperationState{ + SyncResult: &argoappv1.SyncOperationResult{}, + } + + data := fakeData{ + manifestResponse: &apiclient.ManifestResponse{ + Manifests: []string{}, + Namespace: test.FakeDestNamespace, + Server: test.FakeClusterURL, + Revision: "abc123", + }, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(ns): ns, + }, + } + ctrl := newFakeController(&data) + sources := make([]argoappv1.ApplicationSource, 0) + sources = append(sources, app.Spec.GetSource()) + revisions := make([]string, 0) + revisions = append(revisions, "") + compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.NotNil(t, compRes) + assert.NotNil(t, compRes.syncStatus) + assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) + assert.Len(t, compRes.resources, 1) + assert.Len(t, compRes.managedResources, 1) + assert.NotNil(t, compRes.diffResultList) + assert.Len(t, compRes.diffResultList.Diffs, 1) + + result := NewNamespace() + assert.NoError(t, json.Unmarshal(compRes.diffResultList.Diffs[0].PredictedLive, result)) + + labels := result.GetLabels() + delete(labels, "kubernetes.io/metadata.name") + + assert.Equal(t, map[string]string{"foo": "bar"}, labels) + assert.Equal(t, map[string]string{"argocd.argoproj.io/sync-options": "ServerSideApply=true", "bar": "bat", "foo": "bar"}, result.GetAnnotations()) + assert.Len(t, app.Status.Conditions, 0) +} + // TestCompareAppStateNamespaceMetadataIsTheSame tests comparison when managed namespace metadata is the same func TestCompareAppStateNamespaceMetadataIsTheSame(t *testing.T) { app := newFakeApp() From 72245e8557b27bf2141fa5079c155f34a6d8c5ab Mon Sep 17 00:00:00 2001 From: Takumi Sue <23391543+mikutas@users.noreply.github.com> Date: Wed, 8 Nov 2023 21:28:21 +0900 Subject: [PATCH 092/269] fix: failing lint and unit test (#16275) Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> --- controller/state_test.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/controller/state_test.go b/controller/state_test.go index b08cb74f5b6e6..6eb336cff2ffb 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -151,12 +151,13 @@ func TestCompareAppStateNamespaceMetadataDiffersToManifest(t *testing.T) { kube.GetResourceKey(ns): ns, }, } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) @@ -208,12 +209,13 @@ func TestCompareAppStateNamespaceMetadata(t *testing.T) { kube.GetResourceKey(ns): ns, }, } - ctrl := newFakeController(&data) + ctrl := newFakeController(&data, nil) sources := make([]argoappv1.ApplicationSource, 0) sources = append(sources, app.Spec.GetSource()) revisions := make([]string, 0) revisions = append(revisions, "") - compRes := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + compRes, err := ctrl.appStateManager.CompareAppState(app, &defaultProj, revisions, sources, false, false, nil, false) + assert.Nil(t, err) assert.NotNil(t, compRes) assert.NotNil(t, compRes.syncStatus) assert.Equal(t, argoappv1.SyncStatusCodeOutOfSync, compRes.syncStatus.Status) From b33b7fad6acc992e683a790226470b0ea0468023 Mon Sep 17 00:00:00 2001 From: Rafal Date: Thu, 9 Nov 2023 15:49:34 +0100 Subject: [PATCH 093/269] chore(ui): Change testEnvironment from node to jsdom (#16287) Signed-off-by: Rafal Pelczar --- ui/jest.config.js | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/ui/jest.config.js b/ui/jest.config.js index abd8a45bcecd6..524b493f546fc 100644 --- a/ui/jest.config.js +++ b/ui/jest.config.js @@ -1,12 +1,11 @@ module.exports = { preset: 'ts-jest', - testEnvironment: 'node', + testEnvironment: 'jsdom', reporters: ['default', 'jest-junit'], collectCoverage: true, transformIgnorePatterns: ['node_modules/(?!(argo-ui)/)'], globals: { 'self': {}, - 'window': {localStorage: { getItem: () => '{}', setItem: () => null }}, 'ts-jest': { isolatedModules: true, }, @@ -17,20 +16,3 @@ module.exports = { '.+\\.(css|styl|less|sass|scss)$': 'jest-transform-css', }, }; - -const localStorageMock = (() => { - let store = {}; - return { - getItem: (key) => store[key], - setItem: (key, value) => { - store[key] = value.toString(); - }, - clear: () => { - store = {}; - }, - removeItem: (key) => { - delete store[key]; - } - }; -})(); -global.localStorage = localStorageMock; \ No newline at end of file From 3d6568d40490545d620c9536dcbdb92a26a4655f Mon Sep 17 00:00:00 2001 From: Matt Hughes <128392218+matthewhughes-uw@users.noreply.github.com> Date: Thu, 9 Nov 2023 16:18:00 +0000 Subject: [PATCH 094/269] docs: Document `ApplyOutOfSyncOnly` in application spec (#16282) I found this being used in an application I was working on but had a hard time discovering its meaning since it wasn't in the specification[1] though it was in the `sync-options` docs[2] (see also baa0f2e39c45b86bedc3b3cca0878c0f77253529) [1] https://argo-cd.readthedocs.io/en/stable/user-guide/application-specification/ [2] https://argo-cd.readthedocs.io/en/stable/user-guide/sync-options/#selective-sync Signed-off-by: Matt Hughes --- docs/operator-manual/application.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/operator-manual/application.yaml b/docs/operator-manual/application.yaml index 75a0d3b0df8ae..aa2dea5c65b7c 100644 --- a/docs/operator-manual/application.yaml +++ b/docs/operator-manual/application.yaml @@ -189,6 +189,7 @@ spec: - PrunePropagationPolicy=foreground # Supported policies are background, foreground and orphan. - PruneLast=true # Allow the ability for resource pruning to happen as a final, implicit wave of a sync operation - RespectIgnoreDifferences=true # When syncing changes, respect fields ignored by the ignoreDifferences configuration + - ApplyOutOfSyncOnly=true # Only sync out-of-sync resources, rather than applying every object in the application managedNamespaceMetadata: # Sets the metadata for the application namespace. Only valid if CreateNamespace=true (see above), otherwise it's a no-op. labels: # The labels to set on the application namespace any: label From 30ff2e59e0dd6f54f0d239ff3c0a588ebfbe59fd Mon Sep 17 00:00:00 2001 From: Takumi Sue <23391543+mikutas@users.noreply.github.com> Date: Fri, 10 Nov 2023 13:06:54 +0900 Subject: [PATCH 095/269] fix(appset): prevent app deletion according to appset policy (#12172) (#15903) * fix(applicationset): prevent app deletion according to appset policy Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> * test: add unit test Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> * fix: unit test Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> * fix: remove TODO Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> --------- Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> --- .../controllers/applicationset_controller.go | 34 ++++++++- .../applicationset_controller_test.go | 75 +++++++++++++++++++ 2 files changed, 106 insertions(+), 3 deletions(-) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index be73c81ca0c3f..5f1205caf384a 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -108,6 +108,18 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque // Do not attempt to further reconcile the ApplicationSet if it is being deleted. if applicationSetInfo.ObjectMeta.DeletionTimestamp != nil { + if controllerutil.ContainsFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) { + deleteAllowed := utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete() + if !deleteAllowed { + if err := r.removeOwnerReferencesOnDeleteAppSet(ctx, applicationSetInfo); err != nil { + return ctrl.Result{}, err + } + controllerutil.RemoveFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) + if err := r.Update(ctx, &applicationSetInfo); err != nil { + return ctrl.Result{}, err + } + } + } return ctrl.Result{}, nil } @@ -731,10 +743,9 @@ func (r *ApplicationSetReconciler) createInCluster(ctx context.Context, logCtx * return r.createOrUpdateInCluster(ctx, logCtx, applicationSet, createApps) } -func (r *ApplicationSetReconciler) getCurrentApplications(_ context.Context, applicationSet argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) { - // TODO: Should this use the context param? +func (r *ApplicationSetReconciler) getCurrentApplications(ctx context.Context, applicationSet argov1alpha1.ApplicationSet) ([]argov1alpha1.Application, error) { var current argov1alpha1.ApplicationList - err := r.Client.List(context.Background(), ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}, client.InNamespace(applicationSet.Namespace)) + err := r.Client.List(ctx, ¤t, client.MatchingFields{".metadata.controller": applicationSet.Name}, client.InNamespace(applicationSet.Namespace)) if err != nil { return nil, fmt.Errorf("error retrieving applications: %w", err) @@ -875,6 +886,23 @@ func (r *ApplicationSetReconciler) removeFinalizerOnInvalidDestination(ctx conte return nil } +func (r *ApplicationSetReconciler) removeOwnerReferencesOnDeleteAppSet(ctx context.Context, applicationSet argov1alpha1.ApplicationSet) error { + applications, err := r.getCurrentApplications(ctx, applicationSet) + if err != nil { + return err + } + + for _, app := range applications { + app.SetOwnerReferences([]metav1.OwnerReference{}) + err := r.Client.Update(ctx, &app) + if err != nil { + return err + } + } + + return nil +} + func (r *ApplicationSetReconciler) performProgressiveSyncs(ctx context.Context, logCtx *log.Entry, appset argov1alpha1.ApplicationSet, applications []argov1alpha1.Application, desiredApplications []argov1alpha1.Application, appMap map[string]argov1alpha1.Application) (map[string]bool, error) { appDependencyList, appStepMap, err := r.buildAppDependencyList(logCtx, appset, desiredApplications) diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index add37780e7077..65acce4b38edc 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -1593,6 +1593,81 @@ func TestRemoveFinalizerOnInvalidDestination_DestinationTypes(t *testing.T) { } } +func TestRemoveOwnerReferencesOnDeleteAppSet(t *testing.T) { + scheme := runtime.NewScheme() + err := v1alpha1.AddToScheme(scheme) + assert.Nil(t, err) + + err = v1alpha1.AddToScheme(scheme) + assert.Nil(t, err) + + for _, c := range []struct { + // name is human-readable test name + name string + }{ + { + name: "ownerReferences cleared", + }, + } { + t.Run(c.name, func(t *testing.T) { + appSet := v1alpha1.ApplicationSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: "name", + Namespace: "namespace", + Finalizers: []string{v1alpha1.ResourcesFinalizerName}, + }, + Spec: v1alpha1.ApplicationSetSpec{ + Template: v1alpha1.ApplicationSetTemplate{ + Spec: v1alpha1.ApplicationSpec{ + Project: "project", + }, + }, + }, + } + + app := v1alpha1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "app1", + Namespace: "namespace", + }, + Spec: v1alpha1.ApplicationSpec{ + Project: "project", + Source: &v1alpha1.ApplicationSource{Path: "path", TargetRevision: "revision", RepoURL: "repoURL"}, + Destination: v1alpha1.ApplicationDestination{ + Namespace: "namespace", + Server: "https://kubernetes.default.svc", + }, + }, + } + + err := controllerutil.SetControllerReference(&appSet, &app, scheme) + assert.NoError(t, err, "Unexpected error") + + initObjs := []crtclient.Object{&app, &appSet} + + client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(initObjs...).WithIndex(&v1alpha1.Application{}, ".metadata.controller", appControllerIndexer).Build() + + r := ApplicationSetReconciler{ + Client: client, + Scheme: scheme, + Recorder: record.NewFakeRecorder(10), + KubeClientset: nil, + Cache: &fakeCache{}, + } + + err = r.removeOwnerReferencesOnDeleteAppSet(context.Background(), appSet) + assert.NoError(t, err, "Unexpected error") + + retrievedApp := v1alpha1.Application{} + err = client.Get(context.Background(), crtclient.ObjectKeyFromObject(&app), &retrievedApp) + assert.NoError(t, err, "Unexpected error") + + ownerReferencesRemoved := len(retrievedApp.OwnerReferences) == 0 + assert.True(t, ownerReferencesRemoved) + }) + } +} + func TestCreateApplications(t *testing.T) { scheme := runtime.NewScheme() From 4fe2dd832809d3f36bd3f5c3329123d1fef9975c Mon Sep 17 00:00:00 2001 From: Noam Gal Date: Fri, 10 Nov 2023 11:57:54 +0200 Subject: [PATCH 096/269] copy ServerName into clientOpts (#16267) Signed-off-by: Noam Gal Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- cmd/argocd/commands/login.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/argocd/commands/login.go b/cmd/argocd/commands/login.go index 3e2ad4e7d1b73..abb2b004291c2 100644 --- a/cmd/argocd/commands/login.go +++ b/cmd/argocd/commands/login.go @@ -106,6 +106,7 @@ argocd login cd.argoproj.io --core`, PortForwardNamespace: globalClientOpts.PortForwardNamespace, Headers: globalClientOpts.Headers, KubeOverrides: globalClientOpts.KubeOverrides, + ServerName: globalClientOpts.ServerName, } if ctxName == "" { From c18dec12767ef71cdcc0cb1485f729f2d498ab0c Mon Sep 17 00:00:00 2001 From: Rafal Date: Fri, 10 Nov 2023 14:21:10 +0100 Subject: [PATCH 097/269] chore(deps): bump argo-ui (#16264) Signed-off-by: Rafal Pelczar --- ui/yarn.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/yarn.lock b/ui/yarn.lock index 369ef20d7790d..cf75609144850 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -2513,7 +2513,7 @@ arg@^4.1.0: "argo-ui@git+https://github.com/argoproj/argo-ui.git": version "1.0.0" - resolved "git+https://github.com/argoproj/argo-ui.git#002d01b18e8aaf4b21307a3b87341ab05230483f" + resolved "git+https://github.com/argoproj/argo-ui.git#5ff344ac9692c14dd108468bd3c020c3c75181cb" dependencies: "@fortawesome/fontawesome-free" "^6.2.1" "@tippy.js/react" "^3.1.1" From edc213d22902e9676231119522563fa338c62793 Mon Sep 17 00:00:00 2001 From: Rafal Date: Sat, 11 Nov 2023 19:47:25 +0100 Subject: [PATCH 098/269] fix(ui): Issues with overlapping content in the app details view on smaller screens (#16268) Signed-off-by: Rafal Pelczar --- .../application-details.scss | 28 +- .../application-details.tsx | 304 +++++++++--------- .../app/shared/components/layout/layout.tsx | 25 +- ui/src/app/shared/components/page/page.scss | 4 +- 4 files changed, 184 insertions(+), 177 deletions(-) diff --git a/ui/src/app/applications/components/application-details/application-details.scss b/ui/src/app/applications/components/application-details/application-details.scss index af1ca3e9d07dc..82402ffd0d8b4 100644 --- a/ui/src/app/applications/components/application-details/application-details.scss +++ b/ui/src/app/applications/components/application-details/application-details.scss @@ -8,16 +8,16 @@ $header: 120px; .application-details { height: 100vh; width: 100%; - &__status-panel { - position: fixed; - left: $sidebar-width; - right: 0; - z-index: 3; - @media screen and (max-width: map-get($breakpoints, xlarge)) { - top: 150px; - } - @media screen and (max-width: map-get($breakpoints, large)) { - top: 146px; + + &__wrapper { + display: flex; + flex-direction: column; + height: calc(100vh - 2 * $top-bar-height); + overflow: hidden; + + @media screen and (max-width: map-get($breakpoints, xxlarge)) { + height: calc(100vh - 3 * $top-bar-height); + margin-top: $top-bar-height; } } @@ -27,13 +27,11 @@ $header: 120px; &__tree { padding: 1em; + + flex: 1; overflow-x: auto; overflow-y: auto; - margin-top: 150px; - height: calc(100vh - 2 * 70px - 115px); - @media screen and (max-width: map-get($breakpoints, xlarge)) { - margin-top: 165px; - } + overscroll-behavior-x: none; } &__sliding-panel-pagination-wrap { diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 3f12660fb0191..9b0a13f638c7b 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -416,125 +416,20 @@ export class ApplicationDetails extends React.Component ) }}> -
    - this.selectNode(appFullName, 0, 'diff')} - showOperation={() => this.setOperationStatusVisible(true)} - showConditions={() => this.setConditionsStatusVisible(true)} - showMetadataInfo={revision => this.setState({...this.state, revision})} - /> -
    -
    - {refreshing &&

    Refreshing

    } - {((pref.view === 'tree' || pref.view === 'network') && ( - <> - services.viewPreferences.getPreferences()}> - {viewPref => ( - - )} - - - this.filterTreeNode(node, treeFilter)} - selectedNodeFullName={this.selectedNodeKey} - onNodeClick={fullName => this.selectNode(fullName)} - nodeMenu={node => - AppUtils.renderResourceMenu(node, application, tree, this.appContext.apis, this.appChanged, () => - this.getApplicationActionMenu(application, false) - ) - } - showCompactNodes={pref.groupNodes} - userMsgs={pref.userHelpTipMsgs} - tree={tree} - app={application} - showOrphanedResources={pref.orphanedResources} - useNetworkingHierarchy={pref.view === 'network'} - onClearFilter={clearFilter} - onGroupdNodeClick={groupdedNodeIds => openGroupNodeDetails(groupdedNodeIds)} - zoom={pref.zoom} - podGroupCount={pref.podGroupCount} - appContext={this.appContext} - nameDirection={this.state.truncateNameOnRight} - filters={pref.resourceFilter} - setTreeFilterGraph={setFilterGraph} - updateUsrHelpTipMsgs={updateHelpTipState} - setShowCompactNodes={setShowCompactNodes} - setNodeExpansion={(node, isExpanded) => this.setNodeExpansion(node, isExpanded)} - getNodeExpansion={node => this.getNodeExpansion(node)} - /> - - )) || - (pref.view === 'pods' && ( - this.selectNode(fullName)} - nodeMenu={node => - AppUtils.renderResourceMenu(node, application, tree, this.appContext.apis, this.appChanged, () => - this.getApplicationActionMenu(application, false) - ) - } - quickStarts={node => AppUtils.renderResourceButtons(node, application, tree, this.appContext.apis, this.appChanged)} - /> - )) || - (this.state.extensionsMap[pref.view] != null && ( - - )) || ( -
    +
    +
    + this.selectNode(appFullName, 0, 'diff')} + showOperation={() => this.setOperationStatusVisible(true)} + showConditions={() => this.setConditionsStatusVisible(true)} + showMetadataInfo={revision => this.setState({...this.state, revision})} + /> +
    +
    + {refreshing &&

    Refreshing

    } + {((pref.view === 'tree' || pref.view === 'network') && ( + <> services.viewPreferences.getPreferences()}> {viewPref => ( )} - {(filteredRes.length > 0 && ( - this.setState({page})} - preferencesKey='application-details'> - {data => ( - this.selectNode(fullName)} - resources={data} - nodeMenu={node => - AppUtils.renderResourceMenu( - {...node, root: node}, - application, - tree, - this.appContext.apis, - this.appChanged, - () => this.getApplicationActionMenu(application, false) - ) - } + + this.filterTreeNode(node, treeFilter)} + selectedNodeFullName={this.selectedNodeKey} + onNodeClick={fullName => this.selectNode(fullName)} + nodeMenu={node => + AppUtils.renderResourceMenu(node, application, tree, this.appContext.apis, this.appChanged, () => + this.getApplicationActionMenu(application, false) + ) + } + showCompactNodes={pref.groupNodes} + userMsgs={pref.userHelpTipMsgs} + tree={tree} + app={application} + showOrphanedResources={pref.orphanedResources} + useNetworkingHierarchy={pref.view === 'network'} + onClearFilter={clearFilter} + onGroupdNodeClick={groupdedNodeIds => openGroupNodeDetails(groupdedNodeIds)} + zoom={pref.zoom} + podGroupCount={pref.podGroupCount} + appContext={this.appContext} + nameDirection={this.state.truncateNameOnRight} + filters={pref.resourceFilter} + setTreeFilterGraph={setFilterGraph} + updateUsrHelpTipMsgs={updateHelpTipState} + setShowCompactNodes={setShowCompactNodes} + setNodeExpansion={(node, isExpanded) => this.setNodeExpansion(node, isExpanded)} + getNodeExpansion={node => this.getNodeExpansion(node)} + /> + + )) || + (pref.view === 'pods' && ( + this.selectNode(fullName)} + nodeMenu={node => + AppUtils.renderResourceMenu(node, application, tree, this.appContext.apis, this.appChanged, () => + this.getApplicationActionMenu(application, false) + ) + } + quickStarts={node => AppUtils.renderResourceButtons(node, application, tree, this.appContext.apis, this.appChanged)} + /> + )) || + (this.state.extensionsMap[pref.view] != null && ( + + )) || ( +
    + services.viewPreferences.getPreferences()}> + {viewPref => ( + )} - - )) || ( - -

    No resources found

    -
    Try to change filter criteria
    -
    - )} -
    - )} + + {(filteredRes.length > 0 && ( + this.setState({page})} + preferencesKey='application-details'> + {data => ( + this.selectNode(fullName)} + resources={data} + nodeMenu={node => + AppUtils.renderResourceMenu( + {...node, root: node}, + application, + tree, + this.appContext.apis, + this.appChanged, + () => this.getApplicationActionMenu(application, false) + ) + } + tree={tree} + /> + )} + + )) || ( + +

    No resources found

    +
    Try to change filter criteria
    +
    + )} +
    + )} +
    0} onClose={() => this.closeGroupedNodesPanel()}>
    @@ -748,12 +750,12 @@ export class ApplicationDetails extends React.Component, + title: , action: () => this.selectNode(fullName) }, { iconClassName: 'fa fa-file-medical', - title: , + title: , action: () => this.selectNode(fullName, 0, 'diff'), disabled: app.status.sync.status === appModels.SyncStatuses.Synced }, diff --git a/ui/src/app/shared/components/layout/layout.tsx b/ui/src/app/shared/components/layout/layout.tsx index dcf98dde565eb..096fdde68e99b 100644 --- a/ui/src/app/shared/components/layout/layout.tsx +++ b/ui/src/app/shared/components/layout/layout.tsx @@ -14,14 +14,21 @@ export interface LayoutProps { const getBGColor = (theme: string): string => (theme === 'light' ? '#dee6eb' : '#100f0f'); -export const Layout = (props: LayoutProps) => ( -
    -
    - - {props.pref.theme ? (document.body.style.background = getBGColor(props.pref.theme)) : null} -
    - {props.children} +export const Layout = (props: LayoutProps) => { + React.useEffect(() => { + if (props.pref.theme) { + document.body.style.background = getBGColor(props.pref.theme); + } + }, [props.pref.theme]); + + return ( +
    +
    + +
    + {props.children} +
    -
    -); + ); +}; diff --git a/ui/src/app/shared/components/page/page.scss b/ui/src/app/shared/components/page/page.scss index 4194f2b00693f..1031a121bedb4 100644 --- a/ui/src/app/shared/components/page/page.scss +++ b/ui/src/app/shared/components/page/page.scss @@ -75,10 +75,10 @@ } .sb-page-wrapper { - padding-left: $sidebar-width - 60px; + padding-left: $sidebar-width; &__sidebar-collapsed { - padding-left: $collapsed-sidebar-width - 60px; + padding-left: $collapsed-sidebar-width; .flex-top-bar { left: $collapsed-sidebar-width; } From f2c51de26c72ca5c981200e41735bb04bf2d309a Mon Sep 17 00:00:00 2001 From: Michael Over <38833043+m-over@users.noreply.github.com> Date: Tue, 14 Nov 2023 16:12:49 +0100 Subject: [PATCH 099/269] chore(deps): bump Helm to 3.13.2 (#16320) (#16321) * bump helm 3.13.2 Signed-off-by: Michael Over * bump helm 3.13.2 Signed-off-by: Michael Over * Retrigger CI pipeline Signed-off-by: Michael Over * remove checksums from root Signed-off-by: Michael Over --------- Signed-off-by: Michael Over Co-authored-by: Michael Over --- .../installers/checksums/helm-v3.13.2-linux-amd64.tar.gz.sha256 | 1 + .../installers/checksums/helm-v3.13.2-linux-arm64.tar.gz.sha256 | 1 + .../checksums/helm-v3.13.2-linux-ppc64le.tar.gz.sha256 | 1 + .../installers/checksums/helm-v3.13.2-linux-s390x.tar.gz.sha256 | 1 + hack/tool-versions.sh | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 hack/installers/checksums/helm-v3.13.2-linux-amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.13.2-linux-arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.13.2-linux-ppc64le.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.13.2-linux-s390x.tar.gz.sha256 diff --git a/hack/installers/checksums/helm-v3.13.2-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.2-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..8908445e50510 --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.2-linux-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +55a8e6dce87a1e52c61e0ce7a89bf85b38725ba3e8deb51d4a08ade8a2c70b2d helm-v3.13.2-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.13.2-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.2-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..cf6b333b8d98b --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.2-linux-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +f5654aaed63a0da72852776e1d3f851b2ea9529cb5696337202703c2e1ed2321 helm-v3.13.2-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.13.2-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.2-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..696df1bb8df5e --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.2-linux-ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +11d96134cc4ec106c23cd8c163072e9aed6cd73e36a3da120e5876d426203f37 helm-v3.13.2-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.13.2-linux-s390x.tar.gz.sha256 b/hack/installers/checksums/helm-v3.13.2-linux-s390x.tar.gz.sha256 new file mode 100644 index 0000000000000..f539faf320db7 --- /dev/null +++ b/hack/installers/checksums/helm-v3.13.2-linux-s390x.tar.gz.sha256 @@ -0,0 +1 @@ +3ffc5b4a041e5306dc00905ebe5dfea449e34ada268a713d34c69709afd6a9a2 helm-v3.13.2-linux-s390x.tar.gz diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index 842af77c8a2ac..ecc1c424febfa 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -11,7 +11,7 @@ # Use ./hack/installers/checksums/add-helm-checksums.sh and # add-kustomize-checksums.sh to help download checksums. ############################################################################### -helm3_version=3.13.1 +helm3_version=3.13.2 kubectl_version=1.17.8 kubectx_version=0.6.3 kustomize5_version=5.2.1 From 33f075e286423aabbb7c3cc0395788c69ff34c7f Mon Sep 17 00:00:00 2001 From: "Yuan (Terry) Tang" Date: Tue, 14 Nov 2023 13:18:03 -0500 Subject: [PATCH 100/269] docs: Add @gdsoumya to approvers in OWNERS (#16331) Signed-off-by: Yuan (Terry) Tang --- OWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OWNERS b/OWNERS index d8532c550005a..56e037e282a0a 100644 --- a/OWNERS +++ b/OWNERS @@ -5,6 +5,7 @@ owners: approvers: - alexec - alexmt +- gdsoumya - jannfis - jessesuen - jgwest @@ -30,4 +31,3 @@ reviewers: - zachaller - 34fathombelow - alexef -- gdsoumya From 43cc65bef7d46a1db53a7e2c5a3c77d07c630528 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:38:12 -0500 Subject: [PATCH 101/269] docs: fix upgrade instructions (#16326) * docs: fix upgrade instructions Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * more things Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- docs/operator-manual/upgrading/2.8-2.9.md | 11 ++--------- docs/operator-manual/upgrading/2.9-2.10.md | 12 ++++++++++++ docs/operator-manual/upgrading/overview.md | 1 + mkdocs.yml | 2 ++ 4 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 docs/operator-manual/upgrading/2.9-2.10.md diff --git a/docs/operator-manual/upgrading/2.8-2.9.md b/docs/operator-manual/upgrading/2.8-2.9.md index 6a82684019ac4..ef99e09587814 100644 --- a/docs/operator-manual/upgrading/2.8-2.9.md +++ b/docs/operator-manual/upgrading/2.8-2.9.md @@ -1,12 +1,5 @@ # v2.8 to 2.9 -## `managedNamespaceMetadata` no longer preserves client-side-applied labels or annotations +## Upgraded Kustomize Version -Argo CD 2.9 upgraded kubectl from 1.24 to 1.26. This upgrade introduced a change where client-side-applied labels and -annotations are no longer preserved when using a server-side kubectl apply. This change affects the -`managedNamespaceMetadata` field of the `Application` CRD. Previously, labels and annotations applied via a client-side -apply would be preserved when `managedNamespaceMetadata` was enabled. Now, those existing labels and annotation will be -removed. - -To avoid unexpected behavior, follow the [client-side to server-side resource upgrade guide](https://kubernetes.io/docs/reference/using-api/server-side-apply/#upgrading-from-client-side-apply-to-server-side-apply) -before enabling `managedNamespaceMetadata` on an existing namespace. +Note that bundled Kustomize version has been upgraded from 5.1.0 to 5.2.1. diff --git a/docs/operator-manual/upgrading/2.9-2.10.md b/docs/operator-manual/upgrading/2.9-2.10.md new file mode 100644 index 0000000000000..4cd7c379bdc81 --- /dev/null +++ b/docs/operator-manual/upgrading/2.9-2.10.md @@ -0,0 +1,12 @@ +# v2.9 to 2.10 + +## `managedNamespaceMetadata` no longer preserves client-side-applied labels or annotations + +Argo CD 2.10 upgraded kubectl from 1.24 to 1.26. This upgrade introduced a change where client-side-applied labels and +annotations are no longer preserved when using a server-side kubectl apply. This change affects the +`managedNamespaceMetadata` field of the `Application` CRD. Previously, labels and annotations applied via a client-side +apply would be preserved when `managedNamespaceMetadata` was enabled. Now, those existing labels and annotation will be +removed. + +To avoid unexpected behavior, follow the [client-side to server-side resource upgrade guide](https://kubernetes.io/docs/reference/using-api/server-side-apply/#upgrading-from-client-side-apply-to-server-side-apply) +before enabling `managedNamespaceMetadata` on an existing namespace. diff --git a/docs/operator-manual/upgrading/overview.md b/docs/operator-manual/upgrading/overview.md index 67ab78076c648..742c7b191b57a 100644 --- a/docs/operator-manual/upgrading/overview.md +++ b/docs/operator-manual/upgrading/overview.md @@ -37,6 +37,7 @@ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/ +* [v2.9 to v2.10](./2.9-2.10.md) * [v2.8 to v2.9](./2.8-2.9.md) * [v2.7 to v2.8](./2.7-2.8.md) * [v2.6 to v2.7](./2.6-2.7.md) diff --git a/mkdocs.yml b/mkdocs.yml index 61abeae5f8725..4a58580e29619 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -128,6 +128,8 @@ nav: - operator-manual/server-commands/additional-configuration-method.md - Upgrading: - operator-manual/upgrading/overview.md + - operator-manual/upgrading/2.9-2.10.md + - operator-manual/upgrading/2.8-2.9.md - operator-manual/upgrading/2.7-2.8.md - operator-manual/upgrading/2.6-2.7.md - operator-manual/upgrading/2.5-2.6.md From 841d989963e6897d4ed8792279f1a0dc8050575f Mon Sep 17 00:00:00 2001 From: Zubair Haque Date: Tue, 14 Nov 2023 13:50:08 -0500 Subject: [PATCH 102/269] chore(deps): fix superagent vulnerability (#16305) Signed-off-by: zhaque44 --- ui/package.json | 2 +- ui/yarn.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ui/package.json b/ui/package.json index 7c7b0df9c4f52..f0f5c1757894d 100644 --- a/ui/package.json +++ b/ui/package.json @@ -50,7 +50,7 @@ "react-virtualized": "^9.22.3", "redoc": "^2.0.0-rc.64", "rxjs": "^6.6.6", - "superagent": "^8.0.9", + "superagent": "^8.1.2", "timezones-list": "3.0.1", "tsx": "^3.4.0", "unidiff": "^1.0.2", diff --git a/ui/yarn.lock b/ui/yarn.lock index cf75609144850..4bc988182461e 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -8452,20 +8452,20 @@ semver@7.0.0: integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== semver@7.x, semver@^7.3.2, semver@^7.3.8: - version "7.5.2" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb" - integrity sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^6.0.0, semver@^6.3.0: version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== send@0.17.2: @@ -8974,10 +8974,10 @@ stylis@^4.0.13: resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== -superagent@^8.0.9: - version "8.0.9" - resolved "https://registry.npmjs.org/superagent/-/superagent-8.0.9.tgz#2c6fda6fadb40516515f93e9098c0eb1602e0535" - integrity sha512-4C7Bh5pyHTvU33KpZgwrNKh/VQnvgtCSqPRfJAUdmrtSYePVzVg4E4OzsrbkhJj9O7SO6Bnv75K/F8XVZT8YHA== +superagent@^8.1.2: + version "8.1.2" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-8.1.2.tgz#03cb7da3ec8b32472c9d20f6c2a57c7f3765f30b" + integrity sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA== dependencies: component-emitter "^1.3.0" cookiejar "^2.1.4" From 3dffaa4c948651a5db067e82f2694369951d9ee9 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Tue, 14 Nov 2023 15:25:13 -0500 Subject: [PATCH 103/269] docs: update release doc and issue template (#16329) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/release.md | 6 ---- .../release-process-and-cadence.md | 32 +++++++------------ 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/release.md b/.github/ISSUE_TEMPLATE/release.md index dd24ed32aee77..b43b91a0e05ce 100644 --- a/.github/ISSUE_TEMPLATE/release.md +++ b/.github/ISSUE_TEMPLATE/release.md @@ -9,12 +9,6 @@ assignees: '' Target RC1 date: ___. __, ____ Target GA date: ___. __, ____ - - [ ] Create new section in the [Release Planning doc](https://docs.google.com/document/d/1trJIomcgXcfvLw0aYnERrFWfPjQOfYMDJOCh1S8nMBc/edit?usp=sharing) - - [ ] Schedule a Release Planning meeting roughly two weeks before the scheduled Release freeze date by adding it to the community calendar (or delegate this task to someone with write access to the community calendar) - - [ ] Include Zoom link in the invite - - [ ] Post in #argo-cd and #argo-contributors one week before the meeting - - [ ] Post again one hour before the meeting - - [ ] At the meeting, remove issues/PRs from the project's column for that release which have not been “claimed” by at least one Approver (add it to the next column if Approver requests that) - [ ] 1wk before feature freeze post in #argo-contributors that PRs must be merged by DD-MM-YYYY to be included in the release - ask approvers to drop items from milestone they can’t merge - [ ] At least two days before RC1 date, draft RC blog post and submit it for review (or delegate this task) - [ ] Cut RC1 (or delegate this task to an Approver and coordinate timing) diff --git a/docs/developer-guide/release-process-and-cadence.md b/docs/developer-guide/release-process-and-cadence.md index 337d5bafc3528..fff09a8491029 100644 --- a/docs/developer-guide/release-process-and-cadence.md +++ b/docs/developer-guide/release-process-and-cadence.md @@ -6,14 +6,15 @@ These are the upcoming releases dates: -| Release | Release Planning Meeting | Release Candidate 1 | General Availability | Release Champion | Checklist | -|---------|--------------------------|-----------------------|----------------------|-------------------------------------------------------|---------------------------------------------------------------| -| v2.6 | Monday, Dec. 12, 2022 | Monday, Dec. 19, 2022 | Monday, Feb. 6, 2023 | [William Tam](https://github.com/wtam2018) | [checklist](https://github.com/argoproj/argo-cd/issues/11563) | -| v2.7 | Monday, Mar. 6, 2023 | Monday, Mar. 20, 2023 | Monday, May. 1, 2023 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/12762) | -| v2.8 | Monday, Jun. 20, 2023 | Monday, Jun. 26, 2023 | Monday, Aug. 7, 2023 | [Keith Chong](https://github.com/keithchong) | [checklist](https://github.com/argoproj/argo-cd/issues/13742) | -| v2.9 | Monday, Sep. 4, 2023 | Monday, Sep. 18, 2023 | Monday, Nov. 6, 2023 | [Leonardo Almeida](https://github.com/leoluz) | [checklist](https://github.com/argoproj/argo-cd/issues/14078) | -| v2.10 | Monday, Dec. 4, 2023 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | - +| Release | Release Candidate 1 | General Availability | Release Champion | Checklist | +|---------|-----------------------|----------------------|-------------------------------------------------------|---------------------------------------------------------------| +| v2.6 | Monday, Dec. 19, 2022 | Monday, Feb. 6, 2023 | [William Tam](https://github.com/wtam2018) | [checklist](https://github.com/argoproj/argo-cd/issues/11563) | +| v2.7 | Monday, Mar. 20, 2023 | Monday, May 1, 2023 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/12762) | +| v2.8 | Monday, Jun. 26, 2023 | Monday, Aug. 7, 2023 | [Keith Chong](https://github.com/keithchong) | [checklist](https://github.com/argoproj/argo-cd/issues/13742) | +| v2.9 | Monday, Sep. 18, 2023 | Monday, Nov. 6, 2023 | [Leonardo Almeida](https://github.com/leoluz) | [checklist](https://github.com/argoproj/argo-cd/issues/14078) | +| v2.10 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | +| v2.11 | Monday, Mar. 18, 2024 | Monday, May 6, 2024 | +| v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | Actual release dates might differ from the plan by a few days. @@ -22,8 +23,8 @@ Actual release dates might differ from the plan by a few days. #### Minor Releases (e.g. 2.x.0) A minor Argo CD release occurs four times a year, once every three months. Each General Availability (GA) release is -preceded by several Release Candidates (RCs). The first RC is released three weeks before the scheduled GA date. This -effectively means that there is a three-week feature freeze. +preceded by several Release Candidates (RCs). The first RC is released seven weeks before the scheduled GA date. This +effectively means that there is a seven-week feature freeze. These are the approximate release dates: @@ -40,17 +41,6 @@ Argo CD patch releases occur on an as-needed basis. Only the three most recent m releases. Versions older than the three most recent minor versions are considered EOL and will not receive bug fixes or security updates. -#### Minor Release Planning Meeting - -Roughly two weeks before the RC date, there will be a meeting to discuss which features are planned for the RC. This meeting is -for contributors to advocate for certain features. Features which have at least one approver (besides the contributor) -who can assure they will review/merge by the RC date will be included in the release milestone. All other features will -be dropped from the milestone (and potentially shifted to the next one). - -Since not everyone will be able to attend the meeting, there will be a meeting doc. Contributors can add their feature -to a table, and Approvers can add their name to the table. Features with a corresponding approver will remain in the -release milestone. - #### Release Champion To help manage all the steps involved in a release, we will have a Release Champion. The Release Champion will be From ebb8649c4e456466433692edd760ed1a8056a822 Mon Sep 17 00:00:00 2001 From: Aymen Ben Tanfous Date: Wed, 15 Nov 2023 15:44:19 +0100 Subject: [PATCH 104/269] feat(appset): Added 'slugify' sprig function (#15188) * Added 'slugify' sprig function Signed-off-by: Aymen Ben Tanfous * Retrigger CI Signed-off-by: Aymen Ben Tanfous --------- Signed-off-by: Aymen Ben Tanfous --- .../applicationset_controller_test.go | 26 +++++++--- applicationset/utils/utils.go | 50 +++++++++++++++++++ applicationset/utils/utils_test.go | 37 ++++++++++++++ .../applicationset/GoTemplate.md | 23 +++++++++ 4 files changed, 128 insertions(+), 8 deletions(-) diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index 65acce4b38edc..ce9dc485ba4a8 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -2815,17 +2815,24 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { { name: "Generate an application from a go template application set manifest using a pull request generator", params: []map[string]interface{}{{ - "number": "1", - "branch": "branch1", - "branch_slug": "branchSlug1", - "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", - "head_short_sha": "089d92cb", - "labels": []string{"label1"}}}, + "number": "1", + "branch": "branch1", + "branch_slug": "branchSlug1", + "head_sha": "089d92cbf9ff857a39e6feccd32798ca700fb958", + "head_short_sha": "089d92cb", + "branch_slugify_default": "feat/a_really+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", + "branch_slugify_smarttruncate_disabled": "feat/areallylongpullrequestnametotestargoslugificationandbranchnameshorteningfeature", + "branch_slugify_smarttruncate_enabled": "feat/testwithsmarttruncateenabledramdomlonglistofcharacters", + "labels": []string{"label1"}}, + }, template: v1alpha1.ApplicationSetTemplate{ ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{ Name: "AppSet-{{.branch}}-{{.number}}", Labels: map[string]string{ - "app1": "{{index .labels 0}}", + "app1": "{{index .labels 0}}", + "branch-test1": "AppSet-{{.branch_slugify_default | slugify }}", + "branch-test2": "AppSet-{{.branch_slugify_smarttruncate_disabled | slugify 49 false }}", + "branch-test3": "AppSet-{{.branch_slugify_smarttruncate_enabled | slugify 50 true }}", }, }, Spec: v1alpha1.ApplicationSpec{ @@ -2844,7 +2851,10 @@ func TestGenerateAppsUsingPullRequestGenerator(t *testing.T) { ObjectMeta: metav1.ObjectMeta{ Name: "AppSet-branch1-1", Labels: map[string]string{ - "app1": "label1", + "app1": "label1", + "branch-test1": "AppSet-feat-a-really-long-pull-request-name-to-test-argo", + "branch-test2": "AppSet-feat-areallylongpullrequestnametotestargoslugific", + "branch-test3": "AppSet-feat", }, }, Spec: v1alpha1.ApplicationSpec{ diff --git a/applicationset/utils/utils.go b/applicationset/utils/utils.go index 089a6ff103100..3392d386f7426 100644 --- a/applicationset/utils/utils.go +++ b/applicationset/utils/utils.go @@ -16,6 +16,7 @@ import ( "unsafe" "github.com/Masterminds/sprig/v3" + "github.com/gosimple/slug" "github.com/valyala/fasttemplate" "sigs.k8s.io/yaml" @@ -32,6 +33,7 @@ func init() { delete(sprigFuncMap, "expandenv") delete(sprigFuncMap, "getHostByName") sprigFuncMap["normalize"] = SanitizeName + sprigFuncMap["slugify"] = SlugifyName sprigFuncMap["toYaml"] = toYAML sprigFuncMap["fromYaml"] = fromYAML sprigFuncMap["fromYamlArray"] = fromYAMLArray @@ -434,6 +436,54 @@ func NormalizeBitbucketBasePath(basePath string) string { return basePath } +// SlugifyName generates a URL-friendly slug from the provided name and additional options. +// The slug is generated in accordance with the following rules: +// 1. The generated slug will be URL-safe and suitable for use in URLs. +// 2. The maximum length of the slug can be specified using the `maxSize` argument. +// 3. Smart truncation can be enabled or disabled using the `EnableSmartTruncate` argument. +// 4. The input name can be any string value that needs to be converted into a slug. +// +// Args: +// - args: A variadic number of arguments where: +// - The first argument (if provided) is an integer specifying the maximum length of the slug. +// - The second argument (if provided) is a boolean indicating whether smart truncation is enabled. +// - The last argument (if provided) is the input name that needs to be slugified. +// If no name is provided, an empty string will be used. +// +// Returns: +// - string: The generated URL-friendly slug based on the input name and options. +func SlugifyName(args ...interface{}) string { + // Default values for arguments + maxSize := 50 + EnableSmartTruncate := true + name := "" + + // Process the arguments + for idx, arg := range args { + switch idx { + case len(args) - 1: + name = arg.(string) + case 0: + maxSize = arg.(int) + case 1: + EnableSmartTruncate = arg.(bool) + default: + log.Errorf("Bad 'slugify' arguments.") + } + } + + sanitizedName := SanitizeName(name) + + // Configure slug generation options + slug.EnableSmartTruncate = EnableSmartTruncate + slug.MaxLength = maxSize + + // Generate the slug from the input name + urlSlug := slug.Make(sanitizedName) + + return urlSlug +} + func getTlsConfigWithCACert(scmRootCAPath string) *tls.Config { tlsConfig := &tls.Config{} diff --git a/applicationset/utils/utils_test.go b/applicationset/utils/utils_test.go index a1c58769160cc..3b4702bc35c3f 100644 --- a/applicationset/utils/utils_test.go +++ b/applicationset/utils/utils_test.go @@ -1243,6 +1243,43 @@ func TestNormalizeBitbucketBasePath(t *testing.T) { } } +func TestSlugify(t *testing.T) { + for _, c := range []struct { + branch string + smartTruncate bool + length int + expectedBasePath string + }{ + { + branch: "feat/a_really+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", + smartTruncate: false, + length: 50, + expectedBasePath: "feat-a-really-long-pull-request-name-to-test-argo", + }, + { + branch: "feat/a_really+long_pull_request_name_to_test_argo_slugification_and_branch_name_shortening_feature", + smartTruncate: true, + length: 53, + expectedBasePath: "feat-a-really-long-pull-request-name-to-test-argo", + }, + { + branch: "feat/areallylongpullrequestnametotestargoslugificationandbranchnameshorteningfeature", + smartTruncate: true, + length: 50, + expectedBasePath: "feat", + }, + { + branch: "feat/areallylongpullrequestnametotestargoslugificationandbranchnameshorteningfeature", + smartTruncate: false, + length: 50, + expectedBasePath: "feat-areallylongpullrequestnametotestargoslugifica", + }, + } { + result := SlugifyName(c.length, c.smartTruncate, c.branch) + assert.Equal(t, c.expectedBasePath, result, c.branch) + } +} + func TestGetTLSConfig(t *testing.T) { // certParsed, err := tls.X509KeyPair(test.Cert, test.PrivateKey) // require.NoError(t, err) diff --git a/docs/operator-manual/applicationset/GoTemplate.md b/docs/operator-manual/applicationset/GoTemplate.md index 08c1f3feb035a..4a2b6cf55140b 100644 --- a/docs/operator-manual/applicationset/GoTemplate.md +++ b/docs/operator-manual/applicationset/GoTemplate.md @@ -12,6 +12,29 @@ An additional `normalize` function makes any string parameter usable as a valid with hyphens and truncating at 253 characters. This is useful when making parameters safe for things like Application names. +Another function has `slugify` function has been added which, by default, sanitizes and smart truncate (means doesn't cut a word into 2). This function accepts a couple of arguments: +- The first argument (if provided) is an integer specifying the maximum length of the slug. +- The second argument (if provided) is a boolean indicating whether smart truncation is enabled. +- The last argument (if provided) is the input name that needs to be slugified. + +#### Usage example + +``` +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: test-appset +spec: + ... + template: + metadata: + name: 'hellos3-{{.name}}-{{ cat .branch | slugify 23 }}' + annotations: + label-1: '{{ cat .branch | slugify }}' + label-2: '{{ cat .branch | slugify 23 }}' + label-3: '{{ cat .branch | slugify 50 false }}' +``` + If you want to customize [options defined by text/template](https://pkg.go.dev/text/template#Template.Option), you can add the `goTemplateOptions: ["opt1", "opt2", ...]` key to your ApplicationSet next to `goTemplate: true`. Note that at the time of writing, there is only one useful option defined, which is `missingkey=error`. From 8df4bba96bdb04a871cd7b5e5027804e5ce3eb26 Mon Sep 17 00:00:00 2001 From: Katie Lamkin <57961933+kmlamkin9@users.noreply.github.com> Date: Wed, 15 Nov 2023 09:01:41 -0800 Subject: [PATCH 105/269] docs: Katie as Release Champion for 2.10 and Added a column for Release Approver (#16341) Signed-off-by: Katie Lamkin --- .../developer-guide/release-process-and-cadence.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/developer-guide/release-process-and-cadence.md b/docs/developer-guide/release-process-and-cadence.md index fff09a8491029..737c6eba6a8d9 100644 --- a/docs/developer-guide/release-process-and-cadence.md +++ b/docs/developer-guide/release-process-and-cadence.md @@ -6,13 +6,13 @@ These are the upcoming releases dates: -| Release | Release Candidate 1 | General Availability | Release Champion | Checklist | -|---------|-----------------------|----------------------|-------------------------------------------------------|---------------------------------------------------------------| -| v2.6 | Monday, Dec. 19, 2022 | Monday, Feb. 6, 2023 | [William Tam](https://github.com/wtam2018) | [checklist](https://github.com/argoproj/argo-cd/issues/11563) | -| v2.7 | Monday, Mar. 20, 2023 | Monday, May 1, 2023 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/12762) | -| v2.8 | Monday, Jun. 26, 2023 | Monday, Aug. 7, 2023 | [Keith Chong](https://github.com/keithchong) | [checklist](https://github.com/argoproj/argo-cd/issues/13742) | -| v2.9 | Monday, Sep. 18, 2023 | Monday, Nov. 6, 2023 | [Leonardo Almeida](https://github.com/leoluz) | [checklist](https://github.com/argoproj/argo-cd/issues/14078) | -| v2.10 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | +| Release | Release Candidate 1 | General Availability | Release Champion | Release Approver |Checklist | +|---------|-----------------------|----------------------|-------------------------------------------------------|-------------------------------------------------------|---------------------------------------------------------------| +| v2.6 | Monday, Dec. 19, 2022 | Monday, Feb. 6, 2023 | [William Tam](https://github.com/wtam2018) | [William Tam](https://github.com/wtam2018) | [checklist](https://github.com/argoproj/argo-cd/issues/11563) | +| v2.7 | Monday, Mar. 20, 2023 | Monday, May 1, 2023 | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [Pavel Kostohrys](https://github.com/pasha-codefresh) | [checklist](https://github.com/argoproj/argo-cd/issues/12762) | +| v2.8 | Monday, Jun. 26, 2023 | Monday, Aug. 7, 2023 | [Keith Chong](https://github.com/keithchong) | [Keith Chong](https://github.com/keithchong) | [checklist](https://github.com/argoproj/argo-cd/issues/13742) | +| v2.9 | Monday, Sep. 18, 2023 | Monday, Nov. 6, 2023 | [Leonardo Almeida](https://github.com/leoluz) | [Leonardo Almeida](https://github.com/leoluz) | [checklist](https://github.com/argoproj/argo-cd/issues/14078) | +| v2.10 | Monday, Dec. 18, 2023 | Monday, Feb. 5, 2024 | [Katie Lamkin](https://github.com/kmlamkin9) | | [checklist](https://github.com/argoproj/argo-cd/issues/16339) | | v2.11 | Monday, Mar. 18, 2024 | Monday, May 6, 2024 | | v2.12 | Monday, Jun. 17, 2024 | Monday, Aug. 5, 2024 | From ae07eb667e975ebe642de2e2f2300c78209d15da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 Nov 2023 12:02:35 -0500 Subject: [PATCH 106/269] chore(deps): bump @types/superagent from 4.1.15 to 4.1.21 in /ui (#16342) Bumps [@types/superagent](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/superagent) from 4.1.15 to 4.1.21. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/superagent) --- updated-dependencies: - dependency-name: "@types/superagent" 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> --- ui/package.json | 2 +- ui/yarn.lock | 15 +++++---------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/ui/package.json b/ui/package.json index f0f5c1757894d..d290c93be08cb 100644 --- a/ui/package.json +++ b/ui/package.json @@ -13,7 +13,7 @@ "dependencies": { "@fortawesome/fontawesome-free": "^6.4.0", "@types/react-virtualized": "^9.21.21", - "@types/superagent": "^4.1.15", + "@types/superagent": "^4.1.21", "ansi-to-react": "^6.1.6", "argo-ui": "git+https://github.com/argoproj/argo-ui.git", "buffer": "^6.0.3", diff --git a/ui/yarn.lock b/ui/yarn.lock index 4bc988182461e..604bdfb107b04 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -1903,12 +1903,7 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== -"@types/node@*": - version "16.3.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.3.1.tgz#24691fa2b0c3ec8c0d34bfcfd495edac5593ebb4" - integrity sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA== - -"@types/node@20.6.3": +"@types/node@*", "@types/node@20.6.3": version "20.6.3" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.3.tgz#5b763b321cd3b80f6b8dde7a37e1a77ff9358dd9" integrity sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA== @@ -2058,10 +2053,10 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== -"@types/superagent@^4.1.15": - version "4.1.15" - resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.15.tgz#63297de457eba5e2bc502a7609426c4cceab434a" - integrity sha512-mu/N4uvfDN2zVQQ5AYJI/g4qxn2bHB6521t1UuH09ShNWjebTqN0ZFuYK9uYjcgmI0dTQEs+Owi1EO6U0OkOZQ== +"@types/superagent@^4.1.21": + version "4.1.21" + resolved "https://registry.yarnpkg.com/@types/superagent/-/superagent-4.1.21.tgz#78e2c2d6894c5f8ece228f0df4912906133d97c3" + integrity sha512-yrbAccEEY9+BSa1wji3ry8R3/BdW9kyWnjkRKctrtw5ebn/k2a2CsMeaQ7dD4iLfomgHkomBVIVgOFRMV4XYHA== dependencies: "@types/cookiejar" "*" "@types/node" "*" From 6ede1a8c0a1e453c8cc6524cd2fece81966185ce Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Wed, 15 Nov 2023 16:51:03 -0500 Subject: [PATCH 107/269] docs: fix kustomize patches example (#16353) * docs: fix kustomize patches example Related to: https://github.com/argoproj/argo-cd/issues/16352 Also, add an ApplicationSet example. Signed-off-by: Nicholas Morey * fix: spelling Signed-off-by: Nicholas Morey --------- Signed-off-by: Nicholas Morey --- docs/user-guide/kustomize.md | 47 +++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index e97b457666958..9c2bf1fc655a4 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -21,9 +21,9 @@ To use Kustomize with an overlay, point your path to the overlay. If you're generating resources, you should read up how to ignore those generated resources using the [`IgnoreExtraneous` compare option](compare-options.md). ## Patches -Patches are a way to kustomize resources using inline configurations in Argo CD applications. This allows for kustomizing without kustomization file. `patches` follow the same logic as the corresponding Kustomization. Any patches that target existing Kustomization file will be merged. +Patches are a way to kustomize resources using inline configurations in Argo CD applications. `patches` follow the same logic as the corresponding Kustomization. Any patches that target existing Kustomization file will be merged. -The following Kustomization can be done similarly in an Argo CD application. +This Kustomize example sources manifests from the `/kustomize-guestbook` folder of the `argoproj/argocd-example-apps` repository, and patches the `Deployment` to use port `443` on the container. ```yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization @@ -31,8 +31,7 @@ metadata: name: kustomize-inline-example namespace: test1 resources: - - https://raw.githubusercontent.com/argoproj/argocd-example-apps/master/guestbook/guestbook-ui-deployment.yaml - - https://raw.githubusercontent.com/argoproj/argocd-example-apps/master/guestbook/guestbook-ui-svc.yaml + - https://raw.githubusercontent.com/argoproj/argocd-example-apps/master/kustomize-guestbook/ patches: - target: kind: Deployment @@ -42,7 +41,8 @@ patches: path: /spec/template/spec/containers/0/ports/0/containerPort value: 443 ``` -Application will clone the repository, use the specified path, then kustomize using inline patches configuration. + +This `Application` does the equivalent using the inline `kustomize.patches` configuration. ```yaml apiVersion: argoproj.io/v1alpha1 kind: Application @@ -57,7 +57,7 @@ spec: server: https://kubernetes.default.svc project: default source: - path: guestbook + path: kustomize-guestbook repoURL: https://github.com/argoproj/argocd-example-apps.git targetRevision: master kustomize: @@ -71,6 +71,41 @@ spec: value: 443 ``` +The inline kustomize patches work well with `ApplicationSets`, too. Instead of maintaining a patch or overlay for each cluster, patches can now be done in the `Application` template and utilize attributes from the generators. For example, with [`external-dns`](https://github.com/kubernetes-sigs/external-dns/) to set the [`txt-owner-id`](https://github.com/kubernetes-sigs/external-dns/blob/e1adc9079b12774cccac051966b2c6a3f18f7872/docs/registry/registry.md?plain=1#L6) to the cluster name. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: external-dns +spec: + goTemplate: true + goTemplateOptions: ["missingkey=error"] + generators: + - clusters: {} + template: + metadata: + name: 'external-dns' + spec: + project: default + source: + repoURL: https://github.com/kubernetes-sigs/external-dns/ + targetRevision: v0.14.0 + path: kustomize + kustomize: + patches: + - target: + kind: Deployment + name: external-dns + patch: |- + - op: add + path: /spec/template/spec/containers/0/args/3 + value: --txt-owner-id={{.name}} # patch using attribute from generator + destination: + name: 'in-cluster' + namespace: default +``` + ## Private Remote Bases If you have remote bases that are either (a) HTTPS and need username/password (b) SSH and need SSH private key, then they'll inherit that from the app's repo. From 6fa9b17eb757d401cfb815271ad4ee1141152219 Mon Sep 17 00:00:00 2001 From: Talia Stocks <928827+taliastocks@users.noreply.github.com> Date: Fri, 17 Nov 2023 15:24:41 -0500 Subject: [PATCH 108/269] docs: fix documentation of ignoreApplicationDifferences (#16365) Signed-off-by: Talia Stocks <928827+taliastocks@users.noreply.github.com> --- docs/operator-manual/applicationset.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/applicationset.yaml b/docs/operator-manual/applicationset.yaml index 65935802c674a..d05b08f1101a0 100644 --- a/docs/operator-manual/applicationset.yaml +++ b/docs/operator-manual/applicationset.yaml @@ -33,6 +33,6 @@ spec: - jsonPointers: - /spec/source/targetRevision - name: some-app - jqExpressions: + jqPathExpressions: - .spec.source.helm.values From b2a52de80609fb3fe737efff4247931d424013a7 Mon Sep 17 00:00:00 2001 From: Tim Schrumpf Date: Mon, 20 Nov 2023 09:01:11 +0100 Subject: [PATCH 109/269] fix(appset): use topics for Gitlab SCM Provider (#13169) (#13170) * fix(scm gitlab): use project topics instead of tags Signed-off-by: tillepille * feat(scm gitlab): add testcase for labels Signed-off-by: tillepille fix test Signed-off-by: tillepille * feat(scm gitlab): update docs for gitlab filtering Signed-off-by: tillepille * feat(scm gitlab): add fallback for old gitlab versions Signed-off-by: tillepille --------- Signed-off-by: tillepille --- applicationset/services/scm_provider/gitlab.go | 10 +++++++++- applicationset/services/scm_provider/gitlab_test.go | 10 ++++++++++ .../applicationset/Generators-SCM-Provider.md | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/applicationset/services/scm_provider/gitlab.go b/applicationset/services/scm_provider/gitlab.go index f4b92b3ed9e5f..ca174de540887 100644 --- a/applicationset/services/scm_provider/gitlab.go +++ b/applicationset/services/scm_provider/gitlab.go @@ -100,12 +100,20 @@ func (g *GitlabProvider) ListRepos(ctx context.Context, cloneProtocol string) ([ return nil, fmt.Errorf("unknown clone protocol for Gitlab %v", cloneProtocol) } + var repoLabels []string + if len(gitlabRepo.Topics) == 0 { + // fallback to for gitlab prior to 14.5 + repoLabels = gitlabRepo.TagList + } else { + repoLabels = gitlabRepo.Topics + } + repos = append(repos, &Repository{ Organization: gitlabRepo.Namespace.FullPath, Repository: gitlabRepo.Path, URL: url, Branch: gitlabRepo.DefaultBranch, - Labels: gitlabRepo.TagList, + Labels: repoLabels, RepositoryId: gitlabRepo.ID, }) } diff --git a/applicationset/services/scm_provider/gitlab_test.go b/applicationset/services/scm_provider/gitlab_test.go index 11b21cb6da6d4..b93616fa8367f 100644 --- a/applicationset/services/scm_provider/gitlab_test.go +++ b/applicationset/services/scm_provider/gitlab_test.go @@ -1063,6 +1063,16 @@ func TestGitlabListRepos(t *testing.T) { proto: "ssh", url: "git@gitlab.com:test-argocd-proton/argocd.git", }, + { + name: "labelmatch", + proto: "ssh", + url: "git@gitlab.com:test-argocd-proton/argocd.git", + filters: []v1alpha1.SCMProviderGeneratorFilter{ + { + LabelMatch: strp("test-topic"), + }, + }, + }, { name: "https protocol", proto: "https", diff --git a/docs/operator-manual/applicationset/Generators-SCM-Provider.md b/docs/operator-manual/applicationset/Generators-SCM-Provider.md index 6b11d344eac80..40c8e552fe573 100644 --- a/docs/operator-manual/applicationset/Generators-SCM-Provider.md +++ b/docs/operator-manual/applicationset/Generators-SCM-Provider.md @@ -111,7 +111,7 @@ spec: * `tokenRef`: A `Secret` name and key containing the GitLab access token to use for requests. If not specified, will make anonymous requests which have a lower rate limit and can only see public repositories. * `insecure`: By default (false) - Skip checking the validity of the SCM's certificate - useful for self-signed TLS certificates. -For label filtering, the repository tags are used. +For label filtering, the repository topics are used. Available clone protocols are `ssh` and `https`. From 9fa5e25fda8670027049aa46a07cb41dc7fa2ce5 Mon Sep 17 00:00:00 2001 From: Ivan Smirnov Date: Mon, 20 Nov 2023 02:33:11 -0700 Subject: [PATCH 110/269] Add traefik pending ingress solution (#16391) --- docs/faq.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/faq.md b/docs/faq.md index 19273acc04d23..95205ae6bbb4e 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -36,6 +36,15 @@ which might cause health check to return `Progressing` state instead of `Healthy As workaround Argo CD allows providing [health check](operator-manual/health.md) customization which overrides default behavior. +If you are using Traefik for your Ingress, you can update the Traefik config to publish the loadBalancer IP using [publishedservice](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice), which will resolve this issue. + +```yaml +providers: + kubernetesIngress: + publishedService: + enabled: true +``` + ## I forgot the admin password, how do I reset it? For Argo CD v1.8 and earlier, the initial password is set to the name of the server pod, as From 841339d2ff719d5f3f5ca5359afc6c3dc3709453 Mon Sep 17 00:00:00 2001 From: "Marco Maurer (-Kilchhofer)" Date: Mon, 20 Nov 2023 10:34:04 +0100 Subject: [PATCH 111/269] chore: Use safe example domains defined in RFC 2606 (#16389) --- .../pull_request/azure_devops_test.go | 4 +-- controller/cache/info_test.go | 36 +++++++++---------- docs/operator-manual/custom-styles.md | 2 +- docs/operator-manual/declarative-setup.md | 20 +++++------ docs/operator-manual/high_availability.md | 4 +-- docs/operator-manual/ingress.md | 10 +++--- docs/operator-manual/user-management/index.md | 14 ++++---- ...parameterized-config-management-plugins.md | 36 +++++++++---------- docs/proposals/project-repos-and-clusters.md | 2 +- docs/user-guide/ci_automation.md | 2 +- docs/user-guide/environment-variables.md | 2 +- docs/user-guide/external-url.md | 2 +- docs/user-guide/projects.md | 6 ++-- pkg/apis/application/v1alpha1/types_test.go | 2 +- .../testdata/degraded_acmeFailed.yaml | 2 +- .../testdata/healthy_registered.yaml | 2 +- .../testdata/progressing_noStatus.yaml | 2 +- .../Issuer/testdata/degraded_acmeFailed.yaml | 2 +- .../Issuer/testdata/healthy_registered.yaml | 2 +- .../Issuer/testdata/progressing_noStatus.yaml | 2 +- .../Issuer/testdata/degraded_acmeFailed.yaml | 2 +- .../Issuer/testdata/healthy_registered.yaml | 2 +- .../Issuer/testdata/progressing_noStatus.yaml | 2 +- server/application/application_test.go | 16 ++++----- server/applicationset/applicationset_test.go | 2 +- server/deeplinks/deeplinks_test.go | 2 +- server/notification/notification_test.go | 2 +- test/e2e/notification_test.go | 2 +- .../networking/guestbook-ui-svc-ingress.yaml | 4 +-- util/dex/dex_test.go | 4 +-- util/notification/settings/settings_test.go | 2 +- 31 files changed, 97 insertions(+), 97 deletions(-) diff --git a/applicationset/services/pull_request/azure_devops_test.go b/applicationset/services/pull_request/azure_devops_test.go index 15ac1c8233d89..5ed8f4de78b9d 100644 --- a/applicationset/services/pull_request/azure_devops_test.go +++ b/applicationset/services/pull_request/azure_devops_test.go @@ -206,9 +206,9 @@ func TestBuildURL(t *testing.T) { }, { name: "Provided custom URL and organization", - url: "https://azuredevops.mycompany.com/", + url: "https://azuredevops.example.com/", organization: "myorganization", - expected: "https://azuredevops.mycompany.com/myorganization", + expected: "https://azuredevops.example.com/myorganization", }, } diff --git a/controller/cache/info_test.go b/controller/cache/info_test.go index ad5202532589b..7b48040009284 100644 --- a/controller/cache/info_test.go +++ b/controller/cache/info_test.go @@ -52,7 +52,7 @@ var ( resourceVersion: "123" uid: "4" annotations: - link.argocd.argoproj.io/external-link: http://my-grafana.com/pre-generated-link + link.argocd.argoproj.io/external-link: http://my-grafana.example.com/pre-generated-link spec: selector: app: guestbook @@ -74,7 +74,7 @@ var ( serviceName: not-found-service servicePort: 443 rules: - - host: helm-guestbook.com + - host: helm-guestbook.example.com http: paths: - backend: @@ -86,7 +86,7 @@ var ( servicePort: https path: / tls: - - host: helm-guestbook.com + - host: helm-guestbook.example.com secretName: my-tls-secret status: loadBalancer: @@ -101,13 +101,13 @@ var ( namespace: default uid: "4" annotations: - link.argocd.argoproj.io/external-link: http://my-grafana.com/ingress-link + link.argocd.argoproj.io/external-link: http://my-grafana.example.com/ingress-link spec: backend: serviceName: not-found-service servicePort: 443 rules: - - host: helm-guestbook.com + - host: helm-guestbook.example.com http: paths: - backend: @@ -119,7 +119,7 @@ var ( servicePort: https path: / tls: - - host: helm-guestbook.com + - host: helm-guestbook.example.com secretName: my-tls-secret status: loadBalancer: @@ -138,7 +138,7 @@ var ( serviceName: not-found-service servicePort: 443 rules: - - host: helm-guestbook.com + - host: helm-guestbook.example.com http: paths: - backend: @@ -150,7 +150,7 @@ var ( servicePort: https path: /* tls: - - host: helm-guestbook.com + - host: helm-guestbook.example.com secretName: my-tls-secret status: loadBalancer: @@ -169,7 +169,7 @@ var ( serviceName: not-found-service servicePort: 443 rules: - - host: helm-guestbook.com + - host: helm-guestbook.example.com http: paths: - backend: @@ -199,7 +199,7 @@ var ( port: number: 443 rules: - - host: helm-guestbook.com + - host: helm-guestbook.example.com http: paths: - backend: @@ -215,7 +215,7 @@ var ( name: https path: / tls: - - host: helm-guestbook.com + - host: helm-guestbook.example.com secretName: my-tls-secret status: loadBalancer: @@ -327,7 +327,7 @@ func TestGetLinkAnnotatedServiceInfo(t *testing.T) { assert.Equal(t, &v1alpha1.ResourceNetworkingInfo{ TargetLabels: map[string]string{"app": "guestbook"}, Ingress: []v1.LoadBalancerIngress{{Hostname: "localhost"}}, - ExternalURLs: []string{"http://my-grafana.com/pre-generated-link"}, + ExternalURLs: []string{"http://my-grafana.example.com/pre-generated-link"}, }, info.NetworkingInfo) } @@ -381,7 +381,7 @@ func TestGetIngressInfo(t *testing.T) { Kind: kube.ServiceKind, Name: "helm-guestbook", }}, - ExternalURLs: []string{"https://helm-guestbook.com/"}, + ExternalURLs: []string{"https://helm-guestbook.example.com/"}, }, info.NetworkingInfo) } } @@ -406,7 +406,7 @@ func TestGetLinkAnnotatedIngressInfo(t *testing.T) { Kind: kube.ServiceKind, Name: "helm-guestbook", }}, - ExternalURLs: []string{"http://my-grafana.com/ingress-link", "https://helm-guestbook.com/"}, + ExternalURLs: []string{"http://my-grafana.example.com/ingress-link", "https://helm-guestbook.example.com/"}, }, info.NetworkingInfo) } @@ -430,7 +430,7 @@ func TestGetIngressInfoWildCardPath(t *testing.T) { Kind: kube.ServiceKind, Name: "helm-guestbook", }}, - ExternalURLs: []string{"https://helm-guestbook.com/"}, + ExternalURLs: []string{"https://helm-guestbook.example.com/"}, }, info.NetworkingInfo) } @@ -454,7 +454,7 @@ func TestGetIngressInfoWithoutTls(t *testing.T) { Kind: kube.ServiceKind, Name: "helm-guestbook", }}, - ExternalURLs: []string{"http://helm-guestbook.com/"}, + ExternalURLs: []string{"http://helm-guestbook.example.com/"}, }, info.NetworkingInfo) } @@ -563,7 +563,7 @@ func TestExternalUrlWithMultipleSubPaths(t *testing.T) { namespace: default spec: rules: - - host: helm-guestbook.com + - host: helm-guestbook.example.com http: paths: - backend: @@ -587,7 +587,7 @@ func TestExternalUrlWithMultipleSubPaths(t *testing.T) { info := &ResourceInfo{} populateNodeInfo(ingress, info, []string{}) - expectedExternalUrls := []string{"https://helm-guestbook.com/my/sub/path/", "https://helm-guestbook.com/my/sub/path/2", "https://helm-guestbook.com"} + expectedExternalUrls := []string{"https://helm-guestbook.example.com/my/sub/path/", "https://helm-guestbook.example.com/my/sub/path/2", "https://helm-guestbook.example.com"} actualURLs := info.NetworkingInfo.ExternalURLs sort.Strings(expectedExternalUrls) sort.Strings(actualURLs) diff --git a/docs/operator-manual/custom-styles.md b/docs/operator-manual/custom-styles.md index 893720f7bc9c0..6f68d5e23b128 100644 --- a/docs/operator-manual/custom-styles.md +++ b/docs/operator-manual/custom-styles.md @@ -21,7 +21,7 @@ metadata: ... name: argocd-cm data: - ui.cssurl: "https://www.myhost.com/my-styles.css" + ui.cssurl: "https://www.example.com/my-styles.css" ``` ## Adding Styles Via Volume Mounts diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index 1694429ffc25c..a156f27589dbd 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -590,8 +590,8 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: mycluster.com - server: https://mycluster.com + name: mycluster.example.com + server: https://mycluster.example.com config: | { "bearerToken": "", @@ -615,8 +615,8 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: "mycluster.com" - server: "https://mycluster.com" + name: "mycluster.example.com" + server: "https://mycluster.example.com" config: | { "awsAuthConfig": { @@ -742,8 +742,8 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: mycluster.com - server: https://mycluster.com + name: mycluster.example.com + server: https://mycluster.example.com config: | { "execProviderConfig": { @@ -795,8 +795,8 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: mycluster.com - server: https://mycluster.com + name: mycluster.example.com + server: https://mycluster.example.com config: | { "execProviderConfig": { @@ -830,8 +830,8 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: mycluster.com - server: https://mycluster.com + name: mycluster.example.com + server: https://mycluster.example.com config: | { "execProviderConfig": { diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index 7de532d9632c3..b2051ad1a152c 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -98,8 +98,8 @@ metadata: type: Opaque stringData: shard: 1 - name: mycluster.com - server: https://mycluster.com + name: mycluster.example.com + server: https://mycluster.example.com config: | { "bearerToken": "", diff --git a/docs/operator-manual/ingress.md b/docs/operator-manual/ingress.md index 84b2bcaf34a67..5ea947345d507 100644 --- a/docs/operator-manual/ingress.md +++ b/docs/operator-manual/ingress.md @@ -661,9 +661,9 @@ metadata: networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config spec: tls: - - secretName: secret-yourdomain-com + - secretName: secret-example-com rules: - - host: argocd.yourdomain.com + - host: argocd.example.com http: paths: - pathType: ImplementationSpecific @@ -686,9 +686,9 @@ metadata: networking.gke.io/v1beta1.FrontendConfig: argocd-frontend-config spec: tls: - - secretName: secret-yourdomain-com + - secretName: secret-example-com rules: - - host: argocd.yourdomain.com + - host: argocd.example.com http: paths: - pathType: Prefix @@ -700,7 +700,7 @@ spec: number: 80 ``` -As you may know already, it can take some minutes to deploy the load balancer and become ready to accept connections. Once it's ready, get the public IP address for your Load Balancer, go to your DNS server (Google or third party) and point your domain or subdomain (i.e. argocd.yourdomain.com) to that IP address. +As you may know already, it can take some minutes to deploy the load balancer and become ready to accept connections. Once it's ready, get the public IP address for your Load Balancer, go to your DNS server (Google or third party) and point your domain or subdomain (i.e. argocd.example.com) to that IP address. You can get that IP address describing the Ingress object like this: diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index 8e459202456eb..8a5ba7802676d 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -201,7 +201,7 @@ data: id: acme-github name: Acme GitHub config: - hostName: github.acme.com + hostName: github.acme.example.com clientID: abcdefghijklmnopqrst clientSecret: $dex.acme.clientSecret # Alternatively $:dex.acme.clientSecret orgs: @@ -242,7 +242,7 @@ data: id: oidc name: OIDC config: - issuer: https://example-OIDC-provider.com + issuer: https://example-OIDC-provider.example.com clientID: aaaabbbbccccddddeee clientSecret: $dex.oidc.clientSecret ``` @@ -264,7 +264,7 @@ data: id: oidc name: OIDC config: - issuer: https://example-OIDC-provider.com + issuer: https://example-OIDC-provider.example.com clientID: aaaabbbbccccddddeee clientSecret: $dex.oidc.clientSecret insecureEnableGroups: true @@ -294,7 +294,7 @@ data: id: oidc name: OIDC config: - issuer: https://example-OIDC-provider.com + issuer: https://example-OIDC-provider.example.com clientID: aaaabbbbccccddddeee clientSecret: $dex.oidc.clientSecret insecureEnableGroups: true @@ -395,18 +395,18 @@ any active session post logout, you can do so by specifying it as follows: ```yaml oidc.config: | name: example-OIDC-provider - issuer: https://example-OIDC-provider.com + issuer: https://example-OIDC-provider.example.com clientID: xxxxxxxxx clientSecret: xxxxxxxxx requestedScopes: ["openid", "profile", "email", "groups"] requestedIDTokenClaims: {"groups": {"essential": true}} - logoutURL: https://example-OIDC-provider.com/logout?id_token_hint={{token}} + logoutURL: https://example-OIDC-provider.example.com/logout?id_token_hint={{token}} ``` By default, this would take the user to their OIDC provider's login page after logout. If you also wish to redirect the user back to Argo CD after logout, you can specify the logout URL as follows: ```yaml ... - logoutURL: https://example-OIDC-provider.com/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}} + logoutURL: https://example-OIDC-provider.example.com/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}} ``` You are not required to specify a logoutRedirectURL as this is automatically generated by ArgoCD as your base ArgoCD url + Rootpath diff --git a/docs/proposals/parameterized-config-management-plugins.md b/docs/proposals/parameterized-config-management-plugins.md index fa3061b2c3686..749f4efe63687 100644 --- a/docs/proposals/parameterized-config-management-plugins.md +++ b/docs/proposals/parameterized-config-management-plugins.md @@ -256,7 +256,7 @@ spec: array: [values.yaml] - name: helm-parameters map: - image.repository: my.company.com/gcr-proxy/heptio-images/ks-guestbook-demo + image.repository: my.example.com/gcr-proxy/heptio-images/ks-guestbook-demo image.tag: "0.1" ``` @@ -283,7 +283,7 @@ That command, when run by a CMP with the above Application manifest, will print { "name": "helm-parameters", "map": { - "image.repository": "my.company.com/gcr-proxy/heptio-images/ks-guestbook-demo", + "image.repository": "my.example.com/gcr-proxy/heptio-images/ks-guestbook-demo", "image.tag": "0.1" } } @@ -398,7 +398,7 @@ like this: "title": "Helm Parameters", "tooltip": "Parameters to override when generating manifests with Helm", "map": { - "image.repository": "my.company.com/gcr-proxy/heptio-images/ks-guestbook-demo", + "image.repository": "my.example.com/gcr-proxy/heptio-images/ks-guestbook-demo", "image.tag": "0.1" } } @@ -423,7 +423,7 @@ readability.) "title": "Helm Parameters", "tooltip": "Parameters to override when generating manifests with Helm", "map": { - "image.repository": "my.company.com/gcr-proxy/heptio-images/ks-guestbook-demo", + "image.repository": "my.example.com/gcr-proxy/heptio-images/ks-guestbook-demo", "image.tag": "0.1" } } @@ -493,11 +493,11 @@ type ParametersAnnouncement []ParameterAnnouncement - name: images collectionType: map array: # this gets ignored because collectionType is 'map' - - ubuntu:latest=docker.company.com/proxy/ubuntu:latest - - guestbook:v0.1=docker.company.com/proxy/guestbook:v0.1 + - ubuntu:latest=docker.example.com/proxy/ubuntu:latest + - guestbook:v0.1=docker.example.com/proxy/guestbook:v0.1 map: - ubuntu:latest: docker.company.com/proxy/ubuntu:latest - guestbook:v0.1: docker.company.com/proxy/guestbook:v0.1 + ubuntu:latest: docker.example.com/proxy/ubuntu:latest + guestbook:v0.1: docker.example.com/proxy/guestbook:v0.1 ``` 2. **Question**: What do we do if the CMP user sets more than one of `value`/`array`/`map` in the Application spec? @@ -513,11 +513,11 @@ type ParametersAnnouncement []ParameterAnnouncement parameters: - name: images array: # this gets sent to the CMP, but the CMP should ignore it - - ubuntu:latest=docker.company.com/proxy/ubuntu:latest - - guestbook:v0.1=docker.company.com/proxy/guestbook:v0.1 + - ubuntu:latest=docker.example.com/proxy/ubuntu:latest + - guestbook:v0.1=docker.example.com/proxy/guestbook:v0.1 map: - ubuntu:latest: docker.company.com/proxy/ubuntu:latest - guestbook:v0.1: docker.company.com/proxy/guestbook:v0.1 + ubuntu:latest: docker.example.com/proxy/ubuntu:latest + guestbook:v0.1: docker.example.com/proxy/guestbook:v0.1 ``` 3. **Question**: How will the UI know that adding more items to an array or a map is allowed? @@ -528,17 +528,17 @@ type ParametersAnnouncement []ParameterAnnouncement - name: images collectionType: map # users will be allowed to add new items, because this is a map map: - ubuntu:latest: docker.company.com/proxy/ubuntu:latest - guestbook:v0.1: docker.company.com/proxy/guestbook:v0.1 + ubuntu:latest: docker.example.com/proxy/ubuntu:latest + guestbook:v0.1: docker.example.com/proxy/guestbook:v0.1 ``` If the CMP author wants an immutable array or map, they should just break it into individual parameters. ```yaml - name: ubuntu:latest - string: docker.company.com/proxy/ubuntu:latest + string: docker.example.com/proxy/ubuntu:latest - name: guestbook:v0.1 - string: docker.company.com/proxy/guestbook:v0.1 + string: docker.example.com/proxy/guestbook:v0.1 ``` 4. **Question**: What do we do if a CMP announcement doesn't include a `collectionType`? @@ -799,8 +799,8 @@ spec: "title": "Image Overrides", "collectionType": "map", "map": { - "quay.io/argoproj/argocd": "docker.company.com/proxy/argoproj/argocd", - "ubuntu:latest": "docker.company.com/proxy/argoproj/argocd" + "quay.io/argoproj/argocd": "docker.example.com/proxy/argoproj/argocd", + "ubuntu:latest": "docker.example.com/proxy/argoproj/argocd" } } ] diff --git a/docs/proposals/project-repos-and-clusters.md b/docs/proposals/project-repos-and-clusters.md index 1f8258f47a72b..514c389048218 100644 --- a/docs/proposals/project-repos-and-clusters.md +++ b/docs/proposals/project-repos-and-clusters.md @@ -102,7 +102,7 @@ p, proj:my-project:admin, repositories, update, my-project/*, allow This provides extra flexibility so that admin can have stricter rules. e.g.: ``` -p, proj:my-project:admin, repositories, update, my-project/"https://github.my-company.com/*", allow +p, proj:my-project:admin, repositories, update, my-project/"https://github.example.com/*", allow ``` #### UI/CLI Changes diff --git a/docs/user-guide/ci_automation.md b/docs/user-guide/ci_automation.md index 14d35dc3cb2cd..433483eba7a3f 100644 --- a/docs/user-guide/ci_automation.md +++ b/docs/user-guide/ci_automation.md @@ -43,7 +43,7 @@ useful so that the CLI used in the CI pipeline is always kept in-sync and uses a that is always compatible with the Argo CD API server. ```bash -export ARGOCD_SERVER=argocd.mycompany.com +export ARGOCD_SERVER=argocd.example.com export ARGOCD_AUTH_TOKEN= curl -sSL -o /usr/local/bin/argocd https://${ARGOCD_SERVER}/download/argocd-linux-amd64 argocd app sync guestbook diff --git a/docs/user-guide/environment-variables.md b/docs/user-guide/environment-variables.md index c990073363f04..cff6446617fa3 100644 --- a/docs/user-guide/environment-variables.md +++ b/docs/user-guide/environment-variables.md @@ -4,7 +4,7 @@ The following environment variables can be used with `argocd` CLI: | Environment Variable | Description | |--------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ARGOCD_SERVER` | the address of the Argo CD server without `https://` prefix
    (instead of specifying `--server` for every command)
    eg. `ARGOCD_SERVER=argocd.mycompany.com` if served through an ingress with DNS | +| `ARGOCD_SERVER` | the address of the Argo CD server without `https://` prefix
    (instead of specifying `--server` for every command)
    eg. `ARGOCD_SERVER=argocd.example.com` if served through an ingress with DNS | | `ARGOCD_AUTH_TOKEN` | the Argo CD `apiKey` for your Argo CD user to be able to authenticate | | `ARGOCD_OPTS` | command-line options to pass to `argocd` CLI
    eg. `ARGOCD_OPTS="--grpc-web"` | | `ARGOCD_SERVER_NAME` | the Argo CD API Server name (default "argocd-server") | diff --git a/docs/user-guide/external-url.md b/docs/user-guide/external-url.md index 792b8465b233b..7f08ea6c80bf4 100644 --- a/docs/user-guide/external-url.md +++ b/docs/user-guide/external-url.md @@ -12,7 +12,7 @@ kind: Deployment metadata: name: my-svc annotations: - link.argocd.argoproj.io/external-link: http://my-grafana.com/pre-generated-link + link.argocd.argoproj.io/external-link: http://my-grafana.example.com/pre-generated-link ``` ![External link](../assets/external-link.png) diff --git a/docs/user-guide/projects.md b/docs/user-guide/projects.md index 9876405febdeb..f5979cf3c47b3 100644 --- a/docs/user-guide/projects.md +++ b/docs/user-guide/projects.md @@ -292,7 +292,7 @@ p, proj:my-project:admin, repositories, update, my-project/*, allow This provides extra flexibility so that admins can have stricter rules. e.g.: ``` -p, proj:my-project:admin, repositories, update, my-project/https://github.my-company.com/*, allow +p, proj:my-project:admin, repositories, update, my-project/https://github.example.com/*, allow ``` Once the appropriate RBAC rules are in place, developers can create their own Git repositories and (assuming @@ -330,9 +330,9 @@ metadata: argocd.argoproj.io/secret-type: cluster type: Opaque stringData: - name: mycluster.com + name: mycluster.example.com project: my-project1 # Project scoped - server: https://mycluster.com + server: https://mycluster.example.com config: | { "bearerToken": "", diff --git a/pkg/apis/application/v1alpha1/types_test.go b/pkg/apis/application/v1alpha1/types_test.go index 668cf97b07e5a..2374f5fb503e6 100644 --- a/pkg/apis/application/v1alpha1/types_test.go +++ b/pkg/apis/application/v1alpha1/types_test.go @@ -370,7 +370,7 @@ func TestAppProject_IsDestinationPermitted_PermitOnlyProjectScopedClusters(t *te projDest: []ApplicationDestination{{ Server: "https://my-cluster.123.com", Namespace: "default", }}, - appDest: ApplicationDestination{Server: "https://some-other-cluster.com", Namespace: "default"}, + appDest: ApplicationDestination{Server: "https://some-other-cluster.example.com", Namespace: "default"}, clusters: []*Cluster{{ Server: "https://my-cluster.123.com", }}, diff --git a/resource_customizations/cert-manager.io/ClusterIssuer/testdata/degraded_acmeFailed.yaml b/resource_customizations/cert-manager.io/ClusterIssuer/testdata/degraded_acmeFailed.yaml index 75a249feb3da6..c99c1f4f84ba4 100644 --- a/resource_customizations/cert-manager.io/ClusterIssuer/testdata/degraded_acmeFailed.yaml +++ b/resource_customizations/cert-manager.io/ClusterIssuer/testdata/degraded_acmeFailed.yaml @@ -8,7 +8,7 @@ metadata: uid: 37f408e3-3157-11e9-be3f-42010a800011 spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/cert-manager.io/ClusterIssuer/testdata/healthy_registered.yaml b/resource_customizations/cert-manager.io/ClusterIssuer/testdata/healthy_registered.yaml index edad50241c40b..e883b51e3a793 100644 --- a/resource_customizations/cert-manager.io/ClusterIssuer/testdata/healthy_registered.yaml +++ b/resource_customizations/cert-manager.io/ClusterIssuer/testdata/healthy_registered.yaml @@ -8,7 +8,7 @@ metadata: uid: b0045219-e219-11e8-9f93-42010a80021d spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/cert-manager.io/ClusterIssuer/testdata/progressing_noStatus.yaml b/resource_customizations/cert-manager.io/ClusterIssuer/testdata/progressing_noStatus.yaml index b05c4aeb7d13f..4571d229ffed7 100644 --- a/resource_customizations/cert-manager.io/ClusterIssuer/testdata/progressing_noStatus.yaml +++ b/resource_customizations/cert-manager.io/ClusterIssuer/testdata/progressing_noStatus.yaml @@ -8,7 +8,7 @@ metadata: uid: b0045219-e219-11e8-9f93-42010a80021d spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/cert-manager.io/Issuer/testdata/degraded_acmeFailed.yaml b/resource_customizations/cert-manager.io/Issuer/testdata/degraded_acmeFailed.yaml index 62226e3b3be62..a5abcf57a5ac2 100644 --- a/resource_customizations/cert-manager.io/Issuer/testdata/degraded_acmeFailed.yaml +++ b/resource_customizations/cert-manager.io/Issuer/testdata/degraded_acmeFailed.yaml @@ -10,7 +10,7 @@ metadata: uid: 37f408e3-3157-11e9-be3f-42010a800011 spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/cert-manager.io/Issuer/testdata/healthy_registered.yaml b/resource_customizations/cert-manager.io/Issuer/testdata/healthy_registered.yaml index 08b96394ec823..07181567145f2 100644 --- a/resource_customizations/cert-manager.io/Issuer/testdata/healthy_registered.yaml +++ b/resource_customizations/cert-manager.io/Issuer/testdata/healthy_registered.yaml @@ -10,7 +10,7 @@ metadata: uid: b0045219-e219-11e8-9f93-42010a80021d spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/cert-manager.io/Issuer/testdata/progressing_noStatus.yaml b/resource_customizations/cert-manager.io/Issuer/testdata/progressing_noStatus.yaml index 820182e3e1e6a..f2e7b80e7f0b5 100644 --- a/resource_customizations/cert-manager.io/Issuer/testdata/progressing_noStatus.yaml +++ b/resource_customizations/cert-manager.io/Issuer/testdata/progressing_noStatus.yaml @@ -10,7 +10,7 @@ metadata: uid: b0045219-e219-11e8-9f93-42010a80021d spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/certmanager.k8s.io/Issuer/testdata/degraded_acmeFailed.yaml b/resource_customizations/certmanager.k8s.io/Issuer/testdata/degraded_acmeFailed.yaml index dbd819ca9f113..5f0dbec676917 100644 --- a/resource_customizations/certmanager.k8s.io/Issuer/testdata/degraded_acmeFailed.yaml +++ b/resource_customizations/certmanager.k8s.io/Issuer/testdata/degraded_acmeFailed.yaml @@ -10,7 +10,7 @@ metadata: uid: 37f408e3-3157-11e9-be3f-42010a800011 spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/certmanager.k8s.io/Issuer/testdata/healthy_registered.yaml b/resource_customizations/certmanager.k8s.io/Issuer/testdata/healthy_registered.yaml index db0a81b941bab..a5f6aa14986d6 100644 --- a/resource_customizations/certmanager.k8s.io/Issuer/testdata/healthy_registered.yaml +++ b/resource_customizations/certmanager.k8s.io/Issuer/testdata/healthy_registered.yaml @@ -10,7 +10,7 @@ metadata: uid: b0045219-e219-11e8-9f93-42010a80021d spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/resource_customizations/certmanager.k8s.io/Issuer/testdata/progressing_noStatus.yaml b/resource_customizations/certmanager.k8s.io/Issuer/testdata/progressing_noStatus.yaml index 68f35fa773256..501b7aa20060f 100644 --- a/resource_customizations/certmanager.k8s.io/Issuer/testdata/progressing_noStatus.yaml +++ b/resource_customizations/certmanager.k8s.io/Issuer/testdata/progressing_noStatus.yaml @@ -10,7 +10,7 @@ metadata: uid: b0045219-e219-11e8-9f93-42010a80021d spec: acme: - email: myemail@test.com + email: myemail@example.com http01: {} privateKeySecretRef: key: "" diff --git a/server/application/application_test.go b/server/application/application_test.go index c0f7d000b1506..65600ad629d3f 100644 --- a/server/application/application_test.go +++ b/server/application/application_test.go @@ -76,7 +76,7 @@ func fakeRepo() *appsv1.Repository { func fakeCluster() *appsv1.Cluster { return &appsv1.Cluster{ - Server: "https://cluster-api.com", + Server: "https://cluster-api.example.com", Name: "fake-cluster", Config: appsv1.ClusterConfig{}, } @@ -503,7 +503,7 @@ spec: environment: default destination: namespace: ` + test.FakeDestNamespace + ` - server: https://cluster-api.com + server: https://cluster-api.example.com ` const fakeAppWithDestName = ` @@ -541,7 +541,7 @@ spec: environment: default destination: namespace: ` + test.FakeDestNamespace + ` - server: https://cluster-api.com + server: https://cluster-api.example.com ` func newTestAppWithDestName(opts ...func(app *appsv1.Application)) *appsv1.Application { @@ -797,22 +797,22 @@ func TestNoAppEnumeration(t *testing.T) { t.Run("UpdateSpec", func(t *testing.T) { _, err := appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: pointer.String("test"), Spec: &appsv1.ApplicationSpec{ - Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.com"}, + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) assert.NoError(t, err) _, err = appServer.UpdateSpec(noRoleCtx, &application.ApplicationUpdateSpecRequest{Name: pointer.String("test"), Spec: &appsv1.ApplicationSpec{ - Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.com"}, + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: pointer.String("doest-not-exist"), Spec: &appsv1.ApplicationSpec{ - Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.com"}, + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) assert.Equal(t, permissionDeniedErr.Error(), err.Error(), "error message must be _only_ the permission error, to avoid leaking information about app existence") _, err = appServer.UpdateSpec(adminCtx, &application.ApplicationUpdateSpecRequest{Name: pointer.String("doest-not-exist"), Project: pointer.String("test"), Spec: &appsv1.ApplicationSpec{ - Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.com"}, + Destination: appsv1.ApplicationDestination{Namespace: "default", Server: "https://cluster-api.example.com"}, Source: &appsv1.ApplicationSource{RepoURL: "https://some-fake-source", Path: "."}, }}) assert.Equal(t, "rpc error: code = NotFound desc = applications.argoproj.io \"doest-not-exist\" not found", err.Error(), "when the request specifies a project, we can return the standard k8s error message") @@ -1436,7 +1436,7 @@ func TestCreateAppWithDestName(t *testing.T) { app, err := appServer.Create(context.Background(), &createReq) assert.NoError(t, err) assert.NotNil(t, app) - assert.Equal(t, app.Spec.Destination.Server, "https://cluster-api.com") + assert.Equal(t, app.Spec.Destination.Server, "https://cluster-api.example.com") } func TestUpdateApp(t *testing.T) { diff --git a/server/applicationset/applicationset_test.go b/server/applicationset/applicationset_test.go index c5a299c85f358..c49ddb35a7970 100644 --- a/server/applicationset/applicationset_test.go +++ b/server/applicationset/applicationset_test.go @@ -38,7 +38,7 @@ func fakeRepo() *appsv1.Repository { func fakeCluster() *appsv1.Cluster { return &appsv1.Cluster{ - Server: "https://cluster-api.com", + Server: "https://cluster-api.example.com", Name: "fake-cluster", Config: appsv1.ClusterConfig{}, } diff --git a/server/deeplinks/deeplinks_test.go b/server/deeplinks/deeplinks_test.go index abebe691c29c1..09ad64671af9b 100644 --- a/server/deeplinks/deeplinks_test.go +++ b/server/deeplinks/deeplinks_test.go @@ -35,7 +35,7 @@ func TestDeepLinks(t *testing.T) { }, Spec: v1alpha1.ApplicationSpec{ Destination: v1alpha1.ApplicationDestination{ - Server: "test.com", + Server: "test.example.com", Namespace: "testns", }, }, diff --git a/server/notification/notification_test.go b/server/notification/notification_test.go index 47606b24ea855..c1141e7ad6753 100644 --- a/server/notification/notification_test.go +++ b/server/notification/notification_test.go @@ -41,7 +41,7 @@ func TestNotificationServer(t *testing.T) { Name: "argocd-notifications-cm", }, Data: map[string]string{ - "service.webhook.test": "url: https://test.com", + "service.webhook.test": "url: https://test.example.com", "template.app-created": "email:\n subject: Application {{.app.metadata.name}} has been created.\nmessage: Application {{.app.metadata.name}} has been created.\nteams:\n title: Application {{.app.metadata.name}} has been created.\n", "trigger.on-created": "- description: Application is created.\n oncePer: app.metadata.name\n send:\n - app-created\n when: \"true\"\n", }, diff --git a/test/e2e/notification_test.go b/test/e2e/notification_test.go index 363cb87454a0f..eebe4d8991ae5 100644 --- a/test/e2e/notification_test.go +++ b/test/e2e/notification_test.go @@ -12,7 +12,7 @@ import ( func TestNotificationsListServices(t *testing.T) { ctx := notifFixture.Given(t) ctx.When(). - SetParamInNotificationConfigMap("service.webhook.test", "url: https://test.com"). + SetParamInNotificationConfigMap("service.webhook.test", "url: https://test.example.com"). Then().Services(func(services *notification.ServiceList, err error) { assert.Nil(t, err) assert.Equal(t, []*notification.Service{{Name: pointer.String("test")}}, services.Items) diff --git a/test/e2e/testdata/networking/guestbook-ui-svc-ingress.yaml b/test/e2e/testdata/networking/guestbook-ui-svc-ingress.yaml index d499de1e9c308..a4427135b193d 100644 --- a/test/e2e/testdata/networking/guestbook-ui-svc-ingress.yaml +++ b/test/e2e/testdata/networking/guestbook-ui-svc-ingress.yaml @@ -9,7 +9,7 @@ metadata: ingress.kubernetes.io/app-root: "/" spec: rules: - - host: myhost.com + - host: example.com http: paths: - path: / @@ -27,7 +27,7 @@ metadata: ingress.kubernetes.io/app-root: "/" spec: rules: - - host: myhost.com + - host: example.com http: paths: - path: / diff --git a/util/dex/dex_test.go b/util/dex/dex_test.go index b531e1470b788..e15726d44f501 100644 --- a/util/dex/dex_test.go +++ b/util/dex/dex_test.go @@ -42,7 +42,7 @@ connectors: id: acme-github name: Acme GitHub config: - hostName: github.acme.com + hostName: github.acme.example.com clientID: abcdefghijklmnopqrst clientSecret: $dex.acme.clientSecret orgs: @@ -79,7 +79,7 @@ connectors: id: acme-github name: Acme GitHub config: - hostName: github.acme.com + hostName: github.acme.example.com clientID: abcdefghijklmnopqrst clientSecret: $dex.acme.clientSecret orgs: diff --git a/util/notification/settings/settings_test.go b/util/notification/settings/settings_test.go index 21c2eaf416d37..176839b51740e 100644 --- a/util/notification/settings/settings_test.go +++ b/util/notification/settings/settings_test.go @@ -27,7 +27,7 @@ func TestInitGetVars(t *testing.T) { }, Data: map[string]string{ "context": fmt.Sprintf("%s: %s", testContextKey, testContextKeyValue), - "service.webhook.test": "url: https://test.com", + "service.webhook.test": "url: https://test.example.com", "template.app-created": "email:\n subject: Application {{.app.metadata.name}} has been created.\nmessage: Application {{.app.metadata.name}} has been created.\nteams:\n title: Application {{.app.metadata.name}} has been created.\n", "trigger.on-created": "- description: Application is created.\n oncePer: app.metadata.name\n send:\n - app-created\n when: \"true\"\n", }, From 61abc805731962cfd20159c315d8ed436870b0e7 Mon Sep 17 00:00:00 2001 From: Brian Fox <878612+onematchfox@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:58:28 +0100 Subject: [PATCH 112/269] fix: set max for max cookie number to `math.MaxInt` (#16388) * fix: set max for max cookie number to `math.MaxInt32` Signed-off-by: OneMatchFox <878612+onematchfox@users.noreply.github.com> * refactor: set max for max cookie number to `math.MaxInt` Co-authored-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com> --------- Signed-off-by: OneMatchFox <878612+onematchfox@users.noreply.github.com> Signed-off-by: Brian Fox <878612+onematchfox@users.noreply.github.com> Co-authored-by: gdsoumya <44349253+gdsoumya@users.noreply.github.com> --- util/http/http.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/http/http.go b/util/http/http.go index fcf8447e1e2f6..7c13c71fde223 100644 --- a/util/http/http.go +++ b/util/http/http.go @@ -30,7 +30,7 @@ const ( // max number of chunks a cookie can be broken into. To be compatible with // widest range of browsers, you shouldn't create more than 30 cookies per domain -var maxCookieNumber = env.ParseNumFromEnv(common.EnvMaxCookieNumber, 20, 0, math.MaxInt64) +var maxCookieNumber = env.ParseNumFromEnv(common.EnvMaxCookieNumber, 20, 0, math.MaxInt) // MakeCookieMetadata generates a string representing a Web cookie. Yum! func MakeCookieMetadata(key, value string, flags ...string) ([]string, error) { From 8d8009d676b0d46a7dd0764125580742fda06112 Mon Sep 17 00:00:00 2001 From: yushiwho Date: Mon, 20 Nov 2023 22:59:32 +0800 Subject: [PATCH 113/269] feat: add support for ALL_PROXY (#10451) Signed-off-by: xniu Co-authored-by: xniu --- go.mod | 2 +- util/grpc/grpc.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index e03d1709e3220..f396b45234e25 100644 --- a/go.mod +++ b/go.mod @@ -262,7 +262,7 @@ require ( go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.17.0 // indirect + golang.org/x/net v0.17.0 golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 diff --git a/util/grpc/grpc.go b/util/grpc/grpc.go index 1741727a5d604..536da792e3048 100644 --- a/util/grpc/grpc.go +++ b/util/grpc/grpc.go @@ -10,6 +10,7 @@ import ( "github.com/argoproj/argo-cd/v2/common" "github.com/sirupsen/logrus" + "golang.org/x/net/proxy" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/credentials" @@ -63,7 +64,7 @@ func BlockingDial(ctx context.Context, network, address string, creds credential dialer := func(ctx context.Context, address string) (net.Conn, error) { - conn, err := (&net.Dialer{Cancel: ctx.Done()}).Dial(network, address) + conn, err := proxy.Dial(ctx, network, address) if err != nil { writeResult(err) return nil, err From a6b80df6eef07206907373c16dbdba10b4188b4c Mon Sep 17 00:00:00 2001 From: Ferenc Kovacs Date: Mon, 20 Nov 2023 16:47:42 +0100 Subject: [PATCH 114/269] feat(app): Support app sync --dry-run --revision some-revision with arbitrary revisions(#12592) (#16387) Signed-off-by: Ferenc Kovacs --- server/application/application.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/application/application.go b/server/application/application.go index ec600d29b3c6b..23d4d79a767cf 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -1752,7 +1752,7 @@ func (s *Server) Sync(ctx context.Context, syncReq *application.ApplicationSyncR if a.DeletionTimestamp != nil { return nil, status.Errorf(codes.FailedPrecondition, "application is deleting") } - if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil { + if a.Spec.SyncPolicy != nil && a.Spec.SyncPolicy.Automated != nil && !syncReq.GetDryRun() { if syncReq.GetRevision() != "" && syncReq.GetRevision() != text.FirstNonEmpty(source.TargetRevision, "HEAD") { return nil, status.Errorf(codes.FailedPrecondition, "Cannot sync to %s: auto-sync currently set to %s", syncReq.GetRevision(), source.TargetRevision) } From ccdc453aebf6311b5aeb73f88186bd1dfbdb5687 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 10:48:51 -0500 Subject: [PATCH 115/269] chore(deps): bump docker/build-push-action from 4.1.1 to 5.1.0 (#16392) Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4.1.1 to 5.1.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/2eb1c1961a95fc15694676618e422e8ba1d63825...4a13e500e55cf31b7a5d59a38ab2040ab0f42f56) --- updated-dependencies: - dependency-name: docker/build-push-action 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/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 898becc2815f4..ac111ae6395a7 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -145,7 +145,7 @@ jobs: - name: Build and push container image id: image - uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 #v4.1.1 + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 #v5.1.0 with: context: . platforms: ${{ inputs.platforms }} From 819f0b3e8771d1ce4f2c5a3b5c87b90ac2427847 Mon Sep 17 00:00:00 2001 From: Nathanael Liechti Date: Tue, 21 Nov 2023 16:16:50 +0100 Subject: [PATCH 116/269] feat(oidc): optionally query OIDC UserInfo to gather group claims (#12062) Signed-off-by: Nathanael Liechti --- docs/operator-manual/user-management/index.md | 14 + server/server.go | 32 +- server/server_test.go | 125 +++++++- util/cache/inmemory.go | 4 + util/oidc/oidc.go | 182 ++++++++++- util/oidc/oidc_test.go | 294 +++++++++++++++++- util/settings/settings.go | 34 ++ util/test/testutil.go | 10 + 8 files changed, 665 insertions(+), 30 deletions(-) diff --git a/docs/operator-manual/user-management/index.md b/docs/operator-manual/user-management/index.md index 8a5ba7802676d..496dd17a83e9f 100644 --- a/docs/operator-manual/user-management/index.md +++ b/docs/operator-manual/user-management/index.md @@ -387,6 +387,20 @@ For a simple case this can be: oidc.config: | requestedIDTokenClaims: {"groups": {"essential": true}} ``` + +### Retrieving group claims when not in the token + +Some OIDC providers don't return the group information for a user in the ID token, even if explicitly requested using the `requestedIDTokenClaims` setting (Okta for example). They instead provide the groups on the user info endpoint. With the following config, Argo CD queries the user info endpoint during login for groups information of a user: + +```yaml +oidc.config: | + enableUserInfoGroups: true + userInfoPath: /userinfo + userInfoCacheExpiration: "5m" +``` + +**Note: If you omit the `userInfoCacheExpiration` setting or if it's greater than the expiration of the ID token, the argocd-server will cache group information as long as the ID token is valid!** + ### Configuring a custom logout URL for your OIDC provider Optionally, if your OIDC provider exposes a logout API and you wish to configure a custom logout URL for the purposes of invalidating diff --git a/server/server.go b/server/server.go index e52416927143b..d9f1638024c51 100644 --- a/server/server.go +++ b/server/server.go @@ -1121,7 +1121,7 @@ func (a *ArgoCDServer) registerDexHandlers(mux *http.ServeMux) { // Run dex OpenID Connect Identity Provider behind a reverse proxy (served at /api/dex) var err error mux.HandleFunc(common.DexAPIEndpoint+"/", dexutil.NewDexHTTPReverseProxy(a.DexServerAddr, a.BaseHRef, a.DexTLSConfig)) - a.ssoClientApp, err = oidc.NewClientApp(a.settings, a.DexServerAddr, a.DexTLSConfig, a.BaseHRef) + a.ssoClientApp, err = oidc.NewClientApp(a.settings, a.DexServerAddr, a.DexTLSConfig, a.BaseHRef, cacheutil.NewRedisCache(a.RedisClient, a.settings.UserInfoCacheExpiration(), cacheutil.RedisCompressionNone)) errorsutil.CheckError(err) mux.HandleFunc(common.LoginEndpoint, a.ssoClientApp.HandleLogin) mux.HandleFunc(common.CallbackEndpoint, a.ssoClientApp.HandleCallback) @@ -1315,7 +1315,35 @@ func (a *ArgoCDServer) getClaims(ctx context.Context) (jwt.Claims, string, error if err != nil { return claims, "", status.Errorf(codes.Unauthenticated, "invalid session: %v", err) } - return claims, newToken, nil + + // Some SSO implementations (Okta) require a call to + // the OIDC user info path to get attributes like groups + // we assume that everywhere in argocd jwt.MapClaims is used as type for interface jwt.Claims + // otherwise this would cause a panic + var groupClaims jwt.MapClaims + if groupClaims, ok = claims.(jwt.MapClaims); !ok { + if tmpClaims, ok := claims.(*jwt.MapClaims); ok { + groupClaims = *tmpClaims + } + } + iss := jwtutil.StringField(groupClaims, "iss") + if iss != util_session.SessionManagerClaimsIssuer && a.settings.UserInfoGroupsEnabled() && a.settings.UserInfoPath() != "" { + userInfo, unauthorized, err := a.ssoClientApp.GetUserInfo(groupClaims, a.settings.IssuerURL(), a.settings.UserInfoPath()) + if unauthorized { + log.Errorf("error while quering userinfo endpoint: %v", err) + return claims, "", status.Errorf(codes.Unauthenticated, "invalid session") + } + if err != nil { + log.Errorf("error fetching user info endpoint: %v", err) + return claims, "", status.Errorf(codes.Internal, "invalid userinfo response") + } + if groupClaims["sub"] != userInfo["sub"] { + return claims, "", status.Error(codes.Unknown, "subject of claims from user info endpoint didn't match subject of idToken, see https://openid.net/specs/openid-connect-core-1_0.html#UserInfo") + } + groupClaims["groups"] = userInfo["groups"] + } + + return groupClaims, newToken, nil } // getToken extracts the token from gRPC metadata or cookie headers diff --git a/server/server_test.go b/server/server_test.go index 303f938871f38..acfb32e57e5d4 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -32,8 +32,10 @@ import ( "github.com/argoproj/argo-cd/v2/server/rbacpolicy" "github.com/argoproj/argo-cd/v2/test" "github.com/argoproj/argo-cd/v2/util/assets" + "github.com/argoproj/argo-cd/v2/util/cache" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" + "github.com/argoproj/argo-cd/v2/util/oidc" "github.com/argoproj/argo-cd/v2/util/rbac" settings_util "github.com/argoproj/argo-cd/v2/util/settings" testutil "github.com/argoproj/argo-cd/v2/util/test" @@ -533,7 +535,7 @@ func dexMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.Re } } -func getTestServer(t *testing.T, anonymousEnabled bool, withFakeSSO bool, useDexForSSO bool) (argocd *ArgoCDServer, oidcURL string) { +func getTestServer(t *testing.T, anonymousEnabled bool, withFakeSSO bool, useDexForSSO bool, additionalOIDCConfig settings_util.OIDCConfig) (argocd *ArgoCDServer, oidcURL string) { cm := test.NewFakeConfigMap() if anonymousEnabled { cm.Data["users.anonymous.enabled"] = "true" @@ -562,13 +564,12 @@ connectors: clientID: test-client clientSecret: $dex.oidc.clientSecret` } else { - oidcConfig := settings_util.OIDCConfig{ - Name: "Okta", - Issuer: oidcServer.URL, - ClientID: "argo-cd", - ClientSecret: "$oidc.okta.clientSecret", - } - oidcConfigString, err := yaml.Marshal(oidcConfig) + // override required oidc config fields but keep other configs as passed in + additionalOIDCConfig.Name = "Okta" + additionalOIDCConfig.Issuer = oidcServer.URL + additionalOIDCConfig.ClientID = "argo-cd" + additionalOIDCConfig.ClientSecret = "$oidc.okta.clientSecret" + oidcConfigString, err := yaml.Marshal(additionalOIDCConfig) require.NoError(t, err) cm.Data["oidc.config"] = string(oidcConfigString) // Avoid bothering with certs for local tests. @@ -589,9 +590,109 @@ connectors: argoCDOpts.DexServerAddr = ts.URL } argocd = NewServer(context.Background(), argoCDOpts) + var err error + argocd.ssoClientApp, err = oidc.NewClientApp(argocd.settings, argocd.DexServerAddr, argocd.DexTLSConfig, argocd.BaseHRef, cache.NewInMemoryCache(24*time.Hour)) + require.NoError(t, err) return argocd, oidcServer.URL } +func TestGetClaims(t *testing.T) { + + defaultExpiry := jwt.NewNumericDate(time.Now().Add(time.Hour * 24)) + defaultExpiryUnix := float64(defaultExpiry.Unix()) + + type testData struct { + test string + claims jwt.MapClaims + expectedErrorContains string + expectedClaims jwt.MapClaims + expectNewToken bool + additionalOIDCConfig settings_util.OIDCConfig + } + var tests = []testData{ + { + test: "GetClaims", + claims: jwt.MapClaims{ + "aud": "argo-cd", + "exp": defaultExpiry, + "sub": "randomUser", + }, + expectedErrorContains: "", + expectedClaims: jwt.MapClaims{ + "aud": "argo-cd", + "exp": defaultExpiryUnix, + "sub": "randomUser", + }, + expectNewToken: false, + additionalOIDCConfig: settings_util.OIDCConfig{}, + }, + { + // note: a passing test with user info groups can never be achieved since the user never logged in properly + // therefore the oidcClient's cache contains no accessToken for the user info endpoint + // and since the oidcClient cache is unexported (for good reasons) we can't mock this behaviour + test: "GetClaimsWithUserInfoGroupsEnabled", + claims: jwt.MapClaims{ + "aud": common.ArgoCDClientAppID, + "exp": defaultExpiry, + "sub": "randomUser", + }, + expectedErrorContains: "invalid session", + expectedClaims: jwt.MapClaims{ + "aud": common.ArgoCDClientAppID, + "exp": defaultExpiryUnix, + "sub": "randomUser", + }, + expectNewToken: false, + additionalOIDCConfig: settings_util.OIDCConfig{ + EnableUserInfoGroups: true, + UserInfoPath: "/userinfo", + UserInfoCacheExpiration: "5m", + }, + }, + } + + for _, testData := range tests { + testDataCopy := testData + + t.Run(testDataCopy.test, func(t *testing.T) { + t.Parallel() + + // Must be declared here to avoid race. + ctx := context.Background() //nolint:ineffassign,staticcheck + + argocd, oidcURL := getTestServer(t, false, true, false, testDataCopy.additionalOIDCConfig) + + // create new JWT and store it on the context to simulate an incoming request + testDataCopy.claims["iss"] = oidcURL + testDataCopy.expectedClaims["iss"] = oidcURL + token := jwt.NewWithClaims(jwt.SigningMethodRS512, testDataCopy.claims) + key, err := jwt.ParseRSAPrivateKeyFromPEM(testutil.PrivateKey) + require.NoError(t, err) + tokenString, err := token.SignedString(key) + require.NoError(t, err) + ctx = metadata.NewIncomingContext(context.Background(), metadata.Pairs(apiclient.MetaDataTokenKey, tokenString)) + + gotClaims, newToken, err := argocd.getClaims(ctx) + + // Note: testutil.oidcMockHandler currently doesn't implement reissuing expired tokens + // so newToken will always be empty + if testDataCopy.expectNewToken { + assert.NotEmpty(t, newToken) + } + if testDataCopy.expectedClaims == nil { + assert.Nil(t, gotClaims) + } else { + assert.Equal(t, testDataCopy.expectedClaims, gotClaims) + } + if testDataCopy.expectedErrorContains != "" { + assert.ErrorContains(t, err, testDataCopy.expectedErrorContains, "getClaims should have thrown an error and return an error") + } else { + assert.NoError(t, err) + } + }) + } +} + func TestAuthenticate_3rd_party_JWTs(t *testing.T) { // Marshaling single strings to strings is typical, so we test for this relatively common behavior. jwt.MarshalSingleStringAsArray = false @@ -723,7 +824,7 @@ func TestAuthenticate_3rd_party_JWTs(t *testing.T) { // Must be declared here to avoid race. ctx := context.Background() //nolint:ineffassign,staticcheck - argocd, oidcURL := getTestServer(t, testDataCopy.anonymousEnabled, true, testDataCopy.useDex) + argocd, oidcURL := getTestServer(t, testDataCopy.anonymousEnabled, true, testDataCopy.useDex, settings_util.OIDCConfig{}) if testDataCopy.useDex { testDataCopy.claims.Issuer = fmt.Sprintf("%s/api/dex", oidcURL) @@ -779,7 +880,7 @@ func TestAuthenticate_no_request_metadata(t *testing.T) { t.Run(testDataCopy.test, func(t *testing.T) { t.Parallel() - argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true, true) + argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true, true, settings_util.OIDCConfig{}) ctx := context.Background() ctx, err := argocd.Authenticate(ctx) @@ -825,7 +926,7 @@ func TestAuthenticate_no_SSO(t *testing.T) { // Must be declared here to avoid race. ctx := context.Background() //nolint:ineffassign,staticcheck - argocd, dexURL := getTestServer(t, testDataCopy.anonymousEnabled, false, true) + argocd, dexURL := getTestServer(t, testDataCopy.anonymousEnabled, false, true, settings_util.OIDCConfig{}) token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.RegisteredClaims{Issuer: fmt.Sprintf("%s/api/dex", dexURL)}) tokenString, err := token.SignedString([]byte("key")) require.NoError(t, err) @@ -933,7 +1034,7 @@ func TestAuthenticate_bad_request_metadata(t *testing.T) { // Must be declared here to avoid race. ctx := context.Background() //nolint:ineffassign,staticcheck - argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true, true) + argocd, _ := getTestServer(t, testDataCopy.anonymousEnabled, true, true, settings_util.OIDCConfig{}) ctx = metadata.NewIncomingContext(context.Background(), testDataCopy.metadata) ctx, err := argocd.Authenticate(ctx) diff --git a/util/cache/inmemory.go b/util/cache/inmemory.go index 53e690925d940..f75688c275546 100644 --- a/util/cache/inmemory.go +++ b/util/cache/inmemory.go @@ -16,6 +16,10 @@ func NewInMemoryCache(expiration time.Duration) *InMemoryCache { } } +func init() { + gob.Register([]interface{}{}) +} + // compile-time validation of adherance of the CacheClient contract var _ CacheClient = &InMemoryCache{} diff --git a/util/oidc/oidc.go b/util/oidc/oidc.go index 3df3166490172..2c376cc7e5b5b 100644 --- a/util/oidc/oidc.go +++ b/util/oidc/oidc.go @@ -6,6 +6,7 @@ import ( "fmt" "html" "html/template" + "io" "net" "net/http" "net/url" @@ -21,9 +22,12 @@ import ( "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/server/settings/oidc" + "github.com/argoproj/argo-cd/v2/util/cache" "github.com/argoproj/argo-cd/v2/util/crypto" "github.com/argoproj/argo-cd/v2/util/dex" + httputil "github.com/argoproj/argo-cd/v2/util/http" + jwtutil "github.com/argoproj/argo-cd/v2/util/jwt" "github.com/argoproj/argo-cd/v2/util/rand" "github.com/argoproj/argo-cd/v2/util/settings" ) @@ -31,9 +35,11 @@ import ( var InvalidRedirectURLError = fmt.Errorf("invalid return URL") const ( - GrantTypeAuthorizationCode = "authorization_code" - GrantTypeImplicit = "implicit" - ResponseTypeCode = "code" + GrantTypeAuthorizationCode = "authorization_code" + GrantTypeImplicit = "implicit" + ResponseTypeCode = "code" + UserInfoResponseCachePrefix = "userinfo_response" + AccessTokenCachePrefix = "access_token" ) // OIDCConfiguration holds a subset of interested fields from the OIDC configuration spec @@ -57,6 +63,8 @@ type ClientApp struct { redirectURI string // URL of the issuer (e.g. https://argocd.example.com/api/dex) issuerURL string + // the path where the issuer providers user information (e.g /user-info for okta) + userInfoPath string // The URL endpoint at which the ArgoCD server is accessed. baseHRef string // client is the HTTP client which is used to query the IDp @@ -70,6 +78,8 @@ type ClientApp struct { encryptionKey []byte // provider is the OIDC provider provider Provider + // clientCache represent a cache of sso artifact + clientCache cache.CacheClient } func GetScopesOrDefault(scopes []string) []string { @@ -81,7 +91,7 @@ func GetScopesOrDefault(scopes []string) []string { // NewClientApp will register the Argo CD client app (either via Dex or external OIDC) and return an // object which has HTTP handlers for handling the HTTP responses for login and callback -func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTlsConfig *dex.DexTLSConfig, baseHRef string) (*ClientApp, error) { +func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTlsConfig *dex.DexTLSConfig, baseHRef string, cacheClient cache.CacheClient) (*ClientApp, error) { redirectURL, err := settings.RedirectURL() if err != nil { return nil, err @@ -95,8 +105,10 @@ func NewClientApp(settings *settings.ArgoCDSettings, dexServerAddr string, dexTl clientSecret: settings.OAuth2ClientSecret(), redirectURI: redirectURL, issuerURL: settings.IssuerURL(), + userInfoPath: settings.UserInfoPath(), baseHRef: baseHRef, encryptionKey: encryptionKey, + clientCache: cacheClient, } log.Infof("Creating client app (%s)", a.clientID) u, err := url.Parse(settings.URL) @@ -376,6 +388,26 @@ func (a *ClientApp) HandleCallback(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) return } + // save the accessToken in memory for later use + encToken, err := crypto.Encrypt([]byte(token.AccessToken), a.encryptionKey) + if err != nil { + claimsJSON, _ := json.Marshal(claims) + http.Error(w, "failed encrypting token", http.StatusInternalServerError) + log.Errorf("cannot encrypt accessToken: %v (claims=%s)", err, claimsJSON) + return + } + sub := jwtutil.StringField(claims, "sub") + err = a.clientCache.Set(&cache.Item{ + Key: formatAccessTokenCacheKey(AccessTokenCachePrefix, sub), + Object: encToken, + Expiration: getTokenExpiration(claims), + }) + if err != nil { + claimsJSON, _ := json.Marshal(claims) + http.Error(w, fmt.Sprintf("claims=%s, err=%v", claimsJSON, err), http.StatusInternalServerError) + return + } + if idTokenRAW != "" { cookies, err := httputil.MakeCookieMetadata(common.AuthCookieName, idTokenRAW, flags...) if err != nil { @@ -509,3 +541,145 @@ func createClaimsAuthenticationRequestParameter(requestedClaims map[string]*oidc } return oauth2.SetAuthURLParam("claims", string(claimsRequestRAW)), nil } + +// GetUserInfo queries the IDP userinfo endpoint for claims +func (a *ClientApp) GetUserInfo(actualClaims jwt.MapClaims, issuerURL, userInfoPath string) (jwt.MapClaims, bool, error) { + sub := jwtutil.StringField(actualClaims, "sub") + var claims jwt.MapClaims + var encClaims []byte + + // in case we got it in the cache, we just return the item + clientCacheKey := formatUserInfoResponseCacheKey(UserInfoResponseCachePrefix, sub) + if err := a.clientCache.Get(clientCacheKey, &encClaims); err == nil { + claimsRaw, err := crypto.Decrypt(encClaims, a.encryptionKey) + if err != nil { + log.Errorf("decrypting the cached claims failed (sub=%s): %s", sub, err) + } else { + err = json.Unmarshal(claimsRaw, &claims) + if err != nil { + log.Errorf("cannot unmarshal cached claims structure: %s", err) + } else { + // return the cached claims since they are not yet expired, were successfully decrypted and unmarshaled + return claims, false, err + } + } + } + + // check if the accessToken for the user is still present + var encAccessToken []byte + err := a.clientCache.Get(formatAccessTokenCacheKey(AccessTokenCachePrefix, sub), &encAccessToken) + // without an accessToken we can't query the user info endpoint + // thus the user needs to reauthenticate for argocd to get a new accessToken + if err == cache.ErrCacheMiss { + return claims, true, fmt.Errorf("no accessToken for %s: %w", sub, err) + } else if err != nil { + return claims, true, fmt.Errorf("couldn't read accessToken from cache for %s: %w", sub, err) + } + + accessToken, err := crypto.Decrypt(encAccessToken, a.encryptionKey) + if err != nil { + return claims, true, fmt.Errorf("couldn't decrypt accessToken for %s: %w", sub, err) + } + + url := issuerURL + userInfoPath + request, err := http.NewRequest("GET", url, nil) + + if err != nil { + err = fmt.Errorf("failed creating new http request: %w", err) + return claims, false, err + } + + bearer := fmt.Sprintf("Bearer %s", accessToken) + request.Header.Set("Authorization", bearer) + + response, err := a.client.Do(request) + if err != nil { + return claims, false, fmt.Errorf("failed to query userinfo endpoint of IDP: %w", err) + } + defer response.Body.Close() + if response.StatusCode == http.StatusUnauthorized { + return claims, true, err + } + + // according to https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponseValidation + // the response should be validated + header := response.Header.Get("content-type") + rawBody, err := io.ReadAll(response.Body) + if err != nil { + return claims, false, fmt.Errorf("got error reading response body: %w", err) + } + switch header { + case "application/jwt": + // if body is JWT, first validate it before extracting claims + idToken, err := a.provider.Verify(string(rawBody), a.settings) + if err != nil { + return claims, false, fmt.Errorf("user info response in jwt format not valid: %w", err) + } + err = idToken.Claims(claims) + if err != nil { + return claims, false, fmt.Errorf("cannot get claims from userinfo jwt: %w", err) + } + default: + // if body is json, unsigned and unencrypted claims can be deserialized + err = json.Unmarshal(rawBody, &claims) + if err != nil { + return claims, false, fmt.Errorf("failed to decode response body to struct: %w", err) + } + } + + // in case response was successfully validated and there was no error, put item in cache + // but first let's determine the expiry of the cache + var cacheExpiry time.Duration + settingExpiry := a.settings.UserInfoCacheExpiration() + tokenExpiry := getTokenExpiration(claims) + + // only use configured expiry if the token lives longer and the expiry is configured + // if the token has no expiry, use the expiry of the actual token + // otherwise use the expiry of the token + if settingExpiry < tokenExpiry && settingExpiry != 0 { + cacheExpiry = settingExpiry + } else if tokenExpiry < 0 { + cacheExpiry = getTokenExpiration(actualClaims) + } else { + cacheExpiry = tokenExpiry + } + + rawClaims, err := json.Marshal(claims) + if err != nil { + return claims, false, fmt.Errorf("couldn't marshal claim to json: %w", err) + } + encClaims, err = crypto.Encrypt(rawClaims, a.encryptionKey) + if err != nil { + return claims, false, fmt.Errorf("couldn't encrypt user info response: %w", err) + } + + err = a.clientCache.Set(&cache.Item{ + Key: clientCacheKey, + Object: encClaims, + Expiration: cacheExpiry, + }) + if err != nil { + return claims, false, fmt.Errorf("couldn't put item to cache: %w", err) + } + + return claims, false, nil +} + +// getTokenExpiration returns a time.Duration until the token expires +func getTokenExpiration(claims jwt.MapClaims) time.Duration { + // get duration until token expires + exp := jwtutil.Float64Field(claims, "exp") + tm := time.Unix(int64(exp), 0) + tokenExpiry := time.Until(tm) + return tokenExpiry +} + +// formatUserInfoResponseCacheKey returns the key which is used to store userinfo of user in cache +func formatUserInfoResponseCacheKey(prefix, sub string) string { + return fmt.Sprintf("%s_%s", UserInfoResponseCachePrefix, sub) +} + +// formatAccessTokenCacheKey returns the key which is used to store the accessToken of a user in cache +func formatAccessTokenCacheKey(prefix, sub string) string { + return fmt.Sprintf("%s_%s", prefix, sub) +} diff --git a/util/oidc/oidc_test.go b/util/oidc/oidc_test.go index fe5fa77eed3b5..cd1d3fa1bf789 100644 --- a/util/oidc/oidc_test.go +++ b/util/oidc/oidc_test.go @@ -11,8 +11,10 @@ import ( "os" "strings" "testing" + "time" gooidc "github.com/coreos/go-oidc/v3/oidc" + "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/oauth2" @@ -20,6 +22,7 @@ import ( "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/server/settings/oidc" "github.com/argoproj/argo-cd/v2/util" + "github.com/argoproj/argo-cd/v2/util/cache" "github.com/argoproj/argo-cd/v2/util/crypto" "github.com/argoproj/argo-cd/v2/util/dex" "github.com/argoproj/argo-cd/v2/util/settings" @@ -126,7 +129,7 @@ clientID: xxx clientSecret: yyy requestedScopes: ["oidc"]`, oidcTestServer.URL), } - app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com") + app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/login", nil) @@ -141,7 +144,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), cdSettings.OIDCTLSInsecureSkipVerify = true - app, err = NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com") + app, err = NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) w = httptest.NewRecorder() @@ -166,7 +169,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), require.NoError(t, err) cdSettings.Certificate = &cert - app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com") + app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/login", nil) @@ -179,7 +182,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), t.Fatal("did not receive expected certificate verification failure error") } - app, err = NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com") + app, err = NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) w = httptest.NewRecorder() @@ -211,7 +214,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), // The base href (the last argument for NewClientApp) is what HandleLogin will fall back to when no explicit // redirect URL is given. - app, err := NewClientApp(cdSettings, "", nil, "/") + app, err := NewClientApp(cdSettings, "", nil, "/", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) w := httptest.NewRecorder() @@ -254,7 +257,7 @@ clientID: xxx clientSecret: yyy requestedScopes: ["oidc"]`, oidcTestServer.URL), } - app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com") + app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/callback", nil) @@ -269,7 +272,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), cdSettings.OIDCTLSInsecureSkipVerify = true - app, err = NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com") + app, err = NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) w = httptest.NewRecorder() @@ -294,7 +297,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), require.NoError(t, err) cdSettings.Certificate = &cert - app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com") + app, err := NewClientApp(cdSettings, dexTestServer.URL, nil, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) req := httptest.NewRequest(http.MethodGet, "https://argocd.example.com/auth/callback", nil) @@ -307,7 +310,7 @@ requestedScopes: ["oidc"]`, oidcTestServer.URL), t.Fatal("did not receive expected certificate verification failure error") } - app, err = NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com") + app, err = NewClientApp(cdSettings, dexTestServer.URL, &dex.DexTLSConfig{StrictValidation: false}, "https://argocd.example.com", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) w = httptest.NewRecorder() @@ -406,7 +409,7 @@ func TestGenerateAppState(t *testing.T) { signature, err := util.MakeSignature(32) require.NoError(t, err) expectedReturnURL := "http://argocd.example.com/" - app, err := NewClientApp(&settings.ArgoCDSettings{ServerSignature: signature, URL: expectedReturnURL}, "", nil, "") + app, err := NewClientApp(&settings.ArgoCDSettings{ServerSignature: signature, URL: expectedReturnURL}, "", nil, "", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) generateResponse := httptest.NewRecorder() state, err := app.generateAppState(expectedReturnURL, generateResponse) @@ -443,7 +446,7 @@ func TestGenerateAppState_XSS(t *testing.T) { URL: "https://argocd.example.com", ServerSignature: signature, }, - "", nil, "", + "", nil, "", cache.NewInMemoryCache(24*time.Hour), ) require.NoError(t, err) @@ -495,7 +498,7 @@ func TestGenerateAppState_NoReturnURL(t *testing.T) { encrypted, err := crypto.Encrypt([]byte("123"), key) require.NoError(t, err) - app, err := NewClientApp(cdSettings, "", nil, "/argo-cd") + app, err := NewClientApp(cdSettings, "", nil, "/argo-cd", cache.NewInMemoryCache(24*time.Hour)) require.NoError(t, err) req.AddCookie(&http.Cookie{Name: common.StateCookieName, Value: hex.EncodeToString(encrypted)}) @@ -503,3 +506,270 @@ func TestGenerateAppState_NoReturnURL(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "/argo-cd", returnURL) } + +func TestGetUserInfo(t *testing.T) { + + var tests = []struct { + name string + userInfoPath string + expectedOutput interface{} + expectError bool + expectUnauthenticated bool + expectedCacheItems []struct { // items to check in cache after function call + key string + value string + expectEncrypted bool + expectError bool + } + idpHandler func(w http.ResponseWriter, r *http.Request) + idpClaims jwt.MapClaims // as per specification sub and exp are REQUIRED fields + cache cache.CacheClient + cacheItems []struct { // items to put in cache before execution + key string + value string + encrypt bool + } + }{ + { + name: "call UserInfo with wrong userInfoPath", + userInfoPath: "/user", + expectedOutput: jwt.MapClaims(nil), + expectError: true, + expectUnauthenticated: false, + expectedCacheItems: []struct { + key string + value string + expectEncrypted bool + expectError bool + }{ + { + key: formatUserInfoResponseCacheKey(UserInfoResponseCachePrefix, "randomUser"), + expectError: true, + }, + }, + idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, + idpHandler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotFound) + }, + cache: cache.NewInMemoryCache(24 * time.Hour), + cacheItems: []struct { + key string + value string + encrypt bool + }{ + { + key: formatAccessTokenCacheKey(AccessTokenCachePrefix, "randomUser"), + value: "FakeAccessToken", + encrypt: true, + }, + }, + }, + { + name: "call UserInfo with bad accessToken", + userInfoPath: "/user-info", + expectedOutput: jwt.MapClaims(nil), + expectError: false, + expectUnauthenticated: true, + expectedCacheItems: []struct { + key string + value string + expectEncrypted bool + expectError bool + }{ + { + key: formatUserInfoResponseCacheKey(UserInfoResponseCachePrefix, "randomUser"), + expectError: true, + }, + }, + idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, + idpHandler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusUnauthorized) + }, + cache: cache.NewInMemoryCache(24 * time.Hour), + cacheItems: []struct { + key string + value string + encrypt bool + }{ + { + key: formatAccessTokenCacheKey(AccessTokenCachePrefix, "randomUser"), + value: "FakeAccessToken", + encrypt: true, + }, + }, + }, + { + name: "call UserInfo with garbage returned", + userInfoPath: "/user-info", + expectedOutput: jwt.MapClaims(nil), + expectError: true, + expectUnauthenticated: false, + expectedCacheItems: []struct { + key string + value string + expectEncrypted bool + expectError bool + }{ + { + key: formatUserInfoResponseCacheKey(UserInfoResponseCachePrefix, "randomUser"), + expectError: true, + }, + }, + idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, + idpHandler: func(w http.ResponseWriter, r *http.Request) { + userInfoBytes := ` + notevenJsongarbage + ` + _, err := w.Write([]byte(userInfoBytes)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusTeapot) + }, + cache: cache.NewInMemoryCache(24 * time.Hour), + cacheItems: []struct { + key string + value string + encrypt bool + }{ + { + key: formatAccessTokenCacheKey(AccessTokenCachePrefix, "randomUser"), + value: "FakeAccessToken", + encrypt: true, + }, + }, + }, + { + name: "call UserInfo without accessToken in cache", + userInfoPath: "/user-info", + expectedOutput: jwt.MapClaims(nil), + expectError: true, + expectUnauthenticated: true, + expectedCacheItems: []struct { + key string + value string + expectEncrypted bool + expectError bool + }{ + { + key: formatUserInfoResponseCacheKey(UserInfoResponseCachePrefix, "randomUser"), + expectError: true, + }, + }, + idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, + idpHandler: func(w http.ResponseWriter, r *http.Request) { + userInfoBytes := ` + { + "groups":["githubOrg:engineers"] + }` + w.Header().Set("content-type", "application/json") + _, err := w.Write([]byte(userInfoBytes)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + }, + cache: cache.NewInMemoryCache(24 * time.Hour), + }, + { + name: "call UserInfo with valid accessToken in cache", + userInfoPath: "/user-info", + expectedOutput: jwt.MapClaims{"groups": []interface{}{"githubOrg:engineers"}}, + expectError: false, + expectUnauthenticated: false, + expectedCacheItems: []struct { + key string + value string + expectEncrypted bool + expectError bool + }{ + { + key: formatUserInfoResponseCacheKey(UserInfoResponseCachePrefix, "randomUser"), + value: "{\"groups\":[\"githubOrg:engineers\"]}", + expectEncrypted: true, + expectError: false, + }, + }, + idpClaims: jwt.MapClaims{"sub": "randomUser", "exp": float64(time.Now().Add(5 * time.Minute).Unix())}, + idpHandler: func(w http.ResponseWriter, r *http.Request) { + userInfoBytes := ` + { + "groups":["githubOrg:engineers"] + }` + w.Header().Set("content-type", "application/json") + _, err := w.Write([]byte(userInfoBytes)) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + }, + cache: cache.NewInMemoryCache(24 * time.Hour), + cacheItems: []struct { + key string + value string + encrypt bool + }{ + { + key: formatAccessTokenCacheKey(AccessTokenCachePrefix, "randomUser"), + value: "FakeAccessToken", + encrypt: true, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(tt.idpHandler)) + defer ts.Close() + + signature, err := util.MakeSignature(32) + require.NoError(t, err) + cdSettings := &settings.ArgoCDSettings{ServerSignature: signature} + encryptionKey, err := cdSettings.GetServerEncryptionKey() + assert.NoError(t, err) + a, _ := NewClientApp(cdSettings, "", nil, "/argo-cd", tt.cache) + + for _, item := range tt.cacheItems { + var newValue []byte + newValue = []byte(item.value) + if item.encrypt { + newValue, err = crypto.Encrypt([]byte(item.value), encryptionKey) + assert.NoError(t, err) + } + err := a.clientCache.Set(&cache.Item{ + Key: item.key, + Object: newValue, + }) + require.NoError(t, err) + } + + got, unauthenticated, err := a.GetUserInfo(tt.idpClaims, ts.URL, tt.userInfoPath) + assert.Equal(t, tt.expectedOutput, got) + assert.Equal(t, tt.expectUnauthenticated, unauthenticated) + if tt.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + for _, item := range tt.expectedCacheItems { + var tmpValue []byte + err := a.clientCache.Get(item.key, &tmpValue) + if item.expectError { + require.Error(t, err) + } else { + require.NoError(t, err) + if item.expectEncrypted { + tmpValue, err = crypto.Decrypt(tmpValue, encryptionKey) + require.NoError(t, err) + } + assert.Equal(t, item.value, string(tmpValue)) + } + } + }) + } + +} diff --git a/util/settings/settings.go b/util/settings/settings.go index bc091e8b818ec..baff450aa817e 100644 --- a/util/settings/settings.go +++ b/util/settings/settings.go @@ -161,6 +161,9 @@ func (o *oidcConfig) toExported() *OIDCConfig { ClientID: o.ClientID, ClientSecret: o.ClientSecret, CLIClientID: o.CLIClientID, + UserInfoPath: o.UserInfoPath, + EnableUserInfoGroups: o.EnableUserInfoGroups, + UserInfoCacheExpiration: o.UserInfoCacheExpiration, RequestedScopes: o.RequestedScopes, RequestedIDTokenClaims: o.RequestedIDTokenClaims, LogoutURL: o.LogoutURL, @@ -175,6 +178,9 @@ type OIDCConfig struct { ClientID string `json:"clientID,omitempty"` ClientSecret string `json:"clientSecret,omitempty"` CLIClientID string `json:"cliClientID,omitempty"` + EnableUserInfoGroups bool `json:"enableUserInfoGroups,omitempty"` + UserInfoPath string `json:"userInfoPath,omitempty"` + UserInfoCacheExpiration string `json:"userInfoCacheExpiration,omitempty"` RequestedScopes []string `json:"requestedScopes,omitempty"` RequestedIDTokenClaims map[string]*oidc.Claim `json:"requestedIDTokenClaims,omitempty"` LogoutURL string `json:"logoutURL,omitempty"` @@ -1850,6 +1856,34 @@ func (a *ArgoCDSettings) IssuerURL() string { return "" } +// UserInfoGroupsEnabled returns whether group claims should be fetch from UserInfo endpoint +func (a *ArgoCDSettings) UserInfoGroupsEnabled() bool { + if oidcConfig := a.OIDCConfig(); oidcConfig != nil { + return oidcConfig.EnableUserInfoGroups + } + return false +} + +// UserInfoPath returns the sub-path on which the IDP exposes the UserInfo endpoint +func (a *ArgoCDSettings) UserInfoPath() string { + if oidcConfig := a.OIDCConfig(); oidcConfig != nil { + return oidcConfig.UserInfoPath + } + return "" +} + +// UserInfoCacheExpiration returns the expiry time of the UserInfo cache +func (a *ArgoCDSettings) UserInfoCacheExpiration() time.Duration { + if oidcConfig := a.OIDCConfig(); oidcConfig != nil && oidcConfig.UserInfoCacheExpiration != "" { + userInfoCacheExpiration, err := time.ParseDuration(oidcConfig.UserInfoCacheExpiration) + if err != nil { + log.Warnf("Failed to parse 'oidc.config.userInfoCacheExpiration' key: %v", err) + } + return userInfoCacheExpiration + } + return 0 +} + func (a *ArgoCDSettings) OAuth2ClientID() string { if oidcConfig := a.OIDCConfig(); oidcConfig != nil { return oidcConfig.ClientID diff --git a/util/test/testutil.go b/util/test/testutil.go index 6fdbd4151d82c..1cb23bc08bb3e 100644 --- a/util/test/testutil.go +++ b/util/test/testutil.go @@ -168,6 +168,16 @@ func oidcMockHandler(t *testing.T, url string) func(http.ResponseWriter, *http.R "token_endpoint_auth_methods_supported": ["client_secret_basic", "client_secret_post"], "claims_supported": ["sub", "aud", "exp"] }`, url)) + require.NoError(t, err) + case "/userinfo": + w.Header().Set("content-type", "application/json") + _, err := io.WriteString(w, fmt.Sprintf(` +{ + "groups":["githubOrg:engineers"], + "iss": "%[1]s", + "sub": "randomUser" +}`, url)) + require.NoError(t, err) case "/keys": pubKey, err := jwt.ParseRSAPublicKeyFromPEM(Cert) From cbe6e2b9fd0d4093c7840afa3e548f5d5e0ce0db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 21 Nov 2023 19:34:10 -0500 Subject: [PATCH 117/269] chore(deps): bump github.com/go-jose/go-jose/v3 from 3.0.0 to 3.0.1 (#16418) Bumps [github.com/go-jose/go-jose/v3](https://github.com/go-jose/go-jose) from 3.0.0 to 3.0.1. - [Release notes](https://github.com/go-jose/go-jose/releases) - [Changelog](https://github.com/go-jose/go-jose/blob/v3/CHANGELOG.md) - [Commits](https://github.com/go-jose/go-jose/compare/v3.0.0...v3.0.1) --- updated-dependencies: - dependency-name: github.com/go-jose/go-jose/v3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index f396b45234e25..e7bd1ee450ec1 100644 --- a/go.mod +++ b/go.mod @@ -178,7 +178,7 @@ require ( github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.4.1 // indirect - github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect diff --git a/go.sum b/go.sum index 08da01826154c..4ba30a2a7f947 100644 --- a/go.sum +++ b/go.sum @@ -924,8 +924,8 @@ github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0ab github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= -github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= From 78460c4b365bcb1f58514abac1b37482f7eb561d Mon Sep 17 00:00:00 2001 From: dlorenc Date: Wed, 22 Nov 2023 09:44:07 -0500 Subject: [PATCH 118/269] chore: Bump otel to 1.21.0 (#16420) This actually wasn't that bad. It was just a few bumps in the right order. I ran tests and built everything and it appears to work. Signed-off-by: Dan Lorenc --- go.mod | 35 ++++++++++++++--------------- go.sum | 70 ++++++++++++++++++++++++++++++---------------------------- 2 files changed, 53 insertions(+), 52 deletions(-) diff --git a/go.mod b/go.mod index e7bd1ee450ec1..3180996ab5f99 100644 --- a/go.mod +++ b/go.mod @@ -27,7 +27,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.8.1 - github.com/go-logr/logr v1.2.4 + github.com/go-logr/logr v1.3.0 github.com/go-openapi/loads v0.21.2 github.com/go-openapi/runtime v0.26.0 github.com/go-playground/webhooks/v6 v6.3.0 @@ -41,7 +41,7 @@ require ( github.com/google/go-github/v35 v35.3.0 github.com/google/go-jsonnet v0.20.0 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.3.1 github.com/gorilla/handlers v1.5.1 github.com/gorilla/websocket v1.5.0 github.com/gosimple/slug v1.13.1 @@ -75,16 +75,16 @@ require ( github.com/xanzy/go-gitlab v0.91.1 github.com/yuin/gopher-lua v1.1.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 - go.opentelemetry.io/otel v1.16.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 - go.opentelemetry.io/otel/sdk v1.16.0 + go.opentelemetry.io/otel v1.21.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 + go.opentelemetry.io/otel/sdk v1.21.0 golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/oauth2 v0.11.0 golang.org/x/sync v0.3.0 golang.org/x/term v0.13.0 - google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 - google.golang.org/grpc v1.58.3 + google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d + google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v2 v2.4.0 @@ -131,15 +131,15 @@ require ( github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/retry.v1 v1.0.3 // indirect k8s.io/klog v1.0.0 // indirect nhooyr.io/websocket v1.8.7 // indirect ) require ( - cloud.google.com/go/compute v1.21.0 // indirect + cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect @@ -189,7 +189,7 @@ require ( github.com/go-openapi/swag v0.22.3 // indirect github.com/go-openapi/validate v0.22.1 // indirect github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1 // indirect - github.com/golang/glog v1.1.0 // indirect + github.com/golang/glog v1.1.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gnostic v0.6.9 // indirect @@ -200,7 +200,7 @@ require ( github.com/gosimple/unidecode v1.0.1 // indirect github.com/gregdel/pushover v1.2.1 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-version v1.2.1 // indirect github.com/huandu/xstrings v1.3.3 // indirect @@ -255,15 +255,14 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xlab/treeprint v1.1.0 // indirect go.mongodb.org/mongo-driver v1.11.3 // indirect - go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 // indirect - go.opentelemetry.io/otel/metric v1.16.0 // indirect - go.opentelemetry.io/otel/trace v1.16.0 // indirect - go.opentelemetry.io/proto/otlp v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.17.0 - golang.org/x/sys v0.13.0 // indirect + golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 golang.org/x/tools v0.7.0 // indirect diff --git a/go.sum b/go.sum index 4ba30a2a7f947..bb7c2ca8627f6 100644 --- a/go.sum +++ b/go.sum @@ -174,8 +174,8 @@ cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOV cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI= cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= -cloud.google.com/go/compute v1.21.0 h1:JNBsyXVoOoNJtTQcnEY5uYpZIbeCTYIeDe0Xh1bySMk= -cloud.google.com/go/compute v1.21.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= +cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -942,8 +942,8 @@ github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= -github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= @@ -1057,8 +1057,9 @@ github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= 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= @@ -1154,8 +1155,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3 github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -1209,8 +1211,9 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgf github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -1575,8 +1578,8 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1727,24 +1730,23 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= -go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= -go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0 h1:t4ZwRPU+emrcvM2e9DHd0Fsf0JTPVcbfa/BhTDF03d0= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.16.0/go.mod h1:vLarbg68dH2Wa77g71zmKQqlQ8+8Rq3GRG31uc0WcWI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0 h1:cbsD4cUcviQGXdw8+bo5x2wazq10SKz8hEbtCRPcU78= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.16.0/go.mod h1:JgXSGah17croqhJfhByOLVY719k1emAXC8MVhCIJlRs= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0 h1:TVQp/bboR4mhZSav+MdgXB8FaRho1RC8UwVn3T0vjVc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.16.0/go.mod h1:I33vtIe0sR96wfrUcilIzLoA3mLHhRmz9S9Te0S3gDo= -go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= -go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= -go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= -go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= -go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= -go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd h1:Uo/x0Ir5vQJ+683GXB9Ug+4fcjsbp7z7Ul8UaZbhsRM= go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1753,7 +1755,7 @@ go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -2109,8 +2111,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2471,21 +2473,21 @@ google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 h1:Z0hjGZePRE0ZBWotvtrwxFNrNE9CUAGtplaDK5NNI/g= -google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98/go.mod h1:S7mY02OqCJTD0E1OiQy1F72PWFB4bZJ87cAtLPYgDR0= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 h1:FmF5cCW94Ij59cfpoLiwTgodWmm60eEV0CjlsVg2fuw= -google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98/go.mod h1:rsr7RhLuwsDKL7RmgDDCUc6yaGr1iqceVb5Wv6f6YvQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q= +google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk= google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 h1:bVf09lpb+OJbByTj913DRJioFFAjf/ZGxEz7MajTp2U= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -2533,8 +2535,8 @@ google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5v google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= -google.golang.org/grpc v1.58.3 h1:BjnpXut1btbtgN/6sp+brB2Kbm2LjNXnidYujAVbSoQ= -google.golang.org/grpc v1.58.3/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= From 1600c03abafc4a0526d6909b3eddab5071d59508 Mon Sep 17 00:00:00 2001 From: Kyle Dodson Date: Wed, 22 Nov 2023 10:26:16 -0800 Subject: [PATCH 119/269] chore: Update USERS.md (#16425) Add Salad Technologies Signed-off-by: Kyle Dodson --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 0f660ebb5f4d6..431a5ef3944f4 100644 --- a/USERS.md +++ b/USERS.md @@ -243,6 +243,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Robotinfra](https://www.robotinfra.com) 1. [Rubin Observatory](https://www.lsst.org) 1. [Saildrone](https://www.saildrone.com/) +1. [Salad Technologies](https://salad.com/) 1. [Saloodo! GmbH](https://www.saloodo.com) 1. [Sap Labs](http://sap.com) 1. [Sauce Labs](https://saucelabs.com/) From 2f2958a0f42068552de67370caccb84522267c65 Mon Sep 17 00:00:00 2001 From: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> Date: Mon, 27 Nov 2023 09:56:35 +0530 Subject: [PATCH 120/269] fix: fixed cli admin dashboard cmd (#16430) * fix: fixed cli admin dashboard cmd Signed-off-by: Soumya Ghosh Dastidar * feat: update docs Signed-off-by: Soumya Ghosh Dastidar --------- Signed-off-by: Soumya Ghosh Dastidar --- cmd/argocd/commands/admin/admin.go | 2 +- cmd/argocd/commands/admin/dashboard.go | 10 +++++++--- cmd/argocd/commands/headless/headless.go | 11 +++++++---- docs/user-guide/commands/argocd_admin_dashboard.md | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/cmd/argocd/commands/admin/admin.go b/cmd/argocd/commands/admin/admin.go index 0615166175259..49c81e4da4bfe 100644 --- a/cmd/argocd/commands/admin/admin.go +++ b/cmd/argocd/commands/admin/admin.go @@ -138,7 +138,7 @@ $ argocd admin initial-password reset command.AddCommand(NewRepoCommand()) command.AddCommand(NewImportCommand()) command.AddCommand(NewExportCommand()) - command.AddCommand(NewDashboardCommand()) + command.AddCommand(NewDashboardCommand(clientOpts)) command.AddCommand(NewNotificationsCommand()) command.AddCommand(NewInitialPasswordCommand()) diff --git a/cmd/argocd/commands/admin/dashboard.go b/cmd/argocd/commands/admin/dashboard.go index 33d2866e1f1c0..21b621d264022 100644 --- a/cmd/argocd/commands/admin/dashboard.go +++ b/cmd/argocd/commands/admin/dashboard.go @@ -3,7 +3,9 @@ package admin import ( "fmt" + "github.com/argoproj/argo-cd/v2/util/cli" "github.com/spf13/cobra" + "k8s.io/client-go/tools/clientcmd" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/headless" "github.com/argoproj/argo-cd/v2/cmd/argocd/commands/initialize" @@ -14,11 +16,12 @@ import ( "github.com/argoproj/argo-cd/v2/util/errors" ) -func NewDashboardCommand() *cobra.Command { +func NewDashboardCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( port int address string compressionStr string + clientConfig clientcmd.ClientConfig ) cmd := &cobra.Command{ Use: "dashboard", @@ -28,7 +31,8 @@ func NewDashboardCommand() *cobra.Command { compression, err := cache.CompressionTypeFromString(compressionStr) errors.CheckError(err) - errors.CheckError(headless.MaybeStartLocalServer(ctx, &argocdclient.ClientOptions{Core: true}, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, compression)) + clientOpts.Core = true + errors.CheckError(headless.MaybeStartLocalServer(ctx, clientOpts, initialize.RetrieveContextIfChanged(cmd.Flag("context")), &port, &address, compression, clientConfig)) println(fmt.Sprintf("Argo CD UI is available at http://%s:%d", address, port)) <-ctx.Done() }, @@ -42,7 +46,7 @@ $ argocd admin dashboard --port 8080 --address 127.0.0.1 $ argocd admin dashboard --redis-compress gzip `, } - initialize.InitCommand(cmd) + clientConfig = cli.AddKubectlFlagsToSet(cmd.Flags()) cmd.Flags().IntVar(&port, "port", common.DefaultPortAPIServer, "Listen on given port") cmd.Flags().StringVar(&address, "address", common.DefaultAddressAdminDashboard, "Listen on given address") cmd.Flags().StringVar(&compressionStr, "redis-compress", env.StringFromEnv("REDIS_COMPRESSION", string(cache.RedisCompressionGZip)), "Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none)") diff --git a/cmd/argocd/commands/headless/headless.go b/cmd/argocd/commands/headless/headless.go index 070d9c9c83bcb..5c9828fc9f131 100644 --- a/cmd/argocd/commands/headless/headless.go +++ b/cmd/argocd/commands/headless/headless.go @@ -153,9 +153,11 @@ func testAPI(ctx context.Context, clientOpts *apiclient.ClientOptions) error { // // If the clientOpts enables core mode, but the local config does not have core mode enabled, this function will // not start the local server. -func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, compression cache.RedisCompressionType) error { - flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError) - clientConfig := cli.AddKubectlFlagsToSet(flags) +func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOptions, ctxStr string, port *int, address *string, compression cache.RedisCompressionType, clientConfig clientcmd.ClientConfig) error { + if clientConfig == nil { + flags := pflag.NewFlagSet("tmp", pflag.ContinueOnError) + clientConfig = cli.AddKubectlFlagsToSet(flags) + } startInProcessAPI := clientOpts.Core if !startInProcessAPI { // Core mode is enabled on client options. Check the local config to see if we should start the API server. @@ -244,6 +246,7 @@ func MaybeStartLocalServer(ctx context.Context, clientOpts *apiclient.ClientOpti if !cache2.WaitForCacheSync(ctx.Done(), srv.Initialized) { log.Fatal("Timed out waiting for project cache to sync") } + tries := 5 for i := 0; i < tries; i++ { err = testAPI(ctx, clientOpts) @@ -265,7 +268,7 @@ func NewClientOrDie(opts *apiclient.ClientOptions, c *cobra.Command) apiclient.C ctxStr := initialize.RetrieveContextIfChanged(c.Flag("context")) // If we're in core mode, start the API server on the fly and configure the client `opts` to use it. // If we're not in core mode, this function call will do nothing. - err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone) + err := MaybeStartLocalServer(ctx, opts, ctxStr, nil, nil, cache.RedisCompressionNone, nil) if err != nil { log.Fatal(err) } diff --git a/docs/user-guide/commands/argocd_admin_dashboard.md b/docs/user-guide/commands/argocd_admin_dashboard.md index be4d5c18468ab..71e11a173906a 100644 --- a/docs/user-guide/commands/argocd_admin_dashboard.md +++ b/docs/user-guide/commands/argocd_admin_dashboard.md @@ -44,6 +44,7 @@ $ argocd admin dashboard --redis-compress gzip --proxy-url string If provided, this URL will be used to connect via proxy --redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip") --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --server string The address and port of the Kubernetes API server --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use @@ -73,7 +74,6 @@ $ argocd admin dashboard --redis-compress gzip --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") - --server string Argo CD server address --server-crt string Server certificate file --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server") ``` From 11df9900ffbf8ec19dc844f62cc4cc84900d1cd8 Mon Sep 17 00:00:00 2001 From: Prashant Shahi Date: Mon, 27 Nov 2023 10:45:00 +0530 Subject: [PATCH 121/269] feat(opentelemetry): :sparkles: support for secured OTLP endpoint and headers (#15573) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(opentelemetry): :sparkles: support for secured OTLP endpoint and headers Signed-off-by: Prashant Shahi * docs(opentelemetry): 📝 include new otlp headers in docs Signed-off-by: Prashant Shahi * docs(opentelemetry): 📝 update readme docs as per integration tests Signed-off-by: Prashant Shahi * docs(opentelemetry): 📝 update readme docs as per integration tests Signed-off-by: Prashant Shahi * chore: resolve indentation issues Signed-off-by: Prashant Shahi * chore: fix indentation issues Signed-off-by: Prashant Shahi * chore: include OTLP options in deployment manifests Signed-off-by: Prashant Shahi * fix: update manifests to resolve failing CI Signed-off-by: Prashant Shahi --------- Signed-off-by: Prashant Shahi --- .../commands/argocd_application_controller.go | 6 ++- .../commands/argocd_cmp_server.go | 6 ++- .../commands/argocd_repo_server.go | 6 ++- cmd/argocd-server/commands/argocd_server.go | 6 ++- .../operator-manual/argocd-cmd-params-cm.yaml | 6 ++- .../argocd-application-controller.md | 2 + .../server-commands/argocd-repo-server.md | 2 + .../server-commands/argocd-server.md | 2 + ...ocd-application-controller-deployment.yaml | 12 ++++++ ...cd-application-controller-statefulset.yaml | 12 ++++++ .../argocd-repo-server-deployment.yaml | 12 ++++++ .../base/server/argocd-server-deployment.yaml | 12 ++++++ manifests/core-install.yaml | 24 ++++++++++++ manifests/ha/install.yaml | 36 ++++++++++++++++++ manifests/ha/namespace-install.yaml | 36 ++++++++++++++++++ manifests/install.yaml | 36 ++++++++++++++++++ manifests/namespace-install.yaml | 36 ++++++++++++++++++ util/env/env.go | 27 +++++++++++++ util/env/env_test.go | 38 +++++++++++++++++++ util/trace/trace.go | 16 ++++++-- 20 files changed, 325 insertions(+), 8 deletions(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 4f7e587e36564..74d0af45c9d7a 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -66,6 +66,8 @@ func NewCommand() *cobra.Command { repoServerPlaintext bool repoServerStrictTLS bool otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string applicationNamespaces []string persistResourceHealth bool @@ -173,7 +175,7 @@ func NewCommand() *cobra.Command { stats.RegisterHeapDumper("memprofile") if otlpAddress != "" { - closeTracer, err := trace.InitTracer(ctx, "argocd-controller", otlpAddress, otlpAttrs) + closeTracer, err := trace.InitTracer(ctx, "argocd-controller", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -206,6 +208,8 @@ func NewCommand() *cobra.Command { command.Flags().BoolVar(&repoServerStrictTLS, "repo-server-strict-tls", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS", false), "Whether to use strict validation of the TLS cert presented by the repo server") command.Flags().StringSliceVar(&metricsAplicationLabels, "metrics-application-labels", []string{}, "List of Application labels that will be added to the argocd_application_labels metric") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_APPLICATION_CONTROLLER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that applications are allowed to be reconciled from") command.Flags().BoolVar(&persistResourceHealth, "persist-resource-health", env.ParseBoolFromEnv("ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH", true), "Enables storing the managed resources health in the Application CRD") diff --git a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go index 62f45b24aedb5..526a199cb5490 100644 --- a/cmd/argocd-cmp-server/commands/argocd_cmp_server.go +++ b/cmd/argocd-cmp-server/commands/argocd_cmp_server.go @@ -26,6 +26,8 @@ func NewCommand() *cobra.Command { var ( configFilePath string otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string ) var command = cobra.Command{ @@ -56,7 +58,7 @@ func NewCommand() *cobra.Command { if otlpAddress != "" { var closer func() var err error - closer, err = traceutil.InitTracer(ctx, "argocd-cmp-server", otlpAddress, otlpAttrs) + closer, err = traceutil.InitTracer(ctx, "argocd-cmp-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -83,6 +85,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&cmdutil.LogLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error") command.Flags().StringVar(&configFilePath, "config-dir-path", common.DefaultPluginConfigFilePath, "Config management plugin configuration file location, Default is '/home/argocd/cmp-server/config/'") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_CMP_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_CMP_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_CMP_SERVER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_CMP_SERVER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") return &command } diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index 69358d2a91efd..2a16d192e01bd 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -54,6 +54,8 @@ func NewCommand() *cobra.Command { metricsPort int metricsHost string otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string cacheSrc func() (*reposervercache.Cache, error) tlsConfigCustomizer tls.ConfigCustomizer @@ -129,7 +131,7 @@ func NewCommand() *cobra.Command { if otlpAddress != "" { var closer func() var err error - closer, err = traceutil.InitTracer(ctx, "argocd-repo-server", otlpAddress, otlpAttrs) + closer, err = traceutil.InitTracer(ctx, "argocd-repo-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -196,6 +198,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&metricsHost, "metrics-address", env.StringFromEnv("ARGOCD_REPO_SERVER_METRICS_LISTEN_ADDRESS", common.DefaultAddressRepoServerMetrics), "Listen on given address for metrics") command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortRepoServerMetrics, "Start metrics server on given port") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_REPO_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_REPO_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_REPO_SERVER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().BoolVar(&disableTLS, "disable-tls", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_TLS", false), "Disable TLS on the gRPC endpoint") command.Flags().StringVar(&maxCombinedDirectoryManifestsSize, "max-combined-directory-manifests-size", env.StringFromEnv("ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE", "10M"), "Max combined size of manifest files in a directory-type Application") diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 8709c7de09523..6eeb5b299ce0f 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -50,6 +50,8 @@ func NewCommand() *cobra.Command { metricsHost string metricsPort int otlpAddress string + otlpInsecure bool + otlpHeaders map[string]string otlpAttrs []string glogLevel int clientConfig clientcmd.ClientConfig @@ -200,7 +202,7 @@ func NewCommand() *cobra.Command { var closer func() ctx, cancel := context.WithCancel(ctx) if otlpAddress != "" { - closer, err = traceutil.InitTracer(ctx, "argocd-server", otlpAddress, otlpAttrs) + closer, err = traceutil.InitTracer(ctx, "argocd-server", otlpAddress, otlpInsecure, otlpHeaders, otlpAttrs) if err != nil { log.Fatalf("failed to initialize tracing: %v", err) } @@ -239,6 +241,8 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&metricsHost, env.StringFromEnv("ARGOCD_SERVER_METRICS_LISTEN_ADDRESS", "metrics-address"), common.DefaultAddressAPIServerMetrics, "Listen for metrics on given address") command.Flags().IntVar(&metricsPort, "metrics-port", common.DefaultPortArgoCDAPIServerMetrics, "Start metrics on given port") command.Flags().StringVar(&otlpAddress, "otlp-address", env.StringFromEnv("ARGOCD_SERVER_OTLP_ADDRESS", ""), "OpenTelemetry collector address to send traces to") + command.Flags().BoolVar(&otlpInsecure, "otlp-insecure", env.ParseBoolFromEnv("ARGOCD_SERVER_OTLP_INSECURE", true), "OpenTelemetry collector insecure mode") + command.Flags().StringToStringVar(&otlpHeaders, "otlp-headers", env.ParseStringToStringFromEnv("ARGOCD_SERVER_OTLP_HEADERS", map[string]string{}, ","), "List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2)") command.Flags().StringSliceVar(&otlpAttrs, "otlp-attrs", env.StringsFromEnv("ARGOCD_SERVER_OTLP_ATTRS", []string{}, ","), "List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value)") command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") command.Flags().StringVar(&frameOptions, "x-frame-options", env.StringFromEnv("ARGOCD_SERVER_X_FRAME_OPTIONS", "sameorigin"), "Set X-Frame-Options header in HTTP responses to `value`. To disable, set to \"\".") diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index bb55c6fb213f3..695119bf0a27f 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -17,7 +17,11 @@ data: redis.db: # Open-Telemetry collector address: (e.g. "otel-collector:4317") - otlp.address: + otlp.address: "" + # Open-Telemetry collector insecure: (e.g. "true") + otlp.insecure: "true" + # Open-Telemetry collector headers: (e.g. "key1=value1,key2=value2") + otlp.headers: "" # List of additional namespaces where applications may be created in and # reconciled from. The namespace where Argo CD is installed to will always diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index e03cf7fc51536..434c30621b8bd 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -44,6 +44,8 @@ argocd-application-controller [flags] --operation-processors int Number of application operation processors (default 10) --otlp-address string OpenTelemetry collector address to send traces to --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) --password string Password for basic authentication to the API server --persist-resource-health Enables storing the managed resources health in the Application CRD (default true) --proxy-url string If provided, this URL will be used to connect via proxy diff --git a/docs/operator-manual/server-commands/argocd-repo-server.md b/docs/operator-manual/server-commands/argocd-repo-server.md index 33ecaf7c76dd4..7be45fe18d26f 100644 --- a/docs/operator-manual/server-commands/argocd-repo-server.md +++ b/docs/operator-manual/server-commands/argocd-repo-server.md @@ -29,6 +29,8 @@ argocd-repo-server [flags] --metrics-port int Start metrics server on given port (default 8084) --otlp-address string OpenTelemetry collector address to send traces to --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) --parallelismlimit int Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. --plugin-tar-exclude stringArray Globs to filter when sending tarballs to plugins. --port int Listen on given port for incoming connections (default 8081) diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index c33cf0bedcbcf..e3dcc937243df 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -61,6 +61,8 @@ argocd-server [flags] --oidc-cache-expiration duration Cache expiration for OIDC state (default 3m0s) --otlp-address string OpenTelemetry collector address to send traces to --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) --password string Password for basic authentication to the API server --port int Listen on given port (default 8080) --proxy-url string If provided, this URL will be used to connect via proxy diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 9b618d96367dc..4862721961f21 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -136,6 +136,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index 3c576a421a25c..f5e5c759e0750 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -143,6 +143,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/base/repo-server/argocd-repo-server-deployment.yaml b/manifests/base/repo-server/argocd-repo-server-deployment.yaml index 728c80c14bc2a..907bc80a34e56 100644 --- a/manifests/base/repo-server/argocd-repo-server-deployment.yaml +++ b/manifests/base/repo-server/argocd-repo-server-deployment.yaml @@ -120,6 +120,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index b09891d26e529..6df5f9701713f 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -215,6 +215,18 @@ spec: name: argocd-cmd-params-cm key: otlp.address optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 2469f171351fe..beda1e8a5103f 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21262,6 +21262,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -21587,6 +21599,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 0f637cd786dc2..50254b138d6ab 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -22749,6 +22749,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -23144,6 +23156,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -23402,6 +23426,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 33ada40e37004..59aad0e49bda3 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2136,6 +2136,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -2531,6 +2543,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -2789,6 +2813,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/install.yaml b/manifests/install.yaml index cb4cda559caf0..4fd267106eaf6 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21795,6 +21795,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -22188,6 +22200,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -22446,6 +22470,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 9e6f98030d89b..fdd4eacd14efb 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1182,6 +1182,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_REPO_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE valueFrom: configMapKeyRef: @@ -1575,6 +1587,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_SERVER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_SERVER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: @@ -1833,6 +1857,18 @@ spec: key: otlp.address name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE + valueFrom: + configMapKeyRef: + key: otlp.insecure + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS + valueFrom: + configMapKeyRef: + key: otlp.headers + name: argocd-cmd-params-cm + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: configMapKeyRef: diff --git a/util/env/env.go b/util/env/env.go index 221db7b0efaab..985484c1ae80b 100644 --- a/util/env/env.go +++ b/util/env/env.go @@ -186,3 +186,30 @@ func ParseBoolFromEnv(envVar string, defaultValue bool) bool { } return defaultValue } + +// ParseStringToStringVar parses given value from the environment as a map of string. +// Returns default value if envVar is not set. +func ParseStringToStringFromEnv(envVar string, defaultValue map[string]string, seperator string) map[string]string { + str := os.Getenv(envVar) + str = strings.TrimSpace(str) + if str == "" { + return defaultValue + } + + parsed := make(map[string]string) + for _, pair := range strings.Split(str, seperator) { + keyvalue := strings.Split(pair, "=") + if len(keyvalue) != 2 { + log.Warnf("Invalid key-value pair when parsing environment '%s' as a string map", str) + return defaultValue + } + key := strings.TrimSpace(keyvalue[0]) + value := strings.TrimSpace(keyvalue[1]) + if _, ok := parsed[key]; ok { + log.Warnf("Duplicate key '%s' when parsing environment '%s' as a string map", key, str) + return defaultValue + } + parsed[key] = value + } + return parsed +} diff --git a/util/env/env_test.go b/util/env/env_test.go index 691d235805b23..9178592ed3552 100644 --- a/util/env/env_test.go +++ b/util/env/env_test.go @@ -210,3 +210,41 @@ func TestStringsFromEnv(t *testing.T) { }) } } + +func TestParseStringToStringFromEnv(t *testing.T) { + envKey := "SOMEKEY" + def := map[string]string{} + + testCases := []struct { + name string + env string + expected map[string]string + def map[string]string + sep string + }{ + {"success, no key-value", "", map[string]string{}, def, ","}, + {"success, one key, no value", "key1=", map[string]string{"key1": ""}, def, ","}, + {"success, one key, no value, with spaces", "key1 = ", map[string]string{"key1": ""}, def, ","}, + {"success, one pair", "key1=value1", map[string]string{"key1": "value1"}, def, ","}, + {"success, one pair with spaces", "key1 = value1", map[string]string{"key1": "value1"}, def, ","}, + {"success, one pair with spaces and no value", "key1 = ", map[string]string{"key1": ""}, def, ","}, + {"success, two keys, no value", "key1=,key2=", map[string]string{"key1": "", "key2": ""}, def, ","}, + {"success, two keys, no value, with spaces", "key1 = , key2 = ", map[string]string{"key1": "", "key2": ""}, def, ","}, + {"success, two pairs", "key1=value1,key2=value2", map[string]string{"key1": "value1", "key2": "value2"}, def, ","}, + {"success, two pairs with semicolon as seperator", "key1=value1;key2=value2", map[string]string{"key1": "value1", "key2": "value2"}, def, ";"}, + {"success, two pairs with spaces", "key1 = value1, key2 = value2", map[string]string{"key1": "value1", "key2": "value2"}, def, ","}, + {"failure, one key", "key1", map[string]string{}, def, ","}, + {"failure, duplicate keys", "key1=value1,key1=value2", map[string]string{}, def, ","}, + {"failure, one key ending with two successive equals to", "key1==", map[string]string{}, def, ","}, + {"failure, one valid pair and invalid one key", "key1=value1,key2", map[string]string{}, def, ","}, + {"failure, two valid pairs and invalid two keys", "key1=value1,key2=value2,key3,key4", map[string]string{}, def, ","}, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + t.Setenv(envKey, tt.env) + got := ParseStringToStringFromEnv(envKey, tt.def, tt.sep) + assert.Equal(t, tt.expected, got) + }) + } +} diff --git a/util/trace/trace.go b/util/trace/trace.go index 64a0361dfa3d5..9d281bf0d4c76 100644 --- a/util/trace/trace.go +++ b/util/trace/trace.go @@ -13,10 +13,11 @@ import ( "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.6.1" + "google.golang.org/grpc/credentials" ) // InitTracer initializes the trace provider and the otel grpc exporter. -func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpAttrs []string) (func(), error) { +func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpInsecure bool, otlpHeaders map[string]string, otlpAttrs []string) (func(), error) { attrs := make([]attribute.KeyValue, 0, len(otlpAttrs)) for i := range otlpAttrs { attr := otlpAttrs[i] @@ -38,10 +39,19 @@ func InitTracer(ctx context.Context, serviceName, otlpAddress string, otlpAttrs return nil, fmt.Errorf("failed to create resource: %w", err) } - // Set up a trace exporter + // set up grpc options based on secure/insecure connection + var secureOption otlptracegrpc.Option + if otlpInsecure { + secureOption = otlptracegrpc.WithInsecure() + } else { + secureOption = otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(nil, "")) + } + + // set up a trace exporter exporter, err := otlptracegrpc.New(ctx, - otlptracegrpc.WithInsecure(), + secureOption, otlptracegrpc.WithEndpoint(otlpAddress), + otlptracegrpc.WithHeaders(otlpHeaders), ) if err != nil { return nil, fmt.Errorf("failed to create trace exporter: %w", err) From 0cb99808242a9b180015f3593551b6eb75e19ba8 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Mon, 27 Nov 2023 02:22:30 -0600 Subject: [PATCH 122/269] Renamed/corrected OCI proposal filename (#16452) Signed-off-by: Andrew Block --- docs/proposals/{native-ocp-support.md => native-oci-support.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/proposals/{native-ocp-support.md => native-oci-support.md} (100%) diff --git a/docs/proposals/native-ocp-support.md b/docs/proposals/native-oci-support.md similarity index 100% rename from docs/proposals/native-ocp-support.md rename to docs/proposals/native-oci-support.md From b34e587163164dbc589dc438585dad981839b262 Mon Sep 17 00:00:00 2001 From: shijiadong2022 Date: Tue, 28 Nov 2023 16:30:52 +0800 Subject: [PATCH 123/269] fix(ui): User Info blob is too far to the right relative to Applications/Settings/Documentation (#12016) Signed-off-by: Shi, Stone --- ui/src/app/sidebar/sidebar.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/app/sidebar/sidebar.scss b/ui/src/app/sidebar/sidebar.scss index a3ff7a0355c28..20ab71b969294 100644 --- a/ui/src/app/sidebar/sidebar.scss +++ b/ui/src/app/sidebar/sidebar.scss @@ -81,6 +81,7 @@ $deselected-text: #818d94; margin-left: 2px; margin-right: -2px; margin-top: 12px; + width: 32px; } &--active { From 820f4d861a7789f299143ed89816001091abf923 Mon Sep 17 00:00:00 2001 From: nandinisingh759 <40529546+nandinisingh759@users.noreply.github.com> Date: Tue, 28 Nov 2023 13:36:52 -0800 Subject: [PATCH 124/269] feat(server): log app Spec along with event (#16416) * adding in spec to logappevent params ARGO-1017: Signed-off-by: Nandini * updating logappevent to include spec Signed-off-by: Nandini * updated logevent to take marshal logfields into json Signed-off-by: Nandini * removing spec from parameters just grabbing from app.spec Signed-off-by: Nandini * removing app.spec from test Signed-off-by: Nandini --------- Signed-off-by: Nandini Co-authored-by: Nandini Singh --- util/argo/audit_logger.go | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/util/argo/audit_logger.go b/util/argo/audit_logger.go index 1645e8d7d65d8..104b0dcd6143e 100644 --- a/util/argo/audit_logger.go +++ b/util/argo/audit_logger.go @@ -2,6 +2,7 @@ package argo import ( "context" + "encoding/json" "fmt" "time" @@ -45,7 +46,7 @@ const ( EventReasonOperationCompleted = "OperationCompleted" ) -func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, info EventInfo, message string, logFields map[string]string) { +func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, info EventInfo, message string, logFields map[string]interface{}) { logCtx := log.WithFields(log.Fields{ "type": info.Type, "reason": info.Reason, @@ -53,6 +54,19 @@ func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, i for field, val := range logFields { logCtx = logCtx.WithField(field, val) } + logFieldStrings := make(map[string]string) + for field, val := range logFields { + if valStr, ok := val.(string); ok { + logFieldStrings[field] = valStr + continue + } + vJsonStr, err := json.Marshal(val) + if err != nil { + logCtx.Errorf("Unable to marshal audit event field %v: %v", field, err) + continue + } + logFieldStrings[field] = string(vJsonStr) + } switch gvk.Kind { case application.ApplicationKind: @@ -66,7 +80,7 @@ func (l *AuditLogger) logEvent(objMeta ObjectRef, gvk schema.GroupVersionKind, i event := v1.Event{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("%v.%x", objMeta.Name, t.UnixNano()), - Annotations: logFields, + Annotations: logFieldStrings, }, Source: v1.EventSource{ Component: l.component, @@ -101,13 +115,14 @@ func (l *AuditLogger) LogAppEvent(app *v1alpha1.Application, info EventInfo, mes ResourceVersion: app.ObjectMeta.ResourceVersion, UID: app.ObjectMeta.UID, } - fields := map[string]string{ + fields := map[string]interface{}{ "dest-server": app.Spec.Destination.Server, "dest-namespace": app.Spec.Destination.Namespace, } if user != "" { fields["user"] = user } + fields["spec"] = app.Spec l.logEvent(objectMeta, v1alpha1.ApplicationSchemaGroupVersionKind, info, message, fields) } @@ -118,7 +133,7 @@ func (l *AuditLogger) LogAppSetEvent(app *v1alpha1.ApplicationSet, info EventInf ResourceVersion: app.ObjectMeta.ResourceVersion, UID: app.ObjectMeta.UID, } - fields := map[string]string{} + fields := make(map[string]interface{}) if user != "" { fields["user"] = user } @@ -132,7 +147,7 @@ func (l *AuditLogger) LogResourceEvent(res *v1alpha1.ResourceNode, info EventInf ResourceVersion: res.ResourceRef.Version, UID: types.UID(res.ResourceRef.UID), } - fields := map[string]string{} + fields := make(map[string]interface{}) if user != "" { fields["user"] = user } From 0c21ef95983adce4908b958861fc08e088e05740 Mon Sep 17 00:00:00 2001 From: Gilad Salmon Date: Wed, 29 Nov 2023 00:17:49 -0800 Subject: [PATCH 125/269] fix: upgrade notifications-engine (#16354) * fix: upgrade notifications-engine Signed-off-by: Gilad Salmon * update notification-engine version Signed-off-by: pashakostohrys * go mod tidy Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * use correct go version in codeql Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * silly Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * make notifications-docs Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Gilad Salmon Signed-off-by: pashakostohrys Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: pasha-codefresh Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .github/workflows/codeql.yml | 7 ++++- .../notifications/services/awssqs.md | 6 ++-- .../notifications/services/github.md | 9 ++++-- .../notifications/services/googlechat.md | 21 ++++++++------ .../notifications/services/slack.md | 14 ++++++---- .../notifications/services/teams.md | 2 +- .../notifications/services/webhook.md | 15 ++++++++-- go.mod | 11 ++++++-- go.sum | 28 +++++++++++++++++-- 9 files changed, 85 insertions(+), 28 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 58426890abcbf..2311d43925bb7 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,10 +27,15 @@ jobs: # CodeQL runs on ubuntu-latest and windows-latest runs-on: ubuntu-22.04 - steps: - name: Checkout repository uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + + # Use correct go version. https://github.com/github/codeql-action/issues/1842#issuecomment-1704398087 + - name: Setup Golang + uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.0.0 + with: + go-version-file: go.mod # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/docs/operator-manual/notifications/services/awssqs.md b/docs/operator-manual/notifications/services/awssqs.md index 6bbc47cbbc0b5..6b744f4744b93 100755 --- a/docs/operator-manual/notifications/services/awssqs.md +++ b/docs/operator-manual/notifications/services/awssqs.md @@ -4,10 +4,10 @@ This notification service is capable of sending simple messages to AWS SQS queue. -* `queue` - name of the queue you are intending to send messages to. Can be overwriten with target destination annotation. +* `queue` - name of the queue you are intending to send messages to. Can be overridden with target destination annotation. * `region` - region of the sqs queue can be provided via env variable AWS_DEFAULT_REGION * `key` - optional, aws access key must be either referenced from a secret via variable or via env variable AWS_ACCESS_KEY_ID -* `secret` - optional, aws access secret must be either referenced from a secret via variableor via env variable AWS_SECRET_ACCESS_KEY +* `secret` - optional, aws access secret must be either referenced from a secret via variable or via env variable AWS_SECRET_ACCESS_KEY * `account` optional, external accountId of the queue * `endpointUrl` optional, useful for development with localstack @@ -63,7 +63,7 @@ stringData: ### Minimal configuration using AWS Env variables -Ensure following list of enviromental variable is injected via OIDC, or other method. And assuming SQS is local to the account. +Ensure following list of environment variables are injected via OIDC, or other method. And assuming SQS is local to the account. You may skip usage of secret for sensitive data and omit other parameters. (Setting parameters via ConfigMap takes precedent.) Variables: diff --git a/docs/operator-manual/notifications/services/github.md b/docs/operator-manual/notifications/services/github.md index a3f89f8c87ef0..be76ab150d1a1 100755 --- a/docs/operator-manual/notifications/services/github.md +++ b/docs/operator-manual/notifications/services/github.md @@ -12,7 +12,7 @@ The GitHub notification service changes commit status using [GitHub Apps](https: ## Configuration 1. Create a GitHub Apps using https://github.com/settings/apps/new -2. Change repository permissions to enable write commit statuses and/or deployments +2. Change repository permissions to enable write commit statuses and/or deployments and/or pull requests comments ![2](https://user-images.githubusercontent.com/18019529/108397381-3ca57980-725b-11eb-8d17-5b8992dc009e.png) 3. Generate a private key, and download it automatically ![3](https://user-images.githubusercontent.com/18019529/108397926-d4a36300-725b-11eb-83fe-74795c8c3e03.png) @@ -76,6 +76,10 @@ template.app-deployed: | logURL: "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" requiredContexts: [] autoMerge: true + pullRequestComment: + content: | + Application {{.app.metadata.name}} is now running new version of deployments manifests. + See more here: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true ``` **Notes**: @@ -83,4 +87,5 @@ template.app-deployed: | - If `github.repoURLPath` and `github.revisionPath` are same as above, they can be omitted. - Automerge is optional and `true` by default for github deployments to ensure the requested ref is up to date with the default branch. Setting this option to `false` is required if you would like to deploy older refs in your default branch. - For more information see the [Github Deployment API Docs](https://docs.github.com/en/rest/deployments/deployments?apiVersion=2022-11-28#create-a-deployment). + For more information see the [GitHub Deployment API Docs](https://docs.github.com/en/rest/deployments/deployments?apiVersion=2022-11-28#create-a-deployment). +- If `github.pullRequestComment.content` is set to 65536 characters or more, it will be truncated. diff --git a/docs/operator-manual/notifications/services/googlechat.md b/docs/operator-manual/notifications/services/googlechat.md index 041ea6e022ef5..885ce685a4511 100755 --- a/docs/operator-manual/notifications/services/googlechat.md +++ b/docs/operator-manual/notifications/services/googlechat.md @@ -59,24 +59,27 @@ A card message can be defined as follows: ```yaml template.app-sync-succeeded: | googlechat: - cards: | + cardsV2: | - header: title: ArgoCD Bot Notification sections: - widgets: - - textParagraph: + - decoratedText: text: The app {{ .app.metadata.name }} has successfully synced! - widgets: - - keyValue: + - decoratedText: topLabel: Repository - content: {{ call .repo.RepoURLToHTTPS .app.spec.source.repoURL }} - - keyValue: + text: {{ call .repo.RepoURLToHTTPS .app.spec.source.repoURL }} + - decoratedText: topLabel: Revision - content: {{ .app.spec.source.targetRevision }} - - keyValue: + text: {{ .app.spec.source.targetRevision }} + - decoratedText: topLabel: Author - content: {{ (call .repo.GetCommitMetadata .app.status.sync.revision).Author }} + text: {{ (call .repo.GetCommitMetadata .app.status.sync.revision).Author }} ``` +All [Card fields](https://developers.google.com/chat/api/reference/rest/v1/cards#Card_1) are supported and can be used +in notifications. It is also possible to use the previous (now deprecated) `cards` key to use the legacy card fields, +but this is not recommended as Google has deprecated this field and recommends using the newer `cardsV2`. The card message can be written in JSON too. @@ -86,7 +89,7 @@ It is possible send both simple text and card messages in a chat thread by speci ```yaml template.app-sync-succeeded: | - message: The app {{ .app.metadata.name }} has succesfully synced! + message: The app {{ .app.metadata.name }} has successfully synced! googlechat: threadKey: {{ .app.metadata.name }} ``` diff --git a/docs/operator-manual/notifications/services/slack.md b/docs/operator-manual/notifications/services/slack.md index 15937597c19f2..0f3fdf1739210 100755 --- a/docs/operator-manual/notifications/services/slack.md +++ b/docs/operator-manual/notifications/services/slack.md @@ -6,11 +6,15 @@ If you want to send message using incoming webhook, you can use [webhook](./webh The Slack notification service configuration includes following settings: -* `token` - the app token -* `apiURL` - optional, the server url, e.g. https://example.com/api -* `username` - optional, the app username -* `icon` - optional, the app icon, e.g. :robot_face: or https://example.com/image.png -* `insecureSkipVerify` - optional bool, true or false +| **Option** | **Required** | **Type** | **Description** | **Example** | +| -------------------- | ------------ | -------------- | --------------- | ----------- | +| `apiURL` | False | `string` | The server URL. | `https://example.com/api` | +| `channels` | False | `list[string]` | | `["my-channel-1", "my-channel-2"]` | +| `icon` | False | `string` | The app icon. | `:robot_face:` or `https://example.com/image.png` | +| `insecureSkipVerify` | False | `bool` | | `true` | +| `signingSecret` | False | `string` | | `8f742231b10e8888abcd99yyyzzz85a5` | +| `token` | **True** | `string` | The app's OAuth access token. | `xoxb-1234567890-1234567890123-5n38u5ed63fgzqlvuyxvxcx6` | +| `username` | False | `string` | The app username. | `argocd` | ## Configuration diff --git a/docs/operator-manual/notifications/services/teams.md b/docs/operator-manual/notifications/services/teams.md index b5b9a228c43eb..8b8c6b819c795 100755 --- a/docs/operator-manual/notifications/services/teams.md +++ b/docs/operator-manual/notifications/services/teams.md @@ -113,7 +113,7 @@ template.app-sync-succeeded: | ### summary field -You can set a summary of the message that will be shown on Notifcation & Activity Feed +You can set a summary of the message that will be shown on Notification & Activity Feed ![](https://user-images.githubusercontent.com/6957724/116587921-84c4d480-a94d-11eb-9da4-f365151a12e7.jpg) diff --git a/docs/operator-manual/notifications/services/webhook.md b/docs/operator-manual/notifications/services/webhook.md index bd45b1f69e40b..965098402236f 100755 --- a/docs/operator-manual/notifications/services/webhook.md +++ b/docs/operator-manual/notifications/services/webhook.md @@ -1,7 +1,7 @@ # Webhook The webhook notification service allows sending a generic HTTP request using the templatized request body and URL. -Using Webhook you might trigger a Jenkins job, update Github commit status. +Using Webhook you might trigger a Jenkins job, update GitHub commit status. ## Parameters @@ -9,8 +9,17 @@ The Webhook notification service configuration includes following settings: - `url` - the url to send the webhook to - `headers` - optional, the headers to pass along with the webhook -- `basicAuth` - optional, the basic authentication to pass along with the webook +- `basicAuth` - optional, the basic authentication to pass along with the webhook - `insecureSkipVerify` - optional bool, true or false +- `retryWaitMin` - Optional, the minimum wait time between retries. Default value: 1s. +- `retryWaitMax` - Optional, the maximum wait time between retries. Default value: 5s. +- `retryMax` - Optional, the maximum number of retries. Default value: 3. + +## Retry Behavior + +The webhook service will automatically retry the request if it fails due to network errors or if the server returns a 5xx status code. The number of retries and the wait time between retries can be configured using the `retryMax`, `retryWaitMin`, and `retryWaitMax` parameters. + +The wait time between retries is between `retryWaitMin` and `retryWaitMax`. If all retries fail, the `Send` method will return an error. ## Configuration @@ -67,7 +76,7 @@ metadata: ## Examples -### Set Github commit status +### Set GitHub commit status ```yaml apiVersion: v1 diff --git a/go.mod b/go.mod index 3180996ab5f99..8b91fe20eef1b 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/argoproj/argo-cd/v2 -go 1.19 +go 1.21 + +toolchain go1.21.0 require ( code.gitea.io/sdk/gitea v0.15.1 @@ -12,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 - github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf + github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 github.com/bmatcuk/doublestar/v4 v4.6.0 @@ -126,11 +128,16 @@ require ( github.com/aws/aws-sdk-go-v2/service/sts v1.18.0 // indirect github.com/aws/smithy-go v1.13.5 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect + github.com/google/s2a-go v0.1.4 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect github.com/tidwall/gjson v1.14.4 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect + go.opencensus.io v0.24.0 // indirect + google.golang.org/api v0.132.0 // indirect google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/retry.v1 v1.0.3 // indirect diff --git a/go.sum b/go.sum index bb7c2ca8627f6..dbe7107f59cba 100644 --- a/go.sum +++ b/go.sum @@ -686,6 +686,7 @@ github.com/alicebob/miniredis/v2 v2.30.4 h1:8S4/o1/KoUArAGbGwPxcwf0krlzceva2XVOS github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antonmedv/expr v1.15.2 h1:afFXpDWIC2n3bF+kTZE1JvFo+c34uaM3sTqh8z0xfdU= github.com/antonmedv/expr v1.15.2/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= @@ -697,8 +698,8 @@ github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2 github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 h1:vnXMrNkBFC0H0KBkH1Jno31OVgJQR4KSd0ypEcfzQRA= github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48/go.mod h1:1TchqKw9XmYYZluyEHa1dTJQoZgbV6PhabB/e8Wf3KY= -github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf h1:4wliaBwd6iKvT/5huDTJntaYtTSdwPLs00SOQwDSK6A= -github.com/argoproj/notifications-engine v0.4.1-0.20230905144632-9dcecdc3eebf/go.mod h1:TuK0BNKo34DIUOyCCGOB9ij+smGCxeCgt9ZB+0fMWno= +github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 h1:1lt0VXzmLK7Vv0kaeal3S6/JIfzPyBORkUWXhiqF3l0= +github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9/go.mod h1:E/vv4+by868m0mmflaRfGBmKBtAupoF+mmyfekP8QCk= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -761,7 +762,9 @@ github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGpy5Y5BPsz4IfuJtGk= github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk= github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao= +github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= +github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= @@ -805,6 +808,7 @@ github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= @@ -833,6 +837,7 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dnaeon/go-vcr v1.1.0 h1:ReYa/UBrRyQdant9B4fNHGoCNKw6qh6P0fsdGmZpR7c= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= @@ -846,6 +851,7 @@ github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFP github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= +github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -868,6 +874,7 @@ github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA= +github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= @@ -892,6 +899,7 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= @@ -907,6 +915,7 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g= @@ -919,6 +928,7 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= @@ -947,6 +957,7 @@ github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= @@ -1149,6 +1160,7 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM= github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -1163,6 +1175,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -1177,6 +1191,8 @@ github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38 github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw= github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gopackage/ddp v0.0.0-20170117053602-652027933df4 h1:4EZlYQIiyecYJlUbVkFXCXHz1QPhVXcHnQKAzBTPfQo= @@ -1330,6 +1346,7 @@ github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -1580,6 +1597,7 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1727,6 +1745,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= @@ -1756,6 +1775,7 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= @@ -1765,6 +1785,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -2324,6 +2345,8 @@ google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjY google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms= google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4= google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/api v0.132.0 h1:8t2/+qZ26kAOGSmOiHwVycqVaDg7q3JDILrNi/Z6rvc= +google.golang.org/api v0.132.0/go.mod h1:AeTBC6GpJnJSRJjktDcPX0QwtS8pGYZOV6MSuSCusw0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2583,6 +2606,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 23f2767250d055e9eb8855ec5e60dd76c3734d30 Mon Sep 17 00:00:00 2001 From: Yudi A Phanama <11147376+phanama@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:26:40 +0700 Subject: [PATCH 126/269] fix(cli): pass redis compression to cluster stats and shards commands (#16060) (#16421) --- cmd/argocd/commands/admin/cluster.go | 46 +++++++++++++++++++--------- util/cache/cache.go | 7 ++++- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index a72aaebc201a0..6625787de7d71 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -69,7 +69,7 @@ type ClusterWithInfo struct { Namespaces []string } -func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string) ([]ClusterWithInfo, error) { +func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string, redisCompressionStr string) ([]ClusterWithInfo, error) { settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace) argoDB := db.NewDB(namespace, settingsMgr, kubeClient) @@ -88,7 +88,11 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie return nil, err } client := redis.NewClient(&redis.Options{Addr: fmt.Sprintf("localhost:%d", port)}) - cache = appstatecache.NewCache(cacheutil.NewCache(cacheutil.NewRedisCache(client, time.Hour, cacheutil.RedisCompressionNone)), time.Hour) + compressionType, err := cacheutil.CompressionTypeFromString(redisCompressionStr) + if err != nil { + return nil, err + } + cache = appstatecache.NewCache(cacheutil.NewCache(cacheutil.NewRedisCache(client, time.Hour, compressionType)), time.Hour) } else { cache, err = cacheSrc() if err != nil { @@ -161,11 +165,12 @@ func getControllerReplicas(ctx context.Context, kubeClient *kubernetes.Clientset func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - shard int - replicas int - clientConfig clientcmd.ClientConfig - cacheSrc func() (*appstatecache.Cache, error) - portForwardRedis bool + shard int + replicas int + clientConfig clientcmd.ClientConfig + cacheSrc func() (*appstatecache.Cache, error) + portForwardRedis bool + redisCompressionStr string ) var command = cobra.Command{ Use: "shards", @@ -190,7 +195,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm return } - clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName) + clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) errors.CheckError(err) if len(clusters) == 0 { return @@ -204,6 +209,12 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm command.Flags().IntVar(&replicas, "replicas", 0, "Application controller replicas count. Inferred from number of running controller pods if not specified") command.Flags().BoolVar(&portForwardRedis, "port-forward-redis", true, "Automatically port-forward ha proxy redis from current namespace?") cacheSrc = appstatecache.AddCacheFlagsToCmd(&command) + + // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above + // we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later + // nolint:errcheck + command.ParseFlags(os.Args[1:]) + redisCompressionStr, _ = command.Flags().GetString(cacheutil.CLIFlagRedisCompress) return &command } @@ -439,11 +450,12 @@ func NewClusterDisableNamespacedMode() *cobra.Command { func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - shard int - replicas int - clientConfig clientcmd.ClientConfig - cacheSrc func() (*appstatecache.Cache, error) - portForwardRedis bool + shard int + replicas int + clientConfig clientcmd.ClientConfig + cacheSrc func() (*appstatecache.Cache, error) + portForwardRedis bool + redisCompressionStr string ) var command = cobra.Command{ Use: "stats", @@ -464,7 +476,7 @@ func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma replicas, err = getControllerReplicas(ctx, kubeClient, namespace, clientOpts.AppControllerName) errors.CheckError(err) } - clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName) + clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) errors.CheckError(err) w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -480,6 +492,12 @@ func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma command.Flags().IntVar(&replicas, "replicas", 0, "Application controller replicas count. Inferred from number of running controller pods if not specified") command.Flags().BoolVar(&portForwardRedis, "port-forward-redis", true, "Automatically port-forward ha proxy redis from current namespace?") cacheSrc = appstatecache.AddCacheFlagsToCmd(&command) + + // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above + // we can ignore unchecked error here as the command will be parsed again and checked when command.Execute() is run later + // nolint:errcheck + command.ParseFlags(os.Args[1:]) + redisCompressionStr, _ = command.Flags().GetString(cacheutil.CLIFlagRedisCompress) return &command } diff --git a/util/cache/cache.go b/util/cache/cache.go index fdea46cdea0d2..c9cb8c3b8607a 100644 --- a/util/cache/cache.go +++ b/util/cache/cache.go @@ -29,6 +29,11 @@ const ( defaultRedisRetryCount = 3 ) +const ( + // CLIFlagRedisCompress is a cli flag name to define the redis compression setting for data sent to redis + CLIFlagRedisCompress = "redis-compress" +) + func NewCache(client CacheClient) *Cache { return &Cache{client} } @@ -96,7 +101,7 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) cmd.Flags().StringVar(&redisClientKey, "redis-client-key", "", "Path to Redis client key (e.g. /etc/certs/redis/client.crt).") cmd.Flags().BoolVar(&insecureRedis, "redis-insecure-skip-tls-verify", false, "Skip Redis server certificate validation.") cmd.Flags().StringVar(&redisCACertificate, "redis-ca-certificate", "", "Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.") - cmd.Flags().StringVar(&compressionStr, "redis-compress", env.StringFromEnv("REDIS_COMPRESSION", string(RedisCompressionGZip)), "Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none)") + cmd.Flags().StringVar(&compressionStr, CLIFlagRedisCompress, env.StringFromEnv("REDIS_COMPRESSION", string(RedisCompressionGZip)), "Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none)") return func() (*Cache, error) { var tlsConfig *tls.Config = nil if redisUseTLS { From 4875b02b881cff3c2dc4b095792489aad1e38bbf Mon Sep 17 00:00:00 2001 From: Leonardo Luz Almeida Date: Wed, 29 Nov 2023 11:08:29 -0500 Subject: [PATCH 127/269] fix(controller): Address diff cache miss issues (#16458) * fix: Address diff cache miss issues Signed-off-by: Leonardo Luz Almeida * validate mergo.Merge errors Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida * Allow setting log level at the controller Signed-off-by: Leonardo Luz Almeida * remove unnecessary log setup Signed-off-by: Leonardo Luz Almeida --------- Signed-off-by: Leonardo Luz Almeida --- controller/state.go | 57 +++++- controller/state_test.go | 252 +++++++++++++++++++++++++ pkg/apis/application/v1alpha1/types.go | 29 +++ 3 files changed, 329 insertions(+), 9 deletions(-) diff --git a/controller/state.go b/controller/state.go index 15da3d2e624ed..59e7fa31248ae 100644 --- a/controller/state.go +++ b/controller/state.go @@ -116,6 +116,10 @@ type appStateManager struct { repoErrorGracePeriod time.Duration } +// getRepoObjs will generate the manifests for the given application delegating the +// task to the repo-server. It returns the list of generated manifests as unstructured +// objects. It also returns the full response from all calls to the repo server as the +// second argument. func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) { ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) @@ -580,21 +584,16 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 manifestRevisions = append(manifestRevisions, manifestInfo.Revision) } - // restore comparison using cached diff result if previous comparison was performed for the same revision - revisionChanged := len(manifestInfos) != len(sources) || !reflect.DeepEqual(app.Status.Sync.Revisions, manifestRevisions) - specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, v1alpha1.ComparedTo{Source: app.Spec.GetSource(), Destination: app.Spec.Destination, Sources: sources, IgnoreDifferences: app.Spec.IgnoreDifferences}) - - _, refreshRequested := app.IsRefreshRequested() - noCache = noCache || refreshRequested || app.Status.Expired(m.statusRefreshTimeout) || specChanged || revisionChanged + useDiffCache := useDiffCache(noCache, manifestInfos, sources, app, manifestRevisions, m.statusRefreshTimeout, logCtx) diffConfigBuilder := argodiff.NewDiffConfigBuilder(). WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles). WithTracking(appLabelKey, string(trackingMethod)) - if noCache { - diffConfigBuilder.WithNoCache() + if useDiffCache { + diffConfigBuilder.WithCache(m.cache, app.InstanceName(m.namespace)) } else { - diffConfigBuilder.WithCache(m.cache, app.GetName()) + diffConfigBuilder.WithNoCache() } gvkParser, err := m.getGVKParser(app.Spec.Destination.Server) @@ -801,6 +800,46 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 return &compRes, nil } +// useDiffCache will determine if the diff should be calculated based +// on the existing live state cache or not. +func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sources []v1alpha1.ApplicationSource, app *v1alpha1.Application, manifestRevisions []string, statusRefreshTimeout time.Duration, log *log.Entry) bool { + + if noCache { + log.WithField("useDiffCache", "false").Debug("noCache is true") + return false + } + _, refreshRequested := app.IsRefreshRequested() + if refreshRequested { + log.WithField("useDiffCache", "false").Debug("refreshRequested") + return false + } + if app.Status.Expired(statusRefreshTimeout) { + log.WithField("useDiffCache", "false").Debug("app.status.expired") + return false + } + + if len(manifestInfos) != len(sources) { + log.WithField("useDiffCache", "false").Debug("manifestInfos len != sources len") + return false + } + + revisionChanged := !reflect.DeepEqual(app.Status.GetRevisions(), manifestRevisions) + if revisionChanged { + log.WithField("useDiffCache", "false").Debug("revisionChanged") + return false + } + + currentSpec := app.BuildComparedToStatus() + specChanged := !reflect.DeepEqual(app.Status.Sync.ComparedTo, currentSpec) + if specChanged { + log.WithField("useDiffCache", "false").Debug("specChanged") + return false + } + + log.WithField("useDiffCache", "true").Debug("using diff cache") + return true +} + func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, revisions []string, sources []v1alpha1.ApplicationSource, hasMultipleSources bool, startedAt metav1.Time) error { var nextID int64 if len(app.Status.History) > 0 { diff --git a/controller/state_test.go b/controller/state_test.go index 6eb336cff2ffb..a240b30d688df 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -11,6 +11,9 @@ import ( synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" . "github.com/argoproj/gitops-engine/pkg/utils/testing" + "github.com/imdario/mergo" + "github.com/sirupsen/logrus" + logrustest "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/assert" v1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -1393,3 +1396,252 @@ func TestIsLiveResourceManaged(t *testing.T) { assert.True(t, manager.isSelfReferencedObj(managedWrongAPIGroup, config, appName, common.AnnotationKeyAppInstance, argo.TrackingMethodAnnotation)) }) } + +func TestUseDiffCache(t *testing.T) { + type fixture struct { + testName string + noCache bool + manifestInfos []*apiclient.ManifestResponse + sources []argoappv1.ApplicationSource + app *argoappv1.Application + manifestRevisions []string + statusRefreshTimeout time.Duration + expectedUseCache bool + } + + manifestInfos := func(revision string) []*apiclient.ManifestResponse { + return []*apiclient.ManifestResponse{ + { + Manifests: []string{ + "{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-svc\",\"namespace\":\"httpbin\"},\"spec\":{\"ports\":[{\"name\":\"http-port\",\"port\":7777,\"targetPort\":80},{\"name\":\"test\",\"port\":333}],\"selector\":{\"app\":\"httpbin\"}}}", + "{\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"labels\":{\"app.kubernetes.io/instance\":\"httpbin\"},\"name\":\"httpbin-deployment\",\"namespace\":\"httpbin\"},\"spec\":{\"replicas\":2,\"selector\":{\"matchLabels\":{\"app\":\"httpbin\"}},\"template\":{\"metadata\":{\"labels\":{\"app\":\"httpbin\"}},\"spec\":{\"containers\":[{\"image\":\"kennethreitz/httpbin\",\"imagePullPolicy\":\"Always\",\"name\":\"httpbin\",\"ports\":[{\"containerPort\":80}]}]}}}}", + }, + Namespace: "", + Server: "", + Revision: revision, + SourceType: "Kustomize", + VerifyResult: "", + }, + } + } + sources := func() []argoappv1.ApplicationSource { + return []argoappv1.ApplicationSource{ + { + RepoURL: "https://some-repo.com", + Path: "argocd/httpbin", + TargetRevision: "HEAD", + }, + } + } + + app := func(namespace string, revision string, refresh bool, a *argoappv1.Application) *argoappv1.Application { + app := &argoappv1.Application{ + ObjectMeta: metav1.ObjectMeta{ + Name: "httpbin", + Namespace: namespace, + }, + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{ + RepoURL: "https://some-repo.com", + Path: "argocd/httpbin", + TargetRevision: "HEAD", + }, + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "httpbin", + }, + Project: "default", + SyncPolicy: &argoappv1.SyncPolicy{ + SyncOptions: []string{ + "CreateNamespace=true", + "ServerSideApply=true", + }, + }, + }, + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Source: argoappv1.ApplicationSource{ + RepoURL: "https://some-repo.com", + Path: "argocd/httpbin", + TargetRevision: "HEAD", + }, + Destination: argoappv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "httpbin", + }, + }, + Revision: revision, + Revisions: []string{}, + }, + ReconciledAt: &metav1.Time{ + Time: time.Now().Add(-time.Hour), + }, + }, + } + if refresh { + annotations := make(map[string]string) + annotations[argoappv1.AnnotationKeyRefresh] = string(argoappv1.RefreshTypeNormal) + app.SetAnnotations(annotations) + } + if a != nil { + err := mergo.Merge(app, a, mergo.WithOverride, mergo.WithOverwriteWithEmptyValue) + if err != nil { + t.Fatalf("error merging app: %s", err) + } + } + return app + } + + cases := []fixture{ + { + testName: "will use diff cache", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: true, + }, + { + testName: "will use diff cache for multisource", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Source: nil, + Sources: argoappv1.ApplicationSources{ + { + RepoURL: "multisource repo1", + }, + { + RepoURL: "multisource repo2", + }, + }, + }, + Status: argoappv1.ApplicationStatus{ + Resources: []argoappv1.ResourceStatus{}, + Sync: argoappv1.SyncStatus{ + Status: argoappv1.SyncStatusCodeSynced, + ComparedTo: argoappv1.ComparedTo{ + Source: argoappv1.ApplicationSource{}, + Sources: argoappv1.ApplicationSources{ + { + RepoURL: "multisource repo1", + }, + { + RepoURL: "multisource repo2", + }, + }, + }, + Revisions: []string{"rev1", "rev2"}, + }, + ReconciledAt: &metav1.Time{ + Time: time.Now().Add(-time.Hour), + }, + }, + }), + manifestRevisions: []string{"rev1", "rev2"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: true, + }, + { + testName: "will return false if nocache is true", + noCache: true, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if requested refresh", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", true, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if status expired", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Minute, + expectedUseCache: false, + }, + { + testName: "will return false if there is a new revision", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev2"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if app spec repo changed", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + Source: &argoappv1.ApplicationSource{ + RepoURL: "new-repo", + }, + }, + }), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + { + testName: "will return false if app spec IgnoreDifferences changed", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, &argoappv1.Application{ + Spec: argoappv1.ApplicationSpec{ + IgnoreDifferences: []argoappv1.ResourceIgnoreDifferences{ + { + Group: "app/v1", + Kind: "application", + Name: "httpbin", + Namespace: "httpbin", + JQPathExpressions: []string{"."}, + }, + }, + }, + }), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Hour * 24, + expectedUseCache: false, + }, + } + + for _, tc := range cases { + tc := tc + t.Run(tc.testName, func(t *testing.T) { + // Given + t.Parallel() + logger, _ := logrustest.NewNullLogger() + log := logrus.NewEntry(logger) + + // When + useDiffCache := useDiffCache(tc.noCache, tc.manifestInfos, tc.sources, tc.app, tc.manifestRevisions, tc.statusRefreshTimeout, log) + + // Then + assert.Equal(t, useDiffCache, tc.expectedUseCache) + }) + } +} diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 1957ec59a341e..dc6a73f05dee5 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -955,6 +955,35 @@ type ApplicationStatus struct { ControllerNamespace string `json:"controllerNamespace,omitempty" protobuf:"bytes,13,opt,name=controllerNamespace"` } +// GetRevisions will return the current revision associated with the Application. +// If app has multisources, it will return all corresponding revisions preserving +// order from the app.spec.sources. If app has only one source, it will return a +// single revision in the list. +func (a *ApplicationStatus) GetRevisions() []string { + revisions := []string{} + if len(a.Sync.Revisions) > 0 { + revisions = a.Sync.Revisions + } else if a.Sync.Revision != "" { + revisions = append(revisions, a.Sync.Revision) + } + return revisions +} + +// BuildComparedToStatus will build a ComparedTo object based on the current +// Application state. +func (app *Application) BuildComparedToStatus() ComparedTo { + ct := ComparedTo{ + Destination: app.Spec.Destination, + IgnoreDifferences: app.Spec.IgnoreDifferences, + } + if app.Spec.HasMultipleSources() { + ct.Sources = app.Spec.Sources + } else { + ct.Source = app.Spec.GetSource() + } + return ct +} + // JWTTokens represents a list of JWT tokens type JWTTokens struct { Items []JWTToken `json:"items,omitempty" protobuf:"bytes,1,opt,name=items"` From c602302d62d208627004d6c6be4ab359c13be6b3 Mon Sep 17 00:00:00 2001 From: filiprafaj Date: Thu, 30 Nov 2023 04:32:42 +0100 Subject: [PATCH 128/269] fix PerconaXtraDBCluster health (#16434) Signed-off-by: Filip Rafaj Co-authored-by: Filip Rafaj --- .../pxc.percona.com/PerconaXtraDBCluster/health.lua | 2 +- .../PerconaXtraDBCluster/testdata/error.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua index 9de2180197571..d614828d461f2 100644 --- a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua +++ b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/health.lua @@ -27,7 +27,7 @@ if obj.status ~= nil then if obj.status.state == "error" then hs.status = "Degraded" - hs.message = "Cluster is on error: " .. table.concat(obj.status.messages, ", ") + hs.message = "Cluster is on error: " .. table.concat(obj.status.message, ", ") return hs end diff --git a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml index b6f1884be0819..4a373358dcd8c 100644 --- a/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml +++ b/resource_customizations/pxc.percona.com/PerconaXtraDBCluster/testdata/error.yaml @@ -12,7 +12,7 @@ status: pmm: {} proxysql: {} pxc: - image: '' + image: "" ready: 1 size: 2 status: error @@ -20,5 +20,5 @@ status: ready: 1 size: 2 state: error - messages: - - we lost node + message: + - we lost node From 8070725eecac8a98a617049ec128f6149aeb7f03 Mon Sep 17 00:00:00 2001 From: Suraj yadav Date: Thu, 30 Nov 2023 09:22:07 +0530 Subject: [PATCH 129/269] feat(cli): Added example to admin-cluster.go and projectwindow.go files (#16128) * cluster.go, projectwindow.go Signed-off-by: Surajyadav * updated-examples Signed-off-by: Surajyadav * format-corrected Signed-off-by: Surajyadav * spell-mistake Signed-off-by: Surajyadav * format-correction Signed-off-by: Surajyadav * retrigger Signed-off-by: Surajyadav * retrigger-2 Signed-off-by: Surajyadav * retirgger-3 Signed-off-by: Surajyadav * update Signed-off-by: Surajyadav --------- Signed-off-by: Surajyadav Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- cmd/argocd/commands/admin/cluster.go | 30 ++++++++++++ cmd/argocd/commands/projectwindows.go | 49 ++++++++++++++++--- .../commands/argocd_admin_cluster.md | 14 ++++++ .../argocd_admin_cluster_kubeconfig.md | 17 +++++++ .../commands/argocd_admin_cluster_stats.md | 14 ++++++ .../commands/argocd_proj_windows.md | 17 +++++++ .../commands/argocd_proj_windows_add.md | 5 +- .../commands/argocd_proj_windows_delete.md | 11 +++++ ...argocd_proj_windows_disable-manual-sync.md | 11 +++++ .../argocd_proj_windows_enable-manual-sync.md | 14 ++++++ .../commands/argocd_proj_windows_list.md | 9 ++-- 11 files changed, 180 insertions(+), 11 deletions(-) diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 6625787de7d71..5d14717a15e7d 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -44,6 +44,15 @@ func NewClusterCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clientc var command = &cobra.Command{ Use: "cluster", Short: "Manage clusters configuration", + Example: ` +#Generate declarative config for a cluster +argocd admin cluster generate-spec my-cluster -o yaml + +#Generate a kubeconfig for a cluster named "my-cluster" and display it in the console +argocd admin cluster kubeconfig my-cluster + +#Print information namespaces which Argo CD manages in each cluster +argocd admin cluster namespaces my-cluster `, Run: func(c *cobra.Command, args []string) { c.HelpFunc()(c, args) }, @@ -460,6 +469,15 @@ func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma var command = cobra.Command{ Use: "stats", Short: "Prints information cluster statistics and inferred shard number", + Example: ` +#Display stats and shards for clusters +argocd admin cluster stats + +#Display Cluster Statistics for a Specific Shard +argocd admin cluster stats --shard=1 + +#In a multi-cluster environment to print stats for a specific cluster say(target-cluster) +argocd admin cluster stats target-cluster`, Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() @@ -510,6 +528,18 @@ func NewClusterConfig() *cobra.Command { Use: "kubeconfig CLUSTER_URL OUTPUT_PATH", Short: "Generates kubeconfig for the specified cluster", DisableAutoGenTag: true, + Example: ` +#Generate a kubeconfig for a cluster named "my-cluster" on console +argocd admin cluster kubeconfig my-cluster + +#Listing available kubeconfigs for clusters managed by argocd +argocd admin cluster kubeconfig + +#Removing a specific kubeconfig file +argocd admin cluster kubeconfig my-cluster --delete + +#Generate a Kubeconfig for a Cluster with TLS Verification Disabled +argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kubeconfig.yaml --insecure-skip-tls-verify`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/cmd/argocd/commands/projectwindows.go b/cmd/argocd/commands/projectwindows.go index a46f9ece64c36..93843130ebb13 100644 --- a/cmd/argocd/commands/projectwindows.go +++ b/cmd/argocd/commands/projectwindows.go @@ -22,6 +22,18 @@ func NewProjectWindowsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com roleCommand := &cobra.Command{ Use: "windows", Short: "Manage a project's sync windows", + Example: ` +#Add a sync window to a project +argocd proj windows add my-project \ +--schedule "0 0 * * 1-5" \ +--duration 3600 \ +--prune + +#Delete a sync window from a project +argocd proj windows delete + +#List project sync windows +argocd proj windows list `, Run: func(c *cobra.Command, args []string) { c.HelpFunc()(c, args) os.Exit(1) @@ -42,6 +54,12 @@ func NewProjectWindowsDisableManualSyncCommand(clientOpts *argocdclient.ClientOp Use: "disable-manual-sync PROJECT ID", Short: "Disable manual sync for a sync window", Long: "Disable manual sync for a sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: ` +#Disable manual sync for a sync window for the Project +argocd proj windows disable-manual-sync PROJECT ID + +#Disbaling manual sync for a windows set on the default project with Id 0 +argocd proj windows disable-manual-sync default 0`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -79,6 +97,15 @@ func NewProjectWindowsEnableManualSyncCommand(clientOpts *argocdclient.ClientOpt Use: "enable-manual-sync PROJECT ID", Short: "Enable manual sync for a sync window", Long: "Enable manual sync for a sync window. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: ` +#Enabling manual sync for a general case +argocd proj windows enable-manual-sync PROJECT ID + +#Enabling manual sync for a windows set on the default project with Id 2 +argocd proj windows enable-manual-sync default 2 + +#Enabling manual sync with a custom message +argocd proj windows enable-manual-sync my-app-project --message "Manual sync initiated by admin`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -125,14 +152,15 @@ func NewProjectWindowsAddWindowCommand(clientOpts *argocdclient.ClientOptions) * var command = &cobra.Command{ Use: "add PROJECT", Short: "Add a sync window to a project", - Example: `# Add a 1 hour allow sync window + Example: ` +#Add a 1 hour allow sync window argocd proj windows add PROJECT \ --kind allow \ --schedule "0 22 * * *" \ --duration 1h \ --applications "*" -# Add a deny sync window with the ability to manually sync. +#Add a deny sync window with the ability to manually sync. argocd proj windows add PROJECT \ --kind deny \ --schedule "30 10 * * *" \ @@ -180,6 +208,12 @@ func NewProjectWindowsDeleteCommand(clientOpts *argocdclient.ClientOptions) *cob var command = &cobra.Command{ Use: "delete PROJECT ID", Short: "Delete a sync window from a project. Requires ID which can be found by running \"argocd proj windows list PROJECT\"", + Example: ` +#Delete a sync window from a project (default) with ID 0 +argocd proj windows delete default 0 + +#Delete a sync window from a project (new-project) with ID 1 +argocd proj windows delete new-project 1`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -274,12 +308,15 @@ func NewProjectWindowsListCommand(clientOpts *argocdclient.ClientOptions) *cobra var command = &cobra.Command{ Use: "list PROJECT", Short: "List project sync windows", - Example: `# List project windows + Example: ` +#List project windows argocd proj windows list PROJECT - -# List project windows in yaml format + +#List project windows in yaml format argocd proj windows list PROJECT -o yaml -`, + +#List project windows info for a project name (test-project) +argocd proj windows list test-project`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index 1a469c3f818ca..bad60a0dd32bf 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -8,6 +8,20 @@ Manage clusters configuration argocd admin cluster [flags] ``` +### Examples + +``` + +#Generate declarative config for a cluster +argocd admin cluster generate-spec my-cluster -o yaml + +#Generate a kubeconfig for a cluster named "my-cluster" and display it in the console +argocd admin cluster kubeconfig my-cluster + +#Print information namespaces which Argo CD manages in each cluster +argocd admin cluster namespaces my-cluster +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md index 8105605e80cd0..38f61ce5cd8a2 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md +++ b/docs/user-guide/commands/argocd_admin_cluster_kubeconfig.md @@ -8,6 +8,23 @@ Generates kubeconfig for the specified cluster argocd admin cluster kubeconfig CLUSTER_URL OUTPUT_PATH [flags] ``` +### Examples + +``` + +#Generate a kubeconfig for a cluster named "my-cluster" on console +argocd admin cluster kubeconfig my-cluster + +#Listing available kubeconfigs for clusters managed by argocd +argocd admin cluster kubeconfig + +#Removing a specific kubeconfig file +argocd admin cluster kubeconfig my-cluster --delete + +#Generate a Kubeconfig for a Cluster with TLS Verification Disabled +argocd admin cluster kubeconfig https://cluster-api-url:6443 /path/to/output/kubeconfig.yaml --insecure-skip-tls-verify +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index 9e916288adf7e..960fd12caaef1 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -8,6 +8,20 @@ Prints information cluster statistics and inferred shard number argocd admin cluster stats [flags] ``` +### Examples + +``` + +#Display stats and shards for clusters +argocd admin cluster stats + +#Display Cluster Statistics for a Specific Shard +argocd admin cluster stats --shard=1 + +#In a multi-cluster environment to print stats for a specific cluster say(target-cluster) +argocd admin cluster stats target-cluster +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows.md b/docs/user-guide/commands/argocd_proj_windows.md index dc1b68bf0191b..0b22c2098dc82 100644 --- a/docs/user-guide/commands/argocd_proj_windows.md +++ b/docs/user-guide/commands/argocd_proj_windows.md @@ -8,6 +8,23 @@ Manage a project's sync windows argocd proj windows [flags] ``` +### Examples + +``` + +#Add a sync window to a project +argocd proj windows add my-project \ +--schedule "0 0 * * 1-5" \ +--duration 3600 \ +--prune + +#Delete a sync window from a project +argocd proj windows delete + +#List project sync windows +argocd proj windows list +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_add.md b/docs/user-guide/commands/argocd_proj_windows_add.md index 7f9eb50af8f5b..52fd3a8354ee3 100644 --- a/docs/user-guide/commands/argocd_proj_windows_add.md +++ b/docs/user-guide/commands/argocd_proj_windows_add.md @@ -11,14 +11,15 @@ argocd proj windows add PROJECT [flags] ### Examples ``` -# Add a 1 hour allow sync window + +#Add a 1 hour allow sync window argocd proj windows add PROJECT \ --kind allow \ --schedule "0 22 * * *" \ --duration 1h \ --applications "*" -# Add a deny sync window with the ability to manually sync. +#Add a deny sync window with the ability to manually sync. argocd proj windows add PROJECT \ --kind deny \ --schedule "30 10 * * *" \ diff --git a/docs/user-guide/commands/argocd_proj_windows_delete.md b/docs/user-guide/commands/argocd_proj_windows_delete.md index 316b25041fde2..6faf7dbeedc19 100644 --- a/docs/user-guide/commands/argocd_proj_windows_delete.md +++ b/docs/user-guide/commands/argocd_proj_windows_delete.md @@ -8,6 +8,17 @@ Delete a sync window from a project. Requires ID which can be found by running " argocd proj windows delete PROJECT ID [flags] ``` +### Examples + +``` + +#Delete a sync window from a project (default) with ID 0 +argocd proj windows delete default 0 + +#Delete a sync window from a project (new-project) with ID 1 +argocd proj windows delete new-project 1 +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md b/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md index 8951ad9371c90..e3b84ac38cc0e 100644 --- a/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md +++ b/docs/user-guide/commands/argocd_proj_windows_disable-manual-sync.md @@ -12,6 +12,17 @@ Disable manual sync for a sync window. Requires ID which can be found by running argocd proj windows disable-manual-sync PROJECT ID [flags] ``` +### Examples + +``` + +#Disable manual sync for a sync window for the Project +argocd proj windows disable-manual-sync PROJECT ID + +#Disbaling manual sync for a windows set on the default project with Id 0 +argocd proj windows disable-manual-sync default 0 +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md b/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md index a1ca162840f7a..7ecbb50e6ac1b 100644 --- a/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md +++ b/docs/user-guide/commands/argocd_proj_windows_enable-manual-sync.md @@ -12,6 +12,20 @@ Enable manual sync for a sync window. Requires ID which can be found by running argocd proj windows enable-manual-sync PROJECT ID [flags] ``` +### Examples + +``` + +#Enabling manual sync for a general case +argocd proj windows enable-manual-sync PROJECT ID + +#Enabling manual sync for a windows set on the default project with Id 2 +argocd proj windows enable-manual-sync default 2 + +#Enabling manual sync with a custom message +argocd proj windows enable-manual-sync my-app-project --message "Manual sync initiated by admin +``` + ### Options ``` diff --git a/docs/user-guide/commands/argocd_proj_windows_list.md b/docs/user-guide/commands/argocd_proj_windows_list.md index 94073db4775b8..3c361f90d2a68 100644 --- a/docs/user-guide/commands/argocd_proj_windows_list.md +++ b/docs/user-guide/commands/argocd_proj_windows_list.md @@ -11,12 +11,15 @@ argocd proj windows list PROJECT [flags] ### Examples ``` -# List project windows + +#List project windows argocd proj windows list PROJECT - -# List project windows in yaml format + +#List project windows in yaml format argocd proj windows list PROJECT -o yaml +#List project windows info for a project name (test-project) +argocd proj windows list test-project ``` ### Options From 9e92f555419f359656c5d9a67fcb3c06c40402e5 Mon Sep 17 00:00:00 2001 From: AS <11219262+ashutosh16@users.noreply.github.com> Date: Wed, 29 Nov 2023 19:53:46 -0800 Subject: [PATCH 130/269] fix(ui): add exec check to avoid API calls (#16168) * bug: add parent ref node info on resource list Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * bug: add parent ref node info on resource list Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * bug: add parent ref node info on resource list Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * bug: add parent ref node info on resource list Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * bug: add parent ref node info on resource list Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * bug: add parent ref node info on resource list Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> --------- Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> --- .../application-resource-list.tsx | 56 +++++++++++-------- .../resource-details/resource-details.tsx | 2 +- ui/src/app/applications/components/utils.tsx | 4 +- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/ui/src/app/applications/components/application-details/application-resource-list.tsx b/ui/src/app/applications/components/application-details/application-resource-list.tsx index e5cad1bc0a93b..c5519fc4b6ff9 100644 --- a/ui/src/app/applications/components/application-details/application-resource-list.tsx +++ b/ui/src/app/applications/components/application-details/application-resource-list.tsx @@ -31,35 +31,45 @@ export const ApplicationResourceList = ({ return null; } const parentNode = ((resources || []).length > 0 && (getResNode(tree.nodes, nodeKey(resources[0])) as ResourceNode)?.parentRefs?.[0]) || ({} as ResourceRef); + const searchParams = new URLSearchParams(window.location.search); + const view = searchParams.get('view'); + const ParentRefDetails = () => { + return Object.keys(parentNode).length > 0 ? ( +
    +
    Parent Node Info
    +
    +
    Name:
    +
    {parentNode?.name}
    +
    +
    +
    Kind:
    +
    {parentNode?.kind}
    +
    +
    + ) : ( +
    + ); + }; return (
    -
    - {Object.keys(parentNode).length > 0 && ( -
    -
    Parent Node Info
    -
    -
    Name:
    -
    {parentNode?.name}
    -
    -
    -
    Kind:
    -
    {parentNode?.kind}
    -
    -
    - )} -
    + {/* Display only when the view is set to or network */} + {(view === 'tree' || view === 'network') && ( +
    + +
    + )}
    -
    NAME
    +
    NAME
    GROUP/KIND
    SYNC ORDER
    -
    NAMESPACE
    +
    NAMESPACE
    {(parentNode.kind === 'Rollout' || parentNode.kind === 'Deployment') &&
    REVISION
    } -
    CREATED AT
    -
    STATUS
    +
    CREATED AT
    +
    STATUS
    {resources @@ -79,7 +89,7 @@ export const ApplicationResourceList = ({
    {ResourceLabel({kind: res.kind})}
    -
    +
    {res.name} {res.kind === 'Application' && ( @@ -98,7 +108,7 @@ export const ApplicationResourceList = ({
    {[res.group, res.kind].filter(item => !!item).join('/')}
    {res.syncWave || '-'}
    -
    {res.namespace}
    +
    {res.namespace}
    {res.kind === 'ReplicaSet' && ((getResNode(tree.nodes, nodeKey(res)) as ResourceNode).info || []) .filter(tag => !tag.name.includes('Node')) @@ -111,7 +121,7 @@ export const ApplicationResourceList = ({ ); })} -
    +
    {res.createdAt && ( @@ -121,7 +131,7 @@ export const ApplicationResourceList = ({ )}
    -
    +
    {res.health && ( {res.health.status}   diff --git a/ui/src/app/applications/components/resource-details/resource-details.tsx b/ui/src/app/applications/components/resource-details/resource-details.tsx index 6477509370905..52d2fef184703 100644 --- a/ui/src/app/applications/components/resource-details/resource-details.tsx +++ b/ui/src/app/applications/components/resource-details/resource-details.tsx @@ -280,7 +280,7 @@ export const ResourceDetails = (props: ResourceDetailsProps) => { const settings = await services.authService.settings(); const execEnabled = settings.execEnabled; const logsAllowed = await services.accounts.canI('logs', 'get', application.spec.project + '/' + application.metadata.name); - const execAllowed = await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name); + const execAllowed = execEnabled && (await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name)); const links = await services.applications.getResourceLinks(application.metadata.name, application.metadata.namespace, selectedNode).catch(() => null); return {controlledState, liveState, events, podState, execEnabled, execAllowed, logsAllowed, links}; }}> diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index 674ffc6728db4..f11ca2a916307 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -473,8 +473,8 @@ function getActionItems( const execAction = services.authService .settings() .then(async settings => { - const execAllowed = await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name); - if (resource.kind === 'Pod' && settings.execEnabled && execAllowed) { + const execAllowed = settings.execEnabled && (await services.accounts.canI('exec', 'create', application.spec.project + '/' + application.metadata.name)); + if (resource.kind === 'Pod' && execAllowed) { return [ { title: 'Exec', From 673d661821b6f698182c38890652118c8c1f2a1d Mon Sep 17 00:00:00 2001 From: Ashin Sabu <139749674+ashinsabu3@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:55:15 +0530 Subject: [PATCH 131/269] Fix extra space in application tree pod group (#16358) Signed-off-by: Ashin Sabu --- .../application-resource-tree.tsx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx index 6f28a40ea5046..3d5b1782a0e0c 100644 --- a/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx +++ b/ui/src/app/applications/components/application-resource-tree/application-resource-tree.tsx @@ -564,11 +564,13 @@ function renderPodGroup(props: ApplicationResourceTreeProps, id: string, node: R
    {[podGroupHealthy, podGroupDegraded, podGroupInProgress].map((pods, index) => { - return ( -
    - {renderPodGroupByStatus(props, node, pods, showPodGroupByStatus)} -
    - ); + if (pods.length > 0) { + return ( +
    + {renderPodGroupByStatus(props, node, pods, showPodGroupByStatus)} +
    + ); + } })}
    From 5c187a19550c34e452c8c5220450e77515da7c0e Mon Sep 17 00:00:00 2001 From: Nathan Romriell Date: Thu, 30 Nov 2023 07:03:34 -0800 Subject: [PATCH 132/269] fix(repo-server): excess git requests, resolveReferencedSources and runManifestGenAsync not using cache (Issue #14725) (#16410) * fix(repo-server): excess git requests part 1, resolveReferencedSources and runManifestGenAsync Signed-off-by: nromriell * fix: remove unnecessary settings instantiation Signed-off-by: nromriell --------- Signed-off-by: nromriell --- reposerver/cache/mocks/reposervercache.go | 71 ++++ reposerver/repository/repository.go | 11 +- reposerver/repository/repository_test.go | 449 +++++++++++++++++----- util/cache/mocks/cacheclient.go | 65 ++++ 4 files changed, 488 insertions(+), 108 deletions(-) create mode 100644 reposerver/cache/mocks/reposervercache.go create mode 100644 util/cache/mocks/cacheclient.go diff --git a/reposerver/cache/mocks/reposervercache.go b/reposerver/cache/mocks/reposervercache.go new file mode 100644 index 0000000000000..0e49b5816178e --- /dev/null +++ b/reposerver/cache/mocks/reposervercache.go @@ -0,0 +1,71 @@ +package mocks + +import ( + "testing" + "time" + + "github.com/alicebob/miniredis/v2" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" + cacheutilmocks "github.com/argoproj/argo-cd/v2/util/cache/mocks" + "github.com/redis/go-redis/v9" + "github.com/stretchr/testify/mock" +) + +type MockCacheType int + +const ( + MockCacheTypeRedis MockCacheType = iota + MockCacheTypeInMem +) + +type MockRepoCache struct { + mock.Mock + RedisClient *cacheutilmocks.MockCacheClient + StopRedisCallback func() +} + +type MockCacheOptions struct { + RepoCacheExpiration time.Duration + RevisionCacheExpiration time.Duration + ReadDelay time.Duration + WriteDelay time.Duration +} + +type CacheCallCounts struct { + ExternalSets int + ExternalGets int + ExternalDeletes int +} + +// Checks that the cache was called the expected number of times +func (mockCache *MockRepoCache) AssertCacheCalledTimes(t *testing.T, calls *CacheCallCounts) { + mockCache.RedisClient.AssertNumberOfCalls(t, "Get", calls.ExternalGets) + mockCache.RedisClient.AssertNumberOfCalls(t, "Set", calls.ExternalSets) + mockCache.RedisClient.AssertNumberOfCalls(t, "Delete", calls.ExternalDeletes) +} + +func (mockCache *MockRepoCache) ConfigureDefaultCallbacks() { + mockCache.RedisClient.On("Get", mock.Anything, mock.Anything).Return(nil) + mockCache.RedisClient.On("Set", mock.Anything).Return(nil) + mockCache.RedisClient.On("Delete", mock.Anything).Return(nil) +} + +func NewInMemoryRedis() (*redis.Client, func()) { + cacheutil.NewInMemoryCache(5 * time.Second) + mr, err := miniredis.Run() + if err != nil { + panic(err) + } + return redis.NewClient(&redis.Options{Addr: mr.Addr()}), mr.Close +} + +func NewMockRepoCache(cacheOpts *MockCacheOptions) *MockRepoCache { + redisClient, stopRedis := NewInMemoryRedis() + redisCacheClient := &cacheutilmocks.MockCacheClient{ + ReadDelay: cacheOpts.ReadDelay, + WriteDelay: cacheOpts.WriteDelay, + BaseCache: cacheutil.NewRedisCache(redisClient, cacheOpts.RepoCacheExpiration, cacheutil.RedisCompressionNone)} + newMockCache := &MockRepoCache{RedisClient: redisCacheClient, StopRedisCallback: stopRedis} + newMockCache.ConfigureDefaultCallbacks() + return newMockCache +} diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index f66bc71ac4621..f5a934ee12c5c 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -300,6 +300,7 @@ func (s *Service) runRepoOperation( var gitClient git.Client var helmClient helm.Client var err error + gitClientOpts := git.WithCache(s.cache, !settings.noRevisionCache && !settings.noCache) revision = textutils.FirstNonEmpty(revision, source.TargetRevision) unresolvedRevision := revision if source.IsHelm() { @@ -308,13 +309,13 @@ func (s *Service) runRepoOperation( return err } } else { - gitClient, revision, err = s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, !settings.noRevisionCache && !settings.noCache)) + gitClient, revision, err = s.newClientResolveRevision(repo, revision, gitClientOpts) if err != nil { return err } } - repoRefs, err := resolveReferencedSources(hasMultipleSources, source.Helm, refSources, s.newClientResolveRevision) + repoRefs, err := resolveReferencedSources(hasMultipleSources, source.Helm, refSources, s.newClientResolveRevision, gitClientOpts) if err != nil { return err } @@ -463,7 +464,7 @@ type gitClientGetter func(repo *v1alpha1.Repository, revision string, opts ...gi // // Much of this logic is duplicated in runManifestGenAsync. If making changes here, check whether runManifestGenAsync // should be updated. -func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.ApplicationSourceHelm, refSources map[string]*v1alpha1.RefTarget, newClientResolveRevision gitClientGetter) (map[string]string, error) { +func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.ApplicationSourceHelm, refSources map[string]*v1alpha1.RefTarget, newClientResolveRevision gitClientGetter, gitClientOpts git.ClientOpts) (map[string]string, error) { repoRefs := make(map[string]string) if !hasMultipleSources || source == nil { return repoRefs, nil @@ -490,7 +491,7 @@ func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.Applicat normalizedRepoURL := git.NormalizeGitURL(refSourceMapping.Repo.Repo) _, ok = repoRefs[normalizedRepoURL] if !ok { - _, referencedCommitSHA, err := newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision) + _, referencedCommitSHA, err := newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision, gitClientOpts) if err != nil { log.Errorf("Failed to get git client for repo %s: %v", refSourceMapping.Repo.Repo, err) return nil, fmt.Errorf("failed to get git client for repo %s", refSourceMapping.Repo.Repo) @@ -728,7 +729,7 @@ func (s *Service) runManifestGenAsync(ctx context.Context, repoRoot, commitSHA, return } } else { - gitClient, referencedCommitSHA, err := s.newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision) + gitClient, referencedCommitSHA, err := s.newClientResolveRevision(&refSourceMapping.Repo, refSourceMapping.TargetRevision, git.WithCache(s.cache, !q.NoRevisionCache && !q.NoCache)) if err != nil { log.Errorf("Failed to get git client for repo %s: %v", refSourceMapping.Repo.Repo, err) ch.errCh <- fmt.Errorf("failed to get git client for repo %s", refSourceMapping.Repo.Repo) diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index a24eb5008c47b..74d09dd6f86b8 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -1,6 +1,7 @@ package repository import ( + "bytes" "context" "encoding/json" "errors" @@ -17,6 +18,7 @@ import ( "testing" "time" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" log "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/resource" @@ -28,13 +30,14 @@ import ( "k8s.io/apimachinery/pkg/runtime" "sigs.k8s.io/yaml" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" "github.com/argoproj/argo-cd/v2/reposerver/cache" + repositorymocks "github.com/argoproj/argo-cd/v2/reposerver/cache/mocks" "github.com/argoproj/argo-cd/v2/reposerver/metrics" fileutil "github.com/argoproj/argo-cd/v2/test/fixture/path" "github.com/argoproj/argo-cd/v2/util/argo" - cacheutil "github.com/argoproj/argo-cd/v2/util/cache" dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" "github.com/argoproj/argo-cd/v2/util/git" gitmocks "github.com/argoproj/argo-cd/v2/util/git/mocks" @@ -51,12 +54,49 @@ gpg: Good signature from "GitHub (web-flow commit signing) " type clientFunc func(*gitmocks.Client, *helmmocks.Client, *iomocks.TempPaths) -func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) { +type repoCacheMocks struct { + mock.Mock + cacheutilCache *cacheutil.Cache + cache *cache.Cache + mockCache *repositorymocks.MockRepoCache +} + +type newGitRepoHelmChartOptions struct { + chartName string + chartVersion string + // valuesFiles is a map of the values file name to the key/value pairs to be written to the file + valuesFiles map[string]map[string]string +} + +type newGitRepoOptions struct { + path string + createPath bool + remote string + addEmptyCommit bool + helmChartOptions newGitRepoHelmChartOptions +} + +func newCacheMocks() *repoCacheMocks { + mockRepoCache := repositorymocks.NewMockRepoCache(&repositorymocks.MockCacheOptions{ + RepoCacheExpiration: 1 * time.Minute, + RevisionCacheExpiration: 1 * time.Minute, + ReadDelay: 0, + WriteDelay: 0, + }) + cacheutilCache := cacheutil.NewCache(mockRepoCache.RedisClient) + return &repoCacheMocks{ + cacheutilCache: cacheutilCache, + cache: cache.NewCache(cacheutilCache, 1*time.Minute, 1*time.Minute), + mockCache: mockRepoCache, + } +} + +func newServiceWithMocks(t *testing.T, root string, signed bool) (*Service, *gitmocks.Client, *repoCacheMocks) { root, err := filepath.Abs(root) if err != nil { panic(err) } - return newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + return newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) @@ -73,7 +113,7 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) chart := "my-chart" oobChart := "out-of-bounds-chart" version := "1.1.0" - helmClient.On("GetIndex", true).Return(&helm.Index{Entries: map[string]helm.Entries{ + helmClient.On("GetIndex", mock.AnythingOfType("bool")).Return(&helm.Index{Entries: map[string]helm.Entries{ chart: {{Version: "1.0.0"}, {Version: version}}, oobChart: {{Version: "1.0.0"}, {Version: version}}, }}, nil) @@ -89,18 +129,16 @@ func newServiceWithMocks(root string, signed bool) (*Service, *gitmocks.Client) }, root) } -func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) { +func newServiceWithOpt(t *testing.T, cf clientFunc, root string) (*Service, *gitmocks.Client, *repoCacheMocks) { helmClient := &helmmocks.Client{} gitClient := &gitmocks.Client{} paths := &iomocks.TempPaths{} cf(gitClient, helmClient, paths) - service := NewService(metrics.NewMetricsServer(), cache.NewCache( - cacheutil.NewCache(cacheutil.NewInMemoryCache(1*time.Minute)), - 1*time.Minute, - 1*time.Minute, - ), RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, root) + cacheMocks := newCacheMocks() + t.Cleanup(cacheMocks.mockCache.StopRedisCallback) + service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, root) - service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, prosy string, opts ...git.ClientOpts) (client git.Client, e error) { + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { return gitClient, nil } service.newHelmClient = func(repoURL string, creds helm.Creds, enableOci bool, proxy string, opts ...helm.ClientOpts) helm.Client { @@ -110,20 +148,20 @@ func newServiceWithOpt(cf clientFunc, root string) (*Service, *gitmocks.Client) return io.NopCloser } service.gitRepoPaths = paths - return service, gitClient + return service, gitClient, cacheMocks } -func newService(root string) *Service { - service, _ := newServiceWithMocks(root, false) +func newService(t *testing.T, root string) *Service { + service, _, _ := newServiceWithMocks(t, root, false) return service } -func newServiceWithSignature(root string) *Service { - service, _ := newServiceWithMocks(root, true) +func newServiceWithSignature(t *testing.T, root string) *Service { + service, _, _ := newServiceWithMocks(t, root, true) return service } -func newServiceWithCommitSHA(root, revision string) *Service { +func newServiceWithCommitSHA(t *testing.T, root, revision string) *Service { var revisionErr error commitSHARegex := regexp.MustCompile("^[0-9A-Fa-f]{40}$") @@ -131,7 +169,7 @@ func newServiceWithCommitSHA(root, revision string) *Service { revisionErr = errors.New("not a commit SHA") } - service, gitClient := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + service, gitClient, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) @@ -150,7 +188,7 @@ func newServiceWithCommitSHA(root, revision string) *Service { } func TestGenerateYamlManifestInDir(t *testing.T) { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -247,7 +285,7 @@ func TestGenerateManifests_MissingSymlinkDestination(t *testing.T) { } func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -275,7 +313,7 @@ func TestGenerateManifests_K8SAPIResetCache(t *testing.T) { } func TestGenerateManifests_EmptyCache(t *testing.T) { - service := newService("../../manifests/base") + service, gitMocks, mockCache := newServiceWithMocks(t, "../../manifests/base", false) src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -291,11 +329,85 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { res, err := service.GenerateManifest(context.Background(), &q) assert.NoError(t, err) assert.True(t, len(res.Manifests) > 0) + mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 2, + ExternalGets: 2, + ExternalDeletes: 1}) + gitMocks.AssertCalled(t, "LsRemote", mock.Anything) + gitMocks.AssertCalled(t, "Fetch", mock.Anything) +} + +// Test that calling manifest generation on source helm reference helm files that when the revision is cached it does not call ls-remote +func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { + dir := t.TempDir() + repopath := fmt.Sprintf("%s/tmprepo", dir) + cacheMocks := newCacheMocks() + t.Cleanup(func() { + cacheMocks.mockCache.StopRedisCallback() + err := filepath.WalkDir(dir, + func(path string, di fs.DirEntry, err error) error { + if err == nil { + return os.Chmod(path, 0777) + } + return err + }) + if err != nil { + t.Fatal(err) + } + }) + service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) + var gitClient git.Client + var err error + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + opts = append(opts, git.WithEventHandlers(git.EventHandlers{ + // Primary check, we want to make sure ls-remote is not called when the item is in cache + OnLsRemote: func(repo string) func() { + return func() { + assert.Fail(t, "LsRemote should not be called when the item is in cache") + } + }, + })) + gitClient, err = git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, opts...) + return gitClient, err + } + repoRemote := fmt.Sprintf("file://%s", repopath) + revision := initGitRepo(t, newGitRepoOptions{ + path: repopath, + createPath: true, + remote: repoRemote, + helmChartOptions: newGitRepoHelmChartOptions{ + chartName: "my-chart", + chartVersion: "v1.0.0", + valuesFiles: map[string]map[string]string{"test.yaml": {"testval": "test"}}}, + }) + src := argoappv1.ApplicationSource{RepoURL: repoRemote, Path: ".", TargetRevision: "HEAD", Helm: &argoappv1.ApplicationSourceHelm{ + ValueFiles: []string{"$ref/test.yaml"}, + }} + repo := &argoappv1.Repository{ + Repo: repoRemote, + } + q := apiclient.ManifestRequest{ + Repo: repo, + Revision: "HEAD", + HasMultipleSources: true, + ApplicationSource: &src, + ProjectName: "default", + ProjectSourceRepos: []string{"*"}, + RefSources: map[string]*argoappv1.RefTarget{"$ref": {TargetRevision: "HEAD", Repo: *repo}}, + } + err = cacheMocks.cacheutilCache.SetItem(fmt.Sprintf("git-refs|%s", repoRemote), [][2]string{{"HEAD", revision}}, 30*time.Second, false) + assert.NoError(t, err) + _, err = service.GenerateManifest(context.Background(), &q) + assert.NoError(t, err) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 2, + ExternalGets: 5}) } // ensure we can use a semver constraint range (>= 1.0.0) and get back the correct chart (1.0.0) func TestHelmManifestFromChartRepo(t *testing.T) { - service := newService(".") + root := t.TempDir() + service, gitMocks, mockCache := newServiceWithMocks(t, root, false) source := &argoappv1.ApplicationSource{Chart: "my-chart", TargetRevision: ">= 1.0.0"} request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true, ProjectName: "something", ProjectSourceRepos: []string{"*"}} @@ -309,10 +421,14 @@ func TestHelmManifestFromChartRepo(t *testing.T) { Revision: "1.1.0", SourceType: "Helm", }, response) + mockCache.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 0}) + gitMocks.AssertNotCalled(t, "LsRemote", mock.Anything) } func TestHelmChartReferencingExternalValues(t *testing.T) { - service := newService(".") + service := newService(t, ".") spec := argoappv1.ApplicationSpec{ Sources: []argoappv1.ApplicationSource{ {RepoURL: "https://helm.example.com", Chart: "my-chart", TargetRevision: ">= 1.0.0", Helm: &argoappv1.ApplicationSourceHelm{ @@ -342,7 +458,7 @@ func TestHelmChartReferencingExternalValues(t *testing.T) { } func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { - service := newService(".") + service := newService(t, ".") err := os.Mkdir("testdata/oob-symlink", 0755) require.NoError(t, err) t.Cleanup(func() { @@ -376,7 +492,7 @@ func TestHelmChartReferencingExternalValues_OutOfBounds_Symlink(t *testing.T) { } func TestGenerateManifestsUseExactRevision(t *testing.T) { - service, gitClient := newServiceWithMocks(".", false) + service, gitClient, _ := newServiceWithMocks(t, ".", false) src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -390,7 +506,7 @@ func TestGenerateManifestsUseExactRevision(t *testing.T) { } func TestRecurseManifestsInDir(t *testing.T) { - service := newService(".") + service := newService(t, ".") src := argoappv1.ApplicationSource{Path: "./testdata/recurse", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -403,7 +519,7 @@ func TestRecurseManifestsInDir(t *testing.T) { } func TestInvalidManifestsInDir(t *testing.T) { - service := newService(".") + service := newService(t, ".") src := argoappv1.ApplicationSource{Path: "./testdata/invalid-manifests", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -414,7 +530,7 @@ func TestInvalidManifestsInDir(t *testing.T) { } func TestInvalidMetadata(t *testing.T) { - service := newService(".") + service := newService(t, ".") src := argoappv1.ApplicationSource{Path: "./testdata/invalid-metadata", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, AppLabelKey: "test", AppName: "invalid-metadata", TrackingMethod: "annotation+label"} @@ -424,7 +540,7 @@ func TestInvalidMetadata(t *testing.T) { } func TestNilMetadataAccessors(t *testing.T) { - service := newService(".") + service := newService(t, ".") expected := "{\"apiVersion\":\"v1\",\"kind\":\"ConfigMap\",\"metadata\":{\"annotations\":{\"argocd.argoproj.io/tracking-id\":\"nil-metadata-accessors:/ConfigMap:/my-map\"},\"labels\":{\"test\":\"nil-metadata-accessors\"},\"name\":\"my-map\"},\"stringData\":{\"foo\":\"bar\"}}" src := argoappv1.ApplicationSource{Path: "./testdata/nil-metadata-accessors", Directory: &argoappv1.ApplicationSourceDirectory{Recurse: true}} @@ -436,7 +552,7 @@ func TestNilMetadataAccessors(t *testing.T) { } func TestGenerateJsonnetManifestInDir(t *testing.T) { - service := newService(".") + service := newService(t, ".") q := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -459,7 +575,7 @@ func TestGenerateJsonnetManifestInDir(t *testing.T) { } func TestGenerateJsonnetManifestInRootDir(t *testing.T) { - service := newService("testdata/jsonnet-1") + service := newService(t, "testdata/jsonnet-1") q := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -482,7 +598,7 @@ func TestGenerateJsonnetManifestInRootDir(t *testing.T) { } func TestGenerateJsonnetLibOutside(t *testing.T) { - service := newService(".") + service := newService(t, ".") q := apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -553,7 +669,7 @@ func TestManifestGenErrorCacheByNumRequests(t *testing.T) { for _, tt := range tests { testName := fmt.Sprintf("gen-attempts-%d-pause-%d-total-%d", tt.PauseGenerationAfterFailedGenerationAttempts, tt.PauseGenerationOnFailureForRequests, tt.TotalCacheInvocations) t.Run(testName, func(t *testing.T) { - service := newService(".") + service := newService(t, ".") service.initConstants = RepoServerInitConstants{ ParallelismLimit: 1, @@ -631,7 +747,7 @@ func TestManifestGenErrorCacheFileContentsChange(t *testing.T) { tmpDir := t.TempDir() - service := newService(tmpDir) + service := newService(t, tmpDir) service.initConstants = RepoServerInitConstants{ ParallelismLimit: 1, @@ -701,7 +817,7 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { for _, tt := range tests { testName := fmt.Sprintf("pause-time-%d", tt.PauseGenerationOnFailureForMinutes) t.Run(testName, func(t *testing.T) { - service := newService(".") + service := newService(t, ".") // Here we simulate the passage of time by overriding the now() function of Service currentTime := time.Now() @@ -771,7 +887,7 @@ func TestManifestGenErrorCacheByMinutesElapsed(t *testing.T) { func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { - service := newService(".") + service := newService(t, ".") service.initConstants = RepoServerInitConstants{ ParallelismLimit: 1, @@ -828,7 +944,7 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) { } func TestGenerateHelmWithValues(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -865,7 +981,7 @@ func TestGenerateHelmWithValues(t *testing.T) { } func TestHelmWithMissingValueFiles(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") missingValuesFile := "values-prod-overrides.yaml" req := &apiclient.ManifestRequest{ @@ -893,7 +1009,7 @@ func TestHelmWithMissingValueFiles(t *testing.T) { } func TestGenerateHelmWithEnvVars(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -930,7 +1046,7 @@ func TestGenerateHelmWithEnvVars(t *testing.T) { // The requested value file (`../minio/values.yaml`) is outside the app path (`./util/helm/testdata/redis`), however // since the requested value is still under the repo directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { - service := newService("../../util/helm/testdata") + service := newService(t, "../../util/helm/testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -947,7 +1063,7 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { assert.NoError(t, err) // Test the case where the path is "." - service = newService("./testdata") + service = newService(t, "./testdata") _, err = service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -961,7 +1077,7 @@ func TestGenerateHelmWithValuesDirectoryTraversal(t *testing.T) { } func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{Chart: "out-of-bounds-chart", TargetRevision: ">= 1.0.0"} request := &apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: source, NoCache: true} _, err := service.GenerateManifest(context.Background(), request) @@ -971,7 +1087,7 @@ func TestChartRepoWithOutOfBoundsSymlink(t *testing.T) { // This is a Helm first-class app with a values file inside the repo directory // (`~/go/src/github.com/argoproj/argo-cd/reposerver/repository`), so it is allowed func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", @@ -1000,7 +1116,7 @@ func TestHelmManifestFromChartRepoWithValueFile(t *testing.T) { // This is a Helm first-class app with a values file outside the repo directory // (`~/go/src/github.com/argoproj/argo-cd/reposerver/repository`), so it is not allowed func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", @@ -1015,7 +1131,7 @@ func TestHelmManifestFromChartRepoWithValueFileOutsideRepo(t *testing.T) { func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { t.Run("Valid symlink", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") source := &argoappv1.ApplicationSource{ Chart: "my-chart", TargetRevision: ">= 1.0.0", @@ -1031,7 +1147,7 @@ func TestHelmManifestFromChartRepoWithValueFileLinks(t *testing.T) { } func TestGenerateHelmWithURL(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1054,7 +1170,7 @@ func TestGenerateHelmWithURL(t *testing.T) { // (`~/go/src/github.com/argoproj/argo-cd/util/helm/testdata/redis`), so it is blocked func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { t.Run("Values file with relative path pointing outside repo root", func(t *testing.T) { - service := newService("../../util/helm/testdata/redis") + service := newService(t, "../../util/helm/testdata/redis") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1073,7 +1189,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Values file with relative path pointing inside repo root", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1091,7 +1207,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Values file with absolute path stays within repo root", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1109,7 +1225,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Values file with absolute path using back-references outside repo root", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1128,7 +1244,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Remote values file from forbidden protocol", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1147,7 +1263,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { }) t.Run("Remote values file from custom allowed protocol", func(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") _, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, AppName: "test", @@ -1168,7 +1284,7 @@ func TestGenerateHelmWithValuesDirectoryTraversalOutsideRepo(t *testing.T) { // File parameter should not allow traversal outside of the repository root func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { - service := newService("../..") + service := newService(t, "../..") file, err := os.CreateTemp("", "external-secret.txt") assert.NoError(t, err) @@ -1209,7 +1325,7 @@ func TestGenerateHelmWithAbsoluteFileParameter(t *testing.T) { // directory (`~/go/src/github.com/argoproj/argo-cd`), it is allowed. It is used as a means of // providing direct content to a helm chart via a specific key. func TestGenerateHelmWithFileParameter(t *testing.T) { - service := newService("../../util/helm/testdata") + service := newService(t, "../../util/helm/testdata") res, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1234,7 +1350,7 @@ func TestGenerateHelmWithFileParameter(t *testing.T) { } func TestGenerateNullList(t *testing.T) { - service := newService(".") + service := newService(t, ".") t.Run("null list", func(t *testing.T) { res1, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ @@ -1302,7 +1418,7 @@ func TestGenerateFromUTF16(t *testing.T) { } func TestListApps(t *testing.T) { - service := newService("./testdata") + service := newService(t, "./testdata") res, err := service.ListApps(context.Background(), &apiclient.ListAppsRequest{Repo: &argoappv1.Repository{}}) assert.NoError(t, err) @@ -1329,7 +1445,7 @@ func TestListApps(t *testing.T) { } func TestGetAppDetailsHelm(t *testing.T) { - service := newService("../../util/helm/testdata/dependency") + service := newService(t, "../../util/helm/testdata/dependency") res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1344,8 +1460,26 @@ func TestGetAppDetailsHelm(t *testing.T) { assert.Equal(t, "Helm", res.Type) assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) } + +func TestGetAppDetailsHelmUsesCache(t *testing.T) { + service := newService(t, "../../util/helm/testdata/dependency") + + res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ + Repo: &argoappv1.Repository{}, + Source: &argoappv1.ApplicationSource{ + Path: ".", + }, + }) + + assert.NoError(t, err) + assert.NotNil(t, res.Helm) + + assert.Equal(t, "Helm", res.Type) + assert.EqualValues(t, []string{"values-production.yaml", "values.yaml"}, res.Helm.ValueFiles) +} + func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { - service := newService("../../util/helm/testdata/api-versions") + service := newService(t, "../../util/helm/testdata/api-versions") res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1363,7 +1497,7 @@ func TestGetAppDetailsHelm_WithNoValuesFile(t *testing.T) { } func TestGetAppDetailsKustomize(t *testing.T) { - service := newService("../../util/kustomize/testdata/kustomization_yaml") + service := newService(t, "../../util/kustomize/testdata/kustomization_yaml") res, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1380,7 +1514,7 @@ func TestGetAppDetailsKustomize(t *testing.T) { } func TestGetHelmCharts(t *testing.T) { - service := newService("../..") + service := newService(t, "../..") res, err := service.GetHelmCharts(context.Background(), &apiclient.HelmChartsRequest{Repo: &argoappv1.Repository{}}) // fix flakiness @@ -1401,7 +1535,7 @@ func TestGetHelmCharts(t *testing.T) { } func TestGetRevisionMetadata(t *testing.T) { - service, gitClient := newServiceWithMocks("../..", false) + service, gitClient, _ := newServiceWithMocks(t, "../..", false) now := time.Now() gitClient.On("RevisionMetadata", mock.Anything).Return(&git.RevisionMetadata{ @@ -1469,7 +1603,7 @@ func TestGetRevisionMetadata(t *testing.T) { func TestGetSignatureVerificationResult(t *testing.T) { // Commit with signature and verification requested { - service := newServiceWithSignature("../../manifests/base") + service := newServiceWithSignature(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{ @@ -1486,7 +1620,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } // Commit with signature and verification not requested { - service := newServiceWithSignature("../../manifests/base") + service := newServiceWithSignature(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, ProjectName: "something", @@ -1498,7 +1632,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } // Commit without signature and verification requested { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", @@ -1510,7 +1644,7 @@ func TestGetSignatureVerificationResult(t *testing.T) { } // Commit without signature and verification not requested { - service := newService("../../manifests/base") + service := newService(t, "../../manifests/base") src := argoappv1.ApplicationSource{Path: "."} q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, VerifySignature: true, ProjectName: "something", @@ -1543,7 +1677,7 @@ func Test_newEnv(t *testing.T) { } func TestService_newHelmClientResolveRevision(t *testing.T) { - service := newService(".") + service := newService(t, ".") t.Run("EmptyRevision", func(t *testing.T) { _, _, err := service.newHelmClientResolveRevision(&argoappv1.Repository{}, "", "", true) @@ -1557,7 +1691,7 @@ func TestService_newHelmClientResolveRevision(t *testing.T) { func TestGetAppDetailsWithAppParameterFile(t *testing.T) { t.Run("No app name set and app specific file exists", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1570,7 +1704,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("No app specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1584,7 +1718,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("Only app specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1598,7 +1732,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("App specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1612,7 +1746,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("App specific overrides containing non-mergeable field", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { details, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1626,7 +1760,7 @@ func TestGetAppDetailsWithAppParameterFile(t *testing.T) { }) }) t.Run("Broken app-specific overrides", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "multi", func(t *testing.T, path string) { _, err := service.GetAppDetails(context.Background(), &apiclient.RepoServerAppDetailsQuery{ Repo: &argoappv1.Repository{}, @@ -1668,7 +1802,7 @@ func runWithTempTestdata(t *testing.T, path string, runner func(t *testing.T, pa func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Single global override", func(t *testing.T) { runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { - service := newService(".") + service := newService(t, ".") manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -1699,7 +1833,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { t.Run("Single global override Helm", func(t *testing.T) { runWithTempTestdata(t, "single-global-helm", func(t *testing.T, path string) { - service := newService(".") + service := newService(t, ".") manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, ApplicationSource: &argoappv1.ApplicationSource{ @@ -1729,7 +1863,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { }) t.Run("Application specific override", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1760,8 +1894,29 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { }) }) + t.Run("Multi-source with source as ref only does not generate manifests", func(t *testing.T) { + service := newService(t, ".") + runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { + manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ + Repo: &argoappv1.Repository{}, + ApplicationSource: &argoappv1.ApplicationSource{ + Path: "", + Chart: "", + Ref: "test", + }, + AppName: "testapp-multi-ref-only", + ProjectName: "something", + ProjectSourceRepos: []string{"*"}, + HasMultipleSources: true, + }) + assert.NoError(t, err) + assert.Empty(t, manifests.Manifests) + assert.NotEmpty(t, manifests.Revision) + }) + }) + t.Run("Application specific override for other app", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-app-only", func(t *testing.T, path string) { manifests, err := service.GenerateManifest(context.Background(), &apiclient.ManifestRequest{ Repo: &argoappv1.Repository{}, @@ -1793,7 +1948,7 @@ func TestGenerateManifestsWithAppParameterFile(t *testing.T) { }) t.Run("Override info does not appear in cache key", func(t *testing.T) { - service := newService(".") + service := newService(t, ".") runWithTempTestdata(t, "single-global", func(t *testing.T, path string) { source := &argoappv1.ApplicationSource{ Path: path, @@ -1843,7 +1998,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ProjectSourceRepos: []string{"*"}, }, wantError: false, - service: newServiceWithCommitSHA(".", regularGitTagHash), + service: newServiceWithCommitSHA(t, ".", regularGitTagHash), }, { @@ -1859,7 +2014,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ProjectSourceRepos: []string{"*"}, }, wantError: false, - service: newServiceWithCommitSHA(".", annotatedGitTaghash), + service: newServiceWithCommitSHA(t, ".", annotatedGitTaghash), }, { @@ -1875,7 +2030,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { ProjectSourceRepos: []string{"*"}, }, wantError: true, - service: newServiceWithCommitSHA(".", invalidGitTaghash), + service: newServiceWithCommitSHA(t, ".", invalidGitTaghash), }, } for _, tt := range tests { @@ -1900,7 +2055,7 @@ func TestGenerateManifestWithAnnotatedAndRegularGitTagHashes(t *testing.T) { func TestGenerateManifestWithAnnotatedTagsAndMultiSourceApp(t *testing.T) { annotatedGitTaghash := "95249be61b028d566c29d47b19e65c5603388a41" - service := newServiceWithCommitSHA(".", annotatedGitTaghash) + service := newServiceWithCommitSHA(t, ".", annotatedGitTaghash) refSources := map[string]*argoappv1.RefTarget{} @@ -2485,7 +2640,7 @@ func Test_findManifests(t *testing.T) { } func TestTestRepoOCI(t *testing.T) { - service := newService(".") + service := newService(t, ".") _, err := service.TestRepository(context.Background(), &apiclient.TestRepositoryRequest{ Repo: &argoappv1.Repository{ Repo: "https://demo.goharbor.io", @@ -2510,7 +2665,7 @@ func Test_getHelmDependencyRepos(t *testing.T) { func TestResolveRevision(t *testing.T) { - service := newService(".") + service := newService(t, ".") repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ @@ -2532,7 +2687,7 @@ func TestResolveRevision(t *testing.T) { func TestResolveRevisionNegativeScenarios(t *testing.T) { - service := newService(".") + service := newService(t, ".") repo := &argoappv1.Repository{Repo: "https://github.com/argoproj/argo-cd"} app := &argoappv1.Application{Spec: argoappv1.ApplicationSpec{Source: &argoappv1.ApplicationSource{}}} resolveRevisionResponse, err := service.ResolveRevision(context.Background(), &apiclient.ResolveRevisionRequest{ @@ -2579,19 +2734,57 @@ func TestDirectoryPermissionInitializer(t *testing.T) { require.Error(t, err) } -func initGitRepo(repoPath string, remote string) error { - if err := os.Mkdir(repoPath, 0755); err != nil { - return err +func addHelmToGitRepo(t *testing.T, options newGitRepoOptions) { + err := os.WriteFile(filepath.Join(options.path, "Chart.yaml"), []byte("name: test\nversion: v1.0.0"), 0777) + assert.NoError(t, err) + for valuesFileName, values := range options.helmChartOptions.valuesFiles { + valuesFileContents, err := yaml.Marshal(values) + assert.NoError(t, err) + err = os.WriteFile(filepath.Join(options.path, valuesFileName), valuesFileContents, 0777) + assert.NoError(t, err) + } + assert.NoError(t, err) + cmd := exec.Command("git", "add", "-A") + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + cmd = exec.Command("git", "commit", "-m", "Initial commit") + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) +} + +func initGitRepo(t *testing.T, options newGitRepoOptions) (revision string) { + if options.createPath { + assert.NoError(t, os.Mkdir(options.path, 0755)) + } + + cmd := exec.Command("git", "init", options.path) + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + + if options.remote != "" { + cmd = exec.Command("git", "remote", "add", "origin", options.path) + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) } - cmd := exec.Command("git", "init", repoPath) - cmd.Dir = repoPath - if err := cmd.Run(); err != nil { - return err + commitAdded := options.addEmptyCommit || options.helmChartOptions.chartName != "" + if options.addEmptyCommit { + cmd = exec.Command("git", "commit", "-m", "Initial commit", "--allow-empty") + cmd.Dir = options.path + assert.NoError(t, cmd.Run()) + } else if options.helmChartOptions.chartName != "" { + addHelmToGitRepo(t, options) } - cmd = exec.Command("git", "remote", "add", "origin", remote) - cmd.Dir = repoPath - return cmd.Run() + + if commitAdded { + var revB bytes.Buffer + cmd = exec.Command("git", "rev-parse", "HEAD", options.path) + cmd.Dir = options.path + cmd.Stdout = &revB + assert.NoError(t, cmd.Run()) + revision = strings.Split(revB.String(), "\n")[0] + } + return revision } func TestInit(t *testing.T) { @@ -2604,16 +2797,16 @@ func TestInit(t *testing.T) { }) repoPath := path.Join(dir, "repo1") - require.NoError(t, initGitRepo(repoPath, "https://github.com/argo-cd/test-repo1")) + initGitRepo(t, newGitRepoOptions{path: repoPath, remote: "https://github.com/argo-cd/test-repo1", createPath: true, addEmptyCommit: false}) - service := newService(".") + service := newService(t, ".") service.rootDir = dir require.NoError(t, service.Init()) _, err := os.ReadDir(dir) require.Error(t, err) - require.NoError(t, initGitRepo(path.Join(dir, "repo2"), "https://github.com/argo-cd/test-repo2")) + initGitRepo(t, newGitRepoOptions{path: path.Join(dir, "repo2"), remote: "https://github.com/argo-cd/test-repo2", createPath: true, addEmptyCommit: false}) } // TestCheckoutRevisionCanGetNonstandardRefs shows that we can fetch a revision that points to a non-standard ref. In @@ -2926,7 +3119,7 @@ func TestErrorGetGitDirectories(t *testing.T) { want *apiclient.GitDirectoriesResponse wantErr assert.ErrorAssertionFunc }{ - {name: "InvalidRepo", fields: fields{service: newService(".")}, args: args{ + {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ ctx: context.TODO(), request: &apiclient.GitDirectoriesRequest{ Repo: nil, @@ -2935,7 +3128,7 @@ func TestErrorGetGitDirectories(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -2966,7 +3159,7 @@ func TestErrorGetGitDirectories(t *testing.T) { func TestGetGitDirectories(t *testing.T) { // test not using the cache root := "./testdata/git-files-dirs" - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) @@ -2989,6 +3182,10 @@ func TestGetGitDirectories(t *testing.T) { directories, err = s.GetGitDirectories(context.TODO(), dirRequest) assert.Nil(t, err) assert.ElementsMatch(t, []string{"app", "app/bar", "app/foo/bar", "somedir", "app/foo"}, directories.GetPaths()) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 2, + }) } func TestErrorGetGitFiles(t *testing.T) { @@ -3006,7 +3203,7 @@ func TestErrorGetGitFiles(t *testing.T) { want *apiclient.GitFilesResponse wantErr assert.ErrorAssertionFunc }{ - {name: "InvalidRepo", fields: fields{service: newService(".")}, args: args{ + {name: "InvalidRepo", fields: fields{service: newService(t, ".")}, args: args{ ctx: context.TODO(), request: &apiclient.GitFilesRequest{ Repo: nil, @@ -3015,7 +3212,7 @@ func TestErrorGetGitFiles(t *testing.T) { }, }, want: nil, wantErr: assert.Error}, {name: "InvalidResolveRevision", fields: fields{service: func() *Service { - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, _ := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Checkout", mock.Anything, mock.Anything).Return(nil) gitClient.On("LsRemote", mock.Anything).Return("", fmt.Errorf("ah error")) paths.On("GetPath", mock.Anything).Return(".", nil) @@ -3048,7 +3245,7 @@ func TestGetGitFiles(t *testing.T) { files := []string{"./testdata/git-files-dirs/somedir/config.yaml", "./testdata/git-files-dirs/config.yaml", "./testdata/git-files-dirs/config.yaml", "./testdata/git-files-dirs/app/foo/bar/config.yaml"} root := "" - s, _ := newServiceWithOpt(func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { + s, _, cacheMocks := newServiceWithOpt(t, func(gitClient *gitmocks.Client, helmClient *helmmocks.Client, paths *iomocks.TempPaths) { gitClient.On("Init").Return(nil) gitClient.On("Fetch", mock.Anything).Return(nil) gitClient.On("Checkout", mock.Anything, mock.Anything).Once().Return(nil) @@ -3081,6 +3278,10 @@ func TestGetGitFiles(t *testing.T) { fileResponse, err = s.GetGitFiles(context.TODO(), filesRequest) assert.Nil(t, err) assert.Equal(t, expected, fileResponse.GetMap()) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 2, + }) } func Test_getRepoSanitizerRegex(t *testing.T) { @@ -3090,3 +3291,45 @@ func Test_getRepoSanitizerRegex(t *testing.T) { msg = r.ReplaceAllString("error message containing /tmp/_argocd-repo/SENSITIVE/with/trailing/path and other stuff", "") assert.Equal(t, "error message containing /with/trailing/path and other stuff", msg) } + +func TestGetRevisionChartDetails(t *testing.T) { + t.Run("Test revision semvar", func(t *testing.T) { + root := t.TempDir() + service := newService(t, root) + _, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ + Repo: &v1alpha1.Repository{ + Repo: fmt.Sprintf("file://%s", root), + Name: "test-repo-name", + Type: "helm", + }, + Name: "test-name", + Revision: "test-revision", + }) + assert.ErrorContains(t, err, "invalid revision") + }) + + t.Run("Test GetRevisionChartDetails", func(t *testing.T) { + root := t.TempDir() + service := newService(t, root) + repoUrl := fmt.Sprintf("file://%s", root) + err := service.cache.SetRevisionChartDetails(repoUrl, "my-chart", "1.1.0", &argoappv1.ChartDetails{ + Description: "test-description", + Home: "test-home", + Maintainers: []string{"test-maintainer"}, + }) + assert.NoError(t, err) + chartDetails, err := service.GetRevisionChartDetails(context.Background(), &apiclient.RepoServerRevisionChartDetailsRequest{ + Repo: &v1alpha1.Repository{ + Repo: fmt.Sprintf("file://%s", root), + Name: "test-repo-name", + Type: "helm", + }, + Name: "my-chart", + Revision: "1.1.0", + }) + assert.NoError(t, err) + assert.Equal(t, "test-description", chartDetails.Description) + assert.Equal(t, "test-home", chartDetails.Home) + assert.Equal(t, []string{"test-maintainer"}, chartDetails.Maintainers) + }) +} diff --git a/util/cache/mocks/cacheclient.go b/util/cache/mocks/cacheclient.go new file mode 100644 index 0000000000000..e653847ec49a8 --- /dev/null +++ b/util/cache/mocks/cacheclient.go @@ -0,0 +1,65 @@ +package mocks + +import ( + "context" + "time" + + cache "github.com/argoproj/argo-cd/v2/util/cache" + "github.com/stretchr/testify/mock" +) + +type MockCacheClient struct { + mock.Mock + BaseCache cache.CacheClient + ReadDelay time.Duration + WriteDelay time.Duration +} + +func (c *MockCacheClient) Set(item *cache.Item) error { + args := c.Called(item) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + if c.WriteDelay > 0 { + time.Sleep(c.WriteDelay) + } + return c.BaseCache.Set(item) +} + +func (c *MockCacheClient) Get(key string, obj interface{}) error { + args := c.Called(key, obj) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + if c.ReadDelay > 0 { + time.Sleep(c.ReadDelay) + } + return c.BaseCache.Get(key, obj) +} + +func (c *MockCacheClient) Delete(key string) error { + args := c.Called(key) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + if c.WriteDelay > 0 { + time.Sleep(c.WriteDelay) + } + return c.BaseCache.Delete(key) +} + +func (c *MockCacheClient) OnUpdated(ctx context.Context, key string, callback func() error) error { + args := c.Called(ctx, key, callback) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + return c.BaseCache.OnUpdated(ctx, key, callback) +} + +func (c *MockCacheClient) NotifyUpdated(key string) error { + args := c.Called(key) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + return c.BaseCache.NotifyUpdated(key) +} From 27e927be82e7eaddb7735db827149991fb612165 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Thu, 30 Nov 2023 12:02:08 -0500 Subject: [PATCH 133/269] chore(deps): bump cosign-installer from 3.1.2 to 3.2.0 (#16495) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .github/workflows/image-reuse.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/image-reuse.yaml b/.github/workflows/image-reuse.yaml index ac111ae6395a7..0838f38e4230d 100644 --- a/.github/workflows/image-reuse.yaml +++ b/.github/workflows/image-reuse.yaml @@ -74,9 +74,9 @@ jobs: go-version: ${{ inputs.go-version }} - name: Install cosign - uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2 + uses: sigstore/cosign-installer@1fc5bd396d372bee37d608f955b336615edf79c8 # v3.2.0 with: - cosign-release: 'v2.0.2' + cosign-release: 'v2.2.1' - uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0 - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 From 19fa5b94180e96829d6d8d8cd769973ab0a88d0d Mon Sep 17 00:00:00 2001 From: May Zhang Date: Thu, 30 Nov 2023 13:40:33 -0800 Subject: [PATCH 134/269] feat: Argocd notification self service (#16488) * self service notification Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * update notification engine Signed-off-by: May Zhang * re-trigger build Signed-off-by: May Zhang * self service notification Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * update notification engine Signed-off-by: May Zhang * re-trigger build Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * update notification enginer version Signed-off-by: May Zhang * update notification enginer version Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * add back checkAppNotInAdditionalNamespaces Signed-off-by: May Zhang * add cm and secret to clusterRole Signed-off-by: May Zhang * if applicationNamespaces is not used, then use namespaced appClient Signed-off-by: May Zhang * fix merge conflict Signed-off-by: May Zhang * fix doc and test based on review Signed-off-by: May Zhang * self service notification Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * update notification engine Signed-off-by: May Zhang * re-trigger build Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * self service notification Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * revert back the changes for redis-ha Signed-off-by: May Zhang * update notification engine Signed-off-by: May Zhang * re-trigger build Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * fix conflict Signed-off-by: May Zhang * update notification enginer version Signed-off-by: May Zhang * update notification enginer version Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * fixing go tidy Signed-off-by: May Zhang * add back checkAppNotInAdditionalNamespaces Signed-off-by: May Zhang * add cm and secret to clusterRole Signed-off-by: May Zhang * if applicationNamespaces is not used, then use namespaced appClient Signed-off-by: May Zhang * fix doc and test based on review Signed-off-by: May Zhang * disable defining and using secrets within notification templates for self-service Signed-off-by: May Zhang * tweaks Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix docs formatting Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * more docs and Procfile update for local run convenience Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: May Zhang Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- Procfile | 3 +- .../commands/controller.go | 30 ++++---- cmd/argocd/commands/admin/notifications.go | 2 +- docs/operator-manual/app-any-namespace.md | 5 +- .../operator-manual/argocd-cmd-params-cm.yaml | 2 + docs/operator-manual/notifications/index.md | 68 +++++++++++++++++++ ...fications-controller-rbac-clusterrole.yaml | 11 ++- ...d-notifications-controller-deployment.yaml | 6 ++ manifests/ha/install.yaml | 6 ++ manifests/ha/namespace-install.yaml | 6 ++ manifests/install.yaml | 6 ++ manifests/namespace-install.yaml | 6 ++ .../controller/controller.go | 54 ++++++++++----- .../controller/controller_test.go | 45 ++++++------ server/notification/notification_test.go | 2 +- server/server.go | 2 +- util/notification/settings/settings.go | 29 +++++++- 17 files changed, 224 insertions(+), 59 deletions(-) diff --git a/Procfile b/Procfile index 2bb26a086fb1d..92f69ecf8ffbc 100644 --- a/Procfile +++ b/Procfile @@ -9,4 +9,5 @@ git-server: test/fixture/testrepos/start-git.sh helm-registry: test/fixture/testrepos/start-helm-registry.sh dev-mounter: [[ "$ARGOCD_E2E_TEST" != "true" ]] && go run hack/dev-mounter/main.go --configmap argocd-ssh-known-hosts-cm=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} --configmap argocd-tls-certs-cm=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} --configmap argocd-gpg-keys-cm=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} applicationset-controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-applicationset-controller $COMMAND --loglevel debug --metrics-addr localhost:12345 --probe-addr localhost:12346 --argocd-repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}" -notification: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications $COMMAND --loglevel debug" +notification: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=4 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_BINARY_NAME=argocd-notifications $COMMAND --loglevel debug --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --self-service-notification-enabled=${ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED:-'false'}" + diff --git a/cmd/argocd-notification/commands/controller.go b/cmd/argocd-notification/commands/controller.go index abd9a2e8475f0..cb30fd5277d4b 100644 --- a/cmd/argocd-notification/commands/controller.go +++ b/cmd/argocd-notification/commands/controller.go @@ -43,19 +43,20 @@ func addK8SFlagsToCmd(cmd *cobra.Command) clientcmd.ClientConfig { func NewCommand() *cobra.Command { var ( - clientConfig clientcmd.ClientConfig - processorsCount int - namespace string - appLabelSelector string - logLevel string - logFormat string - metricsPort int - argocdRepoServer string - argocdRepoServerPlaintext bool - argocdRepoServerStrictTLS bool - configMapName string - secretName string - applicationNamespaces []string + clientConfig clientcmd.ClientConfig + processorsCount int + namespace string + appLabelSelector string + logLevel string + logFormat string + metricsPort int + argocdRepoServer string + argocdRepoServerPlaintext bool + argocdRepoServerStrictTLS bool + configMapName string + secretName string + applicationNamespaces []string + selfServiceNotificationEnabled bool ) var command = cobra.Command{ Use: "controller", @@ -139,7 +140,7 @@ func NewCommand() *cobra.Command { log.Infof("serving metrics on port %d", metricsPort) log.Infof("loading configuration %d", metricsPort) - ctrl := notificationscontroller.NewController(k8sClient, dynamicClient, argocdService, namespace, applicationNamespaces, appLabelSelector, registry, secretName, configMapName) + ctrl := notificationscontroller.NewController(k8sClient, dynamicClient, argocdService, namespace, applicationNamespaces, appLabelSelector, registry, secretName, configMapName, selfServiceNotificationEnabled) err = ctrl.Init(ctx) if err != nil { return fmt.Errorf("failed to initialize controller: %w", err) @@ -163,5 +164,6 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&configMapName, "config-map-name", "argocd-notifications-cm", "Set notifications ConfigMap name") command.Flags().StringVar(&secretName, "secret-name", "argocd-notifications-secret", "Set notifications Secret name") command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces that this controller should send notifications for") + command.Flags().BoolVar(&selfServiceNotificationEnabled, "self-service-notification-enabled", env.ParseBoolFromEnv("ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED", false), "Allows the Argo CD notification controller to pull notification config from the namespace that the resource is in. This is useful for self-service notification.") return &command } diff --git a/cmd/argocd/commands/admin/notifications.go b/cmd/argocd/commands/admin/notifications.go index a1234cc53b7fe..3cbac0a53b5c2 100644 --- a/cmd/argocd/commands/admin/notifications.go +++ b/cmd/argocd/commands/admin/notifications.go @@ -36,7 +36,7 @@ func NewNotificationsCommand() *cobra.Command { "notifications", "argocd admin notifications", applications, - settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), func(clientConfig clientcmd.ClientConfig) { + settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), func(clientConfig clientcmd.ClientConfig) { k8sCfg, err := clientConfig.ClientConfig() if err != nil { log.Fatalf("Failed to parse k8s config: %v", err) diff --git a/docs/operator-manual/app-any-namespace.md b/docs/operator-manual/app-any-namespace.md index 21743b7bc003d..21bfa5c4f5a0b 100644 --- a/docs/operator-manual/app-any-namespace.md +++ b/docs/operator-manual/app-any-namespace.md @@ -15,7 +15,10 @@ Some manual steps will need to be performed by the Argo CD administrator in orde !!! note This feature is considered beta as of now. Some of the implementation details may change over the course of time until it is promoted to a stable status. We will be happy if early adopters use this feature and provide us with bug reports and feedback. - + + +One additional advantage of adopting applications in any namespace is to allow end-users to configure notifications for their Argo CD application in the namespace where Argo CD application is running in. See notifications [namespace based configuration](notifications/index.md#namespace-based-configuration) page for more information. + ## Prerequisites ### Cluster-scoped Argo CD installation diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index 695119bf0a27f..5e8c04c7e50d6 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -210,3 +210,5 @@ data: notificationscontroller.log.level: "info" # Set the logging format. One of: text|json (default "text") notificationscontroller.log.format: "text" + # Enable self-service notifications config. Used in conjunction with apps-in-any-namespace. (default "false") + notificationscontroller.selfservice.enabled: "false" diff --git a/docs/operator-manual/notifications/index.md b/docs/operator-manual/notifications/index.md index c719d10e7611c..3609089e23d08 100644 --- a/docs/operator-manual/notifications/index.md +++ b/docs/operator-manual/notifications/index.md @@ -45,3 +45,71 @@ So you can just use them instead of reinventing new ones. ``` Try syncing an application to get notified when the sync is completed. + +## Namespace based configuration + +A common installation method for Argo CD Notifications is to install it in a dedicated namespace to manage a whole cluster. In this case, the administrator is the only +person who can configure notifications in that namespace generally. However, in some cases, it is required to allow end-users to configure notifications +for their Argo CD applications. For example, the end-user can configure notifications for their Argo CD application in the namespace where they have access to and their Argo CD application is running in. + +This feature is based on applications in any namespace. See [applications in any namespace](../app-any-namespace.md) page for more information. + +In order to enable this feature, the Argo CD administrator must reconfigure the argocd-notification-controller workloads to add `--application-namespaces` and `--self-service-notification-enabled` parameters to the container's startup command. +`--application-namespaces` controls the list of namespaces that Argo CD applications are in. `--self-service-notification-enabled` turns on this feature. + +The startup parameters for both can also be conveniently set up and kept in sync by specifying +the `application.namespaces` and `notificationscontroller.selfservice.enabled` in the argocd-cmd-params-cm ConfigMap instead of changing the manifests for the respective workloads. For example: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmd-params-cm +data: + application.namespaces: app-team-one, app-team-two + notificationscontroller.selfservice.enabled: true +``` + +To use this feature, you can deploy configmap named `argocd-notifications-cm` and possibly a secret `argocd-notifications-secret` in the namespace where the Argo CD application lives. + +When it is configured this way the controller will send notifications using both the controller level configuration (the configmap located in the same namespaces as the controller) as well as +the configuration located in the same namespace where the Argo CD application is at. + +Example: Application team wants to receive notifications using PagerDutyV2, when the controller level configuration is only supporting Slack. + +The following two resources are deployed in the namespace where the Argo CD application lives. +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-notifications-cm +data: + service.pagerdutyv2: | + serviceKeys: + my-service: $pagerduty-key-my-service +... +``` +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: argo-cd-notification-secret +type: Opaque +data: + pagerduty-key-my-service: +``` + +When an Argo CD application has the following subscriptions, user receives application sync failure message from pager duty. +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + notifications.argoproj.io/subscribe.on-sync-failed.pagerdutyv2: "" +``` + +!!! note + When the same notification service and trigger are defined in controller level configuration and application level configuration, + both notifications will be sent according to its own configuration. + +[Defining and using secrets within notification templates](templates.md/#defining-and-using-secrets-within-notification-templates) function is not available when flag `--self-service-notification-enable` is on. diff --git a/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml b/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml index 05f92abb11717..ecbf6de3efb01 100644 --- a/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml +++ b/examples/k8s-rbac/argocd-server-applications/argocd-notifications-controller-rbac-clusterrole.yaml @@ -16,4 +16,13 @@ rules: - list - watch - update - - patch \ No newline at end of file + - patch +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch \ No newline at end of file diff --git a/manifests/base/notification/argocd-notifications-controller-deployment.yaml b/manifests/base/notification/argocd-notifications-controller-deployment.yaml index 9cd1a068808b1..876a207c16e42 100644 --- a/manifests/base/notification/argocd-notifications-controller-deployment.yaml +++ b/manifests/base/notification/argocd-notifications-controller-deployment.yaml @@ -54,6 +54,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true workingDir: /app livenessProbe: tcpSocket: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 50254b138d6ab..f693fd4eb887c 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -22472,6 +22472,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 59aad0e49bda3..2ecd016092f1b 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -1859,6 +1859,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/manifests/install.yaml b/manifests/install.yaml index 4fd267106eaf6..6e9ebcc8ea178 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21567,6 +21567,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index fdd4eacd14efb..d74ca00b88e4c 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -954,6 +954,12 @@ spec: key: application.namespaces name: argocd-cmd-params-cm optional: true + - name: ARGOCD_NOTIFICATION_CONTROLLER_SELF_SERVICE_NOTIFICATION_ENABLED + valueFrom: + configMapKeyRef: + key: notificationscontroller.selfservice.enabled + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/notification_controller/controller/controller.go b/notification_controller/controller/controller.go index 32dfac2b75a3b..7d871af4c44a3 100644 --- a/notification_controller/controller/controller.go +++ b/notification_controller/controller/controller.go @@ -63,19 +63,27 @@ func NewController( registry *controller.MetricsRegistry, secretName string, configMapName string, + selfServiceNotificationEnabled bool, ) *notificationController { var appClient dynamic.ResourceInterface + namespaceableAppClient := client.Resource(applications) appClient = namespaceableAppClient + if len(applicationNamespaces) == 0 { appClient = namespaceableAppClient.Namespace(namespace) } - appInformer := newInformer(appClient, namespace, applicationNamespaces, appLabelSelector) appProjInformer := newInformer(newAppProjClient(client, namespace), namespace, []string{namespace}, "") - secretInformer := k8s.NewSecretInformer(k8sClient, namespace, secretName) - configMapInformer := k8s.NewConfigMapInformer(k8sClient, namespace, configMapName) - apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, secretName, configMapName), namespace, secretInformer, configMapInformer) + var notificationConfigNamespace string + if selfServiceNotificationEnabled { + notificationConfigNamespace = v1.NamespaceAll + } else { + notificationConfigNamespace = namespace + } + secretInformer := k8s.NewSecretInformer(k8sClient, notificationConfigNamespace, secretName) + configMapInformer := k8s.NewConfigMapInformer(k8sClient, notificationConfigNamespace, configMapName) + apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, secretName, configMapName, selfServiceNotificationEnabled), namespace, secretInformer, configMapInformer) res := ¬ificationController{ secretInformer: secretInformer, @@ -83,19 +91,30 @@ func NewController( appInformer: appInformer, appProjInformer: appProjInformer, apiFactory: apiFactory} - res.ctrl = controller.NewController(namespaceableAppClient, appInformer, apiFactory, - controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { - app, ok := (obj).(*unstructured.Unstructured) - if !ok { - return false, "" - } - if checkAppNotInAdditionalNamespaces(app, namespace, applicationNamespaces) { - return true, "app is not in one of the application-namespaces, nor the notification controller namespace" - } - return !isAppSyncStatusRefreshed(app, log.WithField("app", obj.GetName())), "sync status out of date" - }), - controller.WithMetricsRegistry(registry), - controller.WithAlterDestinations(res.alterDestinations)) + skipProcessingOpt := controller.WithSkipProcessing(func(obj v1.Object) (bool, string) { + app, ok := (obj).(*unstructured.Unstructured) + if !ok { + return false, "" + } + if checkAppNotInAdditionalNamespaces(app, namespace, applicationNamespaces) { + return true, "app is not in one of the application-namespaces, nor the notification controller namespace" + } + return !isAppSyncStatusRefreshed(app, log.WithField("app", obj.GetName())), "sync status out of date" + }) + metricsRegistryOpt := controller.WithMetricsRegistry(registry) + alterDestinationsOpt := controller.WithAlterDestinations(res.alterDestinations) + + if !selfServiceNotificationEnabled { + res.ctrl = controller.NewController(namespaceableAppClient, appInformer, apiFactory, + skipProcessingOpt, + metricsRegistryOpt, + alterDestinationsOpt) + } else { + res.ctrl = controller.NewControllerWithNamespaceSupport(namespaceableAppClient, appInformer, apiFactory, + skipProcessingOpt, + metricsRegistryOpt, + alterDestinationsOpt) + } return res } @@ -118,6 +137,7 @@ func (c *notificationController) alterDestinations(obj v1.Object, destinations s } func newInformer(resClient dynamic.ResourceInterface, controllerNamespace string, applicationNamespaces []string, selector string) cache.SharedIndexInformer { + informer := cache.NewSharedIndexInformer( &cache.ListWatch{ ListFunc: func(options v1.ListOptions) (runtime.Object, error) { diff --git a/notification_controller/controller/controller_test.go b/notification_controller/controller/controller_test.go index 5ad1e520502a3..4eedb28f5e001 100644 --- a/notification_controller/controller/controller_test.go +++ b/notification_controller/controller/controller_test.go @@ -110,26 +110,30 @@ func TestInit(t *testing.T) { k8sClient := k8sfake.NewSimpleClientset() appLabelSelector := "app=test" - nc := NewController( - k8sClient, - dynamicClient, - nil, - "default", - []string{}, - appLabelSelector, - nil, - "my-secret", - "my-configmap", - ) - - assert.NotNil(t, nc) - - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - err = nc.Init(ctx) - - assert.NoError(t, err) + selfServiceNotificationEnabledFlags := []bool{false, true} + for _, selfServiceNotificationEnabled := range selfServiceNotificationEnabledFlags { + nc := NewController( + k8sClient, + dynamicClient, + nil, + "default", + []string{}, + appLabelSelector, + nil, + "my-secret", + "my-configmap", + selfServiceNotificationEnabled, + ) + + assert.NotNil(t, nc) + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + + err = nc.Init(ctx) + + assert.NoError(t, err) + } } func TestInitTimeout(t *testing.T) { @@ -152,6 +156,7 @@ func TestInitTimeout(t *testing.T) { nil, "my-secret", "my-configmap", + false, ) assert.NotNil(t, nc) diff --git a/server/notification/notification_test.go b/server/notification/notification_test.go index c1141e7ad6753..ee913926bc010 100644 --- a/server/notification/notification_test.go +++ b/server/notification/notification_test.go @@ -70,7 +70,7 @@ func TestNotificationServer(t *testing.T) { argocdService, err := service.NewArgoCDService(kubeclientset, testNamespace, mockRepoClient) require.NoError(t, err) defer argocdService.Close() - apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), testNamespace, secretInformer, configMapInformer) + apiFactory := api.NewFactory(settings.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), testNamespace, secretInformer, configMapInformer) t.Run("TestListServices", func(t *testing.T) { server := NewServer(apiFactory) diff --git a/server/server.go b/server/server.go index d9f1638024c51..0f9b0ddadd800 100644 --- a/server/server.go +++ b/server/server.go @@ -288,7 +288,7 @@ func NewServer(ctx context.Context, opts ArgoCDServerOpts) *ArgoCDServer { secretInformer := k8s.NewSecretInformer(opts.KubeClientset, opts.Namespace, "argocd-notifications-secret") configMapInformer := k8s.NewConfigMapInformer(opts.KubeClientset, opts.Namespace, "argocd-notifications-cm") - apiFactory := api.NewFactory(settings_notif.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm"), opts.Namespace, secretInformer, configMapInformer) + apiFactory := api.NewFactory(settings_notif.GetFactorySettings(argocdService, "argocd-notifications-secret", "argocd-notifications-cm", false), opts.Namespace, secretInformer, configMapInformer) dbInstance := db.NewDB(opts.Namespace, settingsMgr, opts.KubeClientset) logger := log.NewEntry(log.StandardLogger()) diff --git a/util/notification/settings/settings.go b/util/notification/settings/settings.go index ed6a44b60f365..79d70499aaea6 100644 --- a/util/notification/settings/settings.go +++ b/util/notification/settings/settings.go @@ -12,17 +12,20 @@ import ( service "github.com/argoproj/argo-cd/v2/util/notification/argocd" ) -func GetFactorySettings(argocdService service.Service, secretName, configMapName string) api.Settings { +func GetFactorySettings(argocdService service.Service, secretName, configMapName string, selfServiceNotificationEnabled bool) api.Settings { return api.Settings{ SecretName: secretName, ConfigMapName: configMapName, InitGetVars: func(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { + if selfServiceNotificationEnabled { + return initGetVarsWithoutSecret(argocdService, cfg, configMap, secret) + } return initGetVars(argocdService, cfg, configMap, secret) }, } } -func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { +func getContext(cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (map[string]string, error) { context := map[string]string{} if contextYaml, ok := configMap.Data["context"]; ok { if err := yaml.Unmarshal([]byte(contextYaml), &context); err != nil { @@ -32,6 +35,28 @@ func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.C if err := ApplyLegacyConfig(cfg, context, configMap, secret); err != nil { return nil, err } + return context, nil +} + +func initGetVarsWithoutSecret(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { + context, err := getContext(cfg, configMap, secret) + if err != nil { + return nil, err + } + + return func(obj map[string]interface{}, dest services.Destination) map[string]interface{} { + return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ + "app": obj, + "context": injectLegacyVar(context, dest.Service), + }) + }, nil +} + +func initGetVars(argocdService service.Service, cfg *api.Config, configMap *v1.ConfigMap, secret *v1.Secret) (api.GetVars, error) { + context, err := getContext(cfg, configMap, secret) + if err != nil { + return nil, err + } return func(obj map[string]interface{}, dest services.Destination) map[string]interface{} { return expression.Spawn(&unstructured.Unstructured{Object: obj}, argocdService, map[string]interface{}{ From 86565852a474347176880b21325a2ebc718658d2 Mon Sep 17 00:00:00 2001 From: Jessie Teng <101035990+JessieTeng89@users.noreply.github.com> Date: Fri, 1 Dec 2023 23:07:34 +0800 Subject: [PATCH 135/269] fix: Tooltips point in wrong direction#11935 (#12578) * fix: Tooltips point in wrong direction#11935 Signed-off-by: Teng, Jessie * fix: Tooltips point in wrong direction#11935 Signed-off-by: Teng --------- Signed-off-by: Teng, Jessie Signed-off-by: Teng Co-authored-by: Teng, Jessie --- ui/src/app/sidebar/sidebar.scss | 7 +++++++ ui/src/app/sidebar/sidebar.tsx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ui/src/app/sidebar/sidebar.scss b/ui/src/app/sidebar/sidebar.scss index 20ab71b969294..d41cbeed3f7cf 100644 --- a/ui/src/app/sidebar/sidebar.scss +++ b/ui/src/app/sidebar/sidebar.scss @@ -58,6 +58,13 @@ $deselected-text: #818d94; text-overflow: ellipsis; } + &__tooltip { + max-width: 300px; + @media screen and (max-width: 590px) { + max-width: 250px; + } + } + &__nav-item { cursor: pointer; display: flex; diff --git a/ui/src/app/sidebar/sidebar.tsx b/ui/src/app/sidebar/sidebar.tsx index c690565d01cb5..1aeb77c9112ee 100644 --- a/ui/src/app/sidebar/sidebar.tsx +++ b/ui/src/app/sidebar/sidebar.tsx @@ -64,7 +64,7 @@ export const Sidebar = (props: SidebarProps) => {
    {(props.navItems || []).map(item => ( - + {item?.tooltip || item.title}
    } {...tooltipProps}>
    Date: Fri, 1 Dec 2023 11:13:33 -0500 Subject: [PATCH 136/269] feat(appset): Advanced Templating using templatePatch (#14893) * fix(11164): Advanced templating using patchTemplate Signed-off-by: gmuselli * small changes Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: gmuselli Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .../controllers/applicationset_controller.go | 31 + .../applicationset_controller_test.go | 12 + applicationset/controllers/templatePatch.go | 46 + .../controllers/templatePatch_test.go | 249 +++ applicationset/utils/utils.go | 1 + assets/swagger.json | 3 + .../applicationset/Template.md | 66 + manifests/core-install.yaml | 2 + manifests/crds/applicationset-crd.yaml | 2 + manifests/ha/install.yaml | 2 + manifests/install.yaml | 2 + .../v1alpha1/applicationset_types.go | 1 + pkg/apis/application/v1alpha1/generated.pb.go | 1388 +++++++++-------- pkg/apis/application/v1alpha1/generated.proto | 2 + .../application/v1alpha1/openapi_generated.go | 6 + .../v1alpha1/zz_generated.deepcopy.go | 5 + test/e2e/applicationset_test.go | 128 ++ 17 files changed, 1275 insertions(+), 671 deletions(-) create mode 100644 applicationset/controllers/templatePatch.go create mode 100644 applicationset/controllers/templatePatch_test.go diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 5f1205caf384a..527a4ae1e3883 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -524,6 +524,7 @@ func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, appli for _, p := range a.Params { app, err := r.Renderer.RenderTemplateParams(tmplApplication, applicationSetInfo.Spec.SyncPolicy, p, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) + if err != nil { logCtx.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). Error("error generating application from params") @@ -534,6 +535,24 @@ func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, appli } continue } + + if applicationSetInfo.Spec.TemplatePatch != nil { + patchedApplication, err := r.applyTemplatePatch(app, applicationSetInfo, p) + + if err != nil { + log.WithError(err).WithField("params", a.Params).WithField("generator", requestedGenerator). + Error("error generating application from params") + + if firstError == nil { + firstError = err + applicationSetReason = argov1alpha1.ApplicationSetReasonRenderTemplateParamsError + } + continue + } + + app = patchedApplication + } + res = append(res, *app) } } @@ -545,6 +564,16 @@ func (r *ApplicationSetReconciler) generateApplications(logCtx *log.Entry, appli return res, applicationSetReason, firstError } +func (r *ApplicationSetReconciler) applyTemplatePatch(app *argov1alpha1.Application, applicationSetInfo argov1alpha1.ApplicationSet, params map[string]interface{}) (*argov1alpha1.Application, error) { + replacedTemplate, err := r.Renderer.Replace(*applicationSetInfo.Spec.TemplatePatch, params, applicationSetInfo.Spec.GoTemplate, applicationSetInfo.Spec.GoTemplateOptions) + + if err != nil { + return nil, fmt.Errorf("error replacing values in templatePatch: %w", err) + } + + return applyTemplatePatch(app, replacedTemplate) +} + func ignoreNotAllowedNamespaces(namespaces []string) predicate.Predicate { return predicate.Funcs{ CreateFunc: func(e event.CreateEvent) bool { @@ -619,6 +648,8 @@ func (r *ApplicationSetReconciler) createOrUpdateInCluster(ctx context.Context, var firstError error // Creates or updates the application in appList for _, generatedApp := range desiredApplications { + // The app's namespace must be the same as the AppSet's namespace to preserve the appsets-in-any-namespace + // security boundary. generatedApp.Namespace = applicationSet.Namespace appLog := logCtx.WithFields(log.Fields{"app": generatedApp.QualifiedName()}) diff --git a/applicationset/controllers/applicationset_controller_test.go b/applicationset/controllers/applicationset_controller_test.go index ce9dc485ba4a8..81fbad95ac50b 100644 --- a/applicationset/controllers/applicationset_controller_test.go +++ b/applicationset/controllers/applicationset_controller_test.go @@ -86,6 +86,12 @@ func (g *generatorMock) GenerateParams(appSetGenerator *v1alpha1.ApplicationSetG return args.Get(0).([]map[string]interface{}), args.Error(1) } +func (g *generatorMock) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { + args := g.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + + return args.Get(0).(string), args.Error(1) +} + type rendererMock struct { mock.Mock } @@ -107,6 +113,12 @@ func (r *rendererMock) RenderTemplateParams(tmpl *v1alpha1.Application, syncPoli } +func (r *rendererMock) Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) { + args := r.Called(tmpl, replaceMap, useGoTemplate, goTemplateOptions) + + return args.Get(0).(string), args.Error(1) +} + func TestExtractApplications(t *testing.T) { scheme := runtime.NewScheme() err := v1alpha1.AddToScheme(scheme) diff --git a/applicationset/controllers/templatePatch.go b/applicationset/controllers/templatePatch.go new file mode 100644 index 0000000000000..f8efd9f376996 --- /dev/null +++ b/applicationset/controllers/templatePatch.go @@ -0,0 +1,46 @@ +package controllers + +import ( + "encoding/json" + "fmt" + + "k8s.io/apimachinery/pkg/util/strategicpatch" + + "github.com/argoproj/argo-cd/v2/applicationset/utils" + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func applyTemplatePatch(app *appv1.Application, templatePatch string) (*appv1.Application, error) { + + appString, err := json.Marshal(app) + if err != nil { + return nil, fmt.Errorf("error while marhsalling Application %w", err) + } + + convertedTemplatePatch, err := utils.ConvertYAMLToJSON(templatePatch) + + if err != nil { + return nil, fmt.Errorf("error while converting template to json %q: %w", convertedTemplatePatch, err) + } + + if err := json.Unmarshal([]byte(convertedTemplatePatch), &appv1.Application{}); err != nil { + return nil, fmt.Errorf("invalid templatePatch %q: %w", convertedTemplatePatch, err) + } + + data, err := strategicpatch.StrategicMergePatch(appString, []byte(convertedTemplatePatch), appv1.Application{}) + + if err != nil { + return nil, fmt.Errorf("error while applying templatePatch template to json %q: %w", convertedTemplatePatch, err) + } + + finalApp := appv1.Application{} + err = json.Unmarshal(data, &finalApp) + if err != nil { + return nil, fmt.Errorf("error while unmarhsalling patched application: %w", err) + } + + // Prevent changes to the `project` field. This helps prevent malicious template patches + finalApp.Spec.Project = app.Spec.Project + + return &finalApp, nil +} diff --git a/applicationset/controllers/templatePatch_test.go b/applicationset/controllers/templatePatch_test.go new file mode 100644 index 0000000000000..c1a794077c8ee --- /dev/null +++ b/applicationset/controllers/templatePatch_test.go @@ -0,0 +1,249 @@ +package controllers + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +func Test_ApplyTemplatePatch(t *testing.T) { + testCases := []struct { + name string + appTemplate *appv1.Application + templatePatch string + expectedApp *appv1.Application + }{ + { + name: "patch with JSON", + appTemplate: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + templatePatch: `{ + "metadata": { + "annotations": { + "annotation-some-key": "annotation-some-value" + } + }, + "spec": { + "source": { + "helm": { + "valueFiles": [ + "values.test.yaml", + "values.big.yaml" + ] + } + }, + "syncPolicy": { + "automated": { + "prune": true + } + } + } + }`, + expectedApp: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Annotations: map[string]string{ + "annotation-some-key": "annotation-some-value", + }, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + Helm: &appv1.ApplicationSourceHelm{ + ValueFiles: []string{ + "values.test.yaml", + "values.big.yaml", + }, + }, + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + SyncPolicy: &appv1.SyncPolicy{ + Automated: &appv1.SyncPolicyAutomated{ + Prune: true, + }, + }, + }, + }, + }, + { + name: "patch with YAML", + appTemplate: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + templatePatch: ` +metadata: + annotations: + annotation-some-key: annotation-some-value +spec: + source: + helm: + valueFiles: + - values.test.yaml + - values.big.yaml + syncPolicy: + automated: + prune: true`, + expectedApp: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Annotations: map[string]string{ + "annotation-some-key": "annotation-some-value", + }, + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + Helm: &appv1.ApplicationSourceHelm{ + ValueFiles: []string{ + "values.test.yaml", + "values.big.yaml", + }, + }, + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + SyncPolicy: &appv1.SyncPolicy{ + Automated: &appv1.SyncPolicyAutomated{ + Prune: true, + }, + }, + }, + }, + }, + { + name: "project field isn't overwritten", + appTemplate: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + templatePatch: ` +spec: + project: my-project`, + expectedApp: &appv1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: "namespace", + }, + Spec: appv1.ApplicationSpec{ + Project: "default", + Source: &appv1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: appv1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + }, + }, + }, + } + + for _, tc := range testCases { + tcc := tc + t.Run(tcc.name, func(t *testing.T) { + result, err := applyTemplatePatch(tcc.appTemplate, tcc.templatePatch) + require.NoError(t, err) + assert.Equal(t, *tcc.expectedApp, *result) + }) + } +} + +func TestError(t *testing.T) { + app := &appv1.Application{} + + result, err := applyTemplatePatch(app, "hello world") + require.Error(t, err) + require.Nil(t, result) +} diff --git a/applicationset/utils/utils.go b/applicationset/utils/utils.go index 3392d386f7426..2d128eb81a16c 100644 --- a/applicationset/utils/utils.go +++ b/applicationset/utils/utils.go @@ -41,6 +41,7 @@ func init() { type Renderer interface { RenderTemplateParams(tmpl *argoappsv1.Application, syncPolicy *argoappsv1.ApplicationSetSyncPolicy, params map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (*argoappsv1.Application, error) + Replace(tmpl string, replaceMap map[string]interface{}, useGoTemplate bool, goTemplateOptions []string) (string, error) } type Render struct { diff --git a/assets/swagger.json b/assets/swagger.json index b7f0cdefabe1c..44e67d0b3923e 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -6143,6 +6143,9 @@ }, "template": { "$ref": "#/definitions/v1alpha1ApplicationSetTemplate" + }, + "templatePatch": { + "type": "string" } } }, diff --git a/docs/operator-manual/applicationset/Template.md b/docs/operator-manual/applicationset/Template.md index f66a403586bbd..76ff9132802d5 100644 --- a/docs/operator-manual/applicationset/Template.md +++ b/docs/operator-manual/applicationset/Template.md @@ -108,3 +108,69 @@ spec: (*The full example can be found [here](https://github.com/argoproj/argo-cd/tree/master/applicationset/examples/template-override).*) In this example, the ApplicationSet controller will generate an `Application` resource using the `path` generated by the List generator, rather than the `path` value defined in `.spec.template`. + +## Template Patch + +Templating is only available on string type. However, some uses cases may require to apply templating on other types. + +Example: + +- Set the automated sync policy +- Switch prune boolean to true +- Add multiple helm value files + +Argo CD has a `templatePatch` feature to allow advanced templating. It supports both json and yaml. + + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: guestbook +spec: + goTemplate: true + generators: + - list: + elements: + - cluster: engineering-dev + url: https://kubernetes.default.svc + autoSync: true + prune: true + valueFiles: + - values.large.yaml + - values.debug.yaml + template: + metadata: + name: '{{.cluster}}-deployment' + spec: + project: "default" + source: + repoURL: https://github.com/infra-team/cluster-deployments.git + targetRevision: HEAD + path: guestbook/{{ .cluster }} + destination: + server: '{{.url}}' + namespace: guestbook + templatePatch: | + spec: + source: + helm: + valueFiles: + {{- range $valueFile := .valueFiles }} + - {{ $valueFile | toJson }} + {{- end }} + {{- if .autoSync }} + syncPolicy: + automated: + prune: {{ .prune | toJson }} + {{- end }} +``` + +!!! important + The `templatePatch` can apply arbitrary changes to the template. If parameters include untrustworthy user input, it + may be possible to inject malicious changes into the template. It is recommended to use `templatePatch` only with + trusted input or to carefully escape the input before using it in the template. Piping input to `toJson` should help + prevent, for example, a user from successfully injecting a string with newlines. + + The `spec.project` field is not supported in `templatePatch`. If you need to change the project, you can use the + `spec.project` field in the `template` field. diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index beda1e8a5103f..5d2d225473452 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -20123,6 +20123,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index c324134df927b..758785832ea78 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -15183,6 +15183,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index f693fd4eb887c..19f8015b04945 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -20123,6 +20123,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template diff --git a/manifests/install.yaml b/manifests/install.yaml index 6e9ebcc8ea178..2f7da39bd9b12 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -20123,6 +20123,8 @@ spec: - metadata - spec type: object + templatePatch: + type: string required: - generators - template diff --git a/pkg/apis/application/v1alpha1/applicationset_types.go b/pkg/apis/application/v1alpha1/applicationset_types.go index 99db8124e51ea..41721d0c2287c 100644 --- a/pkg/apis/application/v1alpha1/applicationset_types.go +++ b/pkg/apis/application/v1alpha1/applicationset_types.go @@ -65,6 +65,7 @@ type ApplicationSetSpec struct { // ApplyNestedSelectors enables selectors defined within the generators of two level-nested matrix or merge generators ApplyNestedSelectors bool `json:"applyNestedSelectors,omitempty" protobuf:"bytes,8,name=applyNestedSelectors"` IgnoreApplicationDifferences ApplicationSetIgnoreDifferences `json:"ignoreApplicationDifferences,omitempty" protobuf:"bytes,9,name=ignoreApplicationDifferences"` + TemplatePatch *string `json:"templatePatch,omitempty" protobuf:"bytes,10,name=templatePatch"` } type ApplicationPreservedFields struct { diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 777ef9fa49bcc..2a9c0f4789bb7 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4448,693 +4448,694 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 10964 bytes of a gzipped FileDescriptorProto + // 10983 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, 0x75, 0x18, 0xae, 0xd9, 0x0f, 0x60, 0xf7, 0xe1, 0x83, 0x64, 0x93, 0xbc, 0x03, 0xa9, 0xbb, 0x03, - 0x3d, 0xf7, 0xf3, 0xe9, 0xfc, 0xd3, 0x1d, 0xe0, 0xa3, 0xee, 0x94, 0x8b, 0xce, 0x96, 0x8c, 0x0f, + 0x3d, 0xf7, 0xf3, 0xe9, 0xfc, 0xd3, 0x1d, 0xe0, 0xa3, 0xef, 0xe4, 0x8b, 0xce, 0x96, 0x8c, 0x0f, 0x12, 0x04, 0x09, 0x10, 0xb8, 0x06, 0x48, 0x4a, 0x27, 0x9f, 0x4e, 0x83, 0xdd, 0xc6, 0x62, 0x88, 0xd9, 0x99, 0xb9, 0x99, 0x59, 0x10, 0x38, 0x4b, 0xb2, 0x64, 0xc9, 0xb6, 0x12, 0x7d, 0x9c, 0x22, - 0x25, 0xe5, 0x73, 0x12, 0x39, 0xb2, 0xe5, 0xa4, 0xec, 0x4a, 0x54, 0x71, 0x92, 0x3f, 0xe2, 0xc4, + 0x25, 0xe5, 0x73, 0x12, 0x29, 0xb2, 0xe5, 0xa4, 0xec, 0x4a, 0x54, 0x71, 0x92, 0x3f, 0xe2, 0xc4, 0x49, 0xb9, 0x6c, 0xa7, 0x52, 0x4a, 0x29, 0x29, 0xbb, 0x52, 0x2e, 0xcb, 0x49, 0x6c, 0x44, 0x62, - 0xca, 0x95, 0x54, 0xaa, 0xe2, 0x2a, 0x27, 0xfe, 0x23, 0x61, 0xf2, 0x47, 0xaa, 0xbf, 0x7b, 0x66, + 0x2a, 0x95, 0x54, 0xaa, 0xe2, 0x2a, 0x27, 0xfe, 0x23, 0x61, 0xf2, 0x47, 0xaa, 0xbf, 0x7b, 0x66, 0x67, 0x81, 0x05, 0x30, 0x20, 0x29, 0xe5, 0xfe, 0xdb, 0xed, 0xf7, 0xe6, 0xbd, 0x9e, 0x9e, 0xee, 0xf7, 0x5e, 0xbf, 0x7e, 0xef, 0x35, 0x2c, 0xb4, 0xdc, 0x64, 0xa3, 0xb3, 0x36, 0xd1, 0x08, 0xda, 0x93, 0x4e, 0xd4, 0x0a, 0xc2, 0x28, 0xb8, 0xcd, 0x7e, 0x3c, 0xdb, 0x68, 0x4e, 0x6e, 0x5d, 0x9c, 0x0c, 0x37, 0x5b, 0x93, 0x4e, 0xe8, 0xc6, 0x93, 0x4e, 0x18, 0x7a, 0x6e, 0xc3, 0x49, 0xdc, 0xc0, 0x9f, 0xdc, 0x7a, 0xce, 0xf1, 0xc2, 0x0d, 0xe7, 0xb9, 0xc9, 0x16, 0xf1, 0x49, 0xe4, 0x24, 0xa4, - 0x39, 0x11, 0x46, 0x41, 0x12, 0xa0, 0x1f, 0xd1, 0xd4, 0x26, 0x24, 0x35, 0xf6, 0xe3, 0xb5, 0x46, + 0x39, 0x11, 0x46, 0x41, 0x12, 0xa0, 0x1f, 0xd3, 0xd4, 0x26, 0x24, 0x35, 0xf6, 0xe3, 0xb5, 0x46, 0x73, 0x62, 0xeb, 0xe2, 0x44, 0xb8, 0xd9, 0x9a, 0xa0, 0xd4, 0x26, 0x0c, 0x6a, 0x13, 0x92, 0xda, 0xf9, 0x67, 0x8d, 0xbe, 0xb4, 0x82, 0x56, 0x30, 0xc9, 0x88, 0xae, 0x75, 0xd6, 0xd9, 0x3f, 0xf6, 0x87, 0xfd, 0xe2, 0xcc, 0xce, 0xdb, 0x9b, 0x2f, 0xc6, 0x13, 0x6e, 0x40, 0xbb, 0x37, 0xd9, 0x08, 0x22, 0x32, 0xb9, 0xd5, 0xd5, 0xa1, 0xf3, 0x57, 0x34, 0x0e, 0xd9, 0x4e, 0x88, 0x1f, 0xbb, 0x81, 0x1f, 0x3f, 0x4b, 0xbb, 0x40, 0xa2, 0x2d, 0x12, 0x99, 0xaf, 0x67, 0x20, 0xe4, 0x51, 0x7a, 0x5e, 0x53, 0x6a, 0x3b, 0x8d, 0x0d, 0xd7, 0x27, 0xd1, 0x8e, 0x7e, 0xbc, 0x4d, 0x12, 0x27, 0xef, 0xa9, - 0xc9, 0x5e, 0x4f, 0x45, 0x1d, 0x3f, 0x71, 0xdb, 0xa4, 0xeb, 0x81, 0xf7, 0xee, 0xf7, 0x40, 0xdc, - 0xd8, 0x20, 0x6d, 0xa7, 0xeb, 0xb9, 0xf7, 0xf4, 0x7a, 0xae, 0x93, 0xb8, 0xde, 0xa4, 0xeb, 0x27, - 0x71, 0x12, 0x65, 0x1f, 0xb2, 0x5f, 0x87, 0x91, 0xa9, 0x5b, 0x2b, 0x53, 0x9d, 0x64, 0x63, 0x26, - 0xf0, 0xd7, 0xdd, 0x16, 0x7a, 0x01, 0x86, 0x1a, 0x5e, 0x27, 0x4e, 0x48, 0x74, 0xdd, 0x69, 0x93, - 0x31, 0xeb, 0x82, 0xf5, 0x74, 0x7d, 0xfa, 0xf4, 0x37, 0x77, 0xc7, 0xdf, 0x71, 0x77, 0x77, 0x7c, - 0x68, 0x46, 0x83, 0xb0, 0x89, 0x87, 0x7e, 0x08, 0x06, 0xa3, 0xc0, 0x23, 0x53, 0xf8, 0xfa, 0x58, - 0x89, 0x3d, 0x72, 0x42, 0x3c, 0x32, 0x88, 0x79, 0x33, 0x96, 0x70, 0xfb, 0x0f, 0x4a, 0x00, 0x53, - 0x61, 0xb8, 0x1c, 0x05, 0xb7, 0x49, 0x23, 0x41, 0x1f, 0x85, 0x1a, 0x1d, 0xba, 0xa6, 0x93, 0x38, - 0x8c, 0xdb, 0xd0, 0xc5, 0x1f, 0x9e, 0xe0, 0x6f, 0x32, 0x61, 0xbe, 0x89, 0x9e, 0x38, 0x14, 0x7b, - 0x62, 0xeb, 0xb9, 0x89, 0xa5, 0x35, 0xfa, 0xfc, 0x22, 0x49, 0x9c, 0x69, 0x24, 0x98, 0x81, 0x6e, - 0xc3, 0x8a, 0x2a, 0xf2, 0xa1, 0x12, 0x87, 0xa4, 0xc1, 0x3a, 0x36, 0x74, 0x71, 0x61, 0xe2, 0x28, - 0x33, 0x74, 0x42, 0xf7, 0x7c, 0x25, 0x24, 0x8d, 0xe9, 0x61, 0xc1, 0xb9, 0x42, 0xff, 0x61, 0xc6, - 0x07, 0x6d, 0xc1, 0x40, 0x9c, 0x38, 0x49, 0x27, 0x1e, 0x2b, 0x33, 0x8e, 0xd7, 0x0b, 0xe3, 0xc8, - 0xa8, 0x4e, 0x8f, 0x0a, 0x9e, 0x03, 0xfc, 0x3f, 0x16, 0xdc, 0xec, 0x3f, 0xb6, 0x60, 0x54, 0x23, - 0x2f, 0xb8, 0x71, 0x82, 0x7e, 0xbc, 0x6b, 0x70, 0x27, 0xfa, 0x1b, 0x5c, 0xfa, 0x34, 0x1b, 0xda, - 0x93, 0x82, 0x59, 0x4d, 0xb6, 0x18, 0x03, 0xdb, 0x86, 0xaa, 0x9b, 0x90, 0x76, 0x3c, 0x56, 0xba, - 0x50, 0x7e, 0x7a, 0xe8, 0xe2, 0x95, 0xa2, 0xde, 0x73, 0x7a, 0x44, 0x30, 0xad, 0xce, 0x53, 0xf2, - 0x98, 0x73, 0xb1, 0x7f, 0x75, 0xd8, 0x7c, 0x3f, 0x3a, 0xe0, 0xe8, 0x39, 0x18, 0x8a, 0x83, 0x4e, - 0xd4, 0x20, 0x98, 0x84, 0x41, 0x3c, 0x66, 0x5d, 0x28, 0xd3, 0xa9, 0x47, 0x67, 0xea, 0x8a, 0x6e, - 0xc6, 0x26, 0x0e, 0xfa, 0xa2, 0x05, 0xc3, 0x4d, 0x12, 0x27, 0xae, 0xcf, 0xf8, 0xcb, 0xce, 0xaf, - 0x1e, 0xb9, 0xf3, 0xb2, 0x71, 0x56, 0x13, 0x9f, 0x3e, 0x23, 0x5e, 0x64, 0xd8, 0x68, 0x8c, 0x71, - 0x8a, 0x3f, 0x5d, 0x71, 0x4d, 0x12, 0x37, 0x22, 0x37, 0xa4, 0xff, 0xd9, 0x9c, 0x31, 0x56, 0xdc, - 0xac, 0x06, 0x61, 0x13, 0x0f, 0xf9, 0x50, 0xa5, 0x2b, 0x2a, 0x1e, 0xab, 0xb0, 0xfe, 0xcf, 0x1f, - 0xad, 0xff, 0x62, 0x50, 0xe9, 0x62, 0xd5, 0xa3, 0x4f, 0xff, 0xc5, 0x98, 0xb3, 0x41, 0x5f, 0xb0, - 0x60, 0x4c, 0xac, 0x78, 0x4c, 0xf8, 0x80, 0xde, 0xda, 0x70, 0x13, 0xe2, 0xb9, 0x71, 0x32, 0x56, - 0x65, 0x7d, 0x98, 0xec, 0x6f, 0x6e, 0xcd, 0x45, 0x41, 0x27, 0xbc, 0xe6, 0xfa, 0xcd, 0xe9, 0x0b, - 0x82, 0xd3, 0xd8, 0x4c, 0x0f, 0xc2, 0xb8, 0x27, 0x4b, 0xf4, 0x15, 0x0b, 0xce, 0xfb, 0x4e, 0x9b, - 0xc4, 0xa1, 0x43, 0x3f, 0x2d, 0x07, 0x4f, 0x7b, 0x4e, 0x63, 0x93, 0xf5, 0x68, 0xe0, 0x70, 0x3d, - 0xb2, 0x45, 0x8f, 0xce, 0x5f, 0xef, 0x49, 0x1a, 0xef, 0xc1, 0x16, 0x7d, 0xdd, 0x82, 0x53, 0x41, - 0x14, 0x6e, 0x38, 0x3e, 0x69, 0x4a, 0x68, 0x3c, 0x36, 0xc8, 0x96, 0xde, 0x47, 0x8e, 0xf6, 0x89, - 0x96, 0xb2, 0x64, 0x17, 0x03, 0xdf, 0x4d, 0x82, 0x68, 0x85, 0x24, 0x89, 0xeb, 0xb7, 0xe2, 0xe9, - 0xb3, 0x77, 0x77, 0xc7, 0x4f, 0x75, 0x61, 0xe1, 0xee, 0xfe, 0xa0, 0x9f, 0x80, 0xa1, 0x78, 0xc7, - 0x6f, 0xdc, 0x72, 0xfd, 0x66, 0x70, 0x27, 0x1e, 0xab, 0x15, 0xb1, 0x7c, 0x57, 0x14, 0x41, 0xb1, - 0x00, 0x35, 0x03, 0x6c, 0x72, 0xcb, 0xff, 0x70, 0x7a, 0x2a, 0xd5, 0x8b, 0xfe, 0x70, 0x7a, 0x32, - 0xed, 0xc1, 0x16, 0xfd, 0xac, 0x05, 0x23, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x91, 0x6b, 0x64, - 0x27, 0x1e, 0x03, 0xd6, 0x91, 0xab, 0x47, 0x1c, 0x15, 0x83, 0xe4, 0xf4, 0x59, 0xd1, 0xc7, 0x11, - 0xb3, 0x35, 0xc6, 0x69, 0xbe, 0x79, 0x0b, 0x4d, 0x4f, 0xeb, 0xa1, 0x62, 0x17, 0x9a, 0x9e, 0xd4, - 0x3d, 0x59, 0xa2, 0x1f, 0x83, 0x93, 0xbc, 0x49, 0x8d, 0x6c, 0x3c, 0x36, 0xcc, 0x04, 0xed, 0x99, - 0xbb, 0xbb, 0xe3, 0x27, 0x57, 0x32, 0x30, 0xdc, 0x85, 0x8d, 0x5e, 0x87, 0xf1, 0x90, 0x44, 0x6d, - 0x37, 0x59, 0xf2, 0xbd, 0x1d, 0x29, 0xbe, 0x1b, 0x41, 0x48, 0x9a, 0xa2, 0x3b, 0xf1, 0xd8, 0xc8, - 0x05, 0xeb, 0xe9, 0xda, 0xf4, 0xbb, 0x44, 0x37, 0xc7, 0x97, 0xf7, 0x46, 0xc7, 0xfb, 0xd1, 0xb3, - 0xff, 0x55, 0x09, 0x4e, 0x66, 0x15, 0x27, 0xfa, 0x3b, 0x16, 0x9c, 0xb8, 0x7d, 0x27, 0x59, 0x0d, - 0x36, 0x89, 0x1f, 0x4f, 0xef, 0x50, 0xf1, 0xc6, 0x54, 0xc6, 0xd0, 0xc5, 0x46, 0xb1, 0x2a, 0x7a, - 0xe2, 0x6a, 0x9a, 0xcb, 0x25, 0x3f, 0x89, 0x76, 0xa6, 0x1f, 0x15, 0x6f, 0x77, 0xe2, 0xea, 0xad, - 0x55, 0x13, 0x8a, 0xb3, 0x9d, 0x3a, 0xff, 0x39, 0x0b, 0xce, 0xe4, 0x91, 0x40, 0x27, 0xa1, 0xbc, - 0x49, 0x76, 0xb8, 0x55, 0x86, 0xe9, 0x4f, 0xf4, 0x2a, 0x54, 0xb7, 0x1c, 0xaf, 0x43, 0x84, 0x75, - 0x33, 0x77, 0xb4, 0x17, 0x51, 0x3d, 0xc3, 0x9c, 0xea, 0xfb, 0x4a, 0x2f, 0x5a, 0xf6, 0xef, 0x96, - 0x61, 0xc8, 0xd0, 0x6f, 0xf7, 0xc1, 0x62, 0x0b, 0x52, 0x16, 0xdb, 0x62, 0x61, 0xaa, 0xb9, 0xa7, - 0xc9, 0x76, 0x27, 0x63, 0xb2, 0x2d, 0x15, 0xc7, 0x72, 0x4f, 0x9b, 0x0d, 0x25, 0x50, 0x0f, 0x42, - 0x6a, 0x91, 0x53, 0xd5, 0x5f, 0x29, 0xe2, 0x13, 0x2e, 0x49, 0x72, 0xd3, 0x23, 0x77, 0x77, 0xc7, - 0xeb, 0xea, 0x2f, 0xd6, 0x8c, 0xec, 0x6f, 0x5b, 0x70, 0xc6, 0xe8, 0xe3, 0x4c, 0xe0, 0x37, 0x5d, - 0xf6, 0x69, 0x2f, 0x40, 0x25, 0xd9, 0x09, 0xa5, 0xd9, 0xaf, 0x46, 0x6a, 0x75, 0x27, 0x24, 0x98, - 0x41, 0xa8, 0xa1, 0xdf, 0x26, 0x71, 0xec, 0xb4, 0x48, 0xd6, 0xd0, 0x5f, 0xe4, 0xcd, 0x58, 0xc2, - 0x51, 0x04, 0xc8, 0x73, 0xe2, 0x64, 0x35, 0x72, 0xfc, 0x98, 0x91, 0x5f, 0x75, 0xdb, 0x44, 0x0c, - 0xf0, 0xff, 0xdf, 0xdf, 0x8c, 0xa1, 0x4f, 0x4c, 0x3f, 0x72, 0x77, 0x77, 0x1c, 0x2d, 0x74, 0x51, - 0xc2, 0x39, 0xd4, 0xed, 0xaf, 0x58, 0xf0, 0x48, 0xbe, 0x2d, 0x86, 0x9e, 0x82, 0x01, 0xbe, 0xe5, - 0x13, 0x6f, 0xa7, 0x3f, 0x09, 0x6b, 0xc5, 0x02, 0x8a, 0x26, 0xa1, 0xae, 0xf4, 0x84, 0x78, 0xc7, - 0x53, 0x02, 0xb5, 0xae, 0x95, 0x8b, 0xc6, 0xa1, 0x83, 0x46, 0xff, 0x08, 0xcb, 0x4d, 0x0d, 0x1a, - 0xdb, 0x24, 0x31, 0x88, 0xfd, 0x1f, 0x2d, 0x38, 0x61, 0xf4, 0xea, 0x3e, 0x98, 0xe6, 0x7e, 0xda, - 0x34, 0x9f, 0x2f, 0x6c, 0x3e, 0xf7, 0xb0, 0xcd, 0xbf, 0x60, 0xc1, 0x79, 0x03, 0x6b, 0xd1, 0x49, - 0x1a, 0x1b, 0x97, 0xb6, 0xc3, 0x88, 0xc4, 0x74, 0x3b, 0x8d, 0x1e, 0x37, 0xe4, 0xd6, 0xf4, 0x90, - 0xa0, 0x50, 0xbe, 0x46, 0x76, 0xb8, 0x10, 0x7b, 0x06, 0x6a, 0x7c, 0x72, 0x06, 0x91, 0x18, 0x71, - 0xf5, 0x6e, 0x4b, 0xa2, 0x1d, 0x2b, 0x0c, 0x64, 0xc3, 0x00, 0x13, 0x4e, 0x74, 0xb1, 0x52, 0x35, - 0x04, 0xf4, 0x23, 0xde, 0x64, 0x2d, 0x58, 0x40, 0xec, 0x38, 0xd5, 0x9d, 0xe5, 0x88, 0xb0, 0x8f, - 0xdb, 0xbc, 0xec, 0x12, 0xaf, 0x19, 0xd3, 0x6d, 0x83, 0xe3, 0xfb, 0x41, 0x22, 0x76, 0x00, 0xc6, - 0xb6, 0x61, 0x4a, 0x37, 0x63, 0x13, 0x87, 0x32, 0xf5, 0x9c, 0x35, 0xe2, 0xf1, 0x11, 0x15, 0x4c, - 0x17, 0x58, 0x0b, 0x16, 0x10, 0xfb, 0x6e, 0x89, 0x6d, 0x50, 0xd4, 0xd2, 0x27, 0xf7, 0x63, 0x77, - 0x1b, 0xa5, 0x64, 0xe5, 0x72, 0x71, 0x82, 0x8b, 0xf4, 0xde, 0xe1, 0xbe, 0x91, 0x11, 0x97, 0xb8, - 0x50, 0xae, 0x7b, 0xef, 0x72, 0x7f, 0xab, 0x04, 0xe3, 0xe9, 0x07, 0xba, 0xa4, 0x2d, 0xdd, 0x52, - 0x19, 0x8c, 0xb2, 0x4e, 0x0c, 0x03, 0x1f, 0x9b, 0x78, 0x3d, 0x04, 0x56, 0xe9, 0x38, 0x05, 0x96, - 0x29, 0x4f, 0xcb, 0xfb, 0xc8, 0xd3, 0xa7, 0xd4, 0xa8, 0x57, 0x32, 0x02, 0x2c, 0xad, 0x53, 0x2e, - 0x40, 0x25, 0x4e, 0x48, 0x38, 0x56, 0x4d, 0xcb, 0xa3, 0x95, 0x84, 0x84, 0x98, 0x41, 0xec, 0xff, - 0x5a, 0x82, 0x47, 0xd3, 0x63, 0xa8, 0x55, 0xc0, 0x07, 0x52, 0x2a, 0xe0, 0xdd, 0xa6, 0x0a, 0xb8, - 0xb7, 0x3b, 0xfe, 0xce, 0x1e, 0x8f, 0x7d, 0xcf, 0x68, 0x08, 0x34, 0x97, 0x19, 0xc5, 0xc9, 0xf4, - 0x28, 0xde, 0xdb, 0x1d, 0x7f, 0xbc, 0xc7, 0x3b, 0x66, 0x86, 0xf9, 0x29, 0x18, 0x88, 0x88, 0x13, - 0x07, 0xbe, 0x18, 0x68, 0xf5, 0x39, 0x30, 0x6b, 0xc5, 0x02, 0x6a, 0xff, 0xdb, 0x7a, 0x76, 0xb0, - 0xe7, 0xb8, 0x13, 0x2e, 0x88, 0x90, 0x0b, 0x15, 0x66, 0xd6, 0x73, 0xd1, 0x70, 0xed, 0x68, 0xcb, - 0x88, 0xaa, 0x01, 0x45, 0x7a, 0xba, 0x46, 0xbf, 0x1a, 0x6d, 0xc2, 0x8c, 0x05, 0xda, 0x86, 0x5a, - 0x43, 0x5a, 0xdb, 0xa5, 0x22, 0xfc, 0x52, 0xc2, 0xd6, 0xd6, 0x1c, 0x87, 0xa9, 0xbc, 0x56, 0x26, - 0xba, 0xe2, 0x86, 0x08, 0x94, 0x5b, 0x6e, 0x22, 0x3e, 0xeb, 0x11, 0xf7, 0x53, 0x73, 0xae, 0xf1, - 0x8a, 0x83, 0x54, 0x89, 0xcc, 0xb9, 0x09, 0xa6, 0xf4, 0xd1, 0x4f, 0x5b, 0x30, 0x14, 0x37, 0xda, - 0xcb, 0x51, 0xb0, 0xe5, 0x36, 0x49, 0x24, 0xac, 0xa9, 0x23, 0x8a, 0xa6, 0x95, 0x99, 0x45, 0x49, - 0x50, 0xf3, 0xe5, 0xfb, 0x5b, 0x0d, 0xc1, 0x26, 0x5f, 0xba, 0xcb, 0x78, 0x54, 0xbc, 0xfb, 0x2c, - 0x69, 0xb8, 0x54, 0xff, 0xc9, 0x4d, 0x15, 0x9b, 0x29, 0x47, 0xb6, 0x2e, 0x67, 0x3b, 0x8d, 0x4d, - 0xba, 0xde, 0x74, 0x87, 0xde, 0x79, 0x77, 0x77, 0xfc, 0xd1, 0x99, 0x7c, 0x9e, 0xb8, 0x57, 0x67, - 0xd8, 0x80, 0x85, 0x1d, 0xcf, 0xc3, 0xe4, 0xf5, 0x0e, 0x61, 0x2e, 0x93, 0x02, 0x06, 0x6c, 0x59, - 0x13, 0xcc, 0x0c, 0x98, 0x01, 0xc1, 0x26, 0x5f, 0xf4, 0x3a, 0x0c, 0xb4, 0x9d, 0x24, 0x72, 0xb7, - 0x85, 0x9f, 0xe4, 0x88, 0xf6, 0xfe, 0x22, 0xa3, 0xa5, 0x99, 0x33, 0x4d, 0xcd, 0x1b, 0xb1, 0x60, - 0x84, 0xda, 0x50, 0x6d, 0x93, 0xa8, 0x45, 0xc6, 0x6a, 0x45, 0xf8, 0x84, 0x17, 0x29, 0x29, 0xcd, - 0xb0, 0x4e, 0xad, 0x23, 0xd6, 0x86, 0x39, 0x17, 0xf4, 0x2a, 0xd4, 0x62, 0xe2, 0x91, 0x06, 0xb5, - 0x6f, 0xea, 0x8c, 0xe3, 0x7b, 0xfa, 0xb4, 0xf5, 0xa8, 0x61, 0xb1, 0x22, 0x1e, 0xe5, 0x0b, 0x4c, - 0xfe, 0xc3, 0x8a, 0x24, 0x1d, 0xc0, 0xd0, 0xeb, 0xb4, 0x5c, 0x7f, 0x0c, 0x8a, 0x18, 0xc0, 0x65, - 0x46, 0x2b, 0x33, 0x80, 0xbc, 0x11, 0x0b, 0x46, 0xf6, 0x9f, 0x58, 0x80, 0xd2, 0x42, 0xed, 0x3e, - 0x18, 0xb5, 0xaf, 0xa7, 0x8d, 0xda, 0x85, 0x22, 0xad, 0x8e, 0x1e, 0x76, 0xed, 0x6f, 0xd4, 0x21, - 0xa3, 0x0e, 0xae, 0x93, 0x38, 0x21, 0xcd, 0xb7, 0x45, 0xf8, 0xdb, 0x22, 0xfc, 0x6d, 0x11, 0xae, - 0x44, 0xf8, 0x5a, 0x46, 0x84, 0xbf, 0xdf, 0x58, 0xf5, 0xfa, 0x50, 0xf5, 0x35, 0x75, 0xea, 0x6a, - 0xf6, 0xc0, 0x40, 0xa0, 0x92, 0xe0, 0xea, 0xca, 0xd2, 0xf5, 0x5c, 0x99, 0xfd, 0x5a, 0x5a, 0x66, - 0x1f, 0x95, 0xc5, 0xff, 0x0b, 0x52, 0xfa, 0x5f, 0x5a, 0xf0, 0xae, 0xb4, 0xf4, 0x92, 0x33, 0x67, - 0xbe, 0xe5, 0x07, 0x11, 0x99, 0x75, 0xd7, 0xd7, 0x49, 0x44, 0xfc, 0x06, 0x89, 0x95, 0x17, 0xc3, - 0xea, 0xe5, 0xc5, 0x40, 0xcf, 0xc3, 0xf0, 0xed, 0x38, 0xf0, 0x97, 0x03, 0xd7, 0x17, 0x22, 0x88, - 0x6e, 0x84, 0x4f, 0xde, 0xdd, 0x1d, 0x1f, 0xa6, 0x23, 0x2a, 0xdb, 0x71, 0x0a, 0x0b, 0xcd, 0xc0, - 0xa9, 0xdb, 0xaf, 0x2f, 0x3b, 0x89, 0xe1, 0x0e, 0x90, 0x1b, 0x77, 0x76, 0x60, 0x71, 0xf5, 0xe5, - 0x0c, 0x10, 0x77, 0xe3, 0xdb, 0x7f, 0xa3, 0x04, 0xe7, 0x32, 0x2f, 0x12, 0x78, 0x5e, 0xd0, 0x49, - 0xe8, 0xa6, 0x06, 0xfd, 0x82, 0x05, 0x27, 0xdb, 0x69, 0x8f, 0x43, 0x2c, 0x1c, 0xbb, 0x1f, 0x2c, - 0x4c, 0x47, 0x64, 0x5c, 0x1a, 0xd3, 0x63, 0x62, 0x84, 0x4e, 0x66, 0x00, 0x31, 0xee, 0xea, 0x0b, - 0x7a, 0x15, 0xea, 0x6d, 0x67, 0xfb, 0x46, 0xd8, 0x74, 0x12, 0xb9, 0x9f, 0xec, 0xed, 0x06, 0xe8, - 0x24, 0xae, 0x37, 0xc1, 0x8f, 0xeb, 0x27, 0xe6, 0xfd, 0x64, 0x29, 0x5a, 0x49, 0x22, 0xd7, 0x6f, - 0x71, 0x77, 0xde, 0xa2, 0x24, 0x83, 0x35, 0x45, 0xfb, 0xab, 0x56, 0x56, 0x49, 0xa9, 0xd1, 0x89, - 0x9c, 0x84, 0xb4, 0x76, 0xd0, 0xc7, 0xa0, 0x4a, 0x37, 0x7e, 0x72, 0x54, 0x6e, 0x15, 0xa9, 0x39, - 0x8d, 0x2f, 0xa1, 0x95, 0x28, 0xfd, 0x17, 0x63, 0xce, 0xd4, 0xfe, 0x93, 0x5a, 0xd6, 0x58, 0x60, - 0x87, 0xb7, 0x17, 0x01, 0x5a, 0xc1, 0x2a, 0x69, 0x87, 0x1e, 0x1d, 0x16, 0x8b, 0x9d, 0x00, 0x28, - 0x5f, 0xc7, 0x9c, 0x82, 0x60, 0x03, 0x0b, 0xfd, 0x25, 0x0b, 0xa0, 0x25, 0xe7, 0xbc, 0x34, 0x04, - 0x6e, 0x14, 0xf9, 0x3a, 0x7a, 0x45, 0xe9, 0xbe, 0x28, 0x86, 0xd8, 0x60, 0x8e, 0x7e, 0xca, 0x82, - 0x5a, 0x22, 0xbb, 0xcf, 0x55, 0xe3, 0x6a, 0x91, 0x3d, 0x91, 0x2f, 0xad, 0x6d, 0x22, 0x35, 0x24, - 0x8a, 0x2f, 0xfa, 0x19, 0x0b, 0x20, 0xde, 0xf1, 0x1b, 0xcb, 0x81, 0xe7, 0x36, 0x76, 0x84, 0xc6, - 0xbc, 0x59, 0xa8, 0x3f, 0x46, 0x51, 0x9f, 0x1e, 0xa5, 0xa3, 0xa1, 0xff, 0x63, 0x83, 0x33, 0xfa, - 0x04, 0xd4, 0x62, 0x31, 0xdd, 0x84, 0x8e, 0x5c, 0x2d, 0xd6, 0x2b, 0xc4, 0x69, 0x0b, 0xf1, 0x2a, - 0xfe, 0x61, 0xc5, 0x13, 0xfd, 0x9c, 0x05, 0x27, 0xc2, 0xb4, 0x9f, 0x4f, 0xa8, 0xc3, 0xe2, 0x64, - 0x40, 0xc6, 0x8f, 0x38, 0x7d, 0xfa, 0xee, 0xee, 0xf8, 0x89, 0x4c, 0x23, 0xce, 0xf6, 0x82, 0x4a, - 0x40, 0x3d, 0x83, 0x97, 0x42, 0xee, 0x73, 0x1c, 0xd4, 0x12, 0x70, 0x2e, 0x0b, 0xc4, 0xdd, 0xf8, - 0x68, 0x19, 0xce, 0xd0, 0xde, 0xed, 0x70, 0xf3, 0x53, 0xaa, 0x97, 0x98, 0x29, 0xc3, 0xda, 0xf4, - 0x63, 0x62, 0x86, 0x30, 0xaf, 0x7e, 0x16, 0x07, 0xe7, 0x3e, 0x89, 0x7e, 0xd7, 0x82, 0xc7, 0x5c, - 0xa6, 0x06, 0x4c, 0x87, 0xb9, 0xd6, 0x08, 0xe2, 0x24, 0x96, 0x14, 0x2a, 0x2b, 0x7a, 0xa9, 0x9f, - 0xe9, 0xff, 0x4f, 0xbc, 0xc1, 0x63, 0xf3, 0x7b, 0x74, 0x09, 0xef, 0xd9, 0x61, 0xfb, 0x5b, 0xa5, - 0xd4, 0xb1, 0x86, 0xf2, 0x25, 0x32, 0xa9, 0xd1, 0x90, 0x6e, 0x1c, 0x29, 0x04, 0x0b, 0x95, 0x1a, - 0xca, 0x49, 0xa4, 0xa5, 0x86, 0x6a, 0x8a, 0xb1, 0xc1, 0x9c, 0xda, 0x96, 0xa7, 0x9c, 0xac, 0xc7, - 0x52, 0x08, 0xb2, 0x57, 0x8b, 0xec, 0x52, 0xf7, 0x21, 0xd4, 0x39, 0xd1, 0xb5, 0x53, 0x5d, 0x20, - 0xdc, 0xdd, 0x25, 0xfb, 0x5b, 0xe9, 0xa3, 0x14, 0x63, 0x0d, 0xf6, 0x71, 0x4c, 0xf4, 0x45, 0x0b, - 0x86, 0xa2, 0xc0, 0xf3, 0x5c, 0xbf, 0x45, 0xe5, 0x85, 0x50, 0x7a, 0x1f, 0x3e, 0x16, 0xbd, 0x23, - 0x04, 0x03, 0xb3, 0x50, 0xb1, 0xe6, 0x89, 0xcd, 0x0e, 0xd8, 0x7f, 0x6c, 0xc1, 0x58, 0x2f, 0xb9, - 0x86, 0x08, 0xbc, 0x53, 0x2e, 0x5a, 0x15, 0x24, 0xb1, 0xe4, 0xcf, 0x12, 0x8f, 0x28, 0xff, 0x71, - 0x6d, 0xfa, 0x49, 0xf1, 0x9a, 0xef, 0x5c, 0xee, 0x8d, 0x8a, 0xf7, 0xa2, 0x83, 0x5e, 0x81, 0x93, - 0xc6, 0x7b, 0xc5, 0x6a, 0x60, 0xea, 0xd3, 0x13, 0xd4, 0x90, 0x98, 0xca, 0xc0, 0xee, 0xed, 0x8e, - 0x3f, 0x92, 0x6d, 0x13, 0x82, 0xb7, 0x8b, 0x8e, 0xfd, 0xcb, 0xa5, 0xec, 0xd7, 0x52, 0x3a, 0xf3, - 0x2d, 0xab, 0x6b, 0x57, 0xfe, 0xc1, 0xe3, 0xd0, 0x53, 0x6c, 0xff, 0xae, 0xe2, 0x30, 0x7a, 0xe3, - 0x3c, 0xc0, 0x83, 0x5e, 0xfb, 0x5f, 0x57, 0x60, 0x8f, 0x9e, 0xf5, 0x61, 0x04, 0x1f, 0xf8, 0x74, - 0xf0, 0xf3, 0x96, 0x3a, 0x39, 0x2a, 0xb3, 0x45, 0xde, 0x3c, 0xae, 0xb1, 0xe7, 0xfb, 0x90, 0x98, - 0x07, 0x1b, 0x28, 0x6f, 0x74, 0xfa, 0x8c, 0x0a, 0x7d, 0xcd, 0x4a, 0x9f, 0x7d, 0xf1, 0xe8, 0x31, - 0xf7, 0xd8, 0xfa, 0x64, 0x1c, 0xa8, 0xf1, 0x8e, 0xe9, 0x63, 0x98, 0x5e, 0x47, 0x6d, 0x13, 0x00, - 0xeb, 0xae, 0xef, 0x78, 0xee, 0x1b, 0x74, 0x97, 0x51, 0x65, 0x8a, 0x92, 0x59, 0x1e, 0x97, 0x55, - 0x2b, 0x36, 0x30, 0xce, 0xff, 0x45, 0x18, 0x32, 0xde, 0x3c, 0x27, 0x46, 0xe2, 0x8c, 0x19, 0x23, - 0x51, 0x37, 0x42, 0x1b, 0xce, 0xbf, 0x1f, 0x4e, 0x66, 0x3b, 0x78, 0x90, 0xe7, 0xed, 0xff, 0x39, - 0x98, 0x3d, 0x8c, 0x5a, 0x25, 0x51, 0x9b, 0x76, 0xed, 0x6d, 0x07, 0xd1, 0xdb, 0x0e, 0xa2, 0xb7, - 0x1d, 0x44, 0xa6, 0x8f, 0x5f, 0x38, 0x3f, 0x06, 0xef, 0x93, 0xf3, 0x23, 0xe5, 0xce, 0xa9, 0x15, - 0xee, 0xce, 0xb1, 0xef, 0x56, 0x21, 0x65, 0x47, 0xf1, 0xf1, 0xfe, 0x21, 0x18, 0x8c, 0x48, 0x18, - 0xdc, 0xc0, 0x0b, 0x42, 0x87, 0xe8, 0x38, 0x78, 0xde, 0x8c, 0x25, 0x9c, 0xea, 0x9a, 0xd0, 0x49, - 0x36, 0x84, 0x12, 0x51, 0xba, 0x66, 0xd9, 0x49, 0x36, 0x30, 0x83, 0xa0, 0xf7, 0xc3, 0x68, 0xe2, - 0x44, 0x2d, 0x6a, 0x36, 0x6f, 0xb1, 0xcf, 0x2a, 0x8e, 0x2c, 0x1f, 0x11, 0xb8, 0xa3, 0xab, 0x29, - 0x28, 0xce, 0x60, 0xa3, 0xd7, 0xa1, 0xb2, 0x41, 0xbc, 0xb6, 0x18, 0xf2, 0x95, 0xe2, 0x64, 0x3c, - 0x7b, 0xd7, 0x2b, 0xc4, 0x6b, 0x73, 0x09, 0x44, 0x7f, 0x61, 0xc6, 0x8a, 0xce, 0xb7, 0xfa, 0x66, - 0x27, 0x4e, 0x82, 0xb6, 0xfb, 0x86, 0xf4, 0xd4, 0x7d, 0xb0, 0x60, 0xc6, 0xd7, 0x24, 0x7d, 0xee, - 0x12, 0x51, 0x7f, 0xb1, 0xe6, 0xcc, 0xfa, 0xd1, 0x74, 0x23, 0xf6, 0xa9, 0x76, 0x84, 0xc3, 0xad, - 0xe8, 0x7e, 0xcc, 0x4a, 0xfa, 0xbc, 0x1f, 0xea, 0x2f, 0xd6, 0x9c, 0xd1, 0x8e, 0x9a, 0xf7, 0x43, - 0xac, 0x0f, 0x37, 0x0a, 0xee, 0x03, 0x9f, 0xf3, 0xb9, 0xf3, 0xff, 0x49, 0xa8, 0x36, 0x36, 0x9c, - 0x28, 0x19, 0x1b, 0x66, 0x93, 0x46, 0xb9, 0x66, 0x66, 0x68, 0x23, 0xe6, 0x30, 0xf4, 0x38, 0x94, - 0x23, 0xb2, 0xce, 0xc2, 0x2f, 0x8d, 0xc0, 0x1c, 0x4c, 0xd6, 0x31, 0x6d, 0xb7, 0x7f, 0xb1, 0x94, - 0x36, 0x97, 0xd2, 0xef, 0xcd, 0x67, 0x7b, 0xa3, 0x13, 0xc5, 0xd2, 0x7d, 0x63, 0xcc, 0x76, 0xd6, - 0x8c, 0x25, 0x1c, 0x7d, 0xca, 0x82, 0xc1, 0xdb, 0x71, 0xe0, 0xfb, 0x24, 0x11, 0xaa, 0xe9, 0x66, - 0xc1, 0x43, 0x71, 0x95, 0x53, 0xd7, 0x7d, 0x10, 0x0d, 0x58, 0xf2, 0xa5, 0xdd, 0x25, 0xdb, 0x0d, - 0xaf, 0xd3, 0xec, 0x8a, 0xb5, 0xb8, 0xc4, 0x9b, 0xb1, 0x84, 0x53, 0x54, 0xd7, 0xe7, 0xa8, 0x95, - 0x34, 0xea, 0xbc, 0x2f, 0x50, 0x05, 0xdc, 0xfe, 0x6b, 0x03, 0x70, 0x36, 0x77, 0x71, 0x50, 0x43, - 0x86, 0x99, 0x0a, 0x97, 0x5d, 0x8f, 0xc8, 0x28, 0x23, 0x66, 0xc8, 0xdc, 0x54, 0xad, 0xd8, 0xc0, - 0x40, 0x3f, 0x09, 0x10, 0x3a, 0x91, 0xd3, 0x26, 0xca, 0xbd, 0x7a, 0x64, 0x7b, 0x81, 0xf6, 0x63, - 0x59, 0xd2, 0xd4, 0x7b, 0x53, 0xd5, 0x14, 0x63, 0x83, 0x25, 0x7a, 0x01, 0x86, 0x22, 0xe2, 0x11, - 0x27, 0x66, 0xd1, 0xbb, 0xd9, 0x54, 0x04, 0xac, 0x41, 0xd8, 0xc4, 0x43, 0x4f, 0xa9, 0x80, 0xac, - 0x4c, 0x60, 0x4a, 0x3a, 0x28, 0x0b, 0xbd, 0x69, 0xc1, 0xe8, 0xba, 0xeb, 0x11, 0xcd, 0x5d, 0x24, - 0x0e, 0x2c, 0x1d, 0xfd, 0x25, 0x2f, 0x9b, 0x74, 0xb5, 0x84, 0x4c, 0x35, 0xc7, 0x38, 0xc3, 0x9e, - 0x7e, 0xe6, 0x2d, 0x12, 0x31, 0xd1, 0x3a, 0x90, 0xfe, 0xcc, 0x37, 0x79, 0x33, 0x96, 0x70, 0x34, - 0x05, 0x27, 0x42, 0x27, 0x8e, 0x67, 0x22, 0xd2, 0x24, 0x7e, 0xe2, 0x3a, 0x1e, 0x0f, 0xeb, 0xaf, - 0xe9, 0xb0, 0xde, 0xe5, 0x34, 0x18, 0x67, 0xf1, 0xd1, 0x87, 0xe0, 0x51, 0xee, 0xbf, 0x58, 0x74, - 0xe3, 0xd8, 0xf5, 0x5b, 0x7a, 0x1a, 0x08, 0x37, 0xce, 0xb8, 0x20, 0xf5, 0xe8, 0x7c, 0x3e, 0x1a, - 0xee, 0xf5, 0x3c, 0x7a, 0x06, 0x6a, 0xf1, 0xa6, 0x1b, 0xce, 0x44, 0xcd, 0x98, 0x9d, 0x5d, 0xd4, - 0xb4, 0xd3, 0x70, 0x45, 0xb4, 0x63, 0x85, 0x81, 0x1a, 0x30, 0xcc, 0x3f, 0x09, 0x8f, 0x28, 0x13, - 0xf2, 0xf1, 0xd9, 0x9e, 0xea, 0x51, 0x64, 0x9e, 0x4d, 0x60, 0xe7, 0xce, 0x25, 0x79, 0x92, 0xc2, - 0x1d, 0xff, 0x37, 0x0d, 0x32, 0x38, 0x45, 0xd4, 0xfe, 0xf9, 0x52, 0x7a, 0xc7, 0x6d, 0x2e, 0x52, - 0x14, 0xd3, 0xa5, 0x98, 0xdc, 0x74, 0x22, 0xe9, 0x8d, 0x39, 0x62, 0xf6, 0x81, 0xa0, 0x7b, 0xd3, - 0x89, 0xcc, 0x45, 0xcd, 0x18, 0x60, 0xc9, 0x09, 0xdd, 0x86, 0x4a, 0xe2, 0x39, 0x05, 0xa5, 0x2b, - 0x19, 0x1c, 0xb5, 0x03, 0x64, 0x61, 0x2a, 0xc6, 0x8c, 0x07, 0x7a, 0x8c, 0x5a, 0xfd, 0x6b, 0xf2, - 0xa4, 0x43, 0x18, 0xea, 0x6b, 0x31, 0x66, 0xad, 0xf6, 0xaf, 0x40, 0x8e, 0x5c, 0x55, 0x8a, 0x0c, - 0x5d, 0x04, 0xa0, 0x1b, 0xc8, 0xe5, 0x88, 0xac, 0xbb, 0xdb, 0xc2, 0x90, 0x50, 0x6b, 0xf7, 0xba, - 0x82, 0x60, 0x03, 0x4b, 0x3e, 0xb3, 0xd2, 0x59, 0xa7, 0xcf, 0x94, 0xba, 0x9f, 0xe1, 0x10, 0x6c, - 0x60, 0xa1, 0xe7, 0x61, 0xc0, 0x6d, 0x3b, 0x2d, 0x15, 0x49, 0xf9, 0x18, 0x5d, 0xb4, 0xf3, 0xac, - 0xe5, 0xde, 0xee, 0xf8, 0xa8, 0xea, 0x10, 0x6b, 0xc2, 0x02, 0x17, 0xfd, 0xb2, 0x05, 0xc3, 0x8d, - 0xa0, 0xdd, 0x0e, 0x7c, 0xbe, 0xed, 0x12, 0x7b, 0xc8, 0xdb, 0xc7, 0xa5, 0xe6, 0x27, 0x66, 0x0c, - 0x66, 0x7c, 0x13, 0xa9, 0xf2, 0xaa, 0x4c, 0x10, 0x4e, 0xf5, 0xca, 0x5c, 0xdb, 0xd5, 0x7d, 0xd6, - 0xf6, 0xaf, 0x5b, 0x70, 0x8a, 0x3f, 0x6b, 0xec, 0x06, 0x45, 0x0a, 0x51, 0x70, 0xcc, 0xaf, 0xd5, - 0xb5, 0x41, 0x56, 0x5e, 0xba, 0x2e, 0x38, 0xee, 0xee, 0x24, 0x9a, 0x83, 0x53, 0xeb, 0x41, 0xd4, - 0x20, 0xe6, 0x40, 0x08, 0xc1, 0xa4, 0x08, 0x5d, 0xce, 0x22, 0xe0, 0xee, 0x67, 0xd0, 0x4d, 0x78, - 0xc4, 0x68, 0x34, 0xc7, 0x81, 0xcb, 0xa6, 0x27, 0x04, 0xb5, 0x47, 0x2e, 0xe7, 0x62, 0xe1, 0x1e, - 0x4f, 0xa7, 0x1d, 0x26, 0xf5, 0x3e, 0x1c, 0x26, 0xaf, 0xc1, 0xb9, 0x46, 0xf7, 0xc8, 0x6c, 0xc5, - 0x9d, 0xb5, 0x98, 0x4b, 0xaa, 0xda, 0xf4, 0x0f, 0x08, 0x02, 0xe7, 0x66, 0x7a, 0x21, 0xe2, 0xde, - 0x34, 0xd0, 0xc7, 0xa0, 0x16, 0x11, 0xf6, 0x55, 0x62, 0x91, 0x4f, 0x73, 0xc4, 0x5d, 0xb2, 0xb6, - 0x40, 0x39, 0x59, 0x2d, 0x7b, 0x45, 0x43, 0x8c, 0x15, 0x47, 0x74, 0x07, 0x06, 0x43, 0x27, 0x69, - 0x6c, 0x88, 0x2c, 0x9a, 0x23, 0x87, 0xb1, 0x28, 0xe6, 0xcb, 0x94, 0xaa, 0x9e, 0xe4, 0xcb, 0x9c, - 0x09, 0x96, 0xdc, 0xa8, 0x35, 0xd2, 0x08, 0xda, 0x61, 0xe0, 0x13, 0x3f, 0x89, 0xc7, 0x46, 0xb4, - 0x35, 0x32, 0xa3, 0x5a, 0xb1, 0x81, 0x71, 0xfe, 0x03, 0x70, 0xaa, 0x6b, 0xe1, 0x1d, 0xc8, 0xb9, - 0x32, 0x0b, 0x8f, 0xe4, 0x4f, 0xf1, 0x03, 0xb9, 0x58, 0xfe, 0x51, 0x26, 0x56, 0xd5, 0x30, 0x7b, - 0xfb, 0x70, 0xd7, 0x39, 0x50, 0x26, 0xfe, 0x96, 0x90, 0xf8, 0x97, 0x8f, 0x36, 0xd2, 0x97, 0xfc, - 0x2d, 0xbe, 0x42, 0x99, 0x4f, 0xe2, 0x92, 0xbf, 0x85, 0x29, 0x6d, 0xf4, 0x65, 0x2b, 0x65, 0xb6, - 0x71, 0x27, 0xdf, 0x47, 0x8e, 0xc5, 0xce, 0xef, 0xdb, 0x92, 0xb3, 0xff, 0x4d, 0x09, 0x2e, 0xec, - 0x47, 0xa4, 0x8f, 0xe1, 0x7b, 0x12, 0x06, 0x62, 0x76, 0xfa, 0x2c, 0x44, 0xe8, 0x10, 0x9d, 0x59, - 0xfc, 0x3c, 0xfa, 0x35, 0x2c, 0x40, 0xc8, 0x83, 0x72, 0xdb, 0x09, 0x85, 0xef, 0x67, 0xfe, 0xa8, - 0xd9, 0x2b, 0xf4, 0xbf, 0xe3, 0x2d, 0x3a, 0x21, 0xf7, 0x28, 0x18, 0x0d, 0x98, 0xb2, 0x41, 0x09, - 0x54, 0x9d, 0x28, 0x72, 0xe4, 0x51, 0xe7, 0xb5, 0x62, 0xf8, 0x4d, 0x51, 0x92, 0xd3, 0xa7, 0xee, - 0xee, 0x8e, 0x8f, 0xa4, 0x9a, 0x30, 0x67, 0x66, 0x7f, 0x7e, 0x30, 0x95, 0xc1, 0xc1, 0xce, 0xaf, - 0x63, 0x18, 0x10, 0x2e, 0x1f, 0xab, 0xe8, 0xa4, 0x21, 0x9e, 0x82, 0xc7, 0x76, 0x75, 0x22, 0x91, - 0x59, 0xb0, 0x42, 0x9f, 0xb3, 0x58, 0xba, 0xb0, 0xcc, 0x6a, 0x11, 0x7b, 0xa9, 0xe3, 0xc9, 0x5e, - 0x36, 0x93, 0x90, 0x65, 0x23, 0x36, 0xb9, 0x53, 0x1d, 0x1b, 0xf2, 0xc4, 0xb7, 0xec, 0x8e, 0x4a, - 0x26, 0x14, 0x4b, 0x38, 0xda, 0xce, 0x39, 0xa7, 0x2e, 0x20, 0xe5, 0xb4, 0x8f, 0x93, 0xe9, 0xaf, - 0x59, 0x70, 0xca, 0xcd, 0x1e, 0x38, 0x8a, 0x9d, 0xc7, 0x11, 0x23, 0x21, 0x7a, 0x9f, 0x67, 0x2a, - 0xe5, 0xdb, 0x05, 0xc2, 0xdd, 0x9d, 0x41, 0x4d, 0xa8, 0xb8, 0xfe, 0x7a, 0x20, 0x4c, 0x8e, 0xe9, - 0xa3, 0x75, 0x6a, 0xde, 0x5f, 0x0f, 0xf4, 0x6a, 0xa6, 0xff, 0x30, 0xa3, 0x8e, 0x16, 0xe0, 0x4c, - 0x24, 0x7c, 0x43, 0x57, 0xdc, 0x98, 0xee, 0xe0, 0x17, 0xdc, 0xb6, 0x9b, 0x30, 0x73, 0xa1, 0x3c, - 0x3d, 0x76, 0x77, 0x77, 0xfc, 0x0c, 0xce, 0x81, 0xe3, 0xdc, 0xa7, 0xd0, 0x1b, 0x30, 0x28, 0xf3, - 0x9b, 0x6b, 0x45, 0xec, 0xe2, 0xba, 0xe7, 0xbf, 0x9a, 0x4c, 0x2b, 0x22, 0x95, 0x59, 0x32, 0xb4, - 0xdf, 0x1c, 0x82, 0xee, 0x43, 0x4c, 0xf4, 0x71, 0xa8, 0x47, 0x2a, 0xe7, 0xda, 0x2a, 0x42, 0xb9, - 0xca, 0xef, 0x2b, 0x0e, 0x50, 0x95, 0xe1, 0xa2, 0xb3, 0xab, 0x35, 0x47, 0xba, 0xbd, 0x88, 0xf5, - 0x59, 0x67, 0x01, 0x73, 0x5b, 0x70, 0xd5, 0xe7, 0x58, 0x3b, 0x7e, 0x03, 0x33, 0x1e, 0x28, 0x82, - 0x81, 0x0d, 0xe2, 0x78, 0xc9, 0x46, 0x31, 0x2e, 0xf7, 0x2b, 0x8c, 0x56, 0x36, 0xf3, 0x86, 0xb7, - 0x62, 0xc1, 0x09, 0x6d, 0xc3, 0xe0, 0x06, 0x9f, 0x00, 0xc2, 0xe2, 0x5f, 0x3c, 0xea, 0xe0, 0xa6, - 0x66, 0x95, 0xfe, 0xdc, 0xa2, 0x01, 0x4b, 0x76, 0x2c, 0xc8, 0xc5, 0x38, 0xbf, 0xe7, 0x4b, 0xb7, - 0xb8, 0xa4, 0xa3, 0xfe, 0x0f, 0xef, 0x3f, 0x0a, 0xc3, 0x11, 0x69, 0x04, 0x7e, 0xc3, 0xf5, 0x48, - 0x73, 0x4a, 0xba, 0xd3, 0x0f, 0x92, 0xaa, 0xc2, 0x76, 0xcd, 0xd8, 0xa0, 0x81, 0x53, 0x14, 0xd1, - 0x67, 0x2d, 0x18, 0x55, 0x89, 0x9a, 0xf4, 0x83, 0x10, 0xe1, 0xbe, 0x5d, 0x28, 0x28, 0x2d, 0x94, - 0xd1, 0x9c, 0x46, 0x77, 0x77, 0xc7, 0x47, 0xd3, 0x6d, 0x38, 0xc3, 0x17, 0xbd, 0x02, 0x10, 0xac, - 0xf1, 0x48, 0x96, 0xa9, 0x44, 0xf8, 0x72, 0x0f, 0xf2, 0xaa, 0xa3, 0x3c, 0x67, 0x4d, 0x52, 0xc0, - 0x06, 0x35, 0x74, 0x0d, 0x80, 0x2f, 0x9b, 0xd5, 0x9d, 0x50, 0x6e, 0x0b, 0x64, 0xae, 0x11, 0xac, - 0x28, 0xc8, 0xbd, 0xdd, 0xf1, 0x6e, 0xdf, 0x1a, 0x0b, 0x33, 0x30, 0x1e, 0x47, 0x3f, 0x01, 0x83, - 0x71, 0xa7, 0xdd, 0x76, 0x94, 0xa7, 0xb7, 0xc0, 0x2c, 0x38, 0x4e, 0xd7, 0x10, 0x45, 0xbc, 0x01, - 0x4b, 0x8e, 0xe8, 0x36, 0x15, 0xaa, 0xb1, 0x70, 0xfa, 0xb1, 0x55, 0xc4, 0x6d, 0x82, 0x21, 0xf6, - 0x4e, 0xef, 0x95, 0x81, 0x39, 0x38, 0x07, 0xe7, 0xde, 0xee, 0xf8, 0x23, 0xe9, 0xf6, 0x85, 0x40, - 0xe4, 0xa5, 0xe5, 0xd2, 0x44, 0x57, 0x65, 0xb9, 0x13, 0xfa, 0xda, 0x32, 0x0b, 0xff, 0x69, 0x5d, - 0xee, 0x84, 0x35, 0xf7, 0x1e, 0x33, 0xf3, 0x61, 0xb4, 0x08, 0xa7, 0x1b, 0x81, 0x9f, 0x44, 0x81, - 0xe7, 0xf1, 0x1a, 0x3e, 0x7c, 0x87, 0xc6, 0x3d, 0xc1, 0xef, 0x14, 0xdd, 0x3e, 0x3d, 0xd3, 0x8d, - 0x82, 0xf3, 0x9e, 0xb3, 0xfd, 0x74, 0x88, 0x9f, 0x18, 0x9c, 0xe7, 0x61, 0x98, 0x6c, 0x27, 0x24, - 0xf2, 0x1d, 0xef, 0x06, 0x5e, 0x90, 0x3e, 0x50, 0xb6, 0x06, 0x2e, 0x19, 0xed, 0x38, 0x85, 0x85, - 0x6c, 0xe5, 0x96, 0x30, 0x72, 0x2d, 0xb9, 0x5b, 0x42, 0x3a, 0x21, 0xec, 0xff, 0x55, 0x4a, 0x19, - 0x64, 0xab, 0x11, 0x21, 0x28, 0x80, 0xaa, 0x1f, 0x34, 0x95, 0xec, 0xbf, 0x5a, 0x8c, 0xec, 0xbf, - 0x1e, 0x34, 0x8d, 0x9a, 0x28, 0xf4, 0x5f, 0x8c, 0x39, 0x1f, 0x56, 0x34, 0x42, 0x56, 0xd7, 0x60, - 0x00, 0xb1, 0xd1, 0x28, 0x92, 0xb3, 0x2a, 0x1a, 0xb1, 0x64, 0x32, 0xc2, 0x69, 0xbe, 0x68, 0x13, - 0xaa, 0x1b, 0x41, 0x9c, 0xc8, 0xed, 0xc7, 0x11, 0x77, 0x3a, 0x57, 0x82, 0x38, 0x61, 0x56, 0x84, - 0x7a, 0x6d, 0xda, 0x12, 0x63, 0xce, 0xc3, 0xfe, 0xcf, 0x56, 0xca, 0xe3, 0x7d, 0x8b, 0x85, 0xbb, - 0x6e, 0x11, 0x9f, 0x2e, 0x6b, 0x33, 0x30, 0xe8, 0x2f, 0x64, 0x92, 0x07, 0xdf, 0xd5, 0xab, 0x42, - 0xd5, 0x1d, 0x4a, 0x61, 0x82, 0x91, 0x30, 0x62, 0x88, 0x3e, 0x69, 0xa5, 0xd3, 0x38, 0x4b, 0x45, - 0x6c, 0x30, 0xcc, 0x54, 0xe6, 0x7d, 0x33, 0x42, 0xed, 0x2f, 0x5b, 0x30, 0x38, 0xed, 0x34, 0x36, - 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0xcc, 0x28, 0x55, 0xdb, 0xfc, 0x59, 0xd1, - 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x26, 0x34, 0x97, 0xf9, 0x1c, 0xbe, 0xcc, 0x5a, - 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xa8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, 0xf6, 0x45, 0x0d, 0xc2, - 0x26, 0x9e, 0xfd, 0x2f, 0x2c, 0x18, 0x9b, 0x76, 0x62, 0xb7, 0x31, 0xd5, 0x49, 0x36, 0xa6, 0xdd, - 0x64, 0xad, 0xd3, 0xd8, 0x24, 0x09, 0xcf, 0x62, 0xa7, 0xbd, 0xec, 0xc4, 0x74, 0x29, 0xa9, 0x7d, - 0x9d, 0xea, 0xe5, 0x0d, 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, 0x27, 0x8e, 0xef, 0x04, - 0x51, 0x13, 0x93, 0xf5, 0x62, 0x6a, 0x48, 0xac, 0x90, 0x46, 0x44, 0x12, 0x4c, 0xd6, 0xc5, 0x91, - 0xb0, 0xa6, 0x8f, 0x4d, 0x66, 0xf6, 0x17, 0x2d, 0x38, 0x37, 0x4d, 0x9c, 0x88, 0x44, 0xac, 0xe4, - 0x84, 0x7a, 0x91, 0x19, 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, 0x33, 0xed, 0x96, 0x55, - 0x6c, 0xb7, 0xd8, 0x89, 0xee, 0xaa, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, 0x5b, 0x30, 0xcc, 0x0e, - 0xc7, 0x66, 0x49, 0xe2, 0xb8, 0x5e, 0x57, 0x65, 0x26, 0xab, 0xcf, 0xca, 0x4c, 0x17, 0xa0, 0xb2, - 0x11, 0xb4, 0x49, 0xf6, 0x60, 0xf7, 0x4a, 0x40, 0xb7, 0xd5, 0x14, 0x82, 0x9e, 0xa3, 0x1f, 0xde, - 0xf5, 0x13, 0x87, 0x2e, 0x01, 0xe9, 0x7c, 0x3d, 0xc1, 0x3f, 0xba, 0x6a, 0xc6, 0x26, 0x8e, 0xfd, - 0x5b, 0x75, 0x18, 0x14, 0xa7, 0xff, 0x7d, 0x57, 0x32, 0x90, 0xfb, 0xfb, 0x52, 0xcf, 0xfd, 0x7d, - 0x0c, 0x03, 0x0d, 0x56, 0xf7, 0x4d, 0x98, 0x91, 0xd7, 0x0a, 0x09, 0x17, 0xe1, 0xa5, 0xe4, 0x74, - 0xb7, 0xf8, 0x7f, 0x2c, 0x58, 0xa1, 0x2f, 0x59, 0x70, 0xa2, 0x11, 0xf8, 0x3e, 0x69, 0x68, 0x1b, - 0xa7, 0x52, 0x44, 0x54, 0xc0, 0x4c, 0x9a, 0xa8, 0x3e, 0x99, 0xc9, 0x00, 0x70, 0x96, 0x3d, 0x7a, - 0x09, 0x46, 0xf8, 0x98, 0xdd, 0x4c, 0x79, 0x8c, 0x75, 0xc1, 0x1e, 0x13, 0x88, 0xd3, 0xb8, 0x68, - 0x82, 0x7b, 0xde, 0x45, 0x69, 0x9c, 0x01, 0xed, 0x58, 0x33, 0x8a, 0xe2, 0x18, 0x18, 0x28, 0x02, - 0x14, 0x91, 0xf5, 0x88, 0xc4, 0x1b, 0x22, 0x3a, 0x82, 0xd9, 0x57, 0x83, 0x87, 0xcb, 0x7a, 0xc6, - 0x5d, 0x94, 0x70, 0x0e, 0x75, 0xb4, 0x29, 0x36, 0x98, 0xb5, 0x22, 0x64, 0xa8, 0xf8, 0xcc, 0x3d, - 0xf7, 0x99, 0xe3, 0x50, 0x8d, 0x37, 0x9c, 0xa8, 0xc9, 0xec, 0xba, 0x32, 0xcf, 0xb4, 0x59, 0xa1, - 0x0d, 0x98, 0xb7, 0xa3, 0x59, 0x38, 0x99, 0x29, 0x37, 0x14, 0x0b, 0xcf, 0xae, 0xca, 0xaa, 0xc8, - 0x14, 0x2a, 0x8a, 0x71, 0xd7, 0x13, 0xa6, 0xf3, 0x61, 0x68, 0x1f, 0xe7, 0xc3, 0x8e, 0x8a, 0xc1, - 0xe3, 0x3e, 0xd7, 0x97, 0x0b, 0x19, 0x80, 0xbe, 0x02, 0xee, 0xbe, 0x90, 0x09, 0xb8, 0x1b, 0x61, - 0x1d, 0xb8, 0x59, 0x4c, 0x07, 0x0e, 0x1e, 0x5d, 0xf7, 0x20, 0xa3, 0xe5, 0xfe, 0xdc, 0x02, 0xf9, - 0x5d, 0x67, 0x9c, 0xc6, 0x06, 0xa1, 0x53, 0x06, 0xbd, 0x1f, 0x46, 0xd5, 0x16, 0x7a, 0x26, 0xe8, - 0xf8, 0x3c, 0x50, 0xae, 0xac, 0x8f, 0x70, 0x71, 0x0a, 0x8a, 0x33, 0xd8, 0x68, 0x12, 0xea, 0x74, - 0x9c, 0xf8, 0xa3, 0x5c, 0xd7, 0xaa, 0x6d, 0xfa, 0xd4, 0xf2, 0xbc, 0x78, 0x4a, 0xe3, 0xa0, 0x00, - 0x4e, 0x79, 0x4e, 0x9c, 0xb0, 0x1e, 0xd0, 0x1d, 0xf5, 0x21, 0x6b, 0x0e, 0xb0, 0xd0, 0xfd, 0x85, - 0x2c, 0x21, 0xdc, 0x4d, 0xdb, 0xfe, 0x76, 0x05, 0x46, 0x52, 0x92, 0xf1, 0x80, 0x4a, 0xfa, 0x19, - 0xa8, 0x49, 0xbd, 0x99, 0xad, 0x8e, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, 0x6b, 0x4d, 0x6b, 0xd5, - 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, 0x8c, 0xe7, 0x12, 0x3f, - 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, 0xce, 0x00, 0x70, 0x96, - 0x3d, 0xfa, 0x8c, 0x05, 0x23, 0xce, 0x9d, 0x58, 0x17, 0x27, 0x15, 0xa1, 0x75, 0x47, 0x54, 0x52, - 0xa9, 0x7a, 0xa7, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, 0x0b, 0x10, 0xd9, 0x26, - 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x50, 0xc4, 0x4e, 0xf3, 0x52, 0x17, 0x5d, 0x2e, 0xd5, 0xbb, - 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x5a, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, 0x3a, 0x46, 0xdc, 0x9b, - 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0xca, 0x98, 0xca, 0x7c, 0x2a, 0x3d, 0xa0, 0xcc, - 0xa7, 0x9f, 0xb2, 0x52, 0x75, 0x80, 0x86, 0x2e, 0xbe, 0x52, 0x6c, 0xac, 0xeb, 0x04, 0x8f, 0x6d, - 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, 0xe1, 0xbf, 0x2f, 0xc3, - 0x90, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, 0x30, 0x8b, 0x7e, 0x12, - 0xea, 0x0d, 0x29, 0xe5, 0x8b, 0xa9, 0x84, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, 0xab, 0x26, 0xac, 0x79, - 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x15, 0xa6, 0x21, 0xf2, 0x32, 0x61, 0x84, 0xa6, 0xe8, - 0x7e, 0x86, 0x95, 0x8b, 0x0a, 0x5d, 0xf1, 0x5e, 0x32, 0x22, 0x9d, 0x97, 0x8b, 0x5a, 0x9e, 0x97, - 0xcd, 0xd8, 0xc4, 0xb1, 0xbf, 0x6d, 0xa9, 0x8f, 0x7b, 0x1f, 0x0a, 0x23, 0xdc, 0x4e, 0x17, 0x46, - 0xb8, 0x54, 0xc8, 0x30, 0xf7, 0xa8, 0x88, 0x70, 0x1d, 0x06, 0x67, 0x82, 0x76, 0xdb, 0xf1, 0x9b, - 0xe8, 0x07, 0x61, 0xb0, 0xc1, 0x7f, 0x0a, 0xc7, 0x0e, 0x3b, 0x1e, 0x14, 0x50, 0x2c, 0x61, 0xe8, - 0x31, 0xa8, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x54, 0xd4, 0x8a, 0x31, 0x6b, 0xb5, - 0xff, 0x61, 0x05, 0xd8, 0x09, 0xb4, 0x13, 0x91, 0xe6, 0x6a, 0xc0, 0x2a, 0xf1, 0x1d, 0xeb, 0xa1, - 0x9a, 0xde, 0x2c, 0x3d, 0xcc, 0x07, 0x6b, 0xc6, 0xe1, 0x4a, 0xf9, 0x3e, 0x1f, 0xae, 0xf4, 0x38, - 0x2f, 0xab, 0x3c, 0x44, 0xe7, 0x65, 0xf6, 0xe7, 0x2d, 0x40, 0x2a, 0x6c, 0x41, 0x1f, 0x68, 0x4f, - 0x42, 0x5d, 0x05, 0x30, 0x08, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, 0xa7, 0x8f, 0x1d, 0xf2, - 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb4, 0x4c, 0xea, 0x0b, 0x71, 0x6e, 0xff, 0x76, 0x09, 0x1e, - 0xe1, 0x2a, 0x79, 0xd1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, 0xa2, 0xd0, 0xa0, 0x5b, - 0x33, 0x57, 0x46, 0xc5, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, 0xbc, 0xef, 0x26, 0x98, - 0x11, 0x47, 0x31, 0xd4, 0x64, 0xe9, 0x77, 0x21, 0x8b, 0x0b, 0x62, 0xa4, 0xc4, 0x92, 0xd0, 0x9b, - 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x26, 0x26, 0x61, 0xc0, 0xe4, 0xae, 0x11, 0x94, - 0xb8, 0x20, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xdb, 0x82, 0xac, 0x46, 0x32, 0x4a, 0x9e, 0x59, 0x7b, - 0x96, 0x3c, 0x3b, 0x40, 0xcd, 0xb1, 0x1f, 0x87, 0x21, 0x27, 0xa1, 0x46, 0x04, 0xdf, 0x76, 0x97, - 0x0f, 0x77, 0xac, 0xb1, 0x18, 0x34, 0xdd, 0x75, 0x97, 0x6d, 0xb7, 0x4d, 0x72, 0xf6, 0x7f, 0xaf, - 0xc0, 0xa9, 0xae, 0xdc, 0x0d, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, 0xa5, 0x43, 0xab, 0x6e, - 0x06, 0xb1, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe1, 0x74, 0x44, 0x37, 0xfa, 0x1d, - 0x32, 0xb5, 0x9e, 0x90, 0x68, 0x85, 0x34, 0x02, 0xbf, 0xc9, 0x0b, 0xf3, 0x95, 0xa7, 0x1f, 0xbd, - 0xbb, 0x3b, 0x7e, 0x1a, 0x77, 0x83, 0x71, 0xde, 0x33, 0x28, 0x84, 0x11, 0xcf, 0xb4, 0x01, 0xc5, - 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, 0x6d, 0x48, 0x56, 0x1f, - 0x90, 0x21, 0xf9, 0x69, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x17, 0x9c, 0xbb, 0x73, 0xdc, 0x96, - 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, 0x48, 0xb4, 0x7b, 0x25, - 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, 0xeb, 0xa3, 0x6d, 0x1e, - 0x97, 0xc5, 0x75, 0xdb, 0x87, 0x8a, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, 0xd2, 0xa0, 0xc2, 0xb5, - 0x2e, 0x02, 0x68, 0x43, 0x4d, 0x04, 0xac, 0xab, 0x63, 0x5f, 0x6d, 0xcf, 0x61, 0x03, 0x8b, 0xee, - 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xe2, 0xfa, 0x89, 0x70, 0x0e, 0x2a, 0x25, 0x3e, 0xaf, - 0x41, 0xd8, 0xc4, 0x3b, 0xff, 0x5e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0x6e, 0xc0, 0xb9, 0x39, 0x37, - 0x51, 0x69, 0x16, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x0d, 0x59, 0x3d, 0xd3, 0x86, 0x8c, 0x34, - 0x87, 0x52, 0x3a, 0x2b, 0x23, 0x9b, 0xe6, 0x60, 0xbf, 0x08, 0x67, 0xe6, 0xdc, 0xe4, 0xb2, 0xeb, - 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x73, 0x00, 0x86, 0xcd, 0x44, 0xbd, 0x83, 0x64, 0x3e, 0x7d, 0x91, - 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xeb, 0xc8, 0x59, 0x83, 0xf9, 0x23, 0x66, 0x58, - 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x40, 0x75, 0x9d, 0x85, 0xe1, 0x97, 0x8b, 0x88, 0x2c, - 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x20, 0x3f, 0xe7, 0x47, 0x35, 0x64, 0x94, 0xce, 0xed, 0x32, - 0x42, 0x47, 0x45, 0x56, 0x97, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, 0xf5, 0x29, 0xc1, 0x3b, - 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0xa9, 0x48, 0x36, 0x98, 0xfd, 0x26, 0x62, 0xdd, 0x07, 0xd9, 0x20, - 0x18, 0x29, 0x15, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x4f, 0x28, 0xd1, 0x5d, 0x2b, 0xc2, 0xaf, 0x6a, - 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2f, 0xc1, 0xe8, 0x9c, 0xdf, 0x59, 0x9e, 0x5b, 0xee, 0xac, - 0x79, 0x6e, 0xe3, 0x1a, 0xd9, 0xa1, 0xa2, 0x79, 0x93, 0xec, 0xcc, 0xcf, 0x8a, 0x15, 0xa4, 0xe6, - 0xcc, 0x35, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x75, 0xd7, 0x6f, 0x91, 0x28, 0x8c, 0x5c, 0xe1, - 0xf2, 0x34, 0x84, 0xd1, 0x65, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, 0xf1, 0x49, 0x94, 0x35, - 0x64, 0x97, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, 0x93, 0x51, 0x21, 0xad, - 0xd2, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x35, 0x16, 0xb8, 0x91, 0x09, 0xac, 0x5f, 0xe1, - 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x26, 0xd9, 0x99, 0xa5, 0xbb, 0xde, 0x4c, 0x7e, 0xcd, 0x35, 0xde, - 0x8c, 0x25, 0x9c, 0x55, 0x14, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x45, 0xc1, 0x74, 0xf7, 0x7b, 0xec, - 0x9f, 0x7f, 0xc9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, 0x52, 0x57, 0x41, 0xda, - 0x1f, 0xcd, 0xbb, 0xa1, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, 0x96, 0xeb, 0x13, 0x76, - 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0x33, 0x41, 0x93, 0x1c, 0xc2, 0x48, 0xb6, 0x6f, 0xc1, - 0xa9, 0xae, 0xa4, 0xaa, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x5a, 0x6d, 0x0c, 0x43, 0x94, 0xb0, 0xac, - 0x6a, 0x33, 0x03, 0xa7, 0xf8, 0x42, 0xa2, 0x9c, 0x56, 0x1a, 0x1b, 0xa4, 0xad, 0x12, 0xe5, 0x98, - 0x7f, 0xfd, 0x66, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x2f, 0x58, 0x30, 0x92, 0xca, 0x73, 0x2b, 0xc8, - 0x08, 0x62, 0x2b, 0x2d, 0x60, 0xd1, 0x7f, 0x2c, 0x04, 0xba, 0xcc, 0x94, 0xa9, 0x5e, 0x69, 0x1a, - 0x84, 0x4d, 0x3c, 0xfb, 0xcb, 0x25, 0xa8, 0xc9, 0x08, 0x8a, 0x3e, 0xba, 0xf2, 0x39, 0x0b, 0x46, - 0xd4, 0x99, 0x06, 0x73, 0x96, 0x95, 0x8a, 0x48, 0x4a, 0xa0, 0x3d, 0x50, 0xdb, 0x6d, 0x7f, 0x3d, - 0xd0, 0x16, 0x39, 0x36, 0x99, 0xe1, 0x34, 0x6f, 0x74, 0x13, 0x20, 0xde, 0x89, 0x13, 0xd2, 0x36, - 0xdc, 0x76, 0xb6, 0xb1, 0xe2, 0x26, 0x1a, 0x41, 0x44, 0xe8, 0xfa, 0xba, 0x1e, 0x34, 0xc9, 0x8a, - 0xc2, 0xd4, 0x26, 0x94, 0x6e, 0xc3, 0x06, 0x25, 0xfb, 0xef, 0x97, 0xe0, 0x64, 0xb6, 0x4b, 0xe8, - 0xc3, 0x30, 0x2c, 0xb9, 0x1b, 0xb7, 0x8d, 0xc9, 0xb0, 0x91, 0x61, 0x6c, 0xc0, 0xee, 0xed, 0x8e, - 0x8f, 0x77, 0xdf, 0xf6, 0x36, 0x61, 0xa2, 0xe0, 0x14, 0x31, 0x7e, 0xb0, 0x24, 0x4e, 0x40, 0xa7, - 0x77, 0xa6, 0xc2, 0x50, 0x9c, 0x0e, 0x19, 0x07, 0x4b, 0x26, 0x14, 0x67, 0xb0, 0xd1, 0x32, 0x9c, - 0x31, 0x5a, 0xae, 0x13, 0xb7, 0xb5, 0xb1, 0x16, 0x44, 0x72, 0x67, 0xf5, 0x98, 0x0e, 0xec, 0xea, - 0xc6, 0xc1, 0xb9, 0x4f, 0x52, 0x6d, 0xdf, 0x70, 0x42, 0xa7, 0xe1, 0x26, 0x3b, 0xc2, 0x0f, 0xa9, - 0x64, 0xd3, 0x8c, 0x68, 0xc7, 0x0a, 0xc3, 0x5e, 0x84, 0x4a, 0x9f, 0x33, 0xa8, 0x2f, 0x8b, 0xfe, - 0x65, 0xa8, 0x51, 0x72, 0xd2, 0xbc, 0x2b, 0x82, 0x64, 0x00, 0x35, 0x79, 0x61, 0x08, 0xb2, 0xa1, - 0xec, 0x3a, 0xf2, 0xec, 0x4e, 0xbd, 0xd6, 0x7c, 0x1c, 0x77, 0xd8, 0x26, 0x99, 0x02, 0xd1, 0x93, - 0x50, 0x26, 0xdb, 0x61, 0xf6, 0x90, 0xee, 0xd2, 0x76, 0xe8, 0x46, 0x24, 0xa6, 0x48, 0x64, 0x3b, - 0x44, 0xe7, 0xa1, 0xe4, 0x36, 0x85, 0x92, 0x02, 0x81, 0x53, 0x9a, 0x9f, 0xc5, 0x25, 0xb7, 0x69, - 0x6f, 0x43, 0x5d, 0xdd, 0x50, 0x82, 0x36, 0xa5, 0xec, 0xb6, 0x8a, 0x08, 0x79, 0x92, 0x74, 0x7b, - 0x48, 0xed, 0x0e, 0x80, 0x4e, 0xf8, 0x2b, 0x4a, 0xbe, 0x5c, 0x80, 0x4a, 0x23, 0x10, 0xc9, 0xc8, - 0x35, 0x4d, 0x86, 0x09, 0x6d, 0x06, 0xb1, 0x6f, 0xc1, 0xe8, 0x35, 0x3f, 0xb8, 0xc3, 0xca, 0xab, - 0xb3, 0x6a, 0x62, 0x94, 0xf0, 0x3a, 0xfd, 0x91, 0x35, 0x11, 0x18, 0x14, 0x73, 0x98, 0xaa, 0xcf, - 0x54, 0xea, 0x55, 0x9f, 0xc9, 0xfe, 0xa4, 0x05, 0xc3, 0x2a, 0x73, 0x68, 0x6e, 0x6b, 0x93, 0xd2, - 0x6d, 0x45, 0x41, 0x27, 0xcc, 0xd2, 0x65, 0x77, 0x08, 0x61, 0x0e, 0x33, 0x53, 0xea, 0x4a, 0xfb, - 0xa4, 0xd4, 0x5d, 0x80, 0xca, 0xa6, 0xeb, 0x37, 0xb3, 0x97, 0x62, 0x5c, 0x73, 0xfd, 0x26, 0x66, - 0x10, 0xda, 0x85, 0x93, 0xaa, 0x0b, 0x52, 0x21, 0xbc, 0x08, 0xc3, 0x6b, 0x1d, 0xd7, 0x6b, 0xca, - 0x32, 0x69, 0x19, 0x4f, 0xc9, 0xb4, 0x01, 0xc3, 0x29, 0x4c, 0xba, 0xaf, 0x5b, 0x73, 0x7d, 0x27, - 0xda, 0x59, 0xd6, 0x1a, 0x48, 0x09, 0xa5, 0x69, 0x05, 0xc1, 0x06, 0x96, 0xfd, 0x66, 0x19, 0x46, - 0xd3, 0xf9, 0x53, 0x7d, 0x6c, 0xaf, 0x9e, 0x84, 0x2a, 0x4b, 0xa9, 0xca, 0x7e, 0x5a, 0xf6, 0x3c, - 0xe6, 0x30, 0x14, 0xc3, 0x00, 0x2f, 0xc6, 0x50, 0xcc, 0x85, 0x32, 0xaa, 0x93, 0xca, 0xbf, 0xc2, - 0xe2, 0xc9, 0x44, 0xfd, 0x07, 0xc1, 0x0a, 0x7d, 0xc6, 0x82, 0xc1, 0x20, 0x34, 0xeb, 0xfa, 0x7c, - 0xa8, 0xc8, 0xdc, 0x32, 0x91, 0x2c, 0x23, 0x2c, 0x62, 0xf5, 0xe9, 0xe5, 0xe7, 0x90, 0xac, 0xcf, - 0xbf, 0x0f, 0x86, 0x4d, 0xcc, 0xfd, 0x8c, 0xe2, 0x9a, 0x69, 0x14, 0x7f, 0xce, 0x9c, 0x14, 0x22, - 0x7b, 0xae, 0x8f, 0xe5, 0x76, 0x03, 0xaa, 0x0d, 0x15, 0x00, 0x70, 0xa8, 0xe2, 0x9a, 0xaa, 0x3a, - 0x02, 0x3b, 0x04, 0xe2, 0xd4, 0xec, 0x6f, 0x5b, 0xc6, 0xfc, 0xc0, 0x24, 0x9e, 0x6f, 0xa2, 0x08, - 0xca, 0xad, 0xad, 0x4d, 0x61, 0x8a, 0x5e, 0x2d, 0x68, 0x78, 0xe7, 0xb6, 0x36, 0xf5, 0x1c, 0x37, - 0x5b, 0x31, 0x65, 0xd6, 0x87, 0x13, 0x30, 0x95, 0x64, 0x59, 0xde, 0x3f, 0xc9, 0xd2, 0x7e, 0xab, - 0x04, 0xa7, 0xba, 0x26, 0x15, 0x7a, 0x03, 0xaa, 0x11, 0x7d, 0x4b, 0xf1, 0x7a, 0x0b, 0x85, 0xa5, - 0x45, 0xc6, 0xf3, 0x4d, 0xad, 0x77, 0xd3, 0xed, 0x98, 0xb3, 0x44, 0x57, 0x01, 0xe9, 0x30, 0x15, - 0xe5, 0x81, 0xe4, 0xaf, 0x7c, 0x5e, 0x3c, 0x8a, 0xa6, 0xba, 0x30, 0x70, 0xce, 0x53, 0xe8, 0xa5, - 0xac, 0x23, 0xb3, 0x9c, 0x3e, 0xb7, 0xdc, 0xcb, 0x27, 0x69, 0xff, 0xb3, 0x12, 0x8c, 0xa4, 0xca, - 0x2c, 0x21, 0x0f, 0x6a, 0xc4, 0x63, 0x4e, 0x7d, 0xa9, 0x6c, 0x8e, 0x5a, 0x7c, 0x58, 0x29, 0xc8, - 0x4b, 0x82, 0x2e, 0x56, 0x1c, 0x1e, 0x8e, 0xc3, 0xf5, 0x17, 0x61, 0x58, 0x76, 0xe8, 0x43, 0x4e, - 0xdb, 0x13, 0x03, 0xa8, 0xe6, 0xe8, 0x25, 0x03, 0x86, 0x53, 0x98, 0xf6, 0xef, 0x94, 0x61, 0x8c, - 0x9f, 0x82, 0x34, 0xd5, 0xcc, 0x5b, 0x94, 0xfb, 0xad, 0xbf, 0xac, 0x8b, 0xa1, 0xf1, 0x81, 0x5c, - 0x3b, 0x6a, 0xad, 0xff, 0x7c, 0x46, 0x7d, 0x45, 0x66, 0xfd, 0x42, 0x26, 0x32, 0x8b, 0x9b, 0xdd, - 0xad, 0x63, 0xea, 0xd1, 0xf7, 0x56, 0xa8, 0xd6, 0xaf, 0x94, 0xe0, 0x44, 0xe6, 0x22, 0x05, 0xf4, - 0x66, 0xba, 0xf6, 0xae, 0x55, 0x84, 0xaf, 0x7c, 0xcf, 0xda, 0xfa, 0x07, 0xab, 0xc0, 0xfb, 0x80, - 0x96, 0x8a, 0xfd, 0xfb, 0x25, 0x18, 0x4d, 0xdf, 0x00, 0xf1, 0x10, 0x8e, 0xd4, 0xbb, 0xa1, 0xce, - 0x8a, 0x9c, 0xb3, 0x9b, 0x2d, 0xb9, 0x4b, 0x9e, 0xd7, 0x93, 0x96, 0x8d, 0x58, 0xc3, 0x1f, 0x8a, - 0xc2, 0xc6, 0xf6, 0xdf, 0xb5, 0xe0, 0x2c, 0x7f, 0xcb, 0xec, 0x3c, 0xfc, 0x2b, 0x79, 0xa3, 0xfb, - 0x6a, 0xb1, 0x1d, 0xcc, 0x14, 0xf1, 0xdb, 0x6f, 0x7c, 0xd9, 0x8d, 0x7a, 0xa2, 0xb7, 0xe9, 0xa9, - 0xf0, 0x10, 0x76, 0xf6, 0x40, 0x93, 0xc1, 0xfe, 0xfd, 0x32, 0xe8, 0x4b, 0x04, 0x91, 0x2b, 0x72, - 0x1c, 0x0b, 0x29, 0x66, 0xb8, 0xb2, 0xe3, 0x37, 0xf4, 0x75, 0x85, 0xb5, 0x4c, 0x8a, 0xe3, 0xcf, - 0x5a, 0x30, 0xe4, 0xfa, 0x6e, 0xe2, 0x3a, 0x6c, 0x1b, 0x5d, 0xcc, 0x05, 0x67, 0x8a, 0xdd, 0x3c, - 0xa7, 0x1c, 0x44, 0xe6, 0x39, 0x8e, 0x62, 0x86, 0x4d, 0xce, 0xe8, 0xa3, 0x22, 0x78, 0xba, 0x5c, - 0x58, 0x76, 0x6e, 0x2d, 0x13, 0x31, 0x1d, 0x52, 0xc3, 0x2b, 0x89, 0x0a, 0x4a, 0x6a, 0xc7, 0x94, - 0x94, 0xaa, 0x8b, 0xab, 0xaf, 0x73, 0xa6, 0xcd, 0x98, 0x33, 0xb2, 0x63, 0x40, 0xdd, 0x63, 0x71, - 0xc0, 0xc0, 0xd4, 0x49, 0xa8, 0x3b, 0x9d, 0x24, 0x68, 0xd3, 0x61, 0x12, 0x47, 0x4d, 0x3a, 0xf4, - 0x56, 0x02, 0xb0, 0xc6, 0xb1, 0xdf, 0xac, 0x42, 0x26, 0xe9, 0x10, 0x6d, 0x9b, 0x17, 0x60, 0x5a, - 0xc5, 0x5e, 0x80, 0xa9, 0x3a, 0x93, 0x77, 0x09, 0x26, 0x6a, 0x41, 0x35, 0xdc, 0x70, 0x62, 0x69, - 0x56, 0xbf, 0xac, 0xf6, 0x71, 0xb4, 0xf1, 0xde, 0xee, 0xf8, 0x8f, 0xf5, 0xe7, 0x75, 0xa5, 0x73, - 0x75, 0x92, 0x17, 0x1b, 0xd1, 0xac, 0x19, 0x0d, 0xcc, 0xe9, 0x1f, 0xe4, 0x8a, 0xb7, 0x4f, 0x89, - 0x6a, 0xee, 0x98, 0xc4, 0x1d, 0x2f, 0x11, 0xb3, 0xe1, 0xe5, 0x02, 0x57, 0x19, 0x27, 0xac, 0xd3, - 0xe5, 0xf9, 0x7f, 0x6c, 0x30, 0x45, 0x1f, 0x86, 0x7a, 0x9c, 0x38, 0x51, 0x72, 0xc8, 0x04, 0x57, - 0x35, 0xe8, 0x2b, 0x92, 0x08, 0xd6, 0xf4, 0xd0, 0x2b, 0xac, 0xb6, 0xab, 0x1b, 0x6f, 0x1c, 0x32, - 0xe7, 0x41, 0xd6, 0x81, 0x15, 0x14, 0xb0, 0x41, 0x0d, 0x5d, 0x04, 0x60, 0x73, 0x9b, 0x07, 0xfa, - 0xd5, 0x98, 0x97, 0x49, 0x89, 0x42, 0xac, 0x20, 0xd8, 0xc0, 0xb2, 0x7f, 0x18, 0xd2, 0xf5, 0x1e, - 0xd0, 0xb8, 0x2c, 0x2f, 0xc1, 0xbd, 0xd0, 0x2c, 0x77, 0x21, 0x55, 0x09, 0xe2, 0xd7, 0x2d, 0x30, - 0x8b, 0x52, 0xa0, 0xd7, 0x79, 0xf5, 0x0b, 0xab, 0x88, 0x93, 0x43, 0x83, 0xee, 0xc4, 0xa2, 0x13, - 0x66, 0x8e, 0xb0, 0x65, 0x09, 0x8c, 0xf3, 0xef, 0x85, 0x9a, 0x84, 0x1e, 0xc8, 0xa8, 0xfb, 0x04, - 0x9c, 0xce, 0x5e, 0x0f, 0x2e, 0x4e, 0x9d, 0xf6, 0x77, 0xfd, 0x48, 0x7f, 0x4e, 0xa9, 0x97, 0x3f, - 0xa7, 0x8f, 0x6b, 0x50, 0x7f, 0xc3, 0x82, 0x0b, 0xfb, 0xdd, 0x62, 0x8e, 0x1e, 0x83, 0xca, 0x1d, - 0x27, 0x92, 0x45, 0xb7, 0x99, 0xa0, 0xbc, 0xe5, 0x44, 0x3e, 0x66, 0xad, 0x68, 0x07, 0x06, 0x78, - 0x34, 0x98, 0xb0, 0xd6, 0x5f, 0x2e, 0xf6, 0x4e, 0xf5, 0x6b, 0xc4, 0xd8, 0x2e, 0xf0, 0x48, 0x34, - 0x2c, 0x18, 0xda, 0xdf, 0xb1, 0x00, 0x2d, 0x6d, 0x91, 0x28, 0x72, 0x9b, 0x46, 0xfc, 0x1a, 0xbb, - 0x15, 0xc5, 0xb8, 0xfd, 0xc4, 0x4c, 0x71, 0xcd, 0xdc, 0x8a, 0x62, 0xfc, 0xcb, 0xbf, 0x15, 0xa5, - 0x74, 0xb0, 0x5b, 0x51, 0xd0, 0x12, 0x9c, 0x6d, 0xf3, 0xed, 0x06, 0xbf, 0x69, 0x80, 0xef, 0x3d, - 0x54, 0x42, 0xd9, 0xb9, 0xbb, 0xbb, 0xe3, 0x67, 0x17, 0xf3, 0x10, 0x70, 0xfe, 0x73, 0xf6, 0x7b, - 0x01, 0xf1, 0xb0, 0xb5, 0x99, 0xbc, 0x18, 0xa4, 0x9e, 0xee, 0x17, 0xfb, 0xab, 0x55, 0x38, 0x91, - 0x29, 0xc9, 0x4a, 0xb7, 0x7a, 0xdd, 0x41, 0x4f, 0x47, 0xd6, 0xdf, 0xdd, 0xdd, 0xeb, 0x2b, 0x8c, - 0xca, 0x87, 0xaa, 0xeb, 0x87, 0x9d, 0xa4, 0x98, 0x1c, 0x52, 0xde, 0x89, 0x79, 0x4a, 0xd0, 0x70, - 0x17, 0xd3, 0xbf, 0x98, 0xb3, 0x29, 0x32, 0x28, 0x2b, 0x65, 0x8c, 0x57, 0x1e, 0x90, 0x3b, 0xe0, - 0x53, 0x3a, 0x44, 0xaa, 0x5a, 0x84, 0x63, 0x31, 0x33, 0x59, 0x8e, 0xfb, 0xa8, 0xfd, 0xd7, 0x4a, - 0x30, 0x64, 0x7c, 0x34, 0xf4, 0x8b, 0xe9, 0x92, 0x4d, 0x56, 0x71, 0xaf, 0xc4, 0xe8, 0x4f, 0xe8, - 0xa2, 0x4c, 0xfc, 0x95, 0x9e, 0xea, 0xae, 0xd6, 0x74, 0x6f, 0x77, 0xfc, 0x64, 0xa6, 0x1e, 0x53, - 0xaa, 0x82, 0xd3, 0xf9, 0x8f, 0xc3, 0x89, 0x0c, 0x99, 0x9c, 0x57, 0x5e, 0x4d, 0xdf, 0xfe, 0x7e, - 0x44, 0xb7, 0x94, 0x39, 0x64, 0xdf, 0xa0, 0x43, 0x26, 0xd2, 0xe8, 0x02, 0x8f, 0xf4, 0xe1, 0x83, - 0xcd, 0x64, 0xcb, 0x96, 0xfa, 0xcc, 0x96, 0x7d, 0x1a, 0x6a, 0x61, 0xe0, 0xb9, 0x0d, 0x57, 0x55, - 0x21, 0x64, 0xf9, 0xb9, 0xcb, 0xa2, 0x0d, 0x2b, 0x28, 0xba, 0x03, 0x75, 0x75, 0x51, 0xbe, 0xf0, - 0x6f, 0x17, 0x75, 0xe8, 0xa3, 0x8c, 0x16, 0x7d, 0x01, 0xbe, 0xe6, 0x85, 0x6c, 0x18, 0x60, 0x4a, - 0x50, 0x86, 0xfe, 0x33, 0xdf, 0x3b, 0xd3, 0x8e, 0x31, 0x16, 0x10, 0xfb, 0xeb, 0x75, 0x38, 0x93, - 0x57, 0x17, 0x1b, 0x7d, 0x0c, 0x06, 0x78, 0x1f, 0x8b, 0xb9, 0x7a, 0x21, 0x8f, 0xc7, 0x1c, 0x23, - 0x28, 0xba, 0xc5, 0x7e, 0x63, 0xc1, 0x53, 0x70, 0xf7, 0x9c, 0x35, 0x31, 0x43, 0x8e, 0x87, 0xfb, - 0x82, 0xa3, 0xb9, 0x2f, 0x38, 0x9c, 0xbb, 0xe7, 0xac, 0xa1, 0x6d, 0xa8, 0xb6, 0xdc, 0x84, 0x38, - 0xc2, 0x89, 0x70, 0xeb, 0x58, 0x98, 0x13, 0x87, 0x5b, 0x69, 0xec, 0x27, 0xe6, 0x0c, 0xd1, 0xd7, - 0x2c, 0x38, 0xb1, 0x96, 0x4e, 0x8d, 0x17, 0xc2, 0xd3, 0x39, 0x86, 0xda, 0xe7, 0x69, 0x46, 0xfc, - 0x5a, 0xa0, 0x4c, 0x23, 0xce, 0x76, 0x07, 0x7d, 0xda, 0x82, 0xc1, 0x75, 0xd7, 0x33, 0xca, 0xe0, - 0x1e, 0xc3, 0xc7, 0xb9, 0xcc, 0x18, 0xe8, 0x1d, 0x07, 0xff, 0x1f, 0x63, 0xc9, 0xb9, 0x97, 0xa6, - 0x1a, 0x38, 0xaa, 0xa6, 0x1a, 0x7c, 0x40, 0x9a, 0xea, 0xb3, 0x16, 0xd4, 0xd5, 0x48, 0x8b, 0x74, - 0xe7, 0x0f, 0x1f, 0xe3, 0x27, 0xe7, 0x9e, 0x13, 0xf5, 0x17, 0x6b, 0xe6, 0xe8, 0x4b, 0x16, 0x0c, - 0x39, 0x6f, 0x74, 0x22, 0xd2, 0x24, 0x5b, 0x41, 0x18, 0x8b, 0x3b, 0x05, 0x5f, 0x2d, 0xbe, 0x33, - 0x53, 0x94, 0xc9, 0x2c, 0xd9, 0x5a, 0x0a, 0x63, 0x91, 0x96, 0xa4, 0x1b, 0xb0, 0xd9, 0x05, 0x7b, - 0xb7, 0x04, 0xe3, 0xfb, 0x50, 0x40, 0x2f, 0xc2, 0x70, 0x10, 0xb5, 0x1c, 0xdf, 0x7d, 0xc3, 0xac, - 0x75, 0xa1, 0xac, 0xac, 0x25, 0x03, 0x86, 0x53, 0x98, 0x66, 0x42, 0x76, 0x69, 0x9f, 0x84, 0xec, - 0x0b, 0x50, 0x89, 0x48, 0x18, 0x64, 0x37, 0x0b, 0x2c, 0x25, 0x80, 0x41, 0xd0, 0xe3, 0x50, 0x76, - 0x42, 0x57, 0x04, 0xa2, 0xa9, 0x3d, 0xd0, 0xd4, 0xf2, 0x3c, 0xa6, 0xed, 0xa9, 0xfa, 0x10, 0xd5, - 0xfb, 0x52, 0x1f, 0x82, 0xaa, 0x01, 0x71, 0x76, 0x31, 0xa0, 0xd5, 0x40, 0xfa, 0x4c, 0xc1, 0x7e, - 0xab, 0x0c, 0x8f, 0xef, 0x39, 0x5f, 0x74, 0x1c, 0x9e, 0xb5, 0x47, 0x1c, 0x9e, 0x1c, 0x9e, 0xd2, - 0x7e, 0xc3, 0x53, 0xee, 0x31, 0x3c, 0x9f, 0xa6, 0xcb, 0x40, 0xd6, 0x08, 0x29, 0xe6, 0x56, 0xb8, - 0x5e, 0x25, 0x47, 0xc4, 0x0a, 0x90, 0x50, 0xac, 0xf9, 0xd2, 0x3d, 0x40, 0x2a, 0x19, 0xb9, 0x5a, - 0x84, 0x1a, 0xe8, 0x59, 0x33, 0x84, 0xcf, 0xfd, 0x5e, 0x19, 0xce, 0xf6, 0xcf, 0x95, 0xe0, 0xc9, - 0x3e, 0xa4, 0xb7, 0x39, 0x8b, 0xad, 0x3e, 0x67, 0xf1, 0xf7, 0xf6, 0x67, 0xb2, 0xff, 0xaa, 0x05, - 0xe7, 0x7b, 0x2b, 0x0f, 0xf4, 0x1c, 0x0c, 0xad, 0x45, 0x8e, 0xdf, 0xd8, 0x60, 0x37, 0x5d, 0xca, - 0x41, 0x61, 0x63, 0xad, 0x9b, 0xb1, 0x89, 0x43, 0xb7, 0xb7, 0x3c, 0x26, 0xc1, 0xc0, 0x90, 0xc9, - 0xa3, 0x74, 0x7b, 0xbb, 0x9a, 0x05, 0xe2, 0x6e, 0x7c, 0xfb, 0xcf, 0x4a, 0xf9, 0xdd, 0xe2, 0x46, - 0xc6, 0x41, 0xbe, 0x93, 0xf8, 0x0a, 0xa5, 0x3e, 0x64, 0x49, 0xf9, 0x7e, 0xcb, 0x92, 0x4a, 0x2f, - 0x59, 0x82, 0x66, 0xe1, 0xa4, 0x71, 0x85, 0x0a, 0x4f, 0x08, 0xe6, 0x01, 0xb7, 0xaa, 0x4a, 0xc6, - 0x72, 0x06, 0x8e, 0xbb, 0x9e, 0x40, 0xcf, 0x40, 0xcd, 0xf5, 0x63, 0xd2, 0xe8, 0x44, 0x3c, 0xd0, - 0xdb, 0x48, 0xc2, 0x9a, 0x17, 0xed, 0x58, 0x61, 0xd8, 0xbf, 0x54, 0x82, 0x73, 0x3d, 0xed, 0xac, - 0xfb, 0x24, 0xbb, 0xcc, 0xcf, 0x51, 0xb9, 0x3f, 0x9f, 0xc3, 0x1c, 0xa4, 0xea, 0xbe, 0x83, 0xf4, - 0x07, 0xbd, 0x27, 0x26, 0xb5, 0xb9, 0xbf, 0x6f, 0x47, 0xe9, 0x25, 0x18, 0x71, 0xc2, 0x90, 0xe3, - 0xb1, 0x78, 0xcd, 0x4c, 0x95, 0x9c, 0x29, 0x13, 0x88, 0xd3, 0xb8, 0x7d, 0x69, 0xcf, 0x3f, 0xb2, - 0xa0, 0x8e, 0xc9, 0x3a, 0x97, 0x0e, 0xe8, 0xb6, 0x18, 0x22, 0xab, 0x88, 0x7a, 0x9a, 0x74, 0x60, - 0x63, 0x97, 0xd5, 0x99, 0xcc, 0x1b, 0xec, 0xee, 0xab, 0x76, 0x4a, 0x07, 0xba, 0x6a, 0x47, 0x5d, - 0xb6, 0x52, 0xee, 0x7d, 0xd9, 0x8a, 0xfd, 0x8d, 0x41, 0xfa, 0x7a, 0x61, 0x30, 0x13, 0x91, 0x66, - 0x4c, 0xbf, 0x6f, 0x27, 0xf2, 0xc4, 0x24, 0x51, 0xdf, 0xf7, 0x06, 0x5e, 0xc0, 0xb4, 0x3d, 0x75, - 0x14, 0x53, 0x3a, 0x50, 0x8d, 0x90, 0xf2, 0xbe, 0x35, 0x42, 0x5e, 0x82, 0x91, 0x38, 0xde, 0x58, - 0x8e, 0xdc, 0x2d, 0x27, 0x21, 0xd7, 0xc8, 0x8e, 0xb0, 0xb2, 0x74, 0x5e, 0xff, 0xca, 0x15, 0x0d, - 0xc4, 0x69, 0x5c, 0x34, 0x07, 0xa7, 0x74, 0xa5, 0x0e, 0x12, 0x25, 0x2c, 0xba, 0x9f, 0xcf, 0x04, - 0x95, 0xc4, 0xab, 0x6b, 0x7b, 0x08, 0x04, 0xdc, 0xfd, 0x0c, 0x95, 0x6f, 0xa9, 0x46, 0xda, 0x91, - 0x81, 0xb4, 0x7c, 0x4b, 0xd1, 0xa1, 0x7d, 0xe9, 0x7a, 0x02, 0x2d, 0xc2, 0x69, 0x3e, 0x31, 0xa6, - 0xc2, 0xd0, 0x78, 0xa3, 0xc1, 0x74, 0x1d, 0xc3, 0xb9, 0x6e, 0x14, 0x9c, 0xf7, 0x1c, 0x7a, 0x01, - 0x86, 0x54, 0xf3, 0xfc, 0xac, 0x38, 0x45, 0x50, 0x5e, 0x0c, 0x45, 0x66, 0xbe, 0x89, 0x4d, 0x3c, - 0xf4, 0x21, 0x78, 0x54, 0xff, 0xe5, 0x29, 0x60, 0xfc, 0x68, 0x6d, 0x56, 0x14, 0x41, 0x52, 0x57, - 0x7b, 0xcc, 0xe5, 0xa2, 0x35, 0x71, 0xaf, 0xe7, 0xd1, 0x1a, 0x9c, 0x57, 0xa0, 0x4b, 0x7e, 0xc2, - 0xf2, 0x39, 0x62, 0x32, 0xed, 0xc4, 0xe4, 0x46, 0xe4, 0xb1, 0xb2, 0x49, 0x75, 0x7d, 0xeb, 0xe2, - 0x9c, 0x9b, 0x5c, 0xc9, 0xc3, 0xc4, 0x0b, 0x78, 0x0f, 0x2a, 0x68, 0x12, 0xea, 0xc4, 0x77, 0xd6, - 0x3c, 0xb2, 0x34, 0x33, 0xcf, 0x8a, 0x29, 0x19, 0x27, 0x79, 0x97, 0x24, 0x00, 0x6b, 0x1c, 0x15, - 0x61, 0x3a, 0xdc, 0xf3, 0x06, 0xd0, 0x65, 0x38, 0xd3, 0x6a, 0x84, 0xd4, 0xf6, 0x70, 0x1b, 0x64, - 0xaa, 0xc1, 0x02, 0xea, 0xe8, 0x87, 0xe1, 0x05, 0x26, 0x55, 0xf8, 0xf4, 0xdc, 0xcc, 0x72, 0x17, - 0x0e, 0xce, 0x7d, 0x92, 0x05, 0x5e, 0x46, 0xc1, 0xf6, 0xce, 0xd8, 0xe9, 0x4c, 0xe0, 0x25, 0x6d, - 0xc4, 0x1c, 0x86, 0xae, 0x02, 0x62, 0xb1, 0xf8, 0x57, 0x92, 0x24, 0x54, 0xc6, 0xce, 0xd8, 0x19, - 0xf6, 0x4a, 0x2a, 0x8c, 0xec, 0x72, 0x17, 0x06, 0xce, 0x79, 0xca, 0xfe, 0x0f, 0x16, 0x8c, 0xa8, - 0xf5, 0x7a, 0x1f, 0xb2, 0x51, 0xbc, 0x74, 0x36, 0xca, 0xdc, 0xd1, 0x25, 0x1e, 0xeb, 0x79, 0x8f, - 0x90, 0xe6, 0x9f, 0x1e, 0x02, 0xd0, 0x52, 0x51, 0x29, 0x24, 0xab, 0xa7, 0x42, 0x7a, 0x68, 0x25, - 0x52, 0x5e, 0xe5, 0x94, 0xea, 0x83, 0xad, 0x9c, 0xb2, 0x02, 0x67, 0xa5, 0xb9, 0xc0, 0xcf, 0x8a, - 0xae, 0x04, 0xb1, 0x12, 0x70, 0xb5, 0xe9, 0xc7, 0x05, 0xa1, 0xb3, 0xf3, 0x79, 0x48, 0x38, 0xff, - 0xd9, 0x94, 0x95, 0x32, 0xb8, 0x9f, 0x95, 0xa2, 0xd7, 0xf4, 0xc2, 0xba, 0xbc, 0xc3, 0x23, 0xb3, - 0xa6, 0x17, 0x2e, 0xaf, 0x60, 0x8d, 0x93, 0x2f, 0xd8, 0xeb, 0x05, 0x09, 0x76, 0x38, 0xb0, 0x60, - 0x97, 0x22, 0x66, 0xa8, 0xa7, 0x88, 0x91, 0x3e, 0xe9, 0xe1, 0x9e, 0x3e, 0xe9, 0xf7, 0xc3, 0xa8, - 0xeb, 0x6f, 0x90, 0xc8, 0x4d, 0x48, 0x93, 0xad, 0x05, 0x26, 0x7e, 0x6a, 0x5a, 0xad, 0xcf, 0xa7, - 0xa0, 0x38, 0x83, 0x9d, 0x96, 0x8b, 0xa3, 0x7d, 0xc8, 0xc5, 0x1e, 0xda, 0xe8, 0x44, 0x31, 0xda, - 0xe8, 0xe4, 0xd1, 0xb5, 0xd1, 0xa9, 0x63, 0xd5, 0x46, 0xa8, 0x10, 0x6d, 0xd4, 0x97, 0xa0, 0x37, - 0xb6, 0x7f, 0x67, 0xf6, 0xd9, 0xfe, 0xf5, 0x52, 0x45, 0x67, 0x0f, 0xad, 0x8a, 0xf2, 0xb5, 0xcc, - 0x23, 0x87, 0xd2, 0x32, 0x9f, 0x2d, 0xc1, 0x59, 0x2d, 0x87, 0xe9, 0xec, 0x77, 0xd7, 0xa9, 0x24, - 0x62, 0xd7, 0x40, 0xf1, 0x73, 0x1b, 0x23, 0x39, 0x4a, 0xe7, 0x59, 0x29, 0x08, 0x36, 0xb0, 0x58, - 0x8e, 0x11, 0x89, 0x58, 0x19, 0xdd, 0xac, 0x90, 0x9e, 0x11, 0xed, 0x58, 0x61, 0xd0, 0xf9, 0x45, - 0x7f, 0x8b, 0xbc, 0xcd, 0x6c, 0xb1, 0xb8, 0x19, 0x0d, 0xc2, 0x26, 0x1e, 0x7a, 0x9a, 0x33, 0x61, - 0x02, 0x82, 0x0a, 0xea, 0x61, 0x71, 0x2f, 0xac, 0x94, 0x09, 0x0a, 0x2a, 0xbb, 0xc3, 0x92, 0xc9, - 0xaa, 0xdd, 0xdd, 0x61, 0x21, 0x50, 0x0a, 0xc3, 0xfe, 0x1f, 0x16, 0x9c, 0xcb, 0x1d, 0x8a, 0xfb, - 0xa0, 0x7c, 0xb7, 0xd3, 0xca, 0x77, 0xa5, 0xa8, 0xed, 0x86, 0xf1, 0x16, 0x3d, 0x14, 0xf1, 0xbf, - 0xb3, 0x60, 0x54, 0xe3, 0xdf, 0x87, 0x57, 0x75, 0xd3, 0xaf, 0x5a, 0xdc, 0xce, 0xaa, 0xde, 0xf5, - 0x6e, 0xbf, 0x53, 0x02, 0x55, 0xc0, 0x71, 0xaa, 0x21, 0xcb, 0xe3, 0xee, 0x73, 0x92, 0xb8, 0x03, - 0x03, 0xec, 0x20, 0x34, 0x2e, 0x26, 0xc8, 0x23, 0xcd, 0x9f, 0x1d, 0xaa, 0xea, 0x43, 0x66, 0xf6, - 0x37, 0xc6, 0x82, 0x21, 0x2b, 0xf2, 0xec, 0xc6, 0x54, 0x9a, 0x37, 0x45, 0x5a, 0x96, 0x2e, 0xf2, - 0x2c, 0xda, 0xb1, 0xc2, 0xa0, 0xea, 0xc1, 0x6d, 0x04, 0xfe, 0x8c, 0xe7, 0xc4, 0xf2, 0xee, 0x43, - 0xa5, 0x1e, 0xe6, 0x25, 0x00, 0x6b, 0x1c, 0x76, 0x46, 0xea, 0xc6, 0xa1, 0xe7, 0xec, 0x18, 0xfb, - 0x67, 0xa3, 0x3e, 0x81, 0x02, 0x61, 0x13, 0xcf, 0x6e, 0xc3, 0x58, 0xfa, 0x25, 0x66, 0xc9, 0x3a, - 0x0b, 0x50, 0xec, 0x6b, 0x38, 0x27, 0xa1, 0xee, 0xb0, 0xa7, 0x16, 0x3a, 0x4e, 0xf6, 0xca, 0xf2, - 0x29, 0x09, 0xc0, 0x1a, 0xc7, 0xfe, 0x55, 0x0b, 0x4e, 0xe7, 0x0c, 0x5a, 0x81, 0x69, 0x6f, 0x89, - 0x96, 0x36, 0x79, 0x8a, 0xfd, 0x87, 0x60, 0xb0, 0x49, 0xd6, 0x1d, 0x19, 0x02, 0x67, 0xc8, 0xf6, - 0x59, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0x6f, 0x16, 0x9c, 0x48, 0xf7, 0x35, 0x66, 0xa9, 0x24, 0x7c, - 0x98, 0xdc, 0xb8, 0x11, 0x6c, 0x91, 0x68, 0x87, 0xbe, 0xb9, 0x95, 0x49, 0x25, 0xe9, 0xc2, 0xc0, - 0x39, 0x4f, 0xb1, 0xf2, 0xad, 0x4d, 0x35, 0xda, 0x72, 0x46, 0xde, 0x2c, 0x72, 0x46, 0xea, 0x8f, - 0x69, 0x1e, 0x97, 0x2b, 0x96, 0xd8, 0xe4, 0x6f, 0x7f, 0xa7, 0x02, 0x2a, 0x2f, 0x96, 0xc5, 0x1f, - 0x15, 0x14, 0xbd, 0x75, 0xd0, 0x0c, 0x22, 0x35, 0x19, 0x2a, 0x7b, 0x05, 0x04, 0x70, 0x2f, 0x89, - 0xe9, 0xba, 0x54, 0x6f, 0xb8, 0xaa, 0x41, 0xd8, 0xc4, 0xa3, 0x3d, 0xf1, 0xdc, 0x2d, 0xc2, 0x1f, - 0x1a, 0x48, 0xf7, 0x64, 0x41, 0x02, 0xb0, 0xc6, 0xa1, 0x3d, 0x69, 0xba, 0xeb, 0xeb, 0x62, 0xcb, - 0xaf, 0x7a, 0x42, 0x47, 0x07, 0x33, 0x08, 0xaf, 0xc8, 0x1d, 0x6c, 0x0a, 0x2b, 0xd8, 0xa8, 0xc8, - 0x1d, 0x6c, 0x62, 0x06, 0xa1, 0x76, 0x9b, 0x1f, 0x44, 0x6d, 0x76, 0xa5, 0x7c, 0x53, 0x71, 0x11, - 0xd6, 0xaf, 0xb2, 0xdb, 0xae, 0x77, 0xa3, 0xe0, 0xbc, 0xe7, 0xe8, 0x0c, 0x0c, 0x23, 0xd2, 0x74, - 0x1b, 0x89, 0x49, 0x0d, 0xd2, 0x33, 0x70, 0xb9, 0x0b, 0x03, 0xe7, 0x3c, 0x85, 0xa6, 0xe0, 0x84, - 0xcc, 0x6b, 0x96, 0x55, 0x6b, 0x86, 0xd2, 0x55, 0x32, 0x70, 0x1a, 0x8c, 0xb3, 0xf8, 0x54, 0xaa, - 0xb5, 0x45, 0xc1, 0x2a, 0x66, 0x2c, 0x1b, 0x52, 0x4d, 0x16, 0xb2, 0xc2, 0x0a, 0xc3, 0xfe, 0x54, - 0x99, 0x6a, 0xe1, 0x1e, 0x85, 0xda, 0xee, 0x5b, 0xb4, 0x60, 0x7a, 0x46, 0x56, 0xfa, 0x98, 0x91, - 0xcf, 0xc3, 0xf0, 0xed, 0x38, 0xf0, 0x55, 0x24, 0x5e, 0xb5, 0x67, 0x24, 0x9e, 0x81, 0x95, 0x1f, - 0x89, 0x37, 0x50, 0x54, 0x24, 0xde, 0xe0, 0x21, 0x23, 0xf1, 0xbe, 0x55, 0x05, 0x75, 0x35, 0xc8, - 0x75, 0x92, 0xdc, 0x09, 0xa2, 0x4d, 0xd7, 0x6f, 0xb1, 0x7c, 0xf0, 0xaf, 0x59, 0x30, 0xcc, 0xd7, - 0xcb, 0x82, 0x99, 0x49, 0xb5, 0x5e, 0xd0, 0x9d, 0x13, 0x29, 0x66, 0x13, 0xab, 0x06, 0xa3, 0xcc, - 0xd5, 0x9b, 0x26, 0x08, 0xa7, 0x7a, 0x84, 0x3e, 0x0e, 0x20, 0xfd, 0xa3, 0xeb, 0x52, 0x64, 0xce, - 0x17, 0xd3, 0x3f, 0x4c, 0xd6, 0xb5, 0x0d, 0xbc, 0xaa, 0x98, 0x60, 0x83, 0x21, 0xfa, 0xac, 0xce, - 0x32, 0xe3, 0x21, 0xfb, 0x1f, 0x3d, 0x96, 0xb1, 0xe9, 0x27, 0xc7, 0x0c, 0xc3, 0xa0, 0xeb, 0xb7, - 0xe8, 0x3c, 0x11, 0x11, 0x4b, 0xef, 0xca, 0xab, 0xa5, 0xb0, 0x10, 0x38, 0xcd, 0x69, 0xc7, 0x73, - 0xfc, 0x06, 0x89, 0xe6, 0x39, 0xba, 0x79, 0xe1, 0x34, 0x6b, 0xc0, 0x92, 0x50, 0xd7, 0xa5, 0x2a, - 0xd5, 0x7e, 0x2e, 0x55, 0x39, 0xff, 0x01, 0x38, 0xd5, 0xf5, 0x31, 0x0f, 0x94, 0x52, 0x76, 0xf8, - 0x6c, 0x34, 0xfb, 0x9f, 0x0f, 0x68, 0xa5, 0x75, 0x3d, 0x68, 0xf2, 0xab, 0x3d, 0x22, 0xfd, 0x45, - 0x85, 0x8d, 0x5b, 0xe0, 0x14, 0x31, 0x2e, 0xad, 0x56, 0x8d, 0xd8, 0x64, 0x49, 0xe7, 0x68, 0xe8, - 0x44, 0xc4, 0x3f, 0xee, 0x39, 0xba, 0xac, 0x98, 0x60, 0x83, 0x21, 0xda, 0x48, 0xe5, 0x94, 0x5c, - 0x3e, 0x7a, 0x4e, 0x09, 0xab, 0x32, 0x95, 0x57, 0x8d, 0xff, 0x4b, 0x16, 0x8c, 0xfa, 0xa9, 0x99, - 0x5b, 0x4c, 0x18, 0x69, 0xfe, 0xaa, 0xe0, 0x37, 0x4b, 0xa5, 0xdb, 0x70, 0x86, 0x7f, 0x9e, 0x4a, - 0xab, 0x1e, 0x50, 0xa5, 0xe9, 0x3b, 0x82, 0x06, 0x7a, 0xdd, 0x11, 0x84, 0x7c, 0x75, 0x49, 0xda, - 0x60, 0xe1, 0x97, 0xa4, 0x41, 0xce, 0x05, 0x69, 0xb7, 0xa0, 0xde, 0x88, 0x88, 0x93, 0x1c, 0xf2, - 0xbe, 0x2c, 0x76, 0x40, 0x3f, 0x23, 0x09, 0x60, 0x4d, 0xcb, 0xfe, 0xdf, 0x15, 0x38, 0x29, 0x47, - 0x44, 0x86, 0xa0, 0x53, 0xfd, 0xc8, 0xf9, 0x6a, 0xe3, 0x56, 0xe9, 0xc7, 0x2b, 0x12, 0x80, 0x35, - 0x0e, 0xb5, 0xc7, 0x3a, 0x31, 0x59, 0x0a, 0x89, 0xbf, 0xe0, 0xae, 0xc5, 0xe2, 0x9c, 0x53, 0x2d, - 0x94, 0x1b, 0x1a, 0x84, 0x4d, 0x3c, 0x6a, 0x8c, 0x73, 0xbb, 0x38, 0xce, 0xa6, 0xaf, 0x08, 0x7b, - 0x1b, 0x4b, 0x38, 0xfa, 0xf9, 0xdc, 0xca, 0xb1, 0xc5, 0x24, 0x6e, 0x75, 0x45, 0xde, 0x1f, 0xf0, - 0x8a, 0xc5, 0xbf, 0x6d, 0xc1, 0x59, 0xde, 0x2a, 0x47, 0xf2, 0x46, 0xd8, 0x74, 0x12, 0x12, 0x17, - 0x53, 0xc9, 0x3d, 0xa7, 0x7f, 0xda, 0xc9, 0x9b, 0xc7, 0x16, 0xe7, 0xf7, 0x06, 0xbd, 0x69, 0xc1, - 0x89, 0xcd, 0x54, 0xcd, 0x0f, 0xa9, 0x3a, 0x8e, 0x9a, 0x8e, 0x9f, 0x22, 0xaa, 0x97, 0x5a, 0xba, - 0x3d, 0xc6, 0x59, 0xee, 0xf6, 0x9f, 0x59, 0x60, 0x8a, 0xd1, 0xfb, 0x5f, 0x2a, 0xe4, 0xe0, 0xa6, - 0xa0, 0xb4, 0x2e, 0xab, 0x3d, 0xad, 0xcb, 0xc7, 0xa1, 0xdc, 0x71, 0x9b, 0x62, 0x7f, 0xa1, 0x4f, - 0x5f, 0xe7, 0x67, 0x31, 0x6d, 0xb7, 0xff, 0x49, 0x55, 0xfb, 0x2d, 0x44, 0x5e, 0xd4, 0xf7, 0xc5, - 0x6b, 0xaf, 0xab, 0x62, 0x63, 0xfc, 0xcd, 0xaf, 0x77, 0x15, 0x1b, 0xfb, 0x91, 0x83, 0xa7, 0xbd, - 0xf1, 0x01, 0xea, 0x55, 0x6b, 0x6c, 0x70, 0x9f, 0x9c, 0xb7, 0xdb, 0x50, 0xa3, 0x5b, 0x30, 0xe6, - 0x80, 0xac, 0xa5, 0x3a, 0x55, 0xbb, 0x22, 0xda, 0xef, 0xed, 0x8e, 0xbf, 0xef, 0xe0, 0xdd, 0x92, - 0x4f, 0x63, 0x45, 0x1f, 0xc5, 0x50, 0xa7, 0xbf, 0x59, 0x7a, 0x9e, 0xd8, 0xdc, 0xdd, 0x50, 0x32, - 0x53, 0x02, 0x0a, 0xc9, 0xfd, 0xd3, 0x7c, 0x90, 0x0f, 0x75, 0x76, 0x1b, 0x2d, 0x63, 0xca, 0xf7, - 0x80, 0xcb, 0x2a, 0x49, 0x4e, 0x02, 0xee, 0xed, 0x8e, 0xbf, 0x74, 0x70, 0xa6, 0xea, 0x71, 0xac, - 0x59, 0xd8, 0x5f, 0xae, 0xe8, 0xb9, 0x2b, 0x6a, 0xcc, 0x7d, 0x5f, 0xcc, 0xdd, 0x17, 0x33, 0x73, - 0xf7, 0x42, 0xd7, 0xdc, 0x1d, 0xd5, 0xb7, 0xa6, 0xa6, 0x66, 0xe3, 0xfd, 0x36, 0x04, 0xf6, 0xf7, - 0x37, 0x30, 0x0b, 0xe8, 0xf5, 0x8e, 0x1b, 0x91, 0x78, 0x39, 0xea, 0xf8, 0xae, 0xdf, 0x62, 0xd3, - 0xb1, 0x66, 0x5a, 0x40, 0x29, 0x30, 0xce, 0xe2, 0xd3, 0x4d, 0x3d, 0xfd, 0xe6, 0xb7, 0x9c, 0x2d, - 0x3e, 0xab, 0x8c, 0xb2, 0x5b, 0x2b, 0xa2, 0x1d, 0x2b, 0x0c, 0xfb, 0x1b, 0xec, 0x2c, 0xdb, 0xc8, - 0x0b, 0xa6, 0x73, 0xc2, 0x63, 0xd7, 0xff, 0xf2, 0x9a, 0x5d, 0x6a, 0x4e, 0xf0, 0x3b, 0x7f, 0x39, - 0x0c, 0xdd, 0x81, 0xc1, 0x35, 0x7e, 0xff, 0x5d, 0x31, 0xf5, 0xc9, 0xc5, 0x65, 0x7a, 0xec, 0x96, - 0x13, 0x79, 0xb3, 0xde, 0x3d, 0xfd, 0x13, 0x4b, 0x6e, 0xf6, 0x37, 0x2b, 0x70, 0x22, 0x73, 0x41, - 0x6c, 0xaa, 0x5a, 0x6a, 0x69, 0xdf, 0x6a, 0xa9, 0x1f, 0x01, 0x68, 0x92, 0xd0, 0x0b, 0x76, 0x98, - 0x39, 0x56, 0x39, 0xb0, 0x39, 0xa6, 0x2c, 0xf8, 0x59, 0x45, 0x05, 0x1b, 0x14, 0x45, 0xa1, 0x32, - 0x5e, 0x7c, 0x35, 0x53, 0xa8, 0xcc, 0xb8, 0xc5, 0x60, 0xe0, 0xfe, 0xde, 0x62, 0xe0, 0xc2, 0x09, - 0xde, 0x45, 0x95, 0x7d, 0x7b, 0x88, 0x24, 0x5b, 0x96, 0xbf, 0x30, 0x9b, 0x26, 0x83, 0xb3, 0x74, - 0x1f, 0xe4, 0xfd, 0xcf, 0xe8, 0xdd, 0x50, 0x97, 0xdf, 0x39, 0x1e, 0xab, 0xeb, 0x0a, 0x06, 0x72, - 0x1a, 0xb0, 0x7b, 0x99, 0xc5, 0x4f, 0xfb, 0x8b, 0x25, 0x6a, 0x3d, 0xf3, 0x7f, 0xaa, 0x12, 0xcd, - 0x53, 0x30, 0xe0, 0x74, 0x92, 0x8d, 0xa0, 0xeb, 0x0e, 0xbd, 0x29, 0xd6, 0x8a, 0x05, 0x14, 0x2d, - 0x40, 0xa5, 0xa9, 0xab, 0x8b, 0x1c, 0x64, 0x14, 0xb5, 0x23, 0xd2, 0x49, 0x08, 0x66, 0x54, 0xd0, - 0x63, 0x50, 0x49, 0x9c, 0x96, 0x4c, 0x74, 0x62, 0xc9, 0xad, 0xab, 0x4e, 0x2b, 0xc6, 0xac, 0xd5, - 0x54, 0x9a, 0x95, 0x7d, 0x94, 0xe6, 0x4b, 0x30, 0x12, 0xbb, 0x2d, 0xdf, 0x49, 0x3a, 0x11, 0x31, - 0x0e, 0xd7, 0x74, 0xbc, 0x84, 0x09, 0xc4, 0x69, 0x5c, 0xfb, 0x37, 0x87, 0xe1, 0xcc, 0xca, 0xcc, - 0xa2, 0xac, 0x99, 0x7d, 0x6c, 0xb9, 0x4a, 0x79, 0x3c, 0xee, 0x5f, 0xae, 0x52, 0x0f, 0xee, 0x9e, - 0x91, 0xab, 0xe4, 0x19, 0xb9, 0x4a, 0xe9, 0xc4, 0x91, 0x72, 0x11, 0x89, 0x23, 0x79, 0x3d, 0xe8, - 0x27, 0x71, 0xe4, 0xd8, 0x92, 0x97, 0xf6, 0xec, 0xd0, 0x81, 0x92, 0x97, 0x54, 0x66, 0x57, 0x21, - 0x21, 0xfd, 0x3d, 0x3e, 0x55, 0x6e, 0x66, 0x97, 0xca, 0xaa, 0xe1, 0xe9, 0x2a, 0x42, 0xc0, 0xbe, - 0x5a, 0x7c, 0x07, 0xfa, 0xc8, 0xaa, 0x11, 0x19, 0x33, 0x66, 0x26, 0xd7, 0x60, 0x11, 0x99, 0x5c, - 0x79, 0xdd, 0xd9, 0x37, 0x93, 0xeb, 0x25, 0x18, 0x69, 0x78, 0x81, 0x4f, 0x96, 0xa3, 0x20, 0x09, - 0x1a, 0x81, 0x27, 0x8c, 0x69, 0x25, 0x12, 0x66, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, 0x4a, 0x03, 0xab, - 0x1f, 0x35, 0x0d, 0x0c, 0x1e, 0x50, 0x1a, 0xd8, 0xcf, 0xe8, 0x84, 0xe5, 0x21, 0xf6, 0x45, 0x3e, - 0x52, 0xfc, 0x17, 0xe9, 0x27, 0x6b, 0x19, 0xbd, 0xc5, 0x2f, 0xb1, 0xa3, 0xe6, 0xe8, 0x4c, 0xd0, - 0xa6, 0xe6, 0xd6, 0x30, 0x1b, 0x92, 0xd7, 0x8e, 0x61, 0xc2, 0xde, 0x5a, 0xd1, 0x6c, 0xd4, 0xc5, - 0x76, 0xba, 0x09, 0xa7, 0x3b, 0x72, 0x94, 0x84, 0xea, 0xaf, 0x96, 0xe0, 0x07, 0xf6, 0xed, 0x02, - 0xba, 0x03, 0x90, 0x38, 0x2d, 0x31, 0x51, 0xc5, 0x31, 0xc5, 0x11, 0x83, 0x1a, 0x57, 0x25, 0x3d, - 0x5e, 0x09, 0x44, 0xfd, 0x65, 0x07, 0x00, 0xf2, 0x37, 0x8b, 0x65, 0x0c, 0xbc, 0xae, 0x82, 0x89, - 0x38, 0xf0, 0x08, 0x66, 0x10, 0xaa, 0xfe, 0x23, 0xd2, 0xd2, 0xb7, 0x2e, 0xab, 0xcf, 0x87, 0x59, - 0x2b, 0x16, 0x50, 0xf4, 0x02, 0x0c, 0x39, 0x9e, 0xc7, 0xb3, 0x52, 0x48, 0x2c, 0x6e, 0xb1, 0xd1, - 0x95, 0xdb, 0x34, 0x08, 0x9b, 0x78, 0xf6, 0x9f, 0x96, 0x60, 0x7c, 0x1f, 0x99, 0xd2, 0x95, 0x67, - 0x57, 0xed, 0x3b, 0xcf, 0x4e, 0x64, 0x06, 0x0c, 0xf4, 0xc8, 0x0c, 0x78, 0x01, 0x86, 0x12, 0xe2, - 0xb4, 0x45, 0x18, 0x94, 0xd8, 0x7f, 0xeb, 0x73, 0x57, 0x0d, 0xc2, 0x26, 0x1e, 0x95, 0x62, 0xa3, - 0x4e, 0xa3, 0x41, 0xe2, 0x58, 0x86, 0xfe, 0x0b, 0x1f, 0x66, 0x61, 0x79, 0x05, 0xcc, 0x35, 0x3c, - 0x95, 0x62, 0x81, 0x33, 0x2c, 0xb3, 0x03, 0x5e, 0xef, 0x73, 0xc0, 0xbf, 0x5e, 0x82, 0xc7, 0xf7, - 0xd4, 0x6e, 0x7d, 0x67, 0x65, 0x74, 0x62, 0x12, 0x65, 0x27, 0xce, 0x8d, 0x98, 0x44, 0x98, 0x41, - 0xf8, 0x28, 0x85, 0xa1, 0x71, 0xab, 0x75, 0xd1, 0x29, 0x43, 0x7c, 0x94, 0x52, 0x2c, 0x70, 0x86, - 0xe5, 0x61, 0xa7, 0xe5, 0xdf, 0x2b, 0xc1, 0x93, 0x7d, 0xd8, 0x00, 0x05, 0xa6, 0x56, 0xa5, 0x13, - 0xdc, 0xca, 0x0f, 0x28, 0x0f, 0xf1, 0x90, 0xc3, 0xf5, 0x8d, 0x12, 0x9c, 0xef, 0xad, 0x8a, 0xd1, - 0x8f, 0xd2, 0x3d, 0xbc, 0x8c, 0x7d, 0x32, 0x73, 0xe3, 0x4e, 0xf3, 0xfd, 0x7b, 0x0a, 0x84, 0xb3, - 0xb8, 0x68, 0x02, 0x20, 0x74, 0x92, 0x8d, 0xf8, 0xd2, 0xb6, 0x1b, 0x27, 0xa2, 0xf6, 0xcb, 0x28, - 0x3f, 0x31, 0x92, 0xad, 0xd8, 0xc0, 0xa0, 0xec, 0xd8, 0xbf, 0xd9, 0xe0, 0x7a, 0x90, 0xf0, 0x87, - 0xf8, 0x36, 0xe2, 0xb4, 0xbc, 0x29, 0xc3, 0x00, 0xe1, 0x2c, 0x2e, 0x65, 0xc7, 0xce, 0x24, 0x79, - 0x47, 0xf9, 0xfe, 0x82, 0xb1, 0x5b, 0x50, 0xad, 0xd8, 0xc0, 0xc8, 0x66, 0xfd, 0x55, 0xf7, 0xcf, - 0xfa, 0xb3, 0xff, 0x71, 0x09, 0xce, 0xf5, 0x34, 0xe5, 0xfa, 0x5b, 0x80, 0x0f, 0x5f, 0xa6, 0xde, - 0xe1, 0xe6, 0xce, 0x01, 0x33, 0xca, 0xfe, 0xa8, 0xc7, 0x4c, 0x13, 0x19, 0x65, 0x87, 0x4f, 0xc9, - 0x7e, 0xf8, 0xc6, 0xb3, 0x2b, 0x89, 0xac, 0x72, 0x80, 0x24, 0xb2, 0xcc, 0xc7, 0xa8, 0xf6, 0xb9, - 0x90, 0xff, 0xbc, 0xdc, 0x73, 0x78, 0xe9, 0xd6, 0xaf, 0x2f, 0xef, 0xe8, 0x2c, 0x9c, 0x74, 0x7d, - 0x76, 0x6b, 0xd2, 0x4a, 0x67, 0x4d, 0x94, 0x03, 0x29, 0xa5, 0xef, 0x2c, 0x9f, 0xcf, 0xc0, 0x71, - 0xd7, 0x13, 0x0f, 0x61, 0x52, 0xdf, 0xe1, 0x86, 0xf4, 0x60, 0x69, 0xa5, 0x68, 0x09, 0xce, 0xca, - 0xa1, 0xd8, 0x70, 0x22, 0xd2, 0x14, 0x6a, 0x24, 0x16, 0x69, 0x0c, 0xe7, 0x78, 0x2a, 0x44, 0x0e, - 0x02, 0xce, 0x7f, 0x8e, 0x5d, 0x54, 0x13, 0x84, 0x6e, 0x43, 0x6c, 0x72, 0xf4, 0x45, 0x35, 0xb4, - 0x11, 0x73, 0x98, 0xfd, 0x11, 0xa8, 0xab, 0xf7, 0xe7, 0xc1, 0xd4, 0x6a, 0xd2, 0x75, 0x05, 0x53, - 0xab, 0x19, 0x67, 0x60, 0xd1, 0xaf, 0x45, 0x4d, 0xe2, 0xcc, 0xea, 0xb9, 0x46, 0x76, 0x98, 0x7d, - 0x6c, 0xbf, 0x07, 0x86, 0x95, 0x9f, 0xa5, 0xdf, 0xeb, 0x7b, 0xec, 0x2f, 0x0f, 0xc0, 0x48, 0xaa, - 0x24, 0x5f, 0xca, 0xad, 0x69, 0xed, 0xeb, 0xd6, 0x64, 0xc1, 0xf1, 0x1d, 0x5f, 0xde, 0xed, 0x65, - 0x04, 0xc7, 0x77, 0x7c, 0x82, 0x39, 0x8c, 0x9a, 0xb7, 0xcd, 0x68, 0x07, 0x77, 0x7c, 0x11, 0xc4, - 0xaa, 0xcc, 0xdb, 0x59, 0xd6, 0x8a, 0x05, 0x14, 0x7d, 0xd2, 0x82, 0xe1, 0x98, 0xf9, 0xcc, 0xb9, - 0x53, 0x58, 0x4c, 0xba, 0xab, 0x47, 0xaf, 0x38, 0xa8, 0xca, 0x4f, 0xb2, 0xb8, 0x14, 0xb3, 0x05, - 0xa7, 0x38, 0xa2, 0xcf, 0x58, 0x50, 0x57, 0x57, 0x90, 0x88, 0x0b, 0xf8, 0x56, 0x8a, 0xad, 0x78, - 0xc8, 0xbd, 0x89, 0xea, 0xf8, 0x41, 0x95, 0x9e, 0xc3, 0x9a, 0x31, 0x8a, 0x95, 0xc7, 0x76, 0xf0, - 0x78, 0x3c, 0xb6, 0x90, 0xe3, 0xad, 0x7d, 0x37, 0xd4, 0xdb, 0x8e, 0xef, 0xae, 0x93, 0x38, 0xe1, - 0x4e, 0x54, 0x59, 0x88, 0x55, 0x36, 0x62, 0x0d, 0xa7, 0x0a, 0x39, 0x66, 0x2f, 0x96, 0x18, 0x5e, - 0x4f, 0xa6, 0x90, 0x57, 0x74, 0x33, 0x36, 0x71, 0x4c, 0x17, 0x2d, 0x3c, 0x50, 0x17, 0xed, 0xd0, - 0x3e, 0x2e, 0xda, 0x7f, 0x60, 0xc1, 0xd9, 0xdc, 0xaf, 0xf6, 0xf0, 0x86, 0x1b, 0xda, 0x5f, 0xa9, - 0xc2, 0xe9, 0x9c, 0xda, 0x9a, 0x68, 0xc7, 0x9c, 0xcf, 0x56, 0x11, 0x27, 0xf7, 0xe9, 0x83, 0x68, - 0x39, 0x8c, 0x39, 0x93, 0xf8, 0x60, 0x07, 0x24, 0xfa, 0x90, 0xa2, 0x7c, 0x7f, 0x0f, 0x29, 0x8c, - 0x69, 0x59, 0x79, 0xa0, 0xd3, 0xb2, 0xba, 0xf7, 0xb4, 0x44, 0xbf, 0x66, 0xc1, 0x58, 0xbb, 0x47, - 0x41, 0x77, 0xe1, 0x78, 0xbc, 0x79, 0x3c, 0xe5, 0xe2, 0xa7, 0x1f, 0xbb, 0xbb, 0x3b, 0xde, 0xb3, - 0x8e, 0x3e, 0xee, 0xd9, 0x2b, 0xfb, 0x3b, 0x65, 0x60, 0x85, 0x5d, 0x59, 0xfd, 0xb4, 0x1d, 0xf4, - 0x09, 0xb3, 0x44, 0xaf, 0x55, 0x54, 0x39, 0x59, 0x4e, 0x5c, 0x95, 0xf8, 0xe5, 0x23, 0x98, 0x57, - 0xf1, 0x37, 0x2b, 0xb4, 0x4a, 0x7d, 0x08, 0x2d, 0x4f, 0xd6, 0x42, 0x2e, 0x17, 0x5f, 0x0b, 0xb9, - 0x9e, 0xad, 0x83, 0xbc, 0xf7, 0x27, 0xae, 0x3c, 0x94, 0x9f, 0xf8, 0x6f, 0x5a, 0x5c, 0xf0, 0x64, - 0xbe, 0x82, 0xb6, 0x0c, 0xac, 0x3d, 0x2c, 0x83, 0x67, 0xa0, 0x16, 0x13, 0x6f, 0xfd, 0x0a, 0x71, - 0x3c, 0x61, 0x41, 0xe8, 0x53, 0x63, 0xd1, 0x8e, 0x15, 0x06, 0xbb, 0x2c, 0xd5, 0xf3, 0x82, 0x3b, - 0x97, 0xda, 0x61, 0xb2, 0x23, 0x6c, 0x09, 0x7d, 0x59, 0xaa, 0x82, 0x60, 0x03, 0xcb, 0xfe, 0x5b, - 0x25, 0x3e, 0x03, 0x45, 0xe8, 0xc1, 0x8b, 0x99, 0xeb, 0xed, 0xfa, 0x3f, 0xb5, 0xff, 0x18, 0x40, - 0x43, 0x5d, 0x0c, 0x2f, 0xce, 0x84, 0xae, 0x1c, 0xf9, 0xd6, 0x6a, 0x41, 0x4f, 0xbf, 0x86, 0x6e, - 0xc3, 0x06, 0xbf, 0x94, 0x2c, 0x2d, 0xef, 0x2b, 0x4b, 0x53, 0x62, 0xa5, 0xb2, 0x8f, 0xb6, 0xfb, - 0x53, 0x0b, 0x52, 0x16, 0x11, 0x0a, 0xa1, 0x4a, 0xbb, 0xbb, 0x53, 0xcc, 0x9d, 0xf7, 0x26, 0x69, - 0x2a, 0x1a, 0xc5, 0xb4, 0x67, 0x3f, 0x31, 0x67, 0x84, 0x3c, 0x11, 0xa1, 0xc0, 0x47, 0xf5, 0x7a, - 0x71, 0x0c, 0xaf, 0x04, 0xc1, 0x26, 0x3f, 0xd8, 0xd4, 0xd1, 0x0e, 0xf6, 0x8b, 0x70, 0xaa, 0xab, - 0x53, 0xec, 0x26, 0xab, 0x40, 0x5e, 0xf4, 0x6f, 0x4c, 0x57, 0x96, 0x36, 0x89, 0x39, 0xcc, 0xfe, - 0x86, 0x05, 0x27, 0xb3, 0xe4, 0xd1, 0x5b, 0x16, 0x9c, 0x8a, 0xb3, 0xf4, 0x8e, 0x6b, 0xec, 0x54, - 0x94, 0x61, 0x17, 0x08, 0x77, 0x77, 0xc2, 0xfe, 0x3f, 0x62, 0xf2, 0xdf, 0x72, 0xfd, 0x66, 0x70, - 0x47, 0x19, 0x26, 0x56, 0x4f, 0xc3, 0x84, 0xae, 0xc7, 0xc6, 0x06, 0x69, 0x76, 0xbc, 0xae, 0x7c, - 0xcd, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0x4b, 0x4f, 0xeb, 0x88, 0x62, 0xe9, 0x99, 0x49, 0x39, 0x2b, - 0xda, 0xb1, 0xc2, 0x40, 0xcf, 0xc3, 0xb0, 0xf1, 0x92, 0x72, 0x5e, 0x32, 0x83, 0xdc, 0x50, 0x99, - 0x31, 0x4e, 0x61, 0xa1, 0x09, 0x00, 0x65, 0xe4, 0x48, 0x15, 0xc9, 0x1c, 0x45, 0x4a, 0x12, 0xc5, - 0xd8, 0xc0, 0x60, 0xc9, 0xa0, 0x5e, 0x27, 0x66, 0x3e, 0xfe, 0x01, 0x5d, 0xc0, 0x73, 0x46, 0xb4, - 0x61, 0x05, 0xa5, 0xd2, 0xa4, 0xed, 0xf8, 0x1d, 0xc7, 0xa3, 0x23, 0x24, 0xb6, 0x7e, 0x6a, 0x19, - 0x2e, 0x2a, 0x08, 0x36, 0xb0, 0xe8, 0x1b, 0x27, 0x6e, 0x9b, 0xbc, 0x12, 0xf8, 0x32, 0x3a, 0x4c, - 0x1f, 0xfb, 0x88, 0x76, 0xac, 0x30, 0xec, 0xff, 0x62, 0xc1, 0x09, 0x9d, 0x5a, 0xce, 0xef, 0xac, - 0x36, 0x77, 0xaa, 0xd6, 0xbe, 0x3b, 0xd5, 0x74, 0xce, 0x6d, 0xa9, 0xaf, 0x9c, 0x5b, 0x33, 0x1d, - 0xb6, 0xbc, 0x67, 0x3a, 0xec, 0x0f, 0xea, 0xfb, 0x50, 0x79, 0xde, 0xec, 0x50, 0xde, 0x5d, 0xa8, - 0xc8, 0x86, 0x81, 0x86, 0xa3, 0xea, 0xaa, 0x0c, 0xf3, 0xbd, 0xc3, 0xcc, 0x14, 0x43, 0x12, 0x10, - 0x7b, 0x09, 0xea, 0xea, 0xf4, 0x43, 0x6e, 0x54, 0xad, 0xfc, 0x8d, 0x6a, 0x5f, 0x69, 0x79, 0xd3, - 0x6b, 0xdf, 0xfc, 0xee, 0x13, 0xef, 0xf8, 0xbd, 0xef, 0x3e, 0xf1, 0x8e, 0x3f, 0xfc, 0xee, 0x13, - 0xef, 0xf8, 0xe4, 0xdd, 0x27, 0xac, 0x6f, 0xde, 0x7d, 0xc2, 0xfa, 0xbd, 0xbb, 0x4f, 0x58, 0x7f, - 0x78, 0xf7, 0x09, 0xeb, 0x3b, 0x77, 0x9f, 0xb0, 0xbe, 0xf4, 0x9f, 0x9e, 0x78, 0xc7, 0x2b, 0xb9, - 0xe1, 0x81, 0xf4, 0xc7, 0xb3, 0x8d, 0xe6, 0xe4, 0xd6, 0x45, 0x16, 0xa1, 0x46, 0x97, 0xd7, 0xa4, - 0x31, 0xa7, 0x26, 0xe5, 0xf2, 0xfa, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xa7, 0x24, 0x1a, 0xa3, - 0x6c, 0xe0, 0x00, 0x00, + 0xc9, 0x5e, 0x4f, 0x45, 0x1d, 0x3f, 0x71, 0xdb, 0xa4, 0xeb, 0x81, 0xf7, 0xec, 0xf7, 0x40, 0xdc, + 0xd8, 0x20, 0x6d, 0xa7, 0xeb, 0xb9, 0x1f, 0xe9, 0xf5, 0x5c, 0x27, 0x71, 0xbd, 0x49, 0xd7, 0x4f, + 0xe2, 0x24, 0xca, 0x3e, 0x64, 0xbf, 0x0e, 0x23, 0x53, 0xb7, 0x56, 0xa6, 0x3a, 0xc9, 0xc6, 0x4c, + 0xe0, 0xaf, 0xbb, 0x2d, 0xf4, 0x02, 0x0c, 0x35, 0xbc, 0x4e, 0x9c, 0x90, 0xe8, 0xba, 0xd3, 0x26, + 0x63, 0xd6, 0x05, 0xeb, 0xe9, 0xfa, 0xf4, 0xe9, 0x6f, 0xee, 0x8e, 0xbf, 0xe3, 0xee, 0xee, 0xf8, + 0xd0, 0x8c, 0x06, 0x61, 0x13, 0x0f, 0xfd, 0x10, 0x0c, 0x46, 0x81, 0x47, 0xa6, 0xf0, 0xf5, 0xb1, + 0x12, 0x7b, 0xe4, 0x84, 0x78, 0x64, 0x10, 0xf3, 0x66, 0x2c, 0xe1, 0xf6, 0x1f, 0x96, 0x00, 0xa6, + 0xc2, 0x70, 0x39, 0x0a, 0x6e, 0x93, 0x46, 0x82, 0x3e, 0x02, 0x35, 0x3a, 0x74, 0x4d, 0x27, 0x71, + 0x18, 0xb7, 0xa1, 0x8b, 0x3f, 0x3c, 0xc1, 0xdf, 0x64, 0xc2, 0x7c, 0x13, 0x3d, 0x71, 0x28, 0xf6, + 0xc4, 0xd6, 0x73, 0x13, 0x4b, 0x6b, 0xf4, 0xf9, 0x45, 0x92, 0x38, 0xd3, 0x48, 0x30, 0x03, 0xdd, + 0x86, 0x15, 0x55, 0xe4, 0x43, 0x25, 0x0e, 0x49, 0x83, 0x75, 0x6c, 0xe8, 0xe2, 0xc2, 0xc4, 0x51, + 0x66, 0xe8, 0x84, 0xee, 0xf9, 0x4a, 0x48, 0x1a, 0xd3, 0xc3, 0x82, 0x73, 0x85, 0xfe, 0xc3, 0x8c, + 0x0f, 0xda, 0x82, 0x81, 0x38, 0x71, 0x92, 0x4e, 0x3c, 0x56, 0x66, 0x1c, 0xaf, 0x17, 0xc6, 0x91, + 0x51, 0x9d, 0x1e, 0x15, 0x3c, 0x07, 0xf8, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x62, 0xc1, 0xa8, 0x46, + 0x5e, 0x70, 0xe3, 0x04, 0xfd, 0x64, 0xd7, 0xe0, 0x4e, 0xf4, 0x37, 0xb8, 0xf4, 0x69, 0x36, 0xb4, + 0x27, 0x05, 0xb3, 0x9a, 0x6c, 0x31, 0x06, 0xb6, 0x0d, 0x55, 0x37, 0x21, 0xed, 0x78, 0xac, 0x74, + 0xa1, 0xfc, 0xf4, 0xd0, 0xc5, 0x2b, 0x45, 0xbd, 0xe7, 0xf4, 0x88, 0x60, 0x5a, 0x9d, 0xa7, 0xe4, + 0x31, 0xe7, 0x62, 0xff, 0xda, 0xb0, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x73, 0x30, 0x14, 0x07, 0x9d, + 0xa8, 0x41, 0x30, 0x09, 0x83, 0x78, 0xcc, 0xba, 0x50, 0xa6, 0x53, 0x8f, 0xce, 0xd4, 0x15, 0xdd, + 0x8c, 0x4d, 0x1c, 0xf4, 0x05, 0x0b, 0x86, 0x9b, 0x24, 0x4e, 0x5c, 0x9f, 0xf1, 0x97, 0x9d, 0x5f, + 0x3d, 0x72, 0xe7, 0x65, 0xe3, 0xac, 0x26, 0x3e, 0x7d, 0x46, 0xbc, 0xc8, 0xb0, 0xd1, 0x18, 0xe3, + 0x14, 0x7f, 0xba, 0xe2, 0x9a, 0x24, 0x6e, 0x44, 0x6e, 0x48, 0xff, 0xb3, 0x39, 0x63, 0xac, 0xb8, + 0x59, 0x0d, 0xc2, 0x26, 0x1e, 0xf2, 0xa1, 0x4a, 0x57, 0x54, 0x3c, 0x56, 0x61, 0xfd, 0x9f, 0x3f, + 0x5a, 0xff, 0xc5, 0xa0, 0xd2, 0xc5, 0xaa, 0x47, 0x9f, 0xfe, 0x8b, 0x31, 0x67, 0x83, 0x3e, 0x6f, + 0xc1, 0x98, 0x58, 0xf1, 0x98, 0xf0, 0x01, 0xbd, 0xb5, 0xe1, 0x26, 0xc4, 0x73, 0xe3, 0x64, 0xac, + 0xca, 0xfa, 0x30, 0xd9, 0xdf, 0xdc, 0x9a, 0x8b, 0x82, 0x4e, 0x78, 0xcd, 0xf5, 0x9b, 0xd3, 0x17, + 0x04, 0xa7, 0xb1, 0x99, 0x1e, 0x84, 0x71, 0x4f, 0x96, 0xe8, 0xcb, 0x16, 0x9c, 0xf7, 0x9d, 0x36, + 0x89, 0x43, 0x87, 0x7e, 0x5a, 0x0e, 0x9e, 0xf6, 0x9c, 0xc6, 0x26, 0xeb, 0xd1, 0xc0, 0xe1, 0x7a, + 0x64, 0x8b, 0x1e, 0x9d, 0xbf, 0xde, 0x93, 0x34, 0xde, 0x83, 0x2d, 0xfa, 0xba, 0x05, 0xa7, 0x82, + 0x28, 0xdc, 0x70, 0x7c, 0xd2, 0x94, 0xd0, 0x78, 0x6c, 0x90, 0x2d, 0xbd, 0x0f, 0x1f, 0xed, 0x13, + 0x2d, 0x65, 0xc9, 0x2e, 0x06, 0xbe, 0x9b, 0x04, 0xd1, 0x0a, 0x49, 0x12, 0xd7, 0x6f, 0xc5, 0xd3, + 0x67, 0xef, 0xee, 0x8e, 0x9f, 0xea, 0xc2, 0xc2, 0xdd, 0xfd, 0x41, 0x3f, 0x05, 0x43, 0xf1, 0x8e, + 0xdf, 0xb8, 0xe5, 0xfa, 0xcd, 0xe0, 0x4e, 0x3c, 0x56, 0x2b, 0x62, 0xf9, 0xae, 0x28, 0x82, 0x62, + 0x01, 0x6a, 0x06, 0xd8, 0xe4, 0x96, 0xff, 0xe1, 0xf4, 0x54, 0xaa, 0x17, 0xfd, 0xe1, 0xf4, 0x64, + 0xda, 0x83, 0x2d, 0xfa, 0x79, 0x0b, 0x46, 0x62, 0xb7, 0xe5, 0x3b, 0x49, 0x27, 0x22, 0xd7, 0xc8, + 0x4e, 0x3c, 0x06, 0xac, 0x23, 0x57, 0x8f, 0x38, 0x2a, 0x06, 0xc9, 0xe9, 0xb3, 0xa2, 0x8f, 0x23, + 0x66, 0x6b, 0x8c, 0xd3, 0x7c, 0xf3, 0x16, 0x9a, 0x9e, 0xd6, 0x43, 0xc5, 0x2e, 0x34, 0x3d, 0xa9, + 0x7b, 0xb2, 0x44, 0x3f, 0x01, 0x27, 0x79, 0x93, 0x1a, 0xd9, 0x78, 0x6c, 0x98, 0x09, 0xda, 0x33, + 0x77, 0x77, 0xc7, 0x4f, 0xae, 0x64, 0x60, 0xb8, 0x0b, 0x1b, 0xbd, 0x0e, 0xe3, 0x21, 0x89, 0xda, + 0x6e, 0xb2, 0xe4, 0x7b, 0x3b, 0x52, 0x7c, 0x37, 0x82, 0x90, 0x34, 0x45, 0x77, 0xe2, 0xb1, 0x91, + 0x0b, 0xd6, 0xd3, 0xb5, 0xe9, 0x77, 0x89, 0x6e, 0x8e, 0x2f, 0xef, 0x8d, 0x8e, 0xf7, 0xa3, 0x67, + 0xff, 0xcb, 0x12, 0x9c, 0xcc, 0x2a, 0x4e, 0xf4, 0xb7, 0x2d, 0x38, 0x71, 0xfb, 0x4e, 0xb2, 0x1a, + 0x6c, 0x12, 0x3f, 0x9e, 0xde, 0xa1, 0xe2, 0x8d, 0xa9, 0x8c, 0xa1, 0x8b, 0x8d, 0x62, 0x55, 0xf4, + 0xc4, 0xd5, 0x34, 0x97, 0x4b, 0x7e, 0x12, 0xed, 0x4c, 0x3f, 0x2a, 0xde, 0xee, 0xc4, 0xd5, 0x5b, + 0xab, 0x26, 0x14, 0x67, 0x3b, 0x75, 0xfe, 0xb3, 0x16, 0x9c, 0xc9, 0x23, 0x81, 0x4e, 0x42, 0x79, + 0x93, 0xec, 0x70, 0xab, 0x0c, 0xd3, 0x9f, 0xe8, 0x55, 0xa8, 0x6e, 0x39, 0x5e, 0x87, 0x08, 0xeb, + 0x66, 0xee, 0x68, 0x2f, 0xa2, 0x7a, 0x86, 0x39, 0xd5, 0xf7, 0x96, 0x5e, 0xb4, 0xec, 0xdf, 0x2b, + 0xc3, 0x90, 0xa1, 0xdf, 0xee, 0x83, 0xc5, 0x16, 0xa4, 0x2c, 0xb6, 0xc5, 0xc2, 0x54, 0x73, 0x4f, + 0x93, 0xed, 0x4e, 0xc6, 0x64, 0x5b, 0x2a, 0x8e, 0xe5, 0x9e, 0x36, 0x1b, 0x4a, 0xa0, 0x1e, 0x84, + 0xd4, 0x22, 0xa7, 0xaa, 0xbf, 0x52, 0xc4, 0x27, 0x5c, 0x92, 0xe4, 0xa6, 0x47, 0xee, 0xee, 0x8e, + 0xd7, 0xd5, 0x5f, 0xac, 0x19, 0xd9, 0xdf, 0xb6, 0xe0, 0x8c, 0xd1, 0xc7, 0x99, 0xc0, 0x6f, 0xba, + 0xec, 0xd3, 0x5e, 0x80, 0x4a, 0xb2, 0x13, 0x4a, 0xb3, 0x5f, 0x8d, 0xd4, 0xea, 0x4e, 0x48, 0x30, + 0x83, 0x50, 0x43, 0xbf, 0x4d, 0xe2, 0xd8, 0x69, 0x91, 0xac, 0xa1, 0xbf, 0xc8, 0x9b, 0xb1, 0x84, + 0xa3, 0x08, 0x90, 0xe7, 0xc4, 0xc9, 0x6a, 0xe4, 0xf8, 0x31, 0x23, 0xbf, 0xea, 0xb6, 0x89, 0x18, + 0xe0, 0xff, 0xbf, 0xbf, 0x19, 0x43, 0x9f, 0x98, 0x7e, 0xe4, 0xee, 0xee, 0x38, 0x5a, 0xe8, 0xa2, + 0x84, 0x73, 0xa8, 0xdb, 0x5f, 0xb6, 0xe0, 0x91, 0x7c, 0x5b, 0x0c, 0x3d, 0x05, 0x03, 0x7c, 0xcb, + 0x27, 0xde, 0x4e, 0x7f, 0x12, 0xd6, 0x8a, 0x05, 0x14, 0x4d, 0x42, 0x5d, 0xe9, 0x09, 0xf1, 0x8e, + 0xa7, 0x04, 0x6a, 0x5d, 0x2b, 0x17, 0x8d, 0x43, 0x07, 0x8d, 0xfe, 0x11, 0x96, 0x9b, 0x1a, 0x34, + 0xb6, 0x49, 0x62, 0x10, 0xfb, 0x3f, 0x58, 0x70, 0xc2, 0xe8, 0xd5, 0x7d, 0x30, 0xcd, 0xfd, 0xb4, + 0x69, 0x3e, 0x5f, 0xd8, 0x7c, 0xee, 0x61, 0x9b, 0x7f, 0xde, 0x82, 0xf3, 0x06, 0xd6, 0xa2, 0x93, + 0x34, 0x36, 0x2e, 0x6d, 0x87, 0x11, 0x89, 0xe9, 0x76, 0x1a, 0x3d, 0x6e, 0xc8, 0xad, 0xe9, 0x21, + 0x41, 0xa1, 0x7c, 0x8d, 0xec, 0x70, 0x21, 0xf6, 0x0c, 0xd4, 0xf8, 0xe4, 0x0c, 0x22, 0x31, 0xe2, + 0xea, 0xdd, 0x96, 0x44, 0x3b, 0x56, 0x18, 0xc8, 0x86, 0x01, 0x26, 0x9c, 0xe8, 0x62, 0xa5, 0x6a, + 0x08, 0xe8, 0x47, 0xbc, 0xc9, 0x5a, 0xb0, 0x80, 0xd8, 0x71, 0xaa, 0x3b, 0xcb, 0x11, 0x61, 0x1f, + 0xb7, 0x79, 0xd9, 0x25, 0x5e, 0x33, 0xa6, 0xdb, 0x06, 0xc7, 0xf7, 0x83, 0x44, 0xec, 0x00, 0x8c, + 0x6d, 0xc3, 0x94, 0x6e, 0xc6, 0x26, 0x0e, 0x65, 0xea, 0x39, 0x6b, 0xc4, 0xe3, 0x23, 0x2a, 0x98, + 0x2e, 0xb0, 0x16, 0x2c, 0x20, 0xf6, 0xdd, 0x12, 0xdb, 0xa0, 0xa8, 0xa5, 0x4f, 0xee, 0xc7, 0xee, + 0x36, 0x4a, 0xc9, 0xca, 0xe5, 0xe2, 0x04, 0x17, 0xe9, 0xbd, 0xc3, 0x7d, 0x23, 0x23, 0x2e, 0x71, + 0xa1, 0x5c, 0xf7, 0xde, 0xe5, 0xfe, 0x76, 0x09, 0xc6, 0xd3, 0x0f, 0x74, 0x49, 0x5b, 0xba, 0xa5, + 0x32, 0x18, 0x65, 0x9d, 0x18, 0x06, 0x3e, 0x36, 0xf1, 0x7a, 0x08, 0xac, 0xd2, 0x71, 0x0a, 0x2c, + 0x53, 0x9e, 0x96, 0xf7, 0x91, 0xa7, 0x4f, 0xa9, 0x51, 0xaf, 0x64, 0x04, 0x58, 0x5a, 0xa7, 0x5c, + 0x80, 0x4a, 0x9c, 0x90, 0x70, 0xac, 0x9a, 0x96, 0x47, 0x2b, 0x09, 0x09, 0x31, 0x83, 0xd8, 0xff, + 0xb5, 0x04, 0x8f, 0xa6, 0xc7, 0x50, 0xab, 0x80, 0xf7, 0xa7, 0x54, 0xc0, 0xbb, 0x4d, 0x15, 0x70, + 0x6f, 0x77, 0xfc, 0x9d, 0x3d, 0x1e, 0xfb, 0x9e, 0xd1, 0x10, 0x68, 0x2e, 0x33, 0x8a, 0x93, 0xe9, + 0x51, 0xbc, 0xb7, 0x3b, 0xfe, 0x78, 0x8f, 0x77, 0xcc, 0x0c, 0xf3, 0x53, 0x30, 0x10, 0x11, 0x27, + 0x0e, 0x7c, 0x31, 0xd0, 0xea, 0x73, 0x60, 0xd6, 0x8a, 0x05, 0xd4, 0xfe, 0x37, 0xf5, 0xec, 0x60, + 0xcf, 0x71, 0x27, 0x5c, 0x10, 0x21, 0x17, 0x2a, 0xcc, 0xac, 0xe7, 0xa2, 0xe1, 0xda, 0xd1, 0x96, + 0x11, 0x55, 0x03, 0x8a, 0xf4, 0x74, 0x8d, 0x7e, 0x35, 0xda, 0x84, 0x19, 0x0b, 0xb4, 0x0d, 0xb5, + 0x86, 0xb4, 0xb6, 0x4b, 0x45, 0xf8, 0xa5, 0x84, 0xad, 0xad, 0x39, 0x0e, 0x53, 0x79, 0xad, 0x4c, + 0x74, 0xc5, 0x0d, 0x11, 0x28, 0xb7, 0xdc, 0x44, 0x7c, 0xd6, 0x23, 0xee, 0xa7, 0xe6, 0x5c, 0xe3, + 0x15, 0x07, 0xa9, 0x12, 0x99, 0x73, 0x13, 0x4c, 0xe9, 0xa3, 0x9f, 0xb5, 0x60, 0x28, 0x6e, 0xb4, + 0x97, 0xa3, 0x60, 0xcb, 0x6d, 0x92, 0x48, 0x58, 0x53, 0x47, 0x14, 0x4d, 0x2b, 0x33, 0x8b, 0x92, + 0xa0, 0xe6, 0xcb, 0xf7, 0xb7, 0x1a, 0x82, 0x4d, 0xbe, 0x74, 0x97, 0xf1, 0xa8, 0x78, 0xf7, 0x59, + 0xd2, 0x70, 0xa9, 0xfe, 0x93, 0x9b, 0x2a, 0x36, 0x53, 0x8e, 0x6c, 0x5d, 0xce, 0x76, 0x1a, 0x9b, + 0x74, 0xbd, 0xe9, 0x0e, 0xbd, 0xf3, 0xee, 0xee, 0xf8, 0xa3, 0x33, 0xf9, 0x3c, 0x71, 0xaf, 0xce, + 0xb0, 0x01, 0x0b, 0x3b, 0x9e, 0x87, 0xc9, 0xeb, 0x1d, 0xc2, 0x5c, 0x26, 0x05, 0x0c, 0xd8, 0xb2, + 0x26, 0x98, 0x19, 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x75, 0x18, 0x68, 0x3b, 0x49, 0xe4, 0x6e, + 0x0b, 0x3f, 0xc9, 0x11, 0xed, 0xfd, 0x45, 0x46, 0x4b, 0x33, 0x67, 0x9a, 0x9a, 0x37, 0x62, 0xc1, + 0x08, 0xb5, 0xa1, 0xda, 0x26, 0x51, 0x8b, 0x8c, 0xd5, 0x8a, 0xf0, 0x09, 0x2f, 0x52, 0x52, 0x9a, + 0x61, 0x9d, 0x5a, 0x47, 0xac, 0x0d, 0x73, 0x2e, 0xe8, 0x55, 0xa8, 0xc5, 0xc4, 0x23, 0x0d, 0x6a, + 0xdf, 0xd4, 0x19, 0xc7, 0x1f, 0xe9, 0xd3, 0xd6, 0xa3, 0x86, 0xc5, 0x8a, 0x78, 0x94, 0x2f, 0x30, + 0xf9, 0x0f, 0x2b, 0x92, 0x74, 0x00, 0x43, 0xaf, 0xd3, 0x72, 0xfd, 0x31, 0x28, 0x62, 0x00, 0x97, + 0x19, 0xad, 0xcc, 0x00, 0xf2, 0x46, 0x2c, 0x18, 0xd9, 0xff, 0xc9, 0x02, 0x94, 0x16, 0x6a, 0xf7, + 0xc1, 0xa8, 0x7d, 0x3d, 0x6d, 0xd4, 0x2e, 0x14, 0x69, 0x75, 0xf4, 0xb0, 0x6b, 0x7f, 0xb3, 0x0e, + 0x19, 0x75, 0x70, 0x9d, 0xc4, 0x09, 0x69, 0xbe, 0x2d, 0xc2, 0xdf, 0x16, 0xe1, 0x6f, 0x8b, 0x70, + 0x25, 0xc2, 0xd7, 0x32, 0x22, 0xfc, 0x7d, 0xc6, 0xaa, 0xd7, 0x87, 0xaa, 0xaf, 0xa9, 0x53, 0x57, + 0xb3, 0x07, 0x06, 0x02, 0x95, 0x04, 0x57, 0x57, 0x96, 0xae, 0xe7, 0xca, 0xec, 0xd7, 0xd2, 0x32, + 0xfb, 0xa8, 0x2c, 0xfe, 0x5f, 0x90, 0xd2, 0xff, 0xc2, 0x82, 0x77, 0xa5, 0xa5, 0x97, 0x9c, 0x39, + 0xf3, 0x2d, 0x3f, 0x88, 0xc8, 0xac, 0xbb, 0xbe, 0x4e, 0x22, 0xe2, 0x37, 0x48, 0xac, 0xbc, 0x18, + 0x56, 0x2f, 0x2f, 0x06, 0x7a, 0x1e, 0x86, 0x6f, 0xc7, 0x81, 0xbf, 0x1c, 0xb8, 0xbe, 0x10, 0x41, + 0x74, 0x23, 0x7c, 0xf2, 0xee, 0xee, 0xf8, 0x30, 0x1d, 0x51, 0xd9, 0x8e, 0x53, 0x58, 0x68, 0x06, + 0x4e, 0xdd, 0x7e, 0x7d, 0xd9, 0x49, 0x0c, 0x77, 0x80, 0xdc, 0xb8, 0xb3, 0x03, 0x8b, 0xab, 0x2f, + 0x67, 0x80, 0xb8, 0x1b, 0xdf, 0xfe, 0xeb, 0x25, 0x38, 0x97, 0x79, 0x91, 0xc0, 0xf3, 0x82, 0x4e, + 0x42, 0x37, 0x35, 0xe8, 0xab, 0x16, 0x9c, 0x6c, 0xa7, 0x3d, 0x0e, 0xb1, 0x70, 0xec, 0x7e, 0xa0, + 0x30, 0x1d, 0x91, 0x71, 0x69, 0x4c, 0x8f, 0x89, 0x11, 0x3a, 0x99, 0x01, 0xc4, 0xb8, 0xab, 0x2f, + 0xe8, 0x55, 0xa8, 0xb7, 0x9d, 0xed, 0x1b, 0x61, 0xd3, 0x49, 0xe4, 0x7e, 0xb2, 0xb7, 0x1b, 0xa0, + 0x93, 0xb8, 0xde, 0x04, 0x3f, 0xae, 0x9f, 0x98, 0xf7, 0x93, 0xa5, 0x68, 0x25, 0x89, 0x5c, 0xbf, + 0xc5, 0xdd, 0x79, 0x8b, 0x92, 0x0c, 0xd6, 0x14, 0xed, 0xaf, 0x58, 0x59, 0x25, 0xa5, 0x46, 0x27, + 0x72, 0x12, 0xd2, 0xda, 0x41, 0x1f, 0x85, 0x2a, 0xdd, 0xf8, 0xc9, 0x51, 0xb9, 0x55, 0xa4, 0xe6, + 0x34, 0xbe, 0x84, 0x56, 0xa2, 0xf4, 0x5f, 0x8c, 0x39, 0x53, 0xfb, 0xab, 0xf5, 0xac, 0xb1, 0xc0, + 0x0e, 0x6f, 0x2f, 0x02, 0xb4, 0x82, 0x55, 0xd2, 0x0e, 0x3d, 0x3a, 0x2c, 0x16, 0x3b, 0x01, 0x50, + 0xbe, 0x8e, 0x39, 0x05, 0xc1, 0x06, 0x16, 0xfa, 0x8b, 0x16, 0x40, 0x4b, 0xce, 0x79, 0x69, 0x08, + 0xdc, 0x28, 0xf2, 0x75, 0xf4, 0x8a, 0xd2, 0x7d, 0x51, 0x0c, 0xb1, 0xc1, 0x1c, 0xfd, 0x8c, 0x05, + 0xb5, 0x44, 0x76, 0x9f, 0xab, 0xc6, 0xd5, 0x22, 0x7b, 0x22, 0x5f, 0x5a, 0xdb, 0x44, 0x6a, 0x48, + 0x14, 0x5f, 0xf4, 0x73, 0x16, 0x40, 0xbc, 0xe3, 0x37, 0x96, 0x03, 0xcf, 0x6d, 0xec, 0x08, 0x8d, + 0x79, 0xb3, 0x50, 0x7f, 0x8c, 0xa2, 0x3e, 0x3d, 0x4a, 0x47, 0x43, 0xff, 0xc7, 0x06, 0x67, 0xf4, + 0x71, 0xa8, 0xc5, 0x62, 0xba, 0x09, 0x1d, 0xb9, 0x5a, 0xac, 0x57, 0x88, 0xd3, 0x16, 0xe2, 0x55, + 0xfc, 0xc3, 0x8a, 0x27, 0xfa, 0x05, 0x0b, 0x4e, 0x84, 0x69, 0x3f, 0x9f, 0x50, 0x87, 0xc5, 0xc9, + 0x80, 0x8c, 0x1f, 0x71, 0xfa, 0xf4, 0xdd, 0xdd, 0xf1, 0x13, 0x99, 0x46, 0x9c, 0xed, 0x05, 0x95, + 0x80, 0x7a, 0x06, 0x2f, 0x85, 0xdc, 0xe7, 0x38, 0xa8, 0x25, 0xe0, 0x5c, 0x16, 0x88, 0xbb, 0xf1, + 0xd1, 0x32, 0x9c, 0xa1, 0xbd, 0xdb, 0xe1, 0xe6, 0xa7, 0x54, 0x2f, 0x31, 0x53, 0x86, 0xb5, 0xe9, + 0xc7, 0xc4, 0x0c, 0x61, 0x5e, 0xfd, 0x2c, 0x0e, 0xce, 0x7d, 0x12, 0xfd, 0x9e, 0x05, 0x8f, 0xb9, + 0x4c, 0x0d, 0x98, 0x0e, 0x73, 0xad, 0x11, 0xc4, 0x49, 0x2c, 0x29, 0x54, 0x56, 0xf4, 0x52, 0x3f, + 0xd3, 0xff, 0x9f, 0x78, 0x83, 0xc7, 0xe6, 0xf7, 0xe8, 0x12, 0xde, 0xb3, 0xc3, 0xe8, 0x47, 0x61, + 0x44, 0xae, 0x8b, 0x65, 0x2a, 0x82, 0x99, 0xa2, 0xad, 0x4f, 0x9f, 0xba, 0xbb, 0x3b, 0x3e, 0xb2, + 0x6a, 0x02, 0x70, 0x1a, 0xcf, 0xfe, 0x56, 0x29, 0x75, 0x1e, 0xa2, 0x9c, 0x90, 0x4c, 0xdc, 0x34, + 0xa4, 0xff, 0x47, 0x4a, 0xcf, 0x42, 0xc5, 0x8d, 0xf2, 0x2e, 0x69, 0x71, 0xa3, 0x9a, 0x62, 0x6c, + 0x30, 0xa7, 0x46, 0xe9, 0x29, 0x27, 0xeb, 0xea, 0x14, 0x12, 0xf0, 0xd5, 0x22, 0xbb, 0xd4, 0x7d, + 0x7a, 0x75, 0x4e, 0x74, 0xed, 0x54, 0x17, 0x08, 0x77, 0x77, 0xc9, 0xfe, 0x56, 0xfa, 0x0c, 0xc6, + 0x58, 0xbc, 0x7d, 0x9c, 0x2f, 0x7d, 0xc1, 0x82, 0xa1, 0x28, 0xf0, 0x3c, 0xd7, 0x6f, 0x51, 0x41, + 0x23, 0xb4, 0xe5, 0x87, 0x8e, 0x45, 0x61, 0x09, 0x89, 0xc2, 0x4c, 0x5b, 0xac, 0x79, 0x62, 0xb3, + 0x03, 0xf6, 0x9f, 0x58, 0x30, 0xd6, 0x4b, 0x20, 0x22, 0x02, 0xef, 0x94, 0xab, 0x5d, 0x45, 0x57, + 0x2c, 0xf9, 0xb3, 0xc4, 0x23, 0xca, 0xf1, 0x5c, 0x9b, 0x7e, 0x52, 0xbc, 0xe6, 0x3b, 0x97, 0x7b, + 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x57, 0xe0, 0xa4, 0xf1, 0x5e, 0xb1, 0x1a, 0x98, 0xfa, 0xf4, 0x04, + 0xb5, 0x40, 0xa6, 0x32, 0xb0, 0x7b, 0xbb, 0xe3, 0x8f, 0x64, 0xdb, 0x84, 0xc4, 0xee, 0xa2, 0x63, + 0xff, 0x4a, 0x29, 0xfb, 0xb5, 0x94, 0xb2, 0x7d, 0xcb, 0xea, 0xda, 0xce, 0x7f, 0xe0, 0x38, 0x14, + 0x1c, 0xdb, 0xf8, 0xab, 0x00, 0x8e, 0xde, 0x38, 0x0f, 0xf0, 0x84, 0xd8, 0xfe, 0x57, 0x15, 0xd8, + 0xa3, 0x67, 0x7d, 0x58, 0xcf, 0x07, 0x3e, 0x56, 0xfc, 0x9c, 0xa5, 0x8e, 0x9c, 0xca, 0x6c, 0x91, + 0x37, 0x8f, 0x6b, 0xec, 0xf9, 0x06, 0x26, 0xe6, 0x51, 0x0a, 0xca, 0x8d, 0x9d, 0x3e, 0xdc, 0x42, + 0x5f, 0xb3, 0xd2, 0x87, 0x66, 0x3c, 0xec, 0xcc, 0x3d, 0xb6, 0x3e, 0x19, 0x27, 0x71, 0xbc, 0x63, + 0xfa, 0xfc, 0xa6, 0xd7, 0x19, 0xdd, 0x04, 0xc0, 0xba, 0xeb, 0x3b, 0x9e, 0xfb, 0x06, 0xdd, 0x9e, + 0x54, 0x99, 0x86, 0x65, 0x26, 0xcb, 0x65, 0xd5, 0x8a, 0x0d, 0x8c, 0xf3, 0x7f, 0x01, 0x86, 0x8c, + 0x37, 0xcf, 0x09, 0xae, 0x38, 0x63, 0x06, 0x57, 0xd4, 0x8d, 0x98, 0x88, 0xf3, 0xef, 0x83, 0x93, + 0xd9, 0x0e, 0x1e, 0xe4, 0x79, 0xfb, 0x7f, 0x0e, 0x66, 0x4f, 0xb1, 0x56, 0x49, 0xd4, 0xa6, 0x5d, + 0x7b, 0xdb, 0xb3, 0xf4, 0xb6, 0x67, 0xe9, 0x6d, 0xcf, 0x92, 0x79, 0x38, 0x20, 0xbc, 0x26, 0x83, + 0xf7, 0xc9, 0x6b, 0x92, 0xf2, 0x03, 0xd5, 0x0a, 0xf7, 0x03, 0xd9, 0x77, 0xab, 0x90, 0xb2, 0xa3, + 0xf8, 0x78, 0xff, 0x10, 0x0c, 0x46, 0x24, 0x0c, 0x6e, 0xe0, 0x05, 0xa1, 0x43, 0x74, 0x00, 0x3d, + 0x6f, 0xc6, 0x12, 0x4e, 0x75, 0x4d, 0xe8, 0x24, 0x1b, 0x42, 0x89, 0x28, 0x5d, 0xb3, 0xec, 0x24, + 0x1b, 0x98, 0x41, 0xd0, 0xfb, 0x60, 0x34, 0x71, 0xa2, 0x16, 0xb5, 0xb7, 0xb7, 0xd8, 0x67, 0x15, + 0x67, 0x9d, 0x8f, 0x08, 0xdc, 0xd1, 0xd5, 0x14, 0x14, 0x67, 0xb0, 0xd1, 0xeb, 0x50, 0xd9, 0x20, + 0x5e, 0x5b, 0x0c, 0xf9, 0x4a, 0x71, 0x32, 0x9e, 0xbd, 0xeb, 0x15, 0xe2, 0xb5, 0xb9, 0x04, 0xa2, + 0xbf, 0x30, 0x63, 0x45, 0xe7, 0x5b, 0x7d, 0xb3, 0x13, 0x27, 0x41, 0xdb, 0x7d, 0x43, 0xba, 0xf8, + 0x3e, 0x50, 0x30, 0xe3, 0x6b, 0x92, 0x3e, 0xf7, 0xa5, 0xa8, 0xbf, 0x58, 0x73, 0x66, 0xfd, 0x68, + 0xba, 0x11, 0xfb, 0x54, 0x3b, 0xc2, 0x53, 0x57, 0x74, 0x3f, 0x66, 0x25, 0x7d, 0xde, 0x0f, 0xf5, + 0x17, 0x6b, 0xce, 0x68, 0x47, 0xcd, 0xfb, 0x21, 0xd6, 0x87, 0x1b, 0x05, 0xf7, 0x81, 0xcf, 0xf9, + 0xdc, 0xf9, 0xff, 0x24, 0x54, 0x1b, 0x1b, 0x4e, 0x94, 0x8c, 0x0d, 0xb3, 0x49, 0xa3, 0x7c, 0x3a, + 0x33, 0xb4, 0x11, 0x73, 0x18, 0x7a, 0x1c, 0xca, 0x11, 0x59, 0x67, 0x71, 0x9b, 0x46, 0x44, 0x0f, + 0x26, 0xeb, 0x98, 0xb6, 0xdb, 0xbf, 0x54, 0x4a, 0x9b, 0x4b, 0xe9, 0xf7, 0xe6, 0xb3, 0xbd, 0xd1, + 0x89, 0x62, 0xe9, 0xf7, 0x31, 0x66, 0x3b, 0x6b, 0xc6, 0x12, 0x8e, 0x3e, 0x69, 0xc1, 0xe0, 0xed, + 0x38, 0xf0, 0x7d, 0x92, 0x08, 0xd5, 0x74, 0xb3, 0xe0, 0xa1, 0xb8, 0xca, 0xa9, 0xeb, 0x3e, 0x88, + 0x06, 0x2c, 0xf9, 0xd2, 0xee, 0x92, 0xed, 0x86, 0xd7, 0x69, 0x76, 0x05, 0x69, 0x5c, 0xe2, 0xcd, + 0x58, 0xc2, 0x29, 0xaa, 0xeb, 0x73, 0xd4, 0x4a, 0x1a, 0x75, 0xde, 0x17, 0xa8, 0x02, 0x6e, 0xff, + 0xd5, 0x01, 0x38, 0x9b, 0xbb, 0x38, 0xa8, 0x21, 0xc3, 0x4c, 0x85, 0xcb, 0xae, 0x47, 0x64, 0x78, + 0x12, 0x33, 0x64, 0x6e, 0xaa, 0x56, 0x6c, 0x60, 0xa0, 0x9f, 0x06, 0x08, 0x9d, 0xc8, 0x69, 0x13, + 0xe5, 0x97, 0x3d, 0xb2, 0xbd, 0x40, 0xfb, 0xb1, 0x2c, 0x69, 0xea, 0xbd, 0xa9, 0x6a, 0x8a, 0xb1, + 0xc1, 0x12, 0xbd, 0x00, 0x43, 0x11, 0xf1, 0x88, 0x13, 0xb3, 0xb0, 0xdf, 0x6c, 0x0e, 0x03, 0xd6, + 0x20, 0x6c, 0xe2, 0xa1, 0xa7, 0x54, 0x24, 0x57, 0x26, 0xa2, 0x25, 0x1d, 0xcd, 0x85, 0xde, 0xb4, + 0x60, 0x74, 0xdd, 0xf5, 0x88, 0xe6, 0x2e, 0x32, 0x0e, 0x96, 0x8e, 0xfe, 0x92, 0x97, 0x4d, 0xba, + 0x5a, 0x42, 0xa6, 0x9a, 0x63, 0x9c, 0x61, 0x4f, 0x3f, 0xf3, 0x16, 0x89, 0x98, 0x68, 0x1d, 0x48, + 0x7f, 0xe6, 0x9b, 0xbc, 0x19, 0x4b, 0x38, 0x9a, 0x82, 0x13, 0xa1, 0x13, 0xc7, 0x33, 0x11, 0x69, + 0x12, 0x3f, 0x71, 0x1d, 0x8f, 0xe7, 0x03, 0xd4, 0x74, 0x3c, 0xf0, 0x72, 0x1a, 0x8c, 0xb3, 0xf8, + 0xe8, 0x83, 0xf0, 0x28, 0x77, 0x7c, 0x2c, 0xba, 0x71, 0xec, 0xfa, 0x2d, 0x3d, 0x0d, 0x84, 0xff, + 0x67, 0x5c, 0x90, 0x7a, 0x74, 0x3e, 0x1f, 0x0d, 0xf7, 0x7a, 0x1e, 0x3d, 0x03, 0xb5, 0x78, 0xd3, + 0x0d, 0x67, 0xa2, 0x66, 0xcc, 0x0e, 0x3d, 0x6a, 0xda, 0xdb, 0xb8, 0x22, 0xda, 0xb1, 0xc2, 0x40, + 0x0d, 0x18, 0xe6, 0x9f, 0x84, 0x87, 0xa2, 0x09, 0xf9, 0xf8, 0x6c, 0x4f, 0xf5, 0x28, 0x52, 0xd6, + 0x26, 0xb0, 0x73, 0xe7, 0x92, 0x3c, 0x82, 0xe1, 0x27, 0x06, 0x37, 0x0d, 0x32, 0x38, 0x45, 0xd4, + 0xfe, 0xc5, 0x52, 0x7a, 0xc7, 0x6d, 0x2e, 0x52, 0x14, 0xd3, 0xa5, 0x98, 0xdc, 0x74, 0x22, 0xe9, + 0x8d, 0x39, 0x62, 0xda, 0x82, 0xa0, 0x7b, 0xd3, 0x89, 0xcc, 0x45, 0xcd, 0x18, 0x60, 0xc9, 0x09, + 0xdd, 0x86, 0x4a, 0xe2, 0x39, 0x05, 0xe5, 0x39, 0x19, 0x1c, 0xb5, 0x03, 0x64, 0x61, 0x2a, 0xc6, + 0x8c, 0x07, 0x7a, 0x8c, 0x5a, 0xfd, 0x6b, 0xf2, 0x88, 0x44, 0x18, 0xea, 0x6b, 0x31, 0x66, 0xad, + 0xf6, 0xaf, 0x42, 0x8e, 0x5c, 0x55, 0x8a, 0x0c, 0x5d, 0x04, 0xa0, 0x1b, 0xc8, 0xe5, 0x88, 0xac, + 0xbb, 0xdb, 0xc2, 0x90, 0x50, 0x6b, 0xf7, 0xba, 0x82, 0x60, 0x03, 0x4b, 0x3e, 0xb3, 0xd2, 0x59, + 0xa7, 0xcf, 0x94, 0xba, 0x9f, 0xe1, 0x10, 0x6c, 0x60, 0xa1, 0xe7, 0x61, 0xc0, 0x6d, 0x3b, 0x2d, + 0x15, 0x82, 0xf9, 0x18, 0x5d, 0xb4, 0xf3, 0xac, 0xe5, 0xde, 0xee, 0xf8, 0xa8, 0xea, 0x10, 0x6b, + 0xc2, 0x02, 0x17, 0xfd, 0x8a, 0x05, 0xc3, 0x8d, 0xa0, 0xdd, 0x0e, 0x7c, 0xbe, 0xed, 0x12, 0x7b, + 0xc8, 0xdb, 0xc7, 0xa5, 0xe6, 0x27, 0x66, 0x0c, 0x66, 0x7c, 0x13, 0xa9, 0x12, 0xb2, 0x4c, 0x10, + 0x4e, 0xf5, 0xca, 0x5c, 0xdb, 0xd5, 0x7d, 0xd6, 0xf6, 0x6f, 0x58, 0x70, 0x8a, 0x3f, 0x6b, 0xec, + 0x06, 0x45, 0xee, 0x51, 0x70, 0xcc, 0xaf, 0xd5, 0xb5, 0x41, 0x56, 0x5e, 0xba, 0x2e, 0x38, 0xee, + 0xee, 0x24, 0x9a, 0x83, 0x53, 0xeb, 0x41, 0xd4, 0x20, 0xe6, 0x40, 0x08, 0xc1, 0xa4, 0x08, 0x5d, + 0xce, 0x22, 0xe0, 0xee, 0x67, 0xd0, 0x4d, 0x78, 0xc4, 0x68, 0x34, 0xc7, 0x81, 0xcb, 0xa6, 0x27, + 0x04, 0xb5, 0x47, 0x2e, 0xe7, 0x62, 0xe1, 0x1e, 0x4f, 0xa7, 0x1d, 0x26, 0xf5, 0x3e, 0x1c, 0x26, + 0xaf, 0xc1, 0xb9, 0x46, 0xf7, 0xc8, 0x6c, 0xc5, 0x9d, 0xb5, 0x98, 0x4b, 0xaa, 0xda, 0xf4, 0x0f, + 0x08, 0x02, 0xe7, 0x66, 0x7a, 0x21, 0xe2, 0xde, 0x34, 0xd0, 0x47, 0xa1, 0x16, 0x11, 0xf6, 0x55, + 0x62, 0x91, 0x88, 0x73, 0xc4, 0x5d, 0xb2, 0xb6, 0x40, 0x39, 0x59, 0x2d, 0x7b, 0x45, 0x43, 0x8c, + 0x15, 0x47, 0x74, 0x07, 0x06, 0x43, 0x27, 0x69, 0x6c, 0x88, 0xf4, 0x9b, 0x23, 0xc7, 0xbf, 0x28, + 0xe6, 0xcc, 0x07, 0xae, 0x27, 0xf9, 0x32, 0x67, 0x82, 0x25, 0x37, 0x6a, 0x8d, 0x34, 0x82, 0x76, + 0x18, 0xf8, 0xc4, 0x4f, 0xe2, 0xb1, 0x11, 0x6d, 0x8d, 0xcc, 0xa8, 0x56, 0x6c, 0x60, 0x9c, 0x7f, + 0x3f, 0x9c, 0xea, 0x5a, 0x78, 0x07, 0x72, 0xae, 0xcc, 0xc2, 0x23, 0xf9, 0x53, 0xfc, 0x40, 0x2e, + 0x96, 0x7f, 0x98, 0x09, 0x72, 0x35, 0xcc, 0xde, 0x3e, 0xdc, 0x75, 0x0e, 0x94, 0x89, 0xbf, 0x25, + 0x24, 0xfe, 0xe5, 0xa3, 0x8d, 0xf4, 0x25, 0x7f, 0x8b, 0xaf, 0x50, 0xe6, 0x93, 0xb8, 0xe4, 0x6f, + 0x61, 0x4a, 0x1b, 0x7d, 0xc9, 0x4a, 0x99, 0x6d, 0xdc, 0xc9, 0xf7, 0xe1, 0x63, 0xb1, 0xf3, 0xfb, + 0xb6, 0xe4, 0xec, 0x7f, 0x5d, 0x82, 0x0b, 0xfb, 0x11, 0xe9, 0x63, 0xf8, 0x9e, 0x84, 0x81, 0x98, + 0x1d, 0x5b, 0x0b, 0x11, 0x3a, 0x44, 0x67, 0x16, 0x3f, 0xc8, 0x7e, 0x0d, 0x0b, 0x10, 0xf2, 0xa0, + 0xdc, 0x76, 0x42, 0xe1, 0xfb, 0x99, 0x3f, 0x6a, 0xda, 0x0b, 0xfd, 0xef, 0x78, 0x8b, 0x4e, 0xc8, + 0x3d, 0x0a, 0x46, 0x03, 0xa6, 0x6c, 0x50, 0x02, 0x55, 0x27, 0x8a, 0x1c, 0x79, 0x46, 0x7a, 0xad, + 0x18, 0x7e, 0x53, 0x94, 0x24, 0x3f, 0x62, 0x4a, 0x35, 0x61, 0xce, 0xcc, 0xfe, 0xdc, 0x60, 0x2a, + 0xf5, 0x83, 0x1d, 0x7c, 0xc7, 0x30, 0x20, 0x5c, 0x3e, 0x56, 0xd1, 0xd9, 0x46, 0x3c, 0x77, 0x8f, + 0xed, 0xea, 0x44, 0x06, 0xb4, 0x60, 0x85, 0x3e, 0x6b, 0xb1, 0x3c, 0x63, 0x99, 0x0e, 0x23, 0xf6, + 0x52, 0xc7, 0x93, 0xf6, 0x6c, 0x66, 0x2f, 0xcb, 0x46, 0x6c, 0x72, 0xa7, 0x3a, 0x36, 0xe4, 0x19, + 0x73, 0xd9, 0x1d, 0x95, 0xcc, 0x44, 0x96, 0x70, 0xb4, 0x9d, 0x73, 0xc0, 0x5d, 0x40, 0xae, 0x6a, + 0x1f, 0x47, 0xda, 0x5f, 0xb3, 0xe0, 0x94, 0x9b, 0x3d, 0xa9, 0x14, 0x3b, 0x8f, 0x23, 0x86, 0x50, + 0xf4, 0x3e, 0x08, 0x55, 0xca, 0xb7, 0x0b, 0x84, 0xbb, 0x3b, 0x83, 0x9a, 0x50, 0x71, 0xfd, 0xf5, + 0x40, 0x98, 0x1c, 0xd3, 0x47, 0xeb, 0xd4, 0xbc, 0xbf, 0x1e, 0xe8, 0xd5, 0x4c, 0xff, 0x61, 0x46, + 0x1d, 0x2d, 0xc0, 0x99, 0x48, 0xf8, 0x86, 0xae, 0xb8, 0x31, 0xdd, 0xc1, 0x2f, 0xb8, 0x6d, 0x37, + 0x61, 0xe6, 0x42, 0x79, 0x7a, 0xec, 0xee, 0xee, 0xf8, 0x19, 0x9c, 0x03, 0xc7, 0xb9, 0x4f, 0xa1, + 0x37, 0x60, 0x50, 0x26, 0x46, 0xd7, 0x8a, 0xd8, 0xc5, 0x75, 0xcf, 0x7f, 0x35, 0x99, 0x56, 0x44, + 0x0e, 0xb4, 0x64, 0x68, 0xbf, 0x39, 0x04, 0xdd, 0x87, 0x98, 0xe8, 0x63, 0x50, 0x8f, 0x54, 0xb2, + 0xb6, 0x55, 0x84, 0x72, 0x95, 0xdf, 0x57, 0x1c, 0xa0, 0x2a, 0xc3, 0x45, 0xa7, 0x65, 0x6b, 0x8e, + 0x74, 0x7b, 0x11, 0xeb, 0xb3, 0xce, 0x02, 0xe6, 0xb6, 0xe0, 0xaa, 0xcf, 0xb1, 0x76, 0xfc, 0x06, + 0x66, 0x3c, 0x50, 0x04, 0x03, 0x1b, 0xc4, 0xf1, 0x92, 0x8d, 0x62, 0x5c, 0xee, 0x57, 0x18, 0xad, + 0x6c, 0xca, 0x0e, 0x6f, 0xc5, 0x82, 0x13, 0xda, 0x86, 0xc1, 0x0d, 0x3e, 0x01, 0x84, 0xc5, 0xbf, + 0x78, 0xd4, 0xc1, 0x4d, 0xcd, 0x2a, 0xfd, 0xb9, 0x45, 0x03, 0x96, 0xec, 0x58, 0x74, 0x8c, 0x71, + 0x7e, 0xcf, 0x97, 0x6e, 0x71, 0xd9, 0x4a, 0xfd, 0x1f, 0xde, 0x7f, 0x04, 0x86, 0x23, 0xd2, 0x08, + 0xfc, 0x86, 0xeb, 0x91, 0xe6, 0x94, 0x74, 0xa7, 0x1f, 0x24, 0xc7, 0x85, 0xed, 0x9a, 0xb1, 0x41, + 0x03, 0xa7, 0x28, 0xa2, 0xcf, 0x58, 0x30, 0xaa, 0x32, 0x3c, 0xe9, 0x07, 0x21, 0xc2, 0x7d, 0xbb, + 0x50, 0x50, 0x3e, 0x29, 0xa3, 0x39, 0x8d, 0xee, 0xee, 0x8e, 0x8f, 0xa6, 0xdb, 0x70, 0x86, 0x2f, + 0x7a, 0x05, 0x20, 0x58, 0xe3, 0x21, 0x30, 0x53, 0x89, 0xf0, 0xe5, 0x1e, 0xe4, 0x55, 0x47, 0x79, + 0xb2, 0x9b, 0xa4, 0x80, 0x0d, 0x6a, 0xe8, 0x1a, 0x00, 0x5f, 0x36, 0xab, 0x3b, 0xa1, 0xdc, 0x16, + 0xc8, 0x24, 0x25, 0x58, 0x51, 0x90, 0x7b, 0xbb, 0xe3, 0xdd, 0xbe, 0x35, 0x16, 0x66, 0x60, 0x3c, + 0x8e, 0x7e, 0x0a, 0x06, 0xe3, 0x4e, 0xbb, 0xed, 0x28, 0x4f, 0x6f, 0x81, 0xe9, 0x73, 0x9c, 0xae, + 0x21, 0x8a, 0x78, 0x03, 0x96, 0x1c, 0xd1, 0x6d, 0x2a, 0x54, 0x63, 0xe1, 0xf4, 0x63, 0xab, 0x88, + 0xdb, 0x04, 0x43, 0xec, 0x9d, 0xde, 0x23, 0x23, 0x7a, 0x70, 0x0e, 0xce, 0xbd, 0xdd, 0xf1, 0x47, + 0xd2, 0xed, 0x0b, 0x81, 0x48, 0x68, 0xcb, 0xa5, 0x89, 0xae, 0xca, 0x3a, 0x29, 0xf4, 0xb5, 0x65, + 0xfa, 0xfe, 0xd3, 0xba, 0x4e, 0x0a, 0x6b, 0xee, 0x3d, 0x66, 0xe6, 0xc3, 0x68, 0x11, 0x4e, 0x37, + 0x02, 0x3f, 0x89, 0x02, 0xcf, 0xe3, 0xc5, 0x7f, 0xf8, 0x0e, 0x8d, 0x7b, 0x82, 0xdf, 0x29, 0xba, + 0x7d, 0x7a, 0xa6, 0x1b, 0x05, 0xe7, 0x3d, 0x67, 0xfb, 0xe9, 0xd8, 0x40, 0x31, 0x38, 0xcf, 0xc3, + 0x30, 0xd9, 0x4e, 0x48, 0xe4, 0x3b, 0xde, 0x0d, 0xbc, 0x20, 0x7d, 0xa0, 0x6c, 0x0d, 0x5c, 0x32, + 0xda, 0x71, 0x0a, 0x0b, 0xd9, 0xca, 0x2d, 0x61, 0x24, 0x69, 0x72, 0xb7, 0x84, 0x74, 0x42, 0xd8, + 0xff, 0xab, 0x94, 0x32, 0xc8, 0x56, 0x23, 0x42, 0x50, 0x00, 0x55, 0x3f, 0x68, 0x2a, 0xd9, 0x7f, + 0xb5, 0x18, 0xd9, 0x7f, 0x3d, 0x68, 0x1a, 0xc5, 0x54, 0xe8, 0xbf, 0x18, 0x73, 0x3e, 0xac, 0xda, + 0x84, 0x2c, 0xcb, 0xc1, 0x00, 0x62, 0xa3, 0x51, 0x24, 0x67, 0x55, 0x6d, 0x62, 0xc9, 0x64, 0x84, + 0xd3, 0x7c, 0xd1, 0x26, 0x54, 0x37, 0x82, 0x38, 0x91, 0xdb, 0x8f, 0x23, 0xee, 0x74, 0xae, 0x04, + 0x71, 0xc2, 0xac, 0x08, 0xf5, 0xda, 0xb4, 0x25, 0xc6, 0x9c, 0x87, 0xfd, 0x9f, 0xad, 0x94, 0xc7, + 0xfb, 0x16, 0x8b, 0x93, 0xdd, 0x22, 0x3e, 0x5d, 0xd6, 0x66, 0x60, 0xd0, 0x8f, 0x66, 0xb2, 0x0e, + 0xdf, 0xd5, 0xab, 0xb4, 0xd5, 0x1d, 0x4a, 0x61, 0x82, 0x91, 0x30, 0x62, 0x88, 0x3e, 0x61, 0xa5, + 0xf3, 0x3f, 0x4b, 0x45, 0x6c, 0x30, 0xcc, 0x1c, 0xe8, 0x7d, 0x53, 0x49, 0xed, 0x2f, 0x59, 0x30, + 0x38, 0xed, 0x34, 0x36, 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0x4c, 0x45, 0x55, + 0xdb, 0xfc, 0x59, 0xd1, 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x66, 0x42, 0x97, 0xf9, + 0x1c, 0xbe, 0xcc, 0x5a, 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xa8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, + 0xf6, 0x45, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0xcf, 0x2d, 0x18, 0x9b, 0x76, 0x62, 0xb7, 0x31, 0xd5, + 0x49, 0x36, 0xa6, 0xdd, 0x64, 0xad, 0xd3, 0xd8, 0x24, 0x09, 0x4f, 0x7f, 0xa7, 0xbd, 0xec, 0xc4, + 0x74, 0x29, 0xa9, 0x7d, 0x9d, 0xea, 0xe5, 0x0d, 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, + 0x27, 0x8e, 0xef, 0x04, 0x51, 0x13, 0x93, 0xf5, 0x62, 0x8a, 0x4f, 0xac, 0x90, 0x46, 0x44, 0x12, + 0x4c, 0xd6, 0xc5, 0x91, 0xb0, 0xa6, 0x8f, 0x4d, 0x66, 0xf6, 0x17, 0x2c, 0x38, 0x37, 0x4d, 0x9c, + 0x88, 0x44, 0xac, 0x56, 0x85, 0x7a, 0x91, 0x19, 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, + 0x33, 0xed, 0x96, 0x55, 0x6c, 0xb7, 0xd8, 0x89, 0xee, 0xaa, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, + 0x59, 0x30, 0xcc, 0x0e, 0xc7, 0x66, 0x49, 0xe2, 0xb8, 0x5e, 0x57, 0x49, 0x27, 0xab, 0xcf, 0x92, + 0x4e, 0x17, 0xa0, 0xb2, 0x11, 0xb4, 0x49, 0xf6, 0x60, 0xf7, 0x4a, 0x40, 0xb7, 0xd5, 0x14, 0x82, + 0x9e, 0xa3, 0x1f, 0xde, 0xf5, 0x13, 0x87, 0x2e, 0x01, 0xe9, 0x7c, 0x3d, 0xc1, 0x3f, 0xba, 0x6a, + 0xc6, 0x26, 0x8e, 0xfd, 0xdb, 0x75, 0x18, 0x14, 0xa7, 0xff, 0x7d, 0x97, 0x40, 0x90, 0xfb, 0xfb, + 0x52, 0xcf, 0xfd, 0x7d, 0x0c, 0x03, 0x0d, 0x56, 0x30, 0x4e, 0x98, 0x91, 0xd7, 0x0a, 0x09, 0x17, + 0xe1, 0x35, 0xe8, 0x74, 0xb7, 0xf8, 0x7f, 0x2c, 0x58, 0xa1, 0x2f, 0x5a, 0x70, 0xa2, 0x11, 0xf8, + 0x3e, 0x69, 0x68, 0x1b, 0xa7, 0x52, 0x44, 0x54, 0xc0, 0x4c, 0x9a, 0xa8, 0x3e, 0x99, 0xc9, 0x00, + 0x70, 0x96, 0x3d, 0x7a, 0x09, 0x46, 0xf8, 0x98, 0xdd, 0x4c, 0x79, 0x8c, 0x75, 0xa5, 0x1f, 0x13, + 0x88, 0xd3, 0xb8, 0x68, 0x82, 0x7b, 0xde, 0x45, 0x4d, 0x9d, 0x01, 0xed, 0x58, 0x33, 0xaa, 0xe9, + 0x18, 0x18, 0x28, 0x02, 0x14, 0x91, 0xf5, 0x88, 0xc4, 0x1b, 0x22, 0x3a, 0x82, 0xd9, 0x57, 0x83, + 0x87, 0x4b, 0x97, 0xc6, 0x5d, 0x94, 0x70, 0x0e, 0x75, 0xb4, 0x29, 0x36, 0x98, 0xb5, 0x22, 0x64, + 0xa8, 0xf8, 0xcc, 0x3d, 0xf7, 0x99, 0xe3, 0x50, 0x8d, 0x37, 0x9c, 0xa8, 0xc9, 0xec, 0xba, 0x32, + 0x4f, 0xd1, 0x59, 0xa1, 0x0d, 0x98, 0xb7, 0xa3, 0x59, 0x38, 0x99, 0xa9, 0x53, 0x14, 0x0b, 0xcf, + 0xae, 0x4a, 0xc7, 0xc8, 0x54, 0x38, 0x8a, 0x71, 0xd7, 0x13, 0xa6, 0xf3, 0x61, 0x68, 0x1f, 0xe7, + 0xc3, 0x8e, 0x8a, 0xc1, 0xe3, 0x3e, 0xd7, 0x97, 0x0b, 0x19, 0x80, 0xbe, 0x02, 0xee, 0x3e, 0x9f, + 0x09, 0xb8, 0x1b, 0x61, 0x1d, 0xb8, 0x59, 0x4c, 0x07, 0x0e, 0x1e, 0x5d, 0xf7, 0x20, 0xa3, 0xe5, + 0xfe, 0xdc, 0x02, 0xf9, 0x5d, 0x67, 0x9c, 0xc6, 0x06, 0xa1, 0x53, 0x06, 0xbd, 0x0f, 0x46, 0xd5, + 0x16, 0x7a, 0x26, 0xe8, 0xf8, 0x3c, 0x50, 0xae, 0xac, 0x8f, 0x70, 0x71, 0x0a, 0x8a, 0x33, 0xd8, + 0x68, 0x12, 0xea, 0x74, 0x9c, 0xf8, 0xa3, 0x5c, 0xd7, 0xaa, 0x6d, 0xfa, 0xd4, 0xf2, 0xbc, 0x78, + 0x4a, 0xe3, 0xa0, 0x00, 0x4e, 0x79, 0x4e, 0x9c, 0xb0, 0x1e, 0xd0, 0x1d, 0xf5, 0x21, 0x8b, 0x15, + 0xb0, 0x98, 0xff, 0x85, 0x2c, 0x21, 0xdc, 0x4d, 0xdb, 0xfe, 0x76, 0x05, 0x46, 0x52, 0x92, 0xf1, + 0x80, 0x4a, 0xfa, 0x19, 0xa8, 0x49, 0xbd, 0x99, 0x2d, 0xab, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, + 0x6b, 0x4d, 0x6b, 0xd5, 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, + 0x8c, 0xe7, 0x12, 0x3f, 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, + 0xce, 0x00, 0x70, 0x96, 0x3d, 0xfa, 0xb4, 0x05, 0x23, 0xce, 0x9d, 0x58, 0x57, 0x35, 0x15, 0xa1, + 0x75, 0x47, 0x54, 0x52, 0xa9, 0x42, 0xa9, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, + 0x0b, 0x10, 0xd9, 0x26, 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x50, 0xc4, 0x4e, 0xf3, 0x52, 0x17, + 0x5d, 0x2e, 0xd5, 0xbb, 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x52, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, + 0x3a, 0x46, 0xdc, 0x9b, 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0x03, 0x99, 0x4a, 0x99, + 0x2a, 0x3d, 0xa0, 0x94, 0xa9, 0x9f, 0xb1, 0x52, 0x05, 0x84, 0x86, 0x2e, 0xbe, 0x52, 0x6c, 0xac, + 0xeb, 0x04, 0x8f, 0x6d, 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, + 0xe1, 0xbf, 0x2b, 0xc3, 0x90, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, + 0x30, 0x8b, 0x7e, 0x1a, 0xea, 0x0d, 0x29, 0xe5, 0x8b, 0x29, 0xa1, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, + 0xab, 0x26, 0xac, 0x79, 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x15, 0xa6, 0x21, 0xf2, 0x32, + 0x61, 0x84, 0xa6, 0xe8, 0x7e, 0x86, 0xd5, 0x99, 0x0a, 0x5d, 0xf1, 0x5e, 0x32, 0x22, 0x9d, 0xd7, + 0x99, 0x5a, 0x9e, 0x97, 0xcd, 0xd8, 0xc4, 0xb1, 0xbf, 0x6d, 0xa9, 0x8f, 0x7b, 0x1f, 0x2a, 0x2a, + 0xdc, 0x4e, 0x57, 0x54, 0xb8, 0x54, 0xc8, 0x30, 0xf7, 0x28, 0xa5, 0x70, 0x1d, 0x06, 0x67, 0x82, + 0x76, 0xdb, 0xf1, 0x9b, 0xe8, 0x07, 0x61, 0xb0, 0xc1, 0x7f, 0x0a, 0xc7, 0x0e, 0x3b, 0x1e, 0x14, + 0x50, 0x2c, 0x61, 0xe8, 0x31, 0xa8, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x54, 0xd4, + 0x8a, 0x31, 0x6b, 0xb5, 0xff, 0x41, 0x05, 0xd8, 0x09, 0xb4, 0x13, 0x91, 0xe6, 0x6a, 0xc0, 0x4a, + 0xf8, 0x1d, 0xeb, 0xa1, 0x9a, 0xde, 0x2c, 0x3d, 0xcc, 0x07, 0x6b, 0xc6, 0xe1, 0x4a, 0xf9, 0x3e, + 0x1f, 0xae, 0xf4, 0x38, 0x2f, 0xab, 0x3c, 0x44, 0xe7, 0x65, 0xf6, 0xe7, 0x2c, 0x40, 0x2a, 0x6c, + 0x41, 0x1f, 0x68, 0x4f, 0x42, 0x5d, 0x05, 0x30, 0x08, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, + 0xa7, 0x8f, 0x1d, 0xf2, 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb4, 0x4c, 0xea, 0x0b, 0x71, 0x6e, + 0xff, 0x4e, 0x09, 0x1e, 0xe1, 0x2a, 0x79, 0xd1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, + 0xa2, 0xd0, 0xa0, 0x5b, 0x33, 0x57, 0x46, 0xc5, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, + 0xbc, 0xef, 0x26, 0x98, 0x11, 0x47, 0x31, 0xd4, 0x64, 0xcd, 0x78, 0x21, 0x8b, 0x0b, 0x62, 0xa4, + 0xc4, 0x92, 0xd0, 0x9b, 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x26, 0x26, 0x61, 0xc0, + 0xe4, 0xae, 0x11, 0x94, 0xb8, 0x20, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xc7, 0x82, 0xac, 0x46, 0x32, + 0x6a, 0xa5, 0x59, 0x7b, 0xd6, 0x4a, 0x3b, 0x40, 0xb1, 0xb2, 0x9f, 0x84, 0x21, 0x27, 0xa1, 0x46, + 0x04, 0xdf, 0x76, 0x97, 0x0f, 0x77, 0xac, 0xb1, 0x18, 0x34, 0xdd, 0x75, 0x97, 0x6d, 0xb7, 0x4d, + 0x72, 0xf6, 0x7f, 0xaf, 0xc0, 0xa9, 0xae, 0xdc, 0x0d, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, + 0xa5, 0x43, 0xab, 0x6e, 0x06, 0xb1, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe1, 0x74, + 0x44, 0x37, 0xfa, 0x1d, 0x32, 0xb5, 0x9e, 0x90, 0x68, 0x85, 0x34, 0x02, 0xbf, 0xc9, 0x2b, 0xfa, + 0x95, 0xa7, 0x1f, 0xbd, 0xbb, 0x3b, 0x7e, 0x1a, 0x77, 0x83, 0x71, 0xde, 0x33, 0x28, 0x84, 0x11, + 0xcf, 0xb4, 0x01, 0xc5, 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, + 0x6d, 0x48, 0x56, 0x1f, 0x90, 0x21, 0xf9, 0x29, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x15, 0x9c, + 0xbb, 0x73, 0xdc, 0x96, 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, + 0x48, 0xb4, 0x7b, 0x25, 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, + 0xeb, 0xa3, 0x6d, 0x1e, 0x97, 0xc5, 0x75, 0xdb, 0x07, 0x8b, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, + 0xd2, 0xa0, 0xc2, 0xb5, 0x2e, 0x02, 0x68, 0x43, 0x4d, 0x04, 0xac, 0xab, 0x63, 0x5f, 0x6d, 0xcf, + 0x61, 0x03, 0x8b, 0xee, 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xe2, 0xfa, 0x89, 0x70, 0x0e, + 0x2a, 0x25, 0x3e, 0xaf, 0x41, 0xd8, 0xc4, 0x3b, 0xff, 0x1e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0x6e, + 0xc0, 0xb9, 0x39, 0x37, 0x51, 0x69, 0x16, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x0d, 0x59, 0x3d, + 0xd3, 0x86, 0x8c, 0x34, 0x87, 0x52, 0x3a, 0x2b, 0x23, 0x9b, 0xe6, 0x60, 0xbf, 0x08, 0x67, 0xe6, + 0xdc, 0xe4, 0xb2, 0xeb, 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x6b, 0x00, 0x86, 0xcd, 0x44, 0xbd, 0x83, + 0x64, 0x3e, 0x7d, 0x81, 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xeb, 0xc8, 0x59, 0x83, + 0xf9, 0x23, 0x66, 0x58, 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x40, 0x75, 0x9d, 0x85, 0xe1, + 0x97, 0x8b, 0x88, 0x2c, 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x20, 0x3f, 0xe7, 0x47, 0x35, 0x64, + 0x94, 0xce, 0xed, 0x32, 0x42, 0x47, 0x45, 0x56, 0x97, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, + 0xf5, 0x29, 0xc1, 0x3b, 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0xa9, 0x48, 0x36, 0x98, 0xfd, 0x26, 0x62, + 0xdd, 0x07, 0xd9, 0x20, 0x18, 0x29, 0x15, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x8f, 0x2b, 0xd1, 0x5d, + 0x2b, 0xc2, 0xaf, 0x6a, 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2b, 0xc1, 0xe8, 0x9c, 0xdf, 0x59, + 0x9e, 0x5b, 0xee, 0xac, 0x79, 0x6e, 0xe3, 0x1a, 0xd9, 0xa1, 0xa2, 0x79, 0x93, 0xec, 0xcc, 0xcf, + 0x8a, 0x15, 0xa4, 0xe6, 0xcc, 0x35, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x75, 0xd7, 0x6f, 0x91, + 0x28, 0x8c, 0x5c, 0xe1, 0xf2, 0x34, 0x84, 0xd1, 0x65, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, + 0xf1, 0x49, 0x94, 0x35, 0x64, 0x97, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, + 0x93, 0x51, 0x21, 0xad, 0xd2, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x35, 0x16, 0xb8, 0x91, + 0x09, 0xac, 0x5f, 0xe1, 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x26, 0xd9, 0x99, 0xa5, 0xbb, 0xde, 0x4c, + 0x7e, 0xcd, 0x35, 0xde, 0x8c, 0x25, 0x9c, 0x95, 0x22, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x29, 0xc2, + 0x74, 0xf7, 0x7b, 0xec, 0x9f, 0x7f, 0xd9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, + 0x52, 0x57, 0x25, 0xdb, 0x1f, 0xcf, 0xbb, 0xda, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, + 0x96, 0xeb, 0x13, 0x76, 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0x33, 0x41, 0x93, 0x1c, 0xc2, + 0x48, 0xb6, 0x6f, 0xc1, 0xa9, 0xae, 0xa4, 0xaa, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x5a, 0x6d, 0x0c, + 0x43, 0x94, 0xb0, 0x2c, 0x87, 0x33, 0x03, 0xa7, 0xf8, 0x42, 0xa2, 0x9c, 0x56, 0x1a, 0x1b, 0xa4, + 0xad, 0x12, 0xe5, 0x98, 0x7f, 0xfd, 0x66, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0xcf, 0x5b, 0x30, 0x92, + 0xca, 0x73, 0x2b, 0xc8, 0x08, 0x62, 0x2b, 0x2d, 0x60, 0xd1, 0x7f, 0x2c, 0x04, 0xba, 0xcc, 0x94, + 0xa9, 0x5e, 0x69, 0x1a, 0x84, 0x4d, 0x3c, 0xfb, 0x4b, 0x25, 0xa8, 0xc9, 0x08, 0x8a, 0x3e, 0xba, + 0xf2, 0x59, 0x0b, 0x46, 0xd4, 0x99, 0x06, 0x73, 0x96, 0x95, 0x8a, 0x48, 0x4a, 0xa0, 0x3d, 0x50, + 0xdb, 0x6d, 0x7f, 0x3d, 0xd0, 0x16, 0x39, 0x36, 0x99, 0xe1, 0x34, 0x6f, 0x74, 0x13, 0x20, 0xde, + 0x89, 0x13, 0xd2, 0x36, 0xdc, 0x76, 0xb6, 0xb1, 0xe2, 0x26, 0x1a, 0x41, 0x44, 0xe8, 0xfa, 0xba, + 0x1e, 0x34, 0xc9, 0x8a, 0xc2, 0xd4, 0x26, 0x94, 0x6e, 0xc3, 0x06, 0x25, 0xfb, 0xef, 0x95, 0xe0, + 0x64, 0xb6, 0x4b, 0xe8, 0x43, 0x30, 0x2c, 0xb9, 0x1b, 0xd7, 0x94, 0xc9, 0xb0, 0x91, 0x61, 0x6c, + 0xc0, 0xee, 0xed, 0x8e, 0x8f, 0x77, 0x5f, 0x13, 0x37, 0x61, 0xa2, 0xe0, 0x14, 0x31, 0x7e, 0xb0, + 0x24, 0x4e, 0x40, 0xa7, 0x77, 0xa6, 0xc2, 0x50, 0x9c, 0x0e, 0x19, 0x07, 0x4b, 0x26, 0x14, 0x67, + 0xb0, 0xd1, 0x32, 0x9c, 0x31, 0x5a, 0xae, 0x13, 0xb7, 0xb5, 0xb1, 0x16, 0x44, 0x72, 0x67, 0xf5, + 0x98, 0x0e, 0xec, 0xea, 0xc6, 0xc1, 0xb9, 0x4f, 0x52, 0x6d, 0xdf, 0x70, 0x42, 0xa7, 0xe1, 0x26, + 0x3b, 0xc2, 0x0f, 0xa9, 0x64, 0xd3, 0x8c, 0x68, 0xc7, 0x0a, 0xc3, 0x5e, 0x84, 0x4a, 0x9f, 0x33, + 0xa8, 0x2f, 0x8b, 0xfe, 0x65, 0xa8, 0x51, 0x72, 0xd2, 0xbc, 0x2b, 0x82, 0x64, 0x00, 0x35, 0x79, + 0xd3, 0x08, 0xb2, 0xa1, 0xec, 0x3a, 0xf2, 0xec, 0x4e, 0xbd, 0xd6, 0x7c, 0x1c, 0x77, 0xd8, 0x26, + 0x99, 0x02, 0xd1, 0x93, 0x50, 0x26, 0xdb, 0x61, 0xf6, 0x90, 0xee, 0xd2, 0x76, 0xe8, 0x46, 0x24, + 0xa6, 0x48, 0x64, 0x3b, 0x44, 0xe7, 0xa1, 0xe4, 0x36, 0x85, 0x92, 0x02, 0x81, 0x53, 0x9a, 0x9f, + 0xc5, 0x25, 0xb7, 0x69, 0x6f, 0x43, 0x5d, 0x5d, 0x6d, 0x82, 0x36, 0xa5, 0xec, 0xb6, 0x8a, 0x08, + 0x79, 0x92, 0x74, 0x7b, 0x48, 0xed, 0x0e, 0x80, 0x4e, 0xf8, 0x2b, 0x4a, 0xbe, 0x5c, 0x80, 0x4a, + 0x23, 0x10, 0xc9, 0xc8, 0x35, 0x4d, 0x86, 0x09, 0x6d, 0x06, 0xb1, 0x6f, 0xc1, 0xe8, 0x35, 0x3f, + 0xb8, 0xc3, 0xea, 0xb2, 0xb3, 0x32, 0x64, 0x94, 0xf0, 0x3a, 0xfd, 0x91, 0x35, 0x11, 0x18, 0x14, + 0x73, 0x98, 0xaa, 0xcf, 0x54, 0xea, 0x55, 0x9f, 0xc9, 0xfe, 0x84, 0x05, 0xc3, 0x2a, 0x73, 0x68, + 0x6e, 0x6b, 0x93, 0xd2, 0x6d, 0x45, 0x41, 0x27, 0xcc, 0xd2, 0x65, 0x97, 0x0f, 0x61, 0x0e, 0x33, + 0x53, 0xea, 0x4a, 0xfb, 0xa4, 0xd4, 0x5d, 0x80, 0xca, 0xa6, 0xeb, 0x37, 0xb3, 0xb7, 0x69, 0x5c, + 0x73, 0xfd, 0x26, 0x66, 0x10, 0xda, 0x85, 0x93, 0xaa, 0x0b, 0x52, 0x21, 0xbc, 0x08, 0xc3, 0x6b, + 0x1d, 0xd7, 0x6b, 0xca, 0xfa, 0x6a, 0x19, 0x4f, 0xc9, 0xb4, 0x01, 0xc3, 0x29, 0x4c, 0xba, 0xaf, + 0x5b, 0x73, 0x7d, 0x27, 0xda, 0x59, 0xd6, 0x1a, 0x48, 0x09, 0xa5, 0x69, 0x05, 0xc1, 0x06, 0x96, + 0xfd, 0x66, 0x19, 0x46, 0xd3, 0xf9, 0x53, 0x7d, 0x6c, 0xaf, 0x9e, 0x84, 0x2a, 0x4b, 0xa9, 0xca, + 0x7e, 0x5a, 0x5e, 0x92, 0x8c, 0xc3, 0x50, 0x0c, 0x03, 0xbc, 0x18, 0x43, 0x31, 0x37, 0xd1, 0xa8, + 0x4e, 0x2a, 0xff, 0x0a, 0x8b, 0x27, 0x13, 0xf5, 0x1f, 0x04, 0x2b, 0xf4, 0x69, 0x0b, 0x06, 0x83, + 0xd0, 0xac, 0xeb, 0xf3, 0xc1, 0x22, 0x73, 0xcb, 0x44, 0xb2, 0x8c, 0xb0, 0x88, 0xd5, 0xa7, 0x97, + 0x9f, 0x43, 0xb2, 0x3e, 0xff, 0x5e, 0x18, 0x36, 0x31, 0xf7, 0x33, 0x8a, 0x6b, 0xa6, 0x51, 0xfc, + 0x59, 0x73, 0x52, 0x88, 0xec, 0xb9, 0x3e, 0x96, 0xdb, 0x0d, 0xa8, 0x36, 0x54, 0x00, 0xc0, 0xa1, + 0xaa, 0x72, 0xaa, 0xea, 0x08, 0xec, 0x10, 0x88, 0x53, 0xb3, 0xbf, 0x6d, 0x19, 0xf3, 0x03, 0x93, + 0x78, 0xbe, 0x89, 0x22, 0x28, 0xb7, 0xb6, 0x36, 0x85, 0x29, 0x7a, 0xb5, 0xa0, 0xe1, 0x9d, 0xdb, + 0xda, 0xd4, 0x73, 0xdc, 0x6c, 0xc5, 0x94, 0x59, 0x1f, 0x4e, 0xc0, 0x54, 0x92, 0x65, 0x79, 0xff, + 0x24, 0x4b, 0xfb, 0xad, 0x12, 0x9c, 0xea, 0x9a, 0x54, 0xe8, 0x0d, 0xa8, 0x46, 0xf4, 0x2d, 0xc5, + 0xeb, 0x2d, 0x14, 0x96, 0x16, 0x19, 0xcf, 0x37, 0xb5, 0xde, 0x4d, 0xb7, 0x63, 0xce, 0x12, 0x5d, + 0x05, 0xa4, 0xc3, 0x54, 0x94, 0x07, 0x92, 0xbf, 0xf2, 0x79, 0xf1, 0x28, 0x9a, 0xea, 0xc2, 0xc0, + 0x39, 0x4f, 0xa1, 0x97, 0xb2, 0x8e, 0xcc, 0x72, 0xfa, 0xdc, 0x72, 0x2f, 0x9f, 0xa4, 0xfd, 0x4f, + 0x4b, 0x30, 0x92, 0x2a, 0xb3, 0x84, 0x3c, 0xa8, 0x11, 0x8f, 0x39, 0xf5, 0xa5, 0xb2, 0x39, 0x6a, + 0xd5, 0x62, 0xa5, 0x20, 0x2f, 0x09, 0xba, 0x58, 0x71, 0x78, 0x38, 0x0e, 0xd7, 0x5f, 0x84, 0x61, + 0xd9, 0xa1, 0x0f, 0x3a, 0x6d, 0x4f, 0x0c, 0xa0, 0x9a, 0xa3, 0x97, 0x0c, 0x18, 0x4e, 0x61, 0xda, + 0xbf, 0x5b, 0x86, 0x31, 0x7e, 0x0a, 0xd2, 0x54, 0x33, 0x6f, 0x51, 0xee, 0xb7, 0xfe, 0x92, 0x2e, + 0x86, 0xc6, 0x07, 0x72, 0xed, 0xa8, 0x97, 0x04, 0xe4, 0x33, 0xea, 0x2b, 0x32, 0xeb, 0xab, 0x99, + 0xc8, 0x2c, 0x6e, 0x76, 0xb7, 0x8e, 0xa9, 0x47, 0xdf, 0x5b, 0xa1, 0x5a, 0xbf, 0x5a, 0x82, 0x13, + 0x99, 0x1b, 0x18, 0xd0, 0x9b, 0xe9, 0xa2, 0xbd, 0x56, 0x11, 0xbe, 0xf2, 0x3d, 0x8b, 0xf2, 0x1f, + 0xac, 0x74, 0xef, 0x03, 0x5a, 0x2a, 0xf6, 0x1f, 0x94, 0x60, 0x34, 0x7d, 0x75, 0xc4, 0x43, 0x38, + 0x52, 0xef, 0x86, 0x3a, 0xab, 0x8e, 0xce, 0xae, 0xc4, 0xe4, 0x2e, 0x79, 0x5e, 0x88, 0x5a, 0x36, + 0x62, 0x0d, 0x7f, 0x28, 0x2a, 0x22, 0xdb, 0x7f, 0xc7, 0x82, 0xb3, 0xfc, 0x2d, 0xb3, 0xf3, 0xf0, + 0x2f, 0xe7, 0x8d, 0xee, 0xab, 0xc5, 0x76, 0x30, 0x53, 0xc4, 0x6f, 0xbf, 0xf1, 0x65, 0x57, 0xf1, + 0x89, 0xde, 0xa6, 0xa7, 0xc2, 0x43, 0xd8, 0xd9, 0x03, 0x4d, 0x06, 0xfb, 0x0f, 0xca, 0xa0, 0x6f, + 0x1f, 0x44, 0xae, 0xc8, 0x71, 0x2c, 0xa4, 0x98, 0xe1, 0xca, 0x8e, 0xdf, 0xd0, 0xf7, 0x1c, 0xd6, + 0x32, 0x29, 0x8e, 0x3f, 0x6f, 0xc1, 0x90, 0xeb, 0xbb, 0x89, 0xeb, 0xb0, 0x6d, 0x74, 0x31, 0x37, + 0xa3, 0x29, 0x76, 0xf3, 0x9c, 0x72, 0x10, 0x99, 0xe7, 0x38, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0x8f, + 0x88, 0xe0, 0xe9, 0x72, 0x61, 0xd9, 0xb9, 0xb5, 0x4c, 0xc4, 0x74, 0x48, 0x0d, 0xaf, 0x24, 0x2a, + 0x28, 0xa9, 0x1d, 0x53, 0x52, 0xaa, 0x2e, 0xae, 0xbe, 0x07, 0x9a, 0x36, 0x63, 0xce, 0xc8, 0x8e, + 0x01, 0x75, 0x8f, 0xc5, 0x01, 0x03, 0x53, 0x27, 0xa1, 0xee, 0x74, 0x92, 0xa0, 0x4d, 0x87, 0x49, + 0x1c, 0x35, 0xe9, 0xd0, 0x5b, 0x09, 0xc0, 0x1a, 0xc7, 0x7e, 0xb3, 0x0a, 0x99, 0xa4, 0x43, 0xb4, + 0x6d, 0xde, 0x9c, 0x69, 0x15, 0x7b, 0x73, 0xa6, 0xea, 0x4c, 0xde, 0xed, 0x99, 0xa8, 0x05, 0xd5, + 0x70, 0xc3, 0x89, 0xa5, 0x59, 0xfd, 0xb2, 0xda, 0xc7, 0xd1, 0xc6, 0x7b, 0xbb, 0xe3, 0x3f, 0xd1, + 0x9f, 0xd7, 0x95, 0xce, 0xd5, 0x49, 0x5e, 0x6c, 0x44, 0xb3, 0x66, 0x34, 0x30, 0xa7, 0x7f, 0x90, + 0xbb, 0xe1, 0x3e, 0x29, 0xca, 0xc0, 0x63, 0x12, 0x77, 0xbc, 0x44, 0xcc, 0x86, 0x97, 0x0b, 0x5c, + 0x65, 0x9c, 0xb0, 0x4e, 0x97, 0xe7, 0xff, 0xb1, 0xc1, 0x14, 0x7d, 0x08, 0xea, 0x71, 0xe2, 0x44, + 0xc9, 0x21, 0x13, 0x5c, 0xd5, 0xa0, 0xaf, 0x48, 0x22, 0x58, 0xd3, 0x43, 0xaf, 0xb0, 0xda, 0xae, + 0x6e, 0xbc, 0x71, 0xc8, 0x9c, 0x07, 0x59, 0x07, 0x56, 0x50, 0xc0, 0x06, 0x35, 0x74, 0x11, 0x80, + 0xcd, 0x6d, 0x1e, 0xe8, 0x57, 0x63, 0x5e, 0x26, 0x25, 0x0a, 0xb1, 0x82, 0x60, 0x03, 0xcb, 0xfe, + 0x61, 0x48, 0xd7, 0x7b, 0x40, 0xe3, 0xb2, 0xbc, 0x04, 0xf7, 0x42, 0xb3, 0xdc, 0x85, 0x54, 0x25, + 0x88, 0xdf, 0xb0, 0xc0, 0x2c, 0x4a, 0x81, 0x5e, 0xe7, 0xd5, 0x2f, 0xac, 0x22, 0x4e, 0x0e, 0x0d, + 0xba, 0x13, 0x8b, 0x4e, 0x98, 0x39, 0xc2, 0x96, 0x25, 0x30, 0xce, 0xbf, 0x07, 0x6a, 0x12, 0x7a, + 0x20, 0xa3, 0xee, 0xe3, 0x70, 0x3a, 0x7b, 0xaf, 0xb8, 0x38, 0x75, 0xda, 0xdf, 0xf5, 0x23, 0xfd, + 0x39, 0xa5, 0x5e, 0xfe, 0x9c, 0x3e, 0xee, 0x4f, 0xfd, 0x4d, 0x0b, 0x2e, 0xec, 0x77, 0xfd, 0x39, + 0x7a, 0x0c, 0x2a, 0x77, 0x9c, 0x48, 0x16, 0xdd, 0x66, 0x82, 0xf2, 0x96, 0x13, 0xf9, 0x98, 0xb5, + 0xa2, 0x1d, 0x18, 0xe0, 0xd1, 0x60, 0xc2, 0x5a, 0x7f, 0xb9, 0xd8, 0xcb, 0xd8, 0xaf, 0x11, 0x63, + 0xbb, 0xc0, 0x23, 0xd1, 0xb0, 0x60, 0x68, 0x7f, 0xc7, 0x02, 0xb4, 0xb4, 0x45, 0xa2, 0xc8, 0x6d, + 0x1a, 0xf1, 0x6b, 0xec, 0x3a, 0x15, 0xe3, 0xda, 0x14, 0x33, 0xc5, 0x35, 0x73, 0x9d, 0x8a, 0xf1, + 0x2f, 0xff, 0x3a, 0x95, 0xd2, 0xc1, 0xae, 0x53, 0x41, 0x4b, 0x70, 0xb6, 0xcd, 0xb7, 0x1b, 0xfc, + 0x8a, 0x02, 0xbe, 0xf7, 0x50, 0x09, 0x65, 0xe7, 0xee, 0xee, 0x8e, 0x9f, 0x5d, 0xcc, 0x43, 0xc0, + 0xf9, 0xcf, 0xd9, 0xef, 0x01, 0xc4, 0xc3, 0xd6, 0x66, 0xf2, 0x62, 0x90, 0x7a, 0xba, 0x5f, 0xec, + 0xaf, 0x54, 0xe1, 0x44, 0xa6, 0x24, 0x2b, 0xdd, 0xea, 0x75, 0x07, 0x3d, 0x1d, 0x59, 0x7f, 0x77, + 0x77, 0xaf, 0xaf, 0x30, 0x2a, 0x1f, 0xaa, 0xae, 0x1f, 0x76, 0x92, 0x62, 0x72, 0x48, 0x79, 0x27, + 0xe6, 0x29, 0x41, 0xc3, 0x5d, 0x4c, 0xff, 0x62, 0xce, 0xa6, 0xc8, 0xa0, 0xac, 0x94, 0x31, 0x5e, + 0x79, 0x40, 0xee, 0x80, 0x4f, 0xea, 0x10, 0xa9, 0x6a, 0x11, 0x8e, 0xc5, 0xcc, 0x64, 0x39, 0xee, + 0xa3, 0xf6, 0x5f, 0x2f, 0xc1, 0x90, 0xf1, 0xd1, 0xd0, 0x2f, 0xa5, 0x4b, 0x36, 0x59, 0xc5, 0xbd, + 0x12, 0xa3, 0x3f, 0xa1, 0x8b, 0x32, 0xf1, 0x57, 0x7a, 0xaa, 0xbb, 0x5a, 0xd3, 0xbd, 0xdd, 0xf1, + 0x93, 0x99, 0x7a, 0x4c, 0xa9, 0x0a, 0x4e, 0xe7, 0x3f, 0x06, 0x27, 0x32, 0x64, 0x72, 0x5e, 0x79, + 0x35, 0x7d, 0x6d, 0xfc, 0x11, 0xdd, 0x52, 0xe6, 0x90, 0x7d, 0x83, 0x0e, 0x99, 0x48, 0xa3, 0x0b, + 0x3c, 0xd2, 0x87, 0x0f, 0x36, 0x93, 0x2d, 0x5b, 0xea, 0x33, 0x5b, 0xf6, 0x69, 0xa8, 0x85, 0x81, + 0xe7, 0x36, 0x5c, 0x55, 0x85, 0x90, 0xe5, 0xe7, 0x2e, 0x8b, 0x36, 0xac, 0xa0, 0xe8, 0x0e, 0xd4, + 0xd5, 0x0d, 0xfb, 0xc2, 0xbf, 0x5d, 0xd4, 0xa1, 0x8f, 0x32, 0x5a, 0xf4, 0xcd, 0xf9, 0x9a, 0x17, + 0xb2, 0x61, 0x80, 0x29, 0x41, 0x19, 0xfa, 0xcf, 0x7c, 0xef, 0x4c, 0x3b, 0xc6, 0x58, 0x40, 0xec, + 0xaf, 0xd7, 0xe1, 0x4c, 0x5e, 0x5d, 0x6c, 0xf4, 0x51, 0x18, 0xe0, 0x7d, 0x2c, 0xe6, 0xea, 0x85, + 0x3c, 0x1e, 0x73, 0x8c, 0xa0, 0xe8, 0x16, 0xfb, 0x8d, 0x05, 0x4f, 0xc1, 0xdd, 0x73, 0xd6, 0xc4, + 0x0c, 0x39, 0x1e, 0xee, 0x0b, 0x8e, 0xe6, 0xbe, 0xe0, 0x70, 0xee, 0x9e, 0xb3, 0x86, 0xb6, 0xa1, + 0xda, 0x72, 0x13, 0xe2, 0x08, 0x27, 0xc2, 0xad, 0x63, 0x61, 0x4e, 0x1c, 0x6e, 0xa5, 0xb1, 0x9f, + 0x98, 0x33, 0x44, 0x5f, 0xb3, 0xe0, 0xc4, 0x5a, 0x3a, 0x35, 0x5e, 0x08, 0x4f, 0xe7, 0x18, 0x6a, + 0x9f, 0xa7, 0x19, 0xf1, 0xfb, 0x84, 0x32, 0x8d, 0x38, 0xdb, 0x1d, 0xf4, 0x29, 0x0b, 0x06, 0xd7, + 0x5d, 0xcf, 0x28, 0x83, 0x7b, 0x0c, 0x1f, 0xe7, 0x32, 0x63, 0xa0, 0x77, 0x1c, 0xfc, 0x7f, 0x8c, + 0x25, 0xe7, 0x5e, 0x9a, 0x6a, 0xe0, 0xa8, 0x9a, 0x6a, 0xf0, 0x01, 0x69, 0xaa, 0xcf, 0x58, 0x50, + 0x57, 0x23, 0x2d, 0xd2, 0x9d, 0x3f, 0x74, 0x8c, 0x9f, 0x9c, 0x7b, 0x4e, 0xd4, 0x5f, 0xac, 0x99, + 0xa3, 0x2f, 0x5a, 0x30, 0xe4, 0xbc, 0xd1, 0x89, 0x48, 0x93, 0x6c, 0x05, 0x61, 0x2c, 0x2e, 0x23, + 0x7c, 0xb5, 0xf8, 0xce, 0x4c, 0x51, 0x26, 0xb3, 0x64, 0x6b, 0x29, 0x8c, 0x45, 0x5a, 0x92, 0x6e, + 0xc0, 0x66, 0x17, 0xec, 0xdd, 0x12, 0x8c, 0xef, 0x43, 0x01, 0xbd, 0x08, 0xc3, 0x41, 0xd4, 0x72, + 0x7c, 0xf7, 0x0d, 0xb3, 0xd6, 0x85, 0xb2, 0xb2, 0x96, 0x0c, 0x18, 0x4e, 0x61, 0x9a, 0x09, 0xd9, + 0xa5, 0x7d, 0x12, 0xb2, 0x2f, 0x40, 0x25, 0x22, 0x61, 0x90, 0xdd, 0x2c, 0xb0, 0x94, 0x00, 0x06, + 0x41, 0x8f, 0x43, 0xd9, 0x09, 0x5d, 0x11, 0x88, 0xa6, 0xf6, 0x40, 0x53, 0xcb, 0xf3, 0x98, 0xb6, + 0xa7, 0xea, 0x43, 0x54, 0xef, 0x4b, 0x7d, 0x08, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0x80, 0x56, 0x03, + 0xe9, 0x33, 0x05, 0xfb, 0xad, 0x32, 0x3c, 0xbe, 0xe7, 0x7c, 0xd1, 0x71, 0x78, 0xd6, 0x1e, 0x71, + 0x78, 0x72, 0x78, 0x4a, 0xfb, 0x0d, 0x4f, 0xb9, 0xc7, 0xf0, 0x7c, 0x8a, 0x2e, 0x03, 0x59, 0x23, + 0xa4, 0x98, 0xeb, 0xe4, 0x7a, 0x95, 0x1c, 0x11, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, + 0xa9, 0x64, 0xe4, 0x6a, 0x11, 0x6a, 0xa0, 0x67, 0xcd, 0x10, 0x3e, 0xf7, 0x7b, 0x65, 0x38, 0xdb, + 0xbf, 0x50, 0x82, 0x27, 0xfb, 0x90, 0xde, 0xe6, 0x2c, 0xb6, 0xfa, 0x9c, 0xc5, 0xdf, 0xdb, 0x9f, + 0xc9, 0xfe, 0x2b, 0x16, 0x9c, 0xef, 0xad, 0x3c, 0xd0, 0x73, 0x30, 0xb4, 0x16, 0x39, 0x7e, 0x63, + 0x83, 0x5d, 0x91, 0x29, 0x07, 0x85, 0x8d, 0xb5, 0x6e, 0xc6, 0x26, 0x0e, 0xdd, 0xde, 0xf2, 0x98, + 0x04, 0x03, 0x43, 0x26, 0x8f, 0xd2, 0xed, 0xed, 0x6a, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x3f, 0x2b, + 0xe5, 0x77, 0x8b, 0x1b, 0x19, 0x07, 0xf9, 0x4e, 0xe2, 0x2b, 0x94, 0xfa, 0x90, 0x25, 0xe5, 0xfb, + 0x2d, 0x4b, 0x2a, 0xbd, 0x64, 0x09, 0x9a, 0x85, 0x93, 0xc6, 0x15, 0x2a, 0x3c, 0x21, 0x98, 0x07, + 0xdc, 0xaa, 0x2a, 0x19, 0xcb, 0x19, 0x38, 0xee, 0x7a, 0x02, 0x3d, 0x03, 0x35, 0xd7, 0x8f, 0x49, + 0xa3, 0x13, 0xf1, 0x40, 0x6f, 0x23, 0x09, 0x6b, 0x5e, 0xb4, 0x63, 0x85, 0x61, 0xff, 0x72, 0x09, + 0xce, 0xf5, 0xb4, 0xb3, 0xee, 0x93, 0xec, 0x32, 0x3f, 0x47, 0xe5, 0xfe, 0x7c, 0x0e, 0x73, 0x90, + 0xaa, 0xfb, 0x0e, 0xd2, 0x1f, 0xf6, 0x9e, 0x98, 0xd4, 0xe6, 0xfe, 0xbe, 0x1d, 0xa5, 0x97, 0x60, + 0xc4, 0x09, 0x43, 0x8e, 0xc7, 0xe2, 0x35, 0x33, 0x55, 0x72, 0xa6, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, + 0xa5, 0x3d, 0xff, 0xd8, 0x82, 0x3a, 0x26, 0xeb, 0x5c, 0x3a, 0xa0, 0xdb, 0x62, 0x88, 0xac, 0x22, + 0xea, 0x69, 0xd2, 0x81, 0x8d, 0x5d, 0x56, 0x67, 0x32, 0x6f, 0xb0, 0xbb, 0xaf, 0xda, 0x29, 0x1d, + 0xe8, 0xaa, 0x1d, 0x75, 0xd9, 0x4a, 0xb9, 0xf7, 0x65, 0x2b, 0xf6, 0x37, 0x06, 0xe9, 0xeb, 0x85, + 0xc1, 0x4c, 0x44, 0x9a, 0x31, 0xfd, 0xbe, 0x9d, 0xc8, 0x13, 0x93, 0x44, 0x7d, 0xdf, 0x1b, 0x78, + 0x01, 0xd3, 0xf6, 0xd4, 0x51, 0x4c, 0xe9, 0x40, 0x35, 0x42, 0xca, 0xfb, 0xd6, 0x08, 0x79, 0x09, + 0x46, 0xe2, 0x78, 0x63, 0x39, 0x72, 0xb7, 0x9c, 0x84, 0x5c, 0x23, 0x3b, 0xc2, 0xca, 0xd2, 0x79, + 0xfd, 0x2b, 0x57, 0x34, 0x10, 0xa7, 0x71, 0xd1, 0x1c, 0x9c, 0xd2, 0x95, 0x3a, 0x48, 0x94, 0xb0, + 0xe8, 0x7e, 0x3e, 0x13, 0x54, 0x12, 0xaf, 0xae, 0xed, 0x21, 0x10, 0x70, 0xf7, 0x33, 0x54, 0xbe, + 0xa5, 0x1a, 0x69, 0x47, 0x06, 0xd2, 0xf2, 0x2d, 0x45, 0x87, 0xf6, 0xa5, 0xeb, 0x09, 0xb4, 0x08, + 0xa7, 0xf9, 0xc4, 0x98, 0x0a, 0x43, 0xe3, 0x8d, 0x06, 0xd3, 0x75, 0x0c, 0xe7, 0xba, 0x51, 0x70, + 0xde, 0x73, 0xe8, 0x05, 0x18, 0x52, 0xcd, 0xf3, 0xb3, 0xe2, 0x14, 0x41, 0x79, 0x31, 0x14, 0x99, + 0xf9, 0x26, 0x36, 0xf1, 0xd0, 0x07, 0xe1, 0x51, 0xfd, 0x97, 0xa7, 0x80, 0xf1, 0xa3, 0xb5, 0x59, + 0x51, 0x04, 0x49, 0x5d, 0xed, 0x31, 0x97, 0x8b, 0xd6, 0xc4, 0xbd, 0x9e, 0x47, 0x6b, 0x70, 0x5e, + 0x81, 0x2e, 0xf9, 0x09, 0xcb, 0xe7, 0x88, 0xc9, 0xb4, 0x13, 0x93, 0x1b, 0x91, 0x27, 0xee, 0x46, + 0x55, 0xb7, 0x2e, 0xce, 0xb9, 0xc9, 0x95, 0x3c, 0x4c, 0xbc, 0x80, 0xf7, 0xa0, 0x82, 0x26, 0xa1, + 0x4e, 0x7c, 0x67, 0xcd, 0x23, 0x4b, 0x33, 0xf3, 0xac, 0x98, 0x92, 0x71, 0x92, 0x77, 0x49, 0x02, + 0xb0, 0xc6, 0x51, 0x11, 0xa6, 0xc3, 0x3d, 0x6f, 0x00, 0x5d, 0x86, 0x33, 0xad, 0x46, 0x48, 0x6d, + 0x0f, 0xb7, 0x41, 0xa6, 0x1a, 0x2c, 0xa0, 0x8e, 0x7e, 0x18, 0x5e, 0x60, 0x52, 0x85, 0x4f, 0xcf, + 0xcd, 0x2c, 0x77, 0xe1, 0xe0, 0xdc, 0x27, 0x59, 0xe0, 0x65, 0x14, 0x6c, 0xef, 0x8c, 0x9d, 0xce, + 0x04, 0x5e, 0xd2, 0x46, 0xcc, 0x61, 0xe8, 0x2a, 0x20, 0x16, 0x8b, 0x7f, 0x25, 0x49, 0x42, 0x65, + 0xec, 0x8c, 0x9d, 0x61, 0xaf, 0xa4, 0xc2, 0xc8, 0x2e, 0x77, 0x61, 0xe0, 0x9c, 0xa7, 0xec, 0x7f, + 0x6f, 0xc1, 0x88, 0x5a, 0xaf, 0xf7, 0x21, 0x1b, 0xc5, 0x4b, 0x67, 0xa3, 0xcc, 0x1d, 0x5d, 0xe2, + 0xb1, 0x9e, 0xf7, 0x08, 0x69, 0xfe, 0xd9, 0x21, 0x00, 0x2d, 0x15, 0x95, 0x42, 0xb2, 0x7a, 0x2a, + 0xa4, 0x87, 0x56, 0x22, 0xe5, 0x55, 0x4e, 0xa9, 0x3e, 0xd8, 0xca, 0x29, 0x2b, 0x70, 0x56, 0x9a, + 0x0b, 0xfc, 0xac, 0xe8, 0x4a, 0x10, 0x2b, 0x01, 0x57, 0x9b, 0x7e, 0x5c, 0x10, 0x3a, 0x3b, 0x9f, + 0x87, 0x84, 0xf3, 0x9f, 0x4d, 0x59, 0x29, 0x83, 0xfb, 0x59, 0x29, 0x7a, 0x4d, 0x2f, 0xac, 0xcb, + 0x3b, 0x3c, 0x32, 0x6b, 0x7a, 0xe1, 0xf2, 0x0a, 0xd6, 0x38, 0xf9, 0x82, 0xbd, 0x5e, 0x90, 0x60, + 0x87, 0x03, 0x0b, 0x76, 0x29, 0x62, 0x86, 0x7a, 0x8a, 0x18, 0xe9, 0x93, 0x1e, 0xee, 0xe9, 0x93, + 0x7e, 0x1f, 0x8c, 0xba, 0xfe, 0x06, 0x89, 0xdc, 0x84, 0x34, 0xd9, 0x5a, 0x60, 0xe2, 0xa7, 0xa6, + 0xd5, 0xfa, 0x7c, 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0xb9, 0x38, 0xda, 0x87, 0x5c, 0xec, 0xa1, 0x8d, + 0x4e, 0x14, 0xa3, 0x8d, 0x4e, 0x1e, 0x5d, 0x1b, 0x9d, 0x3a, 0x56, 0x6d, 0x84, 0x0a, 0xd1, 0x46, + 0x7d, 0x09, 0x7a, 0x63, 0xfb, 0x77, 0x66, 0x9f, 0xed, 0x5f, 0x2f, 0x55, 0x74, 0xf6, 0xd0, 0xaa, + 0x28, 0x5f, 0xcb, 0x3c, 0x72, 0x28, 0x2d, 0xf3, 0x99, 0x12, 0x9c, 0xd5, 0x72, 0x98, 0xce, 0x7e, + 0x77, 0x9d, 0x4a, 0x22, 0x76, 0x0d, 0x14, 0x3f, 0xb7, 0x31, 0x92, 0xa3, 0x74, 0x9e, 0x95, 0x82, + 0x60, 0x03, 0x8b, 0xe5, 0x18, 0x91, 0x88, 0x95, 0xd1, 0xcd, 0x0a, 0xe9, 0x19, 0xd1, 0x8e, 0x15, + 0x06, 0x9d, 0x5f, 0xf4, 0xb7, 0xc8, 0xdb, 0xcc, 0x16, 0x8b, 0x9b, 0xd1, 0x20, 0x6c, 0xe2, 0xa1, + 0xa7, 0x39, 0x13, 0x26, 0x20, 0xa8, 0xa0, 0x1e, 0x16, 0xf7, 0xc2, 0x4a, 0x99, 0xa0, 0xa0, 0xb2, + 0x3b, 0x2c, 0x99, 0xac, 0xda, 0xdd, 0x1d, 0x16, 0x02, 0xa5, 0x30, 0xec, 0xff, 0x61, 0xc1, 0xb9, + 0xdc, 0xa1, 0xb8, 0x0f, 0xca, 0x77, 0x3b, 0xad, 0x7c, 0x57, 0x8a, 0xda, 0x6e, 0x18, 0x6f, 0xd1, + 0x43, 0x11, 0xff, 0x5b, 0x0b, 0x46, 0x35, 0xfe, 0x7d, 0x78, 0x55, 0x37, 0xfd, 0xaa, 0xc5, 0xed, + 0xac, 0xea, 0x5d, 0xef, 0xf6, 0xbb, 0x25, 0x50, 0x05, 0x1c, 0xa7, 0x1a, 0xb2, 0x3c, 0xee, 0x3e, + 0x27, 0x89, 0x3b, 0x30, 0xc0, 0x0e, 0x42, 0xe3, 0x62, 0x82, 0x3c, 0xd2, 0xfc, 0xd9, 0xa1, 0xaa, + 0x3e, 0x64, 0x66, 0x7f, 0x63, 0x2c, 0x18, 0xb2, 0x22, 0xcf, 0x6e, 0x4c, 0xa5, 0x79, 0x53, 0xa4, + 0x65, 0xe9, 0x22, 0xcf, 0xa2, 0x1d, 0x2b, 0x0c, 0xaa, 0x1e, 0xdc, 0x46, 0xe0, 0xcf, 0x78, 0x4e, + 0x2c, 0xef, 0x3e, 0x54, 0xea, 0x61, 0x5e, 0x02, 0xb0, 0xc6, 0x61, 0x67, 0xa4, 0x6e, 0x1c, 0x7a, + 0xce, 0x8e, 0xb1, 0x7f, 0x36, 0xea, 0x13, 0x28, 0x10, 0x36, 0xf1, 0xec, 0x36, 0x8c, 0xa5, 0x5f, + 0x62, 0x96, 0xac, 0xb3, 0x00, 0xc5, 0xbe, 0x86, 0x73, 0x12, 0xea, 0x0e, 0x7b, 0x6a, 0xa1, 0xe3, + 0x64, 0xaf, 0x2c, 0x9f, 0x92, 0x00, 0xac, 0x71, 0xec, 0x5f, 0xb3, 0xe0, 0x74, 0xce, 0xa0, 0x15, + 0x98, 0xf6, 0x96, 0x68, 0x69, 0x93, 0xa7, 0xd8, 0x7f, 0x08, 0x06, 0x9b, 0x64, 0xdd, 0x91, 0x21, + 0x70, 0x86, 0x6c, 0x9f, 0xe5, 0xcd, 0x58, 0xc2, 0xed, 0xff, 0x66, 0xc1, 0x89, 0x74, 0x5f, 0x63, + 0x96, 0x4a, 0xc2, 0x87, 0xc9, 0x8d, 0x1b, 0xc1, 0x16, 0x89, 0x76, 0xe8, 0x9b, 0x5b, 0x99, 0x54, + 0x92, 0x2e, 0x0c, 0x9c, 0xf3, 0x14, 0x2b, 0xdf, 0xda, 0x54, 0xa3, 0x2d, 0x67, 0xe4, 0xcd, 0x22, + 0x67, 0xa4, 0xfe, 0x98, 0xe6, 0x71, 0xb9, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0x77, 0x2a, 0xa0, 0xf2, + 0x62, 0x59, 0xfc, 0x51, 0x41, 0xd1, 0x5b, 0x07, 0xcd, 0x20, 0x52, 0x93, 0xa1, 0xb2, 0x57, 0x40, + 0x00, 0xf7, 0x92, 0x98, 0xae, 0x4b, 0xf5, 0x86, 0xab, 0x1a, 0x84, 0x4d, 0x3c, 0xda, 0x13, 0xcf, + 0xdd, 0x22, 0xfc, 0xa1, 0x81, 0x74, 0x4f, 0x16, 0x24, 0x00, 0x6b, 0x1c, 0xda, 0x93, 0xa6, 0xbb, + 0xbe, 0x2e, 0xb6, 0xfc, 0xaa, 0x27, 0x74, 0x74, 0x30, 0x83, 0xf0, 0x8a, 0xdc, 0xc1, 0xa6, 0xb0, + 0x82, 0x8d, 0x8a, 0xdc, 0xc1, 0x26, 0x66, 0x10, 0x6a, 0xb7, 0xf9, 0x41, 0xd4, 0x66, 0x57, 0xca, + 0x37, 0x15, 0x17, 0x61, 0xfd, 0x2a, 0xbb, 0xed, 0x7a, 0x37, 0x0a, 0xce, 0x7b, 0x8e, 0xce, 0xc0, + 0x30, 0x22, 0x4d, 0xb7, 0x91, 0x98, 0xd4, 0x20, 0x3d, 0x03, 0x97, 0xbb, 0x30, 0x70, 0xce, 0x53, + 0x68, 0x0a, 0x4e, 0xc8, 0xbc, 0x66, 0x59, 0xb5, 0x66, 0x28, 0x5d, 0x25, 0x03, 0xa7, 0xc1, 0x38, + 0x8b, 0x4f, 0xa5, 0x5a, 0x5b, 0x14, 0xac, 0x62, 0xc6, 0xb2, 0x21, 0xd5, 0x64, 0x21, 0x2b, 0xac, + 0x30, 0xec, 0x4f, 0x96, 0xa9, 0x16, 0xee, 0x51, 0xa8, 0xed, 0xbe, 0x45, 0x0b, 0xa6, 0x67, 0x64, + 0xa5, 0x8f, 0x19, 0xf9, 0x3c, 0x0c, 0xdf, 0x8e, 0x03, 0x5f, 0x45, 0xe2, 0x55, 0x7b, 0x46, 0xe2, + 0x19, 0x58, 0xf9, 0x91, 0x78, 0x03, 0x45, 0x45, 0xe2, 0x0d, 0x1e, 0x32, 0x12, 0xef, 0x5b, 0x55, + 0x50, 0x57, 0x83, 0x5c, 0x27, 0xc9, 0x9d, 0x20, 0xda, 0x74, 0xfd, 0x16, 0xcb, 0x07, 0xff, 0x9a, + 0x05, 0xc3, 0x7c, 0xbd, 0x2c, 0x98, 0x99, 0x54, 0xeb, 0x05, 0xdd, 0x39, 0x91, 0x62, 0x36, 0xb1, + 0x6a, 0x30, 0xca, 0x5c, 0xbd, 0x69, 0x82, 0x70, 0xaa, 0x47, 0xe8, 0x63, 0x00, 0xd2, 0x3f, 0xba, + 0x2e, 0x45, 0xe6, 0x7c, 0x31, 0xfd, 0xc3, 0x64, 0x5d, 0xdb, 0xc0, 0xab, 0x8a, 0x09, 0x36, 0x18, + 0xa2, 0xcf, 0xe8, 0x2c, 0x33, 0x1e, 0xb2, 0xff, 0x91, 0x63, 0x19, 0x9b, 0x7e, 0x72, 0xcc, 0x30, + 0x0c, 0xba, 0x7e, 0x8b, 0xce, 0x13, 0x11, 0xb1, 0xf4, 0xae, 0xbc, 0x5a, 0x0a, 0x0b, 0x81, 0xd3, + 0x9c, 0x76, 0x3c, 0xc7, 0x6f, 0x90, 0x68, 0x9e, 0xa3, 0x9b, 0x17, 0x4e, 0xb3, 0x06, 0x2c, 0x09, + 0x75, 0x5d, 0xaa, 0x52, 0xed, 0xe7, 0x52, 0x95, 0xf3, 0xef, 0x87, 0x53, 0x5d, 0x1f, 0xf3, 0x40, + 0x29, 0x65, 0x87, 0xcf, 0x46, 0xb3, 0xff, 0xd9, 0x80, 0x56, 0x5a, 0xd7, 0x83, 0x26, 0xbf, 0xda, + 0x23, 0xd2, 0x5f, 0x54, 0xd8, 0xb8, 0x05, 0x4e, 0x11, 0xe3, 0xd2, 0x6a, 0xd5, 0x88, 0x4d, 0x96, + 0x74, 0x8e, 0x86, 0x4e, 0x44, 0xfc, 0xe3, 0x9e, 0xa3, 0xcb, 0x8a, 0x09, 0x36, 0x18, 0xa2, 0x8d, + 0x54, 0x4e, 0xc9, 0xe5, 0xa3, 0xe7, 0x94, 0xb0, 0x2a, 0x53, 0x79, 0xd5, 0xf8, 0xbf, 0x68, 0xc1, + 0xa8, 0x9f, 0x9a, 0xb9, 0xc5, 0x84, 0x91, 0xe6, 0xaf, 0x0a, 0x7e, 0xb3, 0x54, 0xba, 0x0d, 0x67, + 0xf8, 0xe7, 0xa9, 0xb4, 0xea, 0x01, 0x55, 0x9a, 0xbe, 0x23, 0x68, 0xa0, 0xd7, 0x1d, 0x41, 0xc8, + 0x57, 0x97, 0xa4, 0x0d, 0x16, 0x7e, 0x49, 0x1a, 0xe4, 0x5c, 0x90, 0x76, 0x0b, 0xea, 0x8d, 0x88, + 0x38, 0xc9, 0x21, 0xef, 0xcb, 0x62, 0x07, 0xf4, 0x33, 0x92, 0x00, 0xd6, 0xb4, 0xec, 0xff, 0x5d, + 0x81, 0x93, 0x72, 0x44, 0x64, 0x08, 0x3a, 0xd5, 0x8f, 0x9c, 0xaf, 0x36, 0x6e, 0x95, 0x7e, 0xbc, + 0x22, 0x01, 0x58, 0xe3, 0x50, 0x7b, 0xac, 0x13, 0x93, 0xa5, 0x90, 0xf8, 0x0b, 0xee, 0x5a, 0x2c, + 0xce, 0x39, 0xd5, 0x42, 0xb9, 0xa1, 0x41, 0xd8, 0xc4, 0xa3, 0xc6, 0x38, 0xb7, 0x8b, 0xe3, 0x6c, + 0xfa, 0x8a, 0xb0, 0xb7, 0xb1, 0x84, 0xa3, 0x5f, 0xcc, 0xad, 0x1c, 0x5b, 0x4c, 0xe2, 0x56, 0x57, + 0xe4, 0xfd, 0x01, 0xaf, 0x58, 0xfc, 0x5b, 0x16, 0x9c, 0xe5, 0xad, 0x72, 0x24, 0x6f, 0x84, 0x4d, + 0x27, 0x21, 0x71, 0x31, 0x95, 0xdc, 0x73, 0xfa, 0xa7, 0x9d, 0xbc, 0x79, 0x6c, 0x71, 0x7e, 0x6f, + 0xd0, 0x9b, 0x16, 0x9c, 0xd8, 0x4c, 0xd5, 0xfc, 0x90, 0xaa, 0xe3, 0xa8, 0xe9, 0xf8, 0x29, 0xa2, + 0x7a, 0xa9, 0xa5, 0xdb, 0x63, 0x9c, 0xe5, 0x6e, 0xff, 0x99, 0x05, 0xa6, 0x18, 0xbd, 0xff, 0xa5, + 0x42, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xda, 0xd3, 0xba, 0x7c, 0x1c, 0xca, 0x1d, 0xb7, 0x29, + 0xf6, 0x17, 0xfa, 0xf4, 0x75, 0x7e, 0x16, 0xd3, 0x76, 0xfb, 0x1f, 0x57, 0xb5, 0xdf, 0x42, 0xe4, + 0x45, 0x7d, 0x5f, 0xbc, 0xf6, 0xba, 0x2a, 0x36, 0xc6, 0xdf, 0xfc, 0x7a, 0x57, 0xb1, 0xb1, 0x1f, + 0x3b, 0x78, 0xda, 0x1b, 0x1f, 0xa0, 0x5e, 0xb5, 0xc6, 0x06, 0xf7, 0xc9, 0x79, 0xbb, 0x0d, 0x35, + 0xba, 0x05, 0x63, 0x0e, 0xc8, 0x5a, 0xaa, 0x53, 0xb5, 0x2b, 0xa2, 0xfd, 0xde, 0xee, 0xf8, 0x7b, + 0x0f, 0xde, 0x2d, 0xf9, 0x34, 0x56, 0xf4, 0x51, 0x0c, 0x75, 0xfa, 0x9b, 0xa5, 0xe7, 0x89, 0xcd, + 0xdd, 0x0d, 0x25, 0x33, 0x25, 0xa0, 0x90, 0xdc, 0x3f, 0xcd, 0x07, 0xf9, 0x50, 0x67, 0xb7, 0xd1, + 0x32, 0xa6, 0x7c, 0x0f, 0xb8, 0xac, 0x92, 0xe4, 0x24, 0xe0, 0xde, 0xee, 0xf8, 0x4b, 0x07, 0x67, + 0xaa, 0x1e, 0xc7, 0x9a, 0x85, 0xfd, 0xa5, 0x8a, 0x9e, 0xbb, 0xa2, 0xc6, 0xdc, 0xf7, 0xc5, 0xdc, + 0x7d, 0x31, 0x33, 0x77, 0x2f, 0x74, 0xcd, 0xdd, 0x51, 0x7d, 0x6b, 0x6a, 0x6a, 0x36, 0xde, 0x6f, + 0x43, 0x60, 0x7f, 0x7f, 0x03, 0xb3, 0x80, 0x5e, 0xef, 0xb8, 0x11, 0x89, 0x97, 0xa3, 0x8e, 0xef, + 0xfa, 0x2d, 0x36, 0x1d, 0x6b, 0xa6, 0x05, 0x94, 0x02, 0xe3, 0x2c, 0x3e, 0xdd, 0xd4, 0xd3, 0x6f, + 0x7e, 0xcb, 0xd9, 0xe2, 0xb3, 0xca, 0x28, 0xbb, 0xb5, 0x22, 0xda, 0xb1, 0xc2, 0xb0, 0xbf, 0xc1, + 0xce, 0xb2, 0x8d, 0xbc, 0x60, 0x3a, 0x27, 0x3c, 0x76, 0xfd, 0x2f, 0xaf, 0xd9, 0xa5, 0xe6, 0x04, + 0xbf, 0xf3, 0x97, 0xc3, 0xd0, 0x1d, 0x18, 0x5c, 0xe3, 0xf7, 0xdf, 0x15, 0x53, 0x9f, 0x5c, 0x5c, + 0xa6, 0xc7, 0x6e, 0x39, 0x91, 0x37, 0xeb, 0xdd, 0xd3, 0x3f, 0xb1, 0xe4, 0x66, 0x7f, 0xb3, 0x02, + 0x27, 0x32, 0x17, 0xc4, 0xa6, 0xaa, 0xa5, 0x96, 0xf6, 0xad, 0x96, 0xfa, 0x61, 0x80, 0x26, 0x09, + 0xbd, 0x60, 0x87, 0x99, 0x63, 0x95, 0x03, 0x9b, 0x63, 0xca, 0x82, 0x9f, 0x55, 0x54, 0xb0, 0x41, + 0x51, 0x14, 0x2a, 0xe3, 0xc5, 0x57, 0x33, 0x85, 0xca, 0x8c, 0x5b, 0x0c, 0x06, 0xee, 0xef, 0x2d, + 0x06, 0x2e, 0x9c, 0xe0, 0x5d, 0x54, 0xd9, 0xb7, 0x87, 0x48, 0xb2, 0x65, 0xf9, 0x0b, 0xb3, 0x69, + 0x32, 0x38, 0x4b, 0xf7, 0x41, 0xde, 0xff, 0x8c, 0xde, 0x0d, 0x75, 0xf9, 0x9d, 0xe3, 0xb1, 0xba, + 0xae, 0x60, 0x20, 0xa7, 0x01, 0xbb, 0x97, 0x59, 0xfc, 0xb4, 0xbf, 0x50, 0xa2, 0xd6, 0x33, 0xff, + 0xa7, 0x2a, 0xd1, 0x3c, 0x05, 0x03, 0x4e, 0x27, 0xd9, 0x08, 0xba, 0xee, 0xd0, 0x9b, 0x62, 0xad, + 0x58, 0x40, 0xd1, 0x02, 0x54, 0x9a, 0xba, 0xba, 0xc8, 0x41, 0x46, 0x51, 0x3b, 0x22, 0x9d, 0x84, + 0x60, 0x46, 0x05, 0x3d, 0x06, 0x95, 0xc4, 0x69, 0xc9, 0x44, 0x27, 0x96, 0xdc, 0xba, 0xea, 0xb4, + 0x62, 0xcc, 0x5a, 0x4d, 0xa5, 0x59, 0xd9, 0x47, 0x69, 0xbe, 0x04, 0x23, 0xb1, 0xdb, 0xf2, 0x9d, + 0xa4, 0x13, 0x11, 0xe3, 0x70, 0x4d, 0xc7, 0x4b, 0x98, 0x40, 0x9c, 0xc6, 0xb5, 0x7f, 0x6b, 0x18, + 0xce, 0xac, 0xcc, 0x2c, 0xca, 0x9a, 0xd9, 0xc7, 0x96, 0xab, 0x94, 0xc7, 0xe3, 0xfe, 0xe5, 0x2a, + 0xf5, 0xe0, 0xee, 0x19, 0xb9, 0x4a, 0x9e, 0x91, 0xab, 0x94, 0x4e, 0x1c, 0x29, 0x17, 0x91, 0x38, + 0x92, 0xd7, 0x83, 0x7e, 0x12, 0x47, 0x8e, 0x2d, 0x79, 0x69, 0xcf, 0x0e, 0x1d, 0x28, 0x79, 0x49, + 0x65, 0x76, 0x15, 0x12, 0xd2, 0xdf, 0xe3, 0x53, 0xe5, 0x66, 0x76, 0xa9, 0xac, 0x1a, 0x9e, 0xae, + 0x22, 0x04, 0xec, 0xab, 0xc5, 0x77, 0xa0, 0x8f, 0xac, 0x1a, 0x91, 0x31, 0x63, 0x66, 0x72, 0x0d, + 0x16, 0x91, 0xc9, 0x95, 0xd7, 0x9d, 0x7d, 0x33, 0xb9, 0x5e, 0x82, 0x91, 0x86, 0x17, 0xf8, 0x64, + 0x39, 0x0a, 0x92, 0xa0, 0x11, 0x78, 0xc2, 0x98, 0x56, 0x22, 0x61, 0xc6, 0x04, 0xe2, 0x34, 0x6e, + 0xaf, 0x34, 0xb0, 0xfa, 0x51, 0xd3, 0xc0, 0xe0, 0x01, 0xa5, 0x81, 0xfd, 0x9c, 0x4e, 0x58, 0x1e, + 0x62, 0x5f, 0xe4, 0xc3, 0xc5, 0x7f, 0x91, 0x7e, 0xb2, 0x96, 0xd1, 0x5b, 0xfc, 0x12, 0x3b, 0x6a, + 0x8e, 0xce, 0x04, 0x6d, 0x6a, 0x6e, 0x0d, 0xb3, 0x21, 0x79, 0xed, 0x18, 0x26, 0xec, 0xad, 0x15, + 0xcd, 0x46, 0x5d, 0x6c, 0xa7, 0x9b, 0x70, 0xba, 0x23, 0x47, 0x49, 0xa8, 0xfe, 0x4a, 0x09, 0x7e, + 0x60, 0xdf, 0x2e, 0xa0, 0x3b, 0x00, 0x89, 0xd3, 0x12, 0x13, 0x55, 0x1c, 0x53, 0x1c, 0x31, 0xa8, + 0x71, 0x55, 0xd2, 0xe3, 0x95, 0x40, 0xd4, 0x5f, 0x76, 0x00, 0x20, 0x7f, 0xb3, 0x58, 0xc6, 0xc0, + 0xeb, 0x2a, 0x98, 0x88, 0x03, 0x8f, 0x60, 0x06, 0xa1, 0xea, 0x3f, 0x22, 0x2d, 0x7d, 0xeb, 0xb2, + 0xfa, 0x7c, 0x98, 0xb5, 0x62, 0x01, 0x45, 0x2f, 0xc0, 0x90, 0xe3, 0x79, 0x3c, 0x2b, 0x85, 0xc4, + 0xe2, 0x16, 0x1b, 0x5d, 0xb9, 0x4d, 0x83, 0xb0, 0x89, 0x67, 0xff, 0x69, 0x09, 0xc6, 0xf7, 0x91, + 0x29, 0x5d, 0x79, 0x76, 0xd5, 0xbe, 0xf3, 0xec, 0x44, 0x66, 0xc0, 0x40, 0x8f, 0xcc, 0x80, 0x17, + 0x60, 0x28, 0x21, 0x4e, 0x5b, 0x84, 0x41, 0x89, 0xfd, 0xb7, 0x3e, 0x77, 0xd5, 0x20, 0x6c, 0xe2, + 0x51, 0x29, 0x36, 0xea, 0x34, 0x1a, 0x24, 0x8e, 0x65, 0xe8, 0xbf, 0xf0, 0x61, 0x16, 0x96, 0x57, + 0xc0, 0x5c, 0xc3, 0x53, 0x29, 0x16, 0x38, 0xc3, 0x32, 0x3b, 0xe0, 0xf5, 0x3e, 0x07, 0xfc, 0xeb, + 0x25, 0x78, 0x7c, 0x4f, 0xed, 0xd6, 0x77, 0x56, 0x46, 0x27, 0x26, 0x51, 0x76, 0xe2, 0xdc, 0x88, + 0x49, 0x84, 0x19, 0x84, 0x8f, 0x52, 0x18, 0x1a, 0xb7, 0x5a, 0x17, 0x9d, 0x32, 0xc4, 0x47, 0x29, + 0xc5, 0x02, 0x67, 0x58, 0x1e, 0x76, 0x5a, 0xfe, 0xdd, 0x12, 0x3c, 0xd9, 0x87, 0x0d, 0x50, 0x60, + 0x6a, 0x55, 0x3a, 0xc1, 0xad, 0xfc, 0x80, 0xf2, 0x10, 0x0f, 0x39, 0x5c, 0xdf, 0x28, 0xc1, 0xf9, + 0xde, 0xaa, 0x18, 0xfd, 0x38, 0xdd, 0xc3, 0xcb, 0xd8, 0x27, 0x33, 0x37, 0xee, 0x34, 0xdf, 0xbf, + 0xa7, 0x40, 0x38, 0x8b, 0x8b, 0x26, 0x00, 0x42, 0x27, 0xd9, 0x88, 0x2f, 0x6d, 0xbb, 0x71, 0x22, + 0x6a, 0xbf, 0x8c, 0xf2, 0x13, 0x23, 0xd9, 0x8a, 0x0d, 0x0c, 0xca, 0x8e, 0xfd, 0x9b, 0x0d, 0xae, + 0x07, 0x09, 0x7f, 0x88, 0x6f, 0x23, 0x4e, 0xcb, 0x9b, 0x32, 0x0c, 0x10, 0xce, 0xe2, 0x52, 0x76, + 0xec, 0x4c, 0x92, 0x77, 0x94, 0xef, 0x2f, 0x18, 0xbb, 0x05, 0xd5, 0x8a, 0x0d, 0x8c, 0x6c, 0xd6, + 0x5f, 0x75, 0xff, 0xac, 0x3f, 0xfb, 0x1f, 0x95, 0xe0, 0x5c, 0x4f, 0x53, 0xae, 0xbf, 0x05, 0xf8, + 0xf0, 0x65, 0xea, 0x1d, 0x6e, 0xee, 0x1c, 0x30, 0xa3, 0xec, 0x8f, 0x7b, 0xcc, 0x34, 0x91, 0x51, + 0x76, 0xf8, 0x94, 0xec, 0x87, 0x6f, 0x3c, 0xbb, 0x92, 0xc8, 0x2a, 0x07, 0x48, 0x22, 0xcb, 0x7c, + 0x8c, 0x6a, 0x9f, 0x0b, 0xf9, 0xcf, 0xcb, 0x3d, 0x87, 0x97, 0x6e, 0xfd, 0xfa, 0xf2, 0x8e, 0xce, + 0xc2, 0x49, 0xd7, 0x67, 0xb7, 0x26, 0xad, 0x74, 0xd6, 0x44, 0x39, 0x90, 0x52, 0xfa, 0xce, 0xf2, + 0xf9, 0x0c, 0x1c, 0x77, 0x3d, 0xf1, 0x10, 0x26, 0xf5, 0x1d, 0x6e, 0x48, 0x0f, 0x96, 0x56, 0x8a, + 0x96, 0xe0, 0xac, 0x1c, 0x8a, 0x0d, 0x27, 0x22, 0x4d, 0xa1, 0x46, 0x62, 0x91, 0xc6, 0x70, 0x8e, + 0xa7, 0x42, 0xe4, 0x20, 0xe0, 0xfc, 0xe7, 0xd8, 0x45, 0x35, 0x41, 0xe8, 0x36, 0xc4, 0x26, 0x47, + 0x5f, 0x54, 0x43, 0x1b, 0x31, 0x87, 0xd9, 0x1f, 0x86, 0xba, 0x7a, 0x7f, 0x1e, 0x4c, 0xad, 0x26, + 0x5d, 0x57, 0x30, 0xb5, 0x9a, 0x71, 0x06, 0x16, 0xfd, 0x5a, 0xd4, 0x24, 0xce, 0xac, 0x9e, 0x6b, + 0x64, 0x87, 0xd9, 0xc7, 0xf6, 0x8f, 0xc0, 0xb0, 0xf2, 0xb3, 0xf4, 0x7b, 0x7d, 0x8f, 0xfd, 0xa5, + 0x01, 0x18, 0x49, 0x95, 0xe4, 0x4b, 0xb9, 0x35, 0xad, 0x7d, 0xdd, 0x9a, 0x2c, 0x38, 0xbe, 0xe3, + 0xcb, 0xbb, 0xbd, 0x8c, 0xe0, 0xf8, 0x8e, 0x4f, 0x30, 0x87, 0x51, 0xf3, 0xb6, 0x19, 0xed, 0xe0, + 0x8e, 0x2f, 0x82, 0x58, 0x95, 0x79, 0x3b, 0xcb, 0x5a, 0xb1, 0x80, 0xa2, 0x4f, 0x58, 0x30, 0x1c, + 0x33, 0x9f, 0x39, 0x77, 0x0a, 0x8b, 0x49, 0x77, 0xf5, 0xe8, 0x15, 0x07, 0x55, 0xf9, 0x49, 0x16, + 0x97, 0x62, 0xb6, 0xe0, 0x14, 0x47, 0xf4, 0x69, 0x0b, 0xea, 0xea, 0x0a, 0x12, 0x71, 0x01, 0xdf, + 0x4a, 0xb1, 0x15, 0x0f, 0xb9, 0x37, 0x51, 0x1d, 0x3f, 0xa8, 0xd2, 0x73, 0x58, 0x33, 0x46, 0xb1, + 0xf2, 0xd8, 0x0e, 0x1e, 0x8f, 0xc7, 0x16, 0x72, 0xbc, 0xb5, 0xef, 0x86, 0x7a, 0xdb, 0xf1, 0xdd, + 0x75, 0x12, 0x27, 0xdc, 0x89, 0x2a, 0x0b, 0xb1, 0xca, 0x46, 0xac, 0xe1, 0x54, 0x21, 0xc7, 0xec, + 0xc5, 0x12, 0xc3, 0xeb, 0xc9, 0x14, 0xf2, 0x8a, 0x6e, 0xc6, 0x26, 0x8e, 0xe9, 0xa2, 0x85, 0x07, + 0xea, 0xa2, 0x1d, 0xda, 0xc7, 0x45, 0xfb, 0xf7, 0x2d, 0x38, 0x9b, 0xfb, 0xd5, 0x1e, 0xde, 0x70, + 0x43, 0xfb, 0xcb, 0x55, 0x38, 0x9d, 0x53, 0x5b, 0x13, 0xed, 0x98, 0xf3, 0xd9, 0x2a, 0xe2, 0xe4, + 0x3e, 0x7d, 0x10, 0x2d, 0x87, 0x31, 0x67, 0x12, 0x1f, 0xec, 0x80, 0x44, 0x1f, 0x52, 0x94, 0xef, + 0xef, 0x21, 0x85, 0x31, 0x2d, 0x2b, 0x0f, 0x74, 0x5a, 0x56, 0xf7, 0x9e, 0x96, 0xe8, 0xd7, 0x2d, + 0x18, 0x6b, 0xf7, 0x28, 0xe8, 0x2e, 0x1c, 0x8f, 0x37, 0x8f, 0xa7, 0x5c, 0xfc, 0xf4, 0x63, 0x77, + 0x77, 0xc7, 0x7b, 0xd6, 0xd1, 0xc7, 0x3d, 0x7b, 0x65, 0x7f, 0xa7, 0x0c, 0xac, 0xb0, 0x2b, 0xab, + 0x9f, 0xb6, 0x83, 0x3e, 0x6e, 0x96, 0xe8, 0xb5, 0x8a, 0x2a, 0x27, 0xcb, 0x89, 0xab, 0x12, 0xbf, + 0x7c, 0x04, 0xf3, 0x2a, 0xfe, 0x66, 0x85, 0x56, 0xa9, 0x0f, 0xa1, 0xe5, 0xc9, 0x5a, 0xc8, 0xe5, + 0xe2, 0x6b, 0x21, 0xd7, 0xb3, 0x75, 0x90, 0xf7, 0xfe, 0xc4, 0x95, 0x87, 0xf2, 0x13, 0xff, 0x0d, + 0x8b, 0x0b, 0x9e, 0xcc, 0x57, 0xd0, 0x96, 0x81, 0xb5, 0x87, 0x65, 0xf0, 0x0c, 0xd4, 0x62, 0xe2, + 0xad, 0x5f, 0x21, 0x8e, 0x27, 0x2c, 0x08, 0x7d, 0x6a, 0x2c, 0xda, 0xb1, 0xc2, 0x60, 0x97, 0xa5, + 0x7a, 0x5e, 0x70, 0xe7, 0x52, 0x3b, 0x4c, 0x76, 0x84, 0x2d, 0xa1, 0x2f, 0x4b, 0x55, 0x10, 0x6c, + 0x60, 0xd9, 0x7f, 0xb3, 0xc4, 0x67, 0xa0, 0x08, 0x3d, 0x78, 0x31, 0x73, 0xbd, 0x5d, 0xff, 0xa7, + 0xf6, 0x1f, 0x05, 0x68, 0xa8, 0x8b, 0xe1, 0xc5, 0x99, 0xd0, 0x95, 0x23, 0xdf, 0x5a, 0x2d, 0xe8, + 0xe9, 0xd7, 0xd0, 0x6d, 0xd8, 0xe0, 0x97, 0x92, 0xa5, 0xe5, 0x7d, 0x65, 0x69, 0x4a, 0xac, 0x54, + 0xf6, 0xd1, 0x76, 0x7f, 0x6a, 0x41, 0xca, 0x22, 0x42, 0x21, 0x54, 0x69, 0x77, 0x77, 0x8a, 0xb9, + 0xf3, 0xde, 0x24, 0x4d, 0x45, 0xa3, 0x98, 0xf6, 0xec, 0x27, 0xe6, 0x8c, 0x90, 0x27, 0x22, 0x14, + 0xf8, 0xa8, 0x5e, 0x2f, 0x8e, 0xe1, 0x95, 0x20, 0xd8, 0xe4, 0x07, 0x9b, 0x3a, 0xda, 0xc1, 0x7e, + 0x11, 0x4e, 0x75, 0x75, 0x8a, 0xdd, 0x64, 0x15, 0xc8, 0x8b, 0xfe, 0x8d, 0xe9, 0xca, 0xd2, 0x26, + 0x31, 0x87, 0xd9, 0xdf, 0xb0, 0xe0, 0x64, 0x96, 0x3c, 0x7a, 0xcb, 0x82, 0x53, 0x71, 0x96, 0xde, + 0x71, 0x8d, 0x9d, 0x8a, 0x32, 0xec, 0x02, 0xe1, 0xee, 0x4e, 0xd8, 0xff, 0x47, 0x4c, 0xfe, 0x5b, + 0xae, 0xdf, 0x0c, 0xee, 0x28, 0xc3, 0xc4, 0xea, 0x69, 0x98, 0xd0, 0xf5, 0xd8, 0xd8, 0x20, 0xcd, + 0x8e, 0xd7, 0x95, 0xaf, 0xb9, 0x22, 0xda, 0xb1, 0xc2, 0x60, 0xe9, 0x69, 0x1d, 0x51, 0x2c, 0x3d, + 0x33, 0x29, 0x67, 0x45, 0x3b, 0x56, 0x18, 0xe8, 0x79, 0x18, 0x36, 0x5e, 0x52, 0xce, 0x4b, 0x66, + 0x90, 0x1b, 0x2a, 0x33, 0xc6, 0x29, 0x2c, 0x34, 0x01, 0xa0, 0x8c, 0x1c, 0xa9, 0x22, 0x99, 0xa3, + 0x48, 0x49, 0xa2, 0x18, 0x1b, 0x18, 0x2c, 0x19, 0xd4, 0xeb, 0xc4, 0xcc, 0xc7, 0x3f, 0xa0, 0x0b, + 0x78, 0xce, 0x88, 0x36, 0xac, 0xa0, 0x54, 0x9a, 0xb4, 0x1d, 0xbf, 0xe3, 0x78, 0x74, 0x84, 0xc4, + 0xd6, 0x4f, 0x2d, 0xc3, 0x45, 0x05, 0xc1, 0x06, 0x16, 0x7d, 0xe3, 0xc4, 0x6d, 0x93, 0x57, 0x02, + 0x5f, 0x46, 0x87, 0xe9, 0x63, 0x1f, 0xd1, 0x8e, 0x15, 0x86, 0xfd, 0x5f, 0x2c, 0x38, 0xa1, 0x53, + 0xcb, 0xf9, 0x9d, 0xd5, 0xe6, 0x4e, 0xd5, 0xda, 0x77, 0xa7, 0x9a, 0xce, 0xb9, 0x2d, 0xf5, 0x95, + 0x73, 0x6b, 0xa6, 0xc3, 0x96, 0xf7, 0x4c, 0x87, 0xfd, 0x41, 0x7d, 0x1f, 0x2a, 0xcf, 0x9b, 0x1d, + 0xca, 0xbb, 0x0b, 0x15, 0xd9, 0x30, 0xd0, 0x70, 0x54, 0x5d, 0x95, 0x61, 0xbe, 0x77, 0x98, 0x99, + 0x62, 0x48, 0x02, 0x62, 0x2f, 0x41, 0x5d, 0x9d, 0x7e, 0xc8, 0x8d, 0xaa, 0x95, 0xbf, 0x51, 0xed, + 0x2b, 0x2d, 0x6f, 0x7a, 0xed, 0x9b, 0xdf, 0x7d, 0xe2, 0x1d, 0xbf, 0xff, 0xdd, 0x27, 0xde, 0xf1, + 0x47, 0xdf, 0x7d, 0xe2, 0x1d, 0x9f, 0xb8, 0xfb, 0x84, 0xf5, 0xcd, 0xbb, 0x4f, 0x58, 0xbf, 0x7f, + 0xf7, 0x09, 0xeb, 0x8f, 0xee, 0x3e, 0x61, 0x7d, 0xe7, 0xee, 0x13, 0xd6, 0x17, 0xff, 0xe3, 0x13, + 0xef, 0x78, 0x25, 0x37, 0x3c, 0x90, 0xfe, 0x78, 0xb6, 0xd1, 0x9c, 0xdc, 0xba, 0xc8, 0x22, 0xd4, + 0xe8, 0xf2, 0x9a, 0x34, 0xe6, 0xd4, 0xa4, 0x5c, 0x5e, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x90, + 0x85, 0x5a, 0x45, 0xa5, 0xe0, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -6426,6 +6427,13 @@ func (m *ApplicationSetSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.TemplatePatch != nil { + i -= len(*m.TemplatePatch) + copy(dAtA[i:], *m.TemplatePatch) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.TemplatePatch))) + i-- + dAtA[i] = 0x52 + } if len(m.IgnoreApplicationDifferences) > 0 { for iNdEx := len(m.IgnoreApplicationDifferences) - 1; iNdEx >= 0; iNdEx-- { { @@ -14845,6 +14853,10 @@ func (m *ApplicationSetSpec) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + if m.TemplatePatch != nil { + l = len(*m.TemplatePatch) + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -18133,6 +18145,7 @@ func (this *ApplicationSetSpec) String() string { `GoTemplateOptions:` + fmt.Sprintf("%v", this.GoTemplateOptions) + `,`, `ApplyNestedSelectors:` + fmt.Sprintf("%v", this.ApplyNestedSelectors) + `,`, `IgnoreApplicationDifferences:` + repeatedStringForIgnoreApplicationDifferences + `,`, + `TemplatePatch:` + valueToStringGenerated(this.TemplatePatch) + `,`, `}`, }, "") return s @@ -24402,6 +24415,39 @@ func (m *ApplicationSetSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TemplatePatch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + s := string(dAtA[iNdEx:postIndex]) + m.TemplatePatch = &s + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index ac1415786d032..c080c04c3a088 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -316,6 +316,8 @@ message ApplicationSetSpec { optional bool applyNestedSelectors = 8; repeated ApplicationSetResourceIgnoreDifferences ignoreApplicationDifferences = 9; + + optional string templatePatch = 10; } // ApplicationSetStatus defines the observed state of ApplicationSet diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 5dff99db45d12..723ea884cb75b 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -1281,6 +1281,12 @@ func schema_pkg_apis_application_v1alpha1_ApplicationSetSpec(ref common.Referenc }, }, }, + "templatePatch": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"generators", "template"}, }, diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index 48e7e601670be..c10b610cbd5a7 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -733,6 +733,11 @@ func (in *ApplicationSetSpec) DeepCopyInto(out *ApplicationSetSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.TemplatePatch != nil { + in, out := &in.TemplatePatch, &out.TemplatePatch + *out = new(string) + **out = **in + } return } diff --git a/test/e2e/applicationset_test.go b/test/e2e/applicationset_test.go index 2fef0ace55583..5b9b8190c5437 100644 --- a/test/e2e/applicationset_test.go +++ b/test/e2e/applicationset_test.go @@ -599,6 +599,134 @@ func TestRenderHelmValuesObject(t *testing.T) { } +func TestTemplatePatch(t *testing.T) { + + expectedApp := argov1alpha1.Application{ + TypeMeta: metav1.TypeMeta{ + Kind: application.ApplicationKind, + APIVersion: "argoproj.io/v1alpha1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "my-cluster-guestbook", + Namespace: fixture.TestNamespace(), + Finalizers: []string{"resources-finalizer.argocd.argoproj.io"}, + Annotations: map[string]string{ + "annotation-some-key": "annotation-some-value", + }, + }, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "guestbook", + }, + SyncPolicy: &argov1alpha1.SyncPolicy{ + SyncOptions: argov1alpha1.SyncOptions{"CreateNamespace=true"}, + }, + }, + } + + templatePatch := `{ + "metadata": { + "annotations": { + {{- range $k, $v := .annotations }} + "{{ $k }}": "{{ $v }}" + {{- end }} + } + }, + {{- if .createNamespace }} + "spec": { + "syncPolicy": { + "syncOptions": [ + "CreateNamespace=true" + ] + } + } + {{- end }} + } + ` + + var expectedAppNewNamespace *argov1alpha1.Application + var expectedAppNewMetadata *argov1alpha1.Application + + Given(t). + // Create a ListGenerator-based ApplicationSet + When().Create(v1alpha1.ApplicationSet{ObjectMeta: metav1.ObjectMeta{ + Name: "patch-template", + }, + Spec: v1alpha1.ApplicationSetSpec{ + GoTemplate: true, + Template: v1alpha1.ApplicationSetTemplate{ + ApplicationSetTemplateMeta: v1alpha1.ApplicationSetTemplateMeta{Name: "{{.cluster}}-guestbook"}, + Spec: argov1alpha1.ApplicationSpec{ + Project: "default", + Source: &argov1alpha1.ApplicationSource{ + RepoURL: "https://github.com/argoproj/argocd-example-apps.git", + TargetRevision: "HEAD", + Path: "guestbook", + }, + Destination: argov1alpha1.ApplicationDestination{ + Server: "{{.url}}", + Namespace: "guestbook", + }, + }, + }, + TemplatePatch: &templatePatch, + Generators: []v1alpha1.ApplicationSetGenerator{ + { + List: &v1alpha1.ListGenerator{ + Elements: []apiextensionsv1.JSON{{ + Raw: []byte(`{ + "cluster": "my-cluster", + "url": "https://kubernetes.default.svc", + "createNamespace": true, + "annotations": { + "annotation-some-key": "annotation-some-value" + } + }`), + }}, + }, + }, + }, + }, + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{expectedApp})). + + // Update the ApplicationSet template namespace, and verify it updates the Applications + When(). + And(func() { + expectedAppNewNamespace = expectedApp.DeepCopy() + expectedAppNewNamespace.Spec.Destination.Namespace = "guestbook2" + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Spec.Destination.Namespace = "guestbook2" + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewNamespace})). + + // Update the metadata fields in the appset template, and make sure it propagates to the apps + When(). + And(func() { + expectedAppNewMetadata = expectedAppNewNamespace.DeepCopy() + expectedAppNewMetadata.ObjectMeta.Labels = map[string]string{ + "label-key": "label-value", + } + }). + Update(func(appset *v1alpha1.ApplicationSet) { + appset.Spec.Template.Labels = map[string]string{"label-key": "label-value"} + }).Then().Expect(ApplicationsExist([]argov1alpha1.Application{*expectedAppNewMetadata})). + + // verify the ApplicationSet status conditions were set correctly + Expect(ApplicationSetHasConditions("patch-template", ExpectedConditions)). + + // Delete the ApplicationSet, and verify it deletes the Applications + When(). + Delete().Then().Expect(ApplicationsDoNotExist([]argov1alpha1.Application{*expectedAppNewMetadata})) + +} + func TestSyncPolicyCreateUpdate(t *testing.T) { expectedApp := argov1alpha1.Application{ From 017b08a61cb989deae7502d2e148e08107e824fd Mon Sep 17 00:00:00 2001 From: Jonas Eilers <133217951+jdvgh@users.noreply.github.com> Date: Fri, 1 Dec 2023 21:15:42 +0100 Subject: [PATCH 137/269] feat(ui): Add sourceNamespaces in Projects UI and only show it if AppsInAnyNamespaceEnabled flag is set (#16249) Signed-off-by: Eilers, Jonas <133217951+jdvgh@users.noreply.github.com> --- .../project-details/project-details.tsx | 59 ++++++++++++++++++- .../project-details/resource-lists-panel.tsx | 32 ++++++++++ ui/src/app/shared/models.ts | 1 + 3 files changed, 90 insertions(+), 2 deletions(-) diff --git a/ui/src/app/settings/components/project-details/project-details.tsx b/ui/src/app/settings/components/project-details/project-details.tsx index 224c2e1e45e12..8b00c8590edb7 100644 --- a/ui/src/app/settings/components/project-details/project-details.tsx +++ b/ui/src/app/settings/components/project-details/project-details.tsx @@ -6,7 +6,7 @@ import {FormApi, Text} from 'react-form'; import {RouteComponentProps} from 'react-router'; import {BadgePanel, CheckboxField, DataLoader, EditablePanel, ErrorNotification, MapInputField, Page, Query} from '../../../shared/components'; -import {AppContext, Consumer} from '../../../shared/context'; +import {AppContext, Consumer, AuthSettingsCtx} from '../../../shared/context'; import {GroupKind, Groups, Project, DetailedProjectsResponse, ProjectSpec, ResourceKinds} from '../../../shared/models'; import {CreateJWTTokenParams, DeleteJWTTokenParams, ProjectRoleParams, services} from '../../../shared/services'; @@ -52,6 +52,7 @@ function reduceGlobal(projs: Project[]): ProjectSpec & {count: number} { merged.namespaceResourceWhitelist = merged.namespaceResourceWhitelist.concat(proj.spec.namespaceResourceWhitelist || []); merged.sourceRepos = merged.sourceRepos.concat(proj.spec.sourceRepos || []); merged.destinations = merged.destinations.concat(proj.spec.destinations || []); + merged.sourceNamespaces = merged.sourceNamespaces.concat(proj.spec.sourceNamespaces || []); merged.sourceRepos = merged.sourceRepos.filter((item, index) => { return ( @@ -106,6 +107,15 @@ function reduceGlobal(projs: Project[]): ProjectSpec & {count: number} { }) ); }); + + merged.sourceNamespaces = merged.sourceNamespaces.filter((item, index) => { + return ( + index === + merged.sourceNamespaces.findIndex(obj => { + return obj === item; + }) + ); + }); merged.count += 1; return merged; @@ -116,6 +126,7 @@ function reduceGlobal(projs: Project[]): ProjectSpec & {count: number} { namespaceResourceWhitelist: new Array(), clusterResourceWhitelist: new Array(), sourceRepos: [], + sourceNamespaces: [], signatureKeys: [], destinations: [], description: '', @@ -648,7 +659,51 @@ export class ProjectDetails extends React.Component - + + {authCtx => + authCtx.appsInAnyNamespaceEnabled && ( + this.saveProject(item)} + values={proj} + title={ + SOURCE NAMESPACES {helpTip('Kubernetes namespaces where application resources are allowed to be created in')} + } + view={ + + {proj.spec.sourceNamespaces + ? proj.spec.sourceNamespaces.map((namespace, i) => ( +
    +
    {namespace}
    +
    + )) + : emptyMessage('source namespaces')} +
    + } + edit={formApi => ( + + {(formApi.values.spec.sourceNamespaces || []).map((_: Project, i: number) => ( +
    +
    + + formApi.setValue('spec.sourceNamespaces', removeEl(formApi.values.spec.sourceNamespaces, i))} + /> +
    +
    + ))} + +
    + )} + items={[]} + /> + ) + } +
    this.saveProject(item)} values={proj} diff --git a/ui/src/app/settings/components/project-details/resource-lists-panel.tsx b/ui/src/app/settings/components/project-details/resource-lists-panel.tsx index 2e5c1d1fedd72..ec9e617ac9122 100644 --- a/ui/src/app/settings/components/project-details/resource-lists-panel.tsx +++ b/ui/src/app/settings/components/project-details/resource-lists-panel.tsx @@ -99,6 +99,36 @@ function viewSourceReposInfoList(type: field, proj: Project) { ); } +const sourceNamespacesInfoByField: {[type: string]: {title: string; helpText: string}} = { + sourceNamespaces: { + title: 'source namespaces', + helpText: 'Kubernetes namespaces where application resources are allowed to be created in' + } +}; + +function viewSourceNamespacesInfoList(type: field, proj: Project) { + const info = sourceNamespacesInfoByField[type]; + const list = proj.spec[type] as Array; + return ( + +

    + {info.title} {helpTip(info.helpText)} +

    + {(list || []).length > 0 ? ( + + {list.map((namespace, i) => ( +
    +
    {namespace}
    +
    + ))} +
    + ) : ( +

    The {info.title} is empty

    + )} +
    + ); +} + const destinationsInfoByField: {[type: string]: {title: string; helpText: string}} = { destinations: { title: 'destinations', @@ -180,6 +210,8 @@ export const ResourceListsPanel = ({proj, saveProject, title}: {proj: Project; t {viewList(key as field, proj)} ))} {!proj.metadata && Object.keys(sourceReposInfoByField).map(key => {viewSourceReposInfoList(key as field, proj)})} + {!proj.metadata && + Object.keys(sourceNamespacesInfoByField).map(key => {viewSourceNamespacesInfoList(key as field, proj)})} {!proj.metadata && Object.keys(destinationsInfoByField).map(key => {viewDestinationsInfoList(key as field, proj)})} } diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index b3f4c284dcfc4..861513523c7a3 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -714,6 +714,7 @@ export interface ProjectSignatureKey { export interface ProjectSpec { sourceRepos: string[]; + sourceNamespaces: string[]; destinations: ApplicationDestination[]; description: string; roles: ProjectRole[]; From 7408292bb058fcb1feb62b27cc7b348b2a4b2c68 Mon Sep 17 00:00:00 2001 From: Dhruvang Makadia Date: Sun, 3 Dec 2023 17:54:55 -0800 Subject: [PATCH 138/269] fix(appset): Don't use revision cache when reconciling after webhook (#16062) (#16241) * fix(appset): store sha from webhook to get latest change during reconcile (#16062) Signed-off-by: dhruvang1 * fix(appset): Don't use revision cache when reconciling after webhook(#16062) Signed-off-by: dhruvang1 --------- Signed-off-by: dhruvang1 --- applicationset/generators/git.go | 14 +- applicationset/generators/git_test.go | 8 +- applicationset/generators/matrix_test.go | 2 +- applicationset/services/mocks/Repos.go | 36 +- applicationset/services/repo_service.go | 14 +- applicationset/services/repo_service_test.go | 28 +- reposerver/apiclient/repository.pb.go | 348 ++++++++++++------- reposerver/repository/repository.go | 7 +- reposerver/repository/repository.proto | 2 + 9 files changed, 277 insertions(+), 182 deletions(-) diff --git a/applicationset/generators/git.go b/applicationset/generators/git.go index 07c1b11849cd0..57fe2835b8df0 100644 --- a/applicationset/generators/git.go +++ b/applicationset/generators/git.go @@ -56,12 +56,14 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic return nil, EmptyAppSetGeneratorError } + noRevisionCache := appSet.RefreshRequired() + var err error var res []map[string]interface{} if len(appSetGenerator.Git.Directories) != 0 { - res, err = g.generateParamsForGitDirectories(appSetGenerator, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) + res, err = g.generateParamsForGitDirectories(appSetGenerator, noRevisionCache, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) } else if len(appSetGenerator.Git.Files) != 0 { - res, err = g.generateParamsForGitFiles(appSetGenerator, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) + res, err = g.generateParamsForGitFiles(appSetGenerator, noRevisionCache, appSet.Spec.GoTemplate, appSet.Spec.GoTemplateOptions) } else { return nil, EmptyAppSetGeneratorError } @@ -72,10 +74,10 @@ func (g *GitGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha1.Applic return res, nil } -func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { +func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { // Directories, not files - allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision) + allPaths, err := g.repos.GetDirectories(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, noRevisionCache) if err != nil { return nil, fmt.Errorf("error getting directories from repo: %w", err) } @@ -98,12 +100,12 @@ func (g *GitGenerator) generateParamsForGitDirectories(appSetGenerator *argoproj return res, nil } -func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { +func (g *GitGenerator) generateParamsForGitFiles(appSetGenerator *argoprojiov1alpha1.ApplicationSetGenerator, noRevisionCache bool, useGoTemplate bool, goTemplateOptions []string) ([]map[string]interface{}, error) { // Get all files that match the requested path string, removing duplicates allFiles := make(map[string][]byte) for _, requestedPath := range appSetGenerator.Git.Files { - files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, requestedPath.Path) + files, err := g.repos.GetFiles(context.TODO(), appSetGenerator.Git.RepoURL, appSetGenerator.Git.Revision, requestedPath.Path, noRevisionCache) if err != nil { return nil, err } diff --git a/applicationset/generators/git_test.go b/applicationset/generators/git_test.go index f0d1d29bca6ec..d3fd4965057f8 100644 --- a/applicationset/generators/git_test.go +++ b/applicationset/generators/git_test.go @@ -317,7 +317,7 @@ func TestGitGenerateParamsFromDirectories(t *testing.T) { argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ @@ -613,7 +613,7 @@ func TestGitGenerateParamsFromDirectoriesGoTemplate(t *testing.T) { argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) + argoCDServiceMock.On("GetDirectories", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(testCaseCopy.repoApps, testCaseCopy.repoError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) applicationSetInfo := argoprojiov1alpha1.ApplicationSet{ @@ -972,7 +972,7 @@ cluster: t.Parallel() argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) @@ -1322,7 +1322,7 @@ cluster: t.Parallel() argoCDServiceMock := mocks.Repos{} - argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + argoCDServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). Return(testCaseCopy.repoFileContents, testCaseCopy.repoPathsError) var gitGenerator = NewGitGenerator(&argoCDServiceMock) diff --git a/applicationset/generators/matrix_test.go b/applicationset/generators/matrix_test.go index 35748b98bcf19..21e88710ae618 100644 --- a/applicationset/generators/matrix_test.go +++ b/applicationset/generators/matrix_test.go @@ -1108,7 +1108,7 @@ func TestGitGenerator_GenerateParams_list_x_git_matrix_generator(t *testing.T) { } repoServiceMock := &mocks.Repos{} - repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{ + repoServiceMock.On("GetFiles", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(map[string][]byte{ "some/path.json": []byte("test: content"), }, nil) gitGenerator := NewGitGenerator(repoServiceMock) diff --git a/applicationset/services/mocks/Repos.go b/applicationset/services/mocks/Repos.go index 776b104cae284..b7620b22f08bb 100644 --- a/applicationset/services/mocks/Repos.go +++ b/applicationset/services/mocks/Repos.go @@ -13,25 +13,25 @@ type Repos struct { mock.Mock } -// GetDirectories provides a mock function with given fields: ctx, repoURL, revision -func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error) { - ret := _m.Called(ctx, repoURL, revision) +// GetDirectories provides a mock function with given fields: ctx, repoURL, revision, noRevisionCache +func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool) ([]string, error) { + ret := _m.Called(ctx, repoURL, revision, noRevisionCache) var r0 []string var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string) ([]string, error)); ok { - return rf(ctx, repoURL, revision) + if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) ([]string, error)); ok { + return rf(ctx, repoURL, revision, noRevisionCache) } - if rf, ok := ret.Get(0).(func(context.Context, string, string) []string); ok { - r0 = rf(ctx, repoURL, revision) + if rf, ok := ret.Get(0).(func(context.Context, string, string, bool) []string); ok { + r0 = rf(ctx, repoURL, revision, noRevisionCache) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]string) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok { - r1 = rf(ctx, repoURL, revision) + if rf, ok := ret.Get(1).(func(context.Context, string, string, bool) error); ok { + r1 = rf(ctx, repoURL, revision, noRevisionCache) } else { r1 = ret.Error(1) } @@ -39,25 +39,25 @@ func (_m *Repos) GetDirectories(ctx context.Context, repoURL string, revision st return r0, r1 } -// GetFiles provides a mock function with given fields: ctx, repoURL, revision, pattern -func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, pattern string) (map[string][]byte, error) { - ret := _m.Called(ctx, repoURL, revision, pattern) +// GetFiles provides a mock function with given fields: ctx, repoURL, revision, pattern, noRevisionCache +func (_m *Repos) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool) (map[string][]byte, error) { + ret := _m.Called(ctx, repoURL, revision, pattern, noRevisionCache) var r0 map[string][]byte var r1 error - if rf, ok := ret.Get(0).(func(context.Context, string, string, string) (map[string][]byte, error)); ok { - return rf(ctx, repoURL, revision, pattern) + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool) (map[string][]byte, error)); ok { + return rf(ctx, repoURL, revision, pattern, noRevisionCache) } - if rf, ok := ret.Get(0).(func(context.Context, string, string, string) map[string][]byte); ok { - r0 = rf(ctx, repoURL, revision, pattern) + if rf, ok := ret.Get(0).(func(context.Context, string, string, string, bool) map[string][]byte); ok { + r0 = rf(ctx, repoURL, revision, pattern, noRevisionCache) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(map[string][]byte) } } - if rf, ok := ret.Get(1).(func(context.Context, string, string, string) error); ok { - r1 = rf(ctx, repoURL, revision, pattern) + if rf, ok := ret.Get(1).(func(context.Context, string, string, string, bool) error); ok { + r1 = rf(ctx, repoURL, revision, pattern, noRevisionCache) } else { r1 = ret.Error(1) } diff --git a/applicationset/services/repo_service.go b/applicationset/services/repo_service.go index 8ad261fda11cd..64fedc34390b8 100644 --- a/applicationset/services/repo_service.go +++ b/applicationset/services/repo_service.go @@ -11,6 +11,8 @@ import ( "github.com/argoproj/argo-cd/v2/util/io" ) +//go:generate go run github.com/vektra/mockery/v2@v2.25.1 --name=RepositoryDB + // RepositoryDB Is a lean facade for ArgoDB, // Using a lean interface makes it easier to test the functionality of the git generator type RepositoryDB interface { @@ -25,13 +27,15 @@ type argoCDService struct { newFileGlobbingEnabled bool } +//go:generate go run github.com/vektra/mockery/v2@v2.25.1 --name=Repos + type Repos interface { // GetFiles returns content of files (not directories) within the target repo - GetFiles(ctx context.Context, repoURL string, revision string, pattern string) (map[string][]byte, error) + GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool) (map[string][]byte, error) // GetDirectories returns a list of directories (not files) within the target repo - GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error) + GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool) ([]string, error) } func NewArgoCDService(db db.ArgoDB, submoduleEnabled bool, repoClientset apiclient.Clientset, newFileGlobbingEnabled bool) (Repos, error) { @@ -43,7 +47,7 @@ func NewArgoCDService(db db.ArgoDB, submoduleEnabled bool, repoClientset apiclie }, nil } -func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision string, pattern string) (map[string][]byte, error) { +func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision string, pattern string, noRevisionCache bool) (map[string][]byte, error) { repo, err := a.repositoriesDB.GetRepository(ctx, repoURL) if err != nil { return nil, fmt.Errorf("error in GetRepository: %w", err) @@ -55,6 +59,7 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision s Revision: revision, Path: pattern, NewGitFileGlobbingEnabled: a.newFileGlobbingEnabled, + NoRevisionCache: noRevisionCache, } closer, client, err := a.repoServerClientSet.NewRepoServerClient() if err != nil { @@ -69,7 +74,7 @@ func (a *argoCDService) GetFiles(ctx context.Context, repoURL string, revision s return fileResponse.GetMap(), nil } -func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revision string) ([]string, error) { +func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revision string, noRevisionCache bool) ([]string, error) { repo, err := a.repositoriesDB.GetRepository(ctx, repoURL) if err != nil { return nil, fmt.Errorf("error in GetRepository: %w", err) @@ -79,6 +84,7 @@ func (a *argoCDService) GetDirectories(ctx context.Context, repoURL string, revi Repo: repo, SubmoduleEnabled: a.submoduleEnabled, Revision: revision, + NoRevisionCache: noRevisionCache, } closer, client, err := a.repoServerClientSet.NewRepoServerClient() diff --git a/applicationset/services/repo_service_test.go b/applicationset/services/repo_service_test.go index 62f8c11c172d0..040fe57f96958 100644 --- a/applicationset/services/repo_service_test.go +++ b/applicationset/services/repo_service_test.go @@ -25,9 +25,10 @@ func TestGetDirectories(t *testing.T) { repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient) } type args struct { - ctx context.Context - repoURL string - revision string + ctx context.Context + repoURL string + revision string + noRevisionCache bool } tests := []struct { name string @@ -88,11 +89,11 @@ func TestGetDirectories(t *testing.T) { submoduleEnabled: tt.fields.submoduleEnabled, repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient}, } - got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision) - if !tt.wantErr(t, err, fmt.Sprintf("GetDirectories(%v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision)) { + got, err := a.GetDirectories(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache) + if !tt.wantErr(t, err, fmt.Sprintf("GetDirectories(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache)) { return } - assert.Equalf(t, tt.want, got, "GetDirectories(%v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision) + assert.Equalf(t, tt.want, got, "GetDirectories(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.noRevisionCache) }) } } @@ -105,10 +106,11 @@ func TestGetFiles(t *testing.T) { repoServerClientFuncs []func(*repo_mocks.RepoServerServiceClient) } type args struct { - ctx context.Context - repoURL string - revision string - pattern string + ctx context.Context + repoURL string + revision string + pattern string + noRevisionCache bool } tests := []struct { name string @@ -175,11 +177,11 @@ func TestGetFiles(t *testing.T) { submoduleEnabled: tt.fields.submoduleEnabled, repoServerClientSet: &repo_mocks.Clientset{RepoServerServiceClient: mockRepoClient}, } - got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern) - if !tt.wantErr(t, err, fmt.Sprintf("GetFiles(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern)) { + got, err := a.GetFiles(tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache) + if !tt.wantErr(t, err, fmt.Sprintf("GetFiles(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache)) { return } - assert.Equalf(t, tt.want, got, "GetFiles(%v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern) + assert.Equalf(t, tt.want, got, "GetFiles(%v, %v, %v, %v, %v)", tt.args.ctx, tt.args.repoURL, tt.args.revision, tt.args.pattern, tt.args.noRevisionCache) }) } } diff --git a/reposerver/apiclient/repository.pb.go b/reposerver/apiclient/repository.pb.go index 4c05248b87e16..914a967db3dfc 100644 --- a/reposerver/apiclient/repository.pb.go +++ b/reposerver/apiclient/repository.pb.go @@ -1910,6 +1910,7 @@ type GitFilesRequest struct { Revision string `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` NewGitFileGlobbingEnabled bool `protobuf:"varint,5,opt,name=NewGitFileGlobbingEnabled,proto3" json:"NewGitFileGlobbingEnabled,omitempty"` + NoRevisionCache bool `protobuf:"varint,6,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -1983,6 +1984,13 @@ func (m *GitFilesRequest) GetNewGitFileGlobbingEnabled() bool { return false } +func (m *GitFilesRequest) GetNoRevisionCache() bool { + if m != nil { + return m.NoRevisionCache + } + return false +} + type GitFilesResponse struct { // Map consisting of path of the path to its contents in bytes Map map[string][]byte `protobuf:"bytes,1,rep,name=map,proto3" json:"map,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` @@ -2035,6 +2043,7 @@ type GitDirectoriesRequest struct { Repo *v1alpha1.Repository `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"` SubmoduleEnabled bool `protobuf:"varint,2,opt,name=submoduleEnabled,proto3" json:"submoduleEnabled,omitempty"` Revision string `protobuf:"bytes,3,opt,name=revision,proto3" json:"revision,omitempty"` + NoRevisionCache bool `protobuf:"varint,4,opt,name=noRevisionCache,proto3" json:"noRevisionCache,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -2094,6 +2103,13 @@ func (m *GitDirectoriesRequest) GetRevision() string { return "" } +func (m *GitDirectoriesRequest) GetNoRevisionCache() bool { + if m != nil { + return m.NoRevisionCache + } + return false +} + type GitDirectoriesResponse struct { // A set of directory paths Paths []string `protobuf:"bytes,1,rep,name=paths,proto3" json:"paths,omitempty"` @@ -2189,140 +2205,140 @@ func init() { } var fileDescriptor_dd8723cfcc820480 = []byte{ - // 2114 bytes of a gzipped FileDescriptorProto + // 2127 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5a, 0x5b, 0x6f, 0x1b, 0xc7, - 0x15, 0xe6, 0x92, 0xba, 0x90, 0x47, 0xb2, 0x44, 0x8d, 0x75, 0x59, 0x31, 0x8e, 0xa0, 0x6c, 0x6b, - 0x43, 0xb5, 0x13, 0x12, 0x92, 0x91, 0xb8, 0x70, 0xd2, 0x14, 0x8a, 0x62, 0x4b, 0x8e, 0x2d, 0x5b, - 0x5d, 0xbb, 0x2d, 0xd2, 0xba, 0x2d, 0x86, 0xcb, 0x21, 0xb9, 0xe1, 0x5e, 0xc6, 0xbb, 0xb3, 0x0a, - 0x64, 0xa0, 0x0f, 0x45, 0x8b, 0x02, 0xfd, 0x03, 0x7d, 0xe8, 0xff, 0x28, 0xfa, 0x54, 0xf4, 0xa9, - 0x97, 0xc7, 0xa0, 0x7f, 0xa0, 0x85, 0x1f, 0xfb, 0x2b, 0x8a, 0xb9, 0xec, 0x95, 0x2b, 0xd9, 0x29, - 0x65, 0x19, 0xcd, 0x8b, 0xbd, 0x73, 0xe6, 0xcc, 0x39, 0x67, 0xce, 0x9c, 0xcb, 0x37, 0x43, 0xc1, - 0xb5, 0x80, 0x50, 0x3f, 0x24, 0xc1, 0x31, 0x09, 0x3a, 0xe2, 0xd3, 0x66, 0x7e, 0x70, 0x92, 0xf9, - 0x6c, 0xd3, 0xc0, 0x67, 0x3e, 0x82, 0x94, 0xd2, 0x7a, 0x30, 0xb0, 0xd9, 0x30, 0xea, 0xb6, 0x2d, - 0xdf, 0xed, 0xe0, 0x60, 0xe0, 0xd3, 0xc0, 0xff, 0x42, 0x7c, 0xbc, 0x67, 0xf5, 0x3a, 0xc7, 0x3b, - 0x1d, 0x3a, 0x1a, 0x74, 0x30, 0xb5, 0xc3, 0x0e, 0xa6, 0xd4, 0xb1, 0x2d, 0xcc, 0x6c, 0xdf, 0xeb, - 0x1c, 0x6f, 0x63, 0x87, 0x0e, 0xf1, 0x76, 0x67, 0x40, 0x3c, 0x12, 0x60, 0x46, 0x7a, 0x52, 0x72, - 0xeb, 0xad, 0x81, 0xef, 0x0f, 0x1c, 0xd2, 0x11, 0xa3, 0x6e, 0xd4, 0xef, 0x10, 0x97, 0x32, 0xa5, - 0xd6, 0xf8, 0xcf, 0x3c, 0x2c, 0x1e, 0x62, 0xcf, 0xee, 0x93, 0x90, 0x99, 0xe4, 0x59, 0x44, 0x42, - 0x86, 0x9e, 0xc2, 0x14, 0x37, 0x46, 0xd7, 0x36, 0xb5, 0xad, 0xb9, 0x9d, 0x83, 0x76, 0x6a, 0x4d, - 0x3b, 0xb6, 0x46, 0x7c, 0xfc, 0xc2, 0xea, 0xb5, 0x8f, 0x77, 0xda, 0x74, 0x34, 0x68, 0x73, 0x6b, - 0xda, 0x19, 0x6b, 0xda, 0xb1, 0x35, 0x6d, 0x33, 0xd9, 0x96, 0x29, 0xa4, 0xa2, 0x16, 0xd4, 0x03, - 0x72, 0x6c, 0x87, 0xb6, 0xef, 0xe9, 0xd5, 0x4d, 0x6d, 0xab, 0x61, 0x26, 0x63, 0xa4, 0xc3, 0xac, - 0xe7, 0xef, 0x61, 0x6b, 0x48, 0xf4, 0xda, 0xa6, 0xb6, 0x55, 0x37, 0xe3, 0x21, 0xda, 0x84, 0x39, - 0x4c, 0xe9, 0x03, 0xdc, 0x25, 0xce, 0x7d, 0x72, 0xa2, 0x4f, 0x89, 0x85, 0x59, 0x12, 0x5f, 0x8b, - 0x29, 0x7d, 0x88, 0x5d, 0xa2, 0x4f, 0x8b, 0xd9, 0x78, 0x88, 0xae, 0x40, 0xc3, 0xc3, 0x2e, 0x09, - 0x29, 0xb6, 0x88, 0x5e, 0x17, 0x73, 0x29, 0x01, 0xfd, 0x12, 0x96, 0x32, 0x86, 0x3f, 0xf6, 0xa3, - 0xc0, 0x22, 0x3a, 0x88, 0xad, 0x3f, 0x9a, 0x6c, 0xeb, 0xbb, 0x45, 0xb1, 0xe6, 0xb8, 0x26, 0xf4, - 0x73, 0x98, 0x16, 0x27, 0xaf, 0xcf, 0x6d, 0xd6, 0xce, 0xd5, 0xdb, 0x52, 0x2c, 0xf2, 0x60, 0x96, - 0x3a, 0xd1, 0xc0, 0xf6, 0x42, 0x7d, 0x5e, 0x68, 0x78, 0x32, 0x99, 0x86, 0x3d, 0xdf, 0xeb, 0xdb, - 0x83, 0x43, 0xec, 0xe1, 0x01, 0x71, 0x89, 0xc7, 0x8e, 0x84, 0x70, 0x33, 0x56, 0x82, 0x9e, 0x43, - 0x73, 0x14, 0x85, 0xcc, 0x77, 0xed, 0xe7, 0xe4, 0x11, 0xe5, 0x6b, 0x43, 0xfd, 0x92, 0xf0, 0xe6, - 0xc3, 0xc9, 0x14, 0xdf, 0x2f, 0x48, 0x35, 0xc7, 0xf4, 0xf0, 0x20, 0x19, 0x45, 0x5d, 0xf2, 0x23, - 0x12, 0x88, 0xe8, 0x5a, 0x90, 0x41, 0x92, 0x21, 0xc9, 0x30, 0xb2, 0xd5, 0x28, 0xd4, 0x17, 0x37, - 0x6b, 0x32, 0x8c, 0x12, 0x12, 0xda, 0x82, 0xc5, 0x63, 0x12, 0xd8, 0xfd, 0x93, 0xc7, 0xf6, 0xc0, - 0xc3, 0x2c, 0x0a, 0x88, 0xde, 0x14, 0xa1, 0x58, 0x24, 0x23, 0x17, 0x2e, 0x0d, 0x89, 0xe3, 0x72, - 0x97, 0xef, 0x05, 0xa4, 0x17, 0xea, 0x4b, 0xc2, 0xbf, 0xfb, 0x93, 0x9f, 0xa0, 0x10, 0x67, 0xe6, - 0xa5, 0x73, 0xc3, 0x3c, 0xdf, 0x54, 0x99, 0x22, 0x73, 0x04, 0x49, 0xc3, 0x0a, 0x64, 0x74, 0x0d, - 0x16, 0x58, 0x80, 0xad, 0x91, 0xed, 0x0d, 0x0e, 0x09, 0x1b, 0xfa, 0x3d, 0xfd, 0xb2, 0xf0, 0x44, - 0x81, 0x8a, 0x2c, 0x40, 0xc4, 0xc3, 0x5d, 0x87, 0xf4, 0x64, 0x2c, 0x3e, 0x39, 0xa1, 0x24, 0xd4, - 0x97, 0xc5, 0x2e, 0x6e, 0xb6, 0x33, 0x15, 0xaa, 0x50, 0x20, 0xda, 0x77, 0xc6, 0x56, 0xdd, 0xf1, - 0x58, 0x70, 0x62, 0x96, 0x88, 0x43, 0x23, 0x98, 0xe3, 0xfb, 0x88, 0x43, 0x61, 0x45, 0x84, 0xc2, - 0xbd, 0xc9, 0x7c, 0x74, 0x90, 0x0a, 0x34, 0xb3, 0xd2, 0x51, 0x1b, 0xd0, 0x10, 0x87, 0x87, 0x91, - 0xc3, 0x6c, 0xea, 0x10, 0x69, 0x46, 0xa8, 0xaf, 0x0a, 0x37, 0x95, 0xcc, 0xa0, 0xfb, 0x00, 0x01, - 0xe9, 0xc7, 0x7c, 0x6b, 0x62, 0xe7, 0x37, 0xce, 0xda, 0xb9, 0x99, 0x70, 0xcb, 0x1d, 0x67, 0x96, - 0x73, 0xe5, 0x7c, 0x1b, 0xc4, 0x62, 0x2a, 0xdb, 0x45, 0x5a, 0xeb, 0x22, 0xc4, 0x4a, 0x66, 0x78, - 0x2c, 0x2a, 0xaa, 0x28, 0x5a, 0xeb, 0x32, 0x5a, 0x33, 0xa4, 0xd6, 0x1d, 0x58, 0x3b, 0xc5, 0xd5, - 0xa8, 0x09, 0xb5, 0x11, 0x39, 0x11, 0x25, 0xba, 0x61, 0xf2, 0x4f, 0xb4, 0x0c, 0xd3, 0xc7, 0xd8, - 0x89, 0x88, 0x28, 0xaa, 0x75, 0x53, 0x0e, 0x6e, 0x57, 0xbf, 0xab, 0xb5, 0x7e, 0xab, 0xc1, 0x62, - 0xc1, 0xf0, 0x92, 0xf5, 0x3f, 0xcb, 0xae, 0x3f, 0x87, 0x30, 0xee, 0x3f, 0xc1, 0xc1, 0x80, 0xb0, - 0x8c, 0x21, 0xc6, 0x3f, 0x35, 0xd0, 0x0b, 0x1e, 0xfd, 0xb1, 0xcd, 0x86, 0x77, 0x6d, 0x87, 0x84, - 0xe8, 0x16, 0xcc, 0x06, 0x92, 0xa6, 0x1a, 0xcf, 0x5b, 0x67, 0x1c, 0xc4, 0x41, 0xc5, 0x8c, 0xb9, - 0xd1, 0xc7, 0x50, 0x77, 0x09, 0xc3, 0x3d, 0xcc, 0xb0, 0xb2, 0x7d, 0xb3, 0x6c, 0x25, 0xd7, 0x72, - 0xa8, 0xf8, 0x0e, 0x2a, 0x66, 0xb2, 0x06, 0xbd, 0x0f, 0xd3, 0xd6, 0x30, 0xf2, 0x46, 0xa2, 0xe5, - 0xcc, 0xed, 0xbc, 0x7d, 0xda, 0xe2, 0x3d, 0xce, 0x74, 0x50, 0x31, 0x25, 0xf7, 0x27, 0x33, 0x30, - 0x45, 0x71, 0xc0, 0x8c, 0xbb, 0xb0, 0x5c, 0xa6, 0x82, 0xf7, 0x39, 0x6b, 0x48, 0xac, 0x51, 0x18, - 0xb9, 0xca, 0xcd, 0xc9, 0x18, 0x21, 0x98, 0x0a, 0xed, 0xe7, 0xd2, 0xd5, 0x35, 0x53, 0x7c, 0x1b, - 0xdf, 0x81, 0xa5, 0x31, 0x6d, 0xfc, 0x50, 0xa5, 0x6d, 0x5c, 0xc2, 0xbc, 0x52, 0x6d, 0x44, 0xb0, - 0xf2, 0x44, 0xf8, 0x22, 0x29, 0xf6, 0x17, 0xd1, 0xb9, 0x8d, 0x03, 0x58, 0x2d, 0xaa, 0x0d, 0xa9, - 0xef, 0x85, 0x84, 0x87, 0xbe, 0xa8, 0x8e, 0x36, 0xe9, 0xa5, 0xb3, 0xc2, 0x8a, 0xba, 0x59, 0x32, - 0x63, 0xfc, 0xaa, 0x0a, 0xab, 0x26, 0x09, 0x7d, 0xe7, 0x98, 0xc4, 0xa5, 0xeb, 0x62, 0xc0, 0xc7, - 0x4f, 0xa1, 0x86, 0x29, 0x55, 0x61, 0x72, 0xef, 0xdc, 0xda, 0xbb, 0xc9, 0xa5, 0xa2, 0x77, 0x61, - 0x09, 0xbb, 0x5d, 0x7b, 0x10, 0xf9, 0x51, 0x18, 0x6f, 0x4b, 0x04, 0x55, 0xc3, 0x1c, 0x9f, 0x30, - 0x2c, 0x58, 0x1b, 0x73, 0x81, 0x72, 0x67, 0x16, 0x22, 0x69, 0x05, 0x88, 0x54, 0xaa, 0xa4, 0x7a, - 0x9a, 0x92, 0xbf, 0x69, 0xd0, 0x4c, 0x53, 0x47, 0x89, 0xbf, 0x02, 0x0d, 0x57, 0xd1, 0x42, 0x5d, - 0x13, 0xf5, 0x29, 0x25, 0xe4, 0xd1, 0x52, 0xb5, 0x88, 0x96, 0x56, 0x61, 0x46, 0x82, 0x59, 0xb5, - 0x31, 0x35, 0xca, 0x99, 0x3c, 0x55, 0x30, 0x79, 0x03, 0x20, 0x4c, 0xea, 0x97, 0x3e, 0x23, 0x66, - 0x33, 0x14, 0x64, 0xc0, 0xbc, 0xec, 0xad, 0x26, 0x09, 0x23, 0x87, 0xe9, 0xb3, 0x82, 0x23, 0x47, - 0x33, 0x7c, 0x58, 0x7c, 0x60, 0xf3, 0x3d, 0xf4, 0xc3, 0x8b, 0x09, 0xf6, 0x0f, 0x60, 0x8a, 0x2b, - 0xe3, 0x1b, 0xeb, 0x06, 0xd8, 0xb3, 0x86, 0x24, 0xf6, 0x55, 0x32, 0xe6, 0x69, 0xcc, 0xf0, 0x20, - 0xd4, 0xab, 0x82, 0x2e, 0xbe, 0x8d, 0x3f, 0x55, 0xa5, 0xa5, 0xbb, 0x94, 0x86, 0x6f, 0x1e, 0x50, - 0x97, 0xb7, 0xf8, 0xda, 0x78, 0x8b, 0x2f, 0x98, 0xfc, 0x75, 0x5a, 0xfc, 0x39, 0xb5, 0x29, 0x23, - 0x82, 0xd9, 0x5d, 0x4a, 0xb9, 0x21, 0x68, 0x1b, 0xa6, 0x30, 0xa5, 0xd2, 0xe1, 0x85, 0x8a, 0xac, - 0x58, 0xf8, 0xff, 0xca, 0x24, 0xc1, 0xda, 0xba, 0x05, 0x8d, 0x84, 0xf4, 0x32, 0xb5, 0x8d, 0xac, - 0xda, 0x4d, 0x00, 0x89, 0x61, 0xef, 0x79, 0x7d, 0x9f, 0x1f, 0x29, 0x0f, 0x76, 0xb5, 0x54, 0x7c, - 0x1b, 0xb7, 0x63, 0x0e, 0x61, 0xdb, 0xbb, 0x30, 0x6d, 0x33, 0xe2, 0xc6, 0xc6, 0xad, 0x66, 0x8d, - 0x4b, 0x05, 0x99, 0x92, 0xc9, 0xf8, 0x7b, 0x1d, 0xd6, 0xf9, 0x89, 0x3d, 0x16, 0x69, 0xb2, 0x4b, - 0xe9, 0xa7, 0x84, 0x61, 0xdb, 0x09, 0x7f, 0x10, 0x91, 0xe0, 0xe4, 0x35, 0x07, 0xc6, 0x00, 0x66, - 0x64, 0x96, 0xa9, 0x7a, 0x77, 0xee, 0xd7, 0x19, 0x25, 0x3e, 0xbd, 0xc3, 0xd4, 0x5e, 0xcf, 0x1d, - 0xa6, 0xec, 0x4e, 0x31, 0x75, 0x41, 0x77, 0x8a, 0xd3, 0xaf, 0x95, 0x99, 0xcb, 0xea, 0x4c, 0xfe, - 0xb2, 0x5a, 0x02, 0xd5, 0x67, 0x5f, 0x15, 0xaa, 0xd7, 0x4b, 0xa1, 0xba, 0x5b, 0x9a, 0xc7, 0x0d, - 0xe1, 0xee, 0xef, 0x65, 0x23, 0xf0, 0xd4, 0x58, 0x9b, 0x04, 0xb4, 0xc3, 0x6b, 0x05, 0xed, 0x3f, - 0xcc, 0x81, 0x70, 0x79, 0x0d, 0x7e, 0xff, 0xd5, 0xf6, 0x74, 0x06, 0x1c, 0xff, 0xc6, 0x81, 0xe7, - 0xdf, 0x08, 0xcc, 0x44, 0xfd, 0xd4, 0x07, 0x49, 0x43, 0xe7, 0x7d, 0x88, 0xb7, 0x56, 0x55, 0xb4, - 0xf8, 0x37, 0xba, 0x01, 0x53, 0xdc, 0xc9, 0x0a, 0xd4, 0xae, 0x65, 0xfd, 0xc9, 0x4f, 0x62, 0x97, - 0xd2, 0xc7, 0x94, 0x58, 0xa6, 0x60, 0x42, 0xb7, 0xa1, 0x91, 0x04, 0xbe, 0xca, 0xac, 0x2b, 0xd9, - 0x15, 0x49, 0x9e, 0xc4, 0xcb, 0x52, 0x76, 0xbe, 0xb6, 0x67, 0x07, 0xc4, 0x12, 0x90, 0x6f, 0x7a, - 0x7c, 0xed, 0xa7, 0xf1, 0x64, 0xb2, 0x36, 0x61, 0x47, 0xdb, 0x30, 0x23, 0xdf, 0x0d, 0x44, 0x06, - 0xcd, 0xed, 0xac, 0x8f, 0x17, 0xd3, 0x78, 0x95, 0x62, 0x34, 0xfe, 0xaa, 0xc1, 0x3b, 0x69, 0x40, - 0xc4, 0xd9, 0x14, 0xa3, 0xee, 0x37, 0xdf, 0x71, 0xaf, 0xc1, 0x82, 0x80, 0xf9, 0xe9, 0xf3, 0x81, - 0x7c, 0xc9, 0x2a, 0x50, 0x8d, 0x3f, 0x6a, 0x70, 0x75, 0x7c, 0x1f, 0x7b, 0x43, 0x1c, 0xb0, 0xe4, - 0x78, 0x2f, 0x62, 0x2f, 0x71, 0xc3, 0xab, 0xa6, 0x0d, 0x2f, 0xb7, 0xbf, 0x5a, 0x7e, 0x7f, 0xc6, - 0x5f, 0xaa, 0x30, 0x97, 0x09, 0xa0, 0xb2, 0x86, 0xc9, 0x01, 0x9f, 0x88, 0x5b, 0x71, 0xb1, 0x13, - 0x4d, 0xa1, 0x61, 0x66, 0x28, 0x68, 0x04, 0x40, 0x71, 0x80, 0x5d, 0xc2, 0x48, 0xc0, 0x2b, 0x39, - 0xcf, 0xf8, 0xfb, 0x93, 0x57, 0x97, 0xa3, 0x58, 0xa6, 0x99, 0x11, 0xcf, 0x11, 0xab, 0x50, 0x1d, - 0xaa, 0xfa, 0xad, 0x46, 0xe8, 0x4b, 0x58, 0xe8, 0xdb, 0x0e, 0x39, 0x4a, 0x0d, 0x99, 0x11, 0x86, - 0x3c, 0x9a, 0xdc, 0x90, 0xbb, 0x59, 0xb9, 0x66, 0x41, 0x8d, 0x71, 0x1d, 0x9a, 0xc5, 0x7c, 0xe2, - 0x46, 0xda, 0x2e, 0x1e, 0x24, 0xde, 0x52, 0x23, 0x03, 0x41, 0xb3, 0x98, 0x3f, 0xc6, 0xbf, 0xaa, - 0xb0, 0x92, 0x88, 0xdb, 0xf5, 0x3c, 0x3f, 0xf2, 0x2c, 0xf1, 0x14, 0x57, 0x7a, 0x16, 0xcb, 0x30, - 0xcd, 0x6c, 0xe6, 0x24, 0xc0, 0x47, 0x0c, 0x78, 0xef, 0x62, 0xbe, 0xef, 0x30, 0x9b, 0xaa, 0x03, - 0x8e, 0x87, 0xf2, 0xec, 0x9f, 0x45, 0x76, 0x40, 0x7a, 0xa2, 0x12, 0xd4, 0xcd, 0x64, 0xcc, 0xe7, - 0x38, 0xaa, 0x11, 0x30, 0x5e, 0x3a, 0x33, 0x19, 0x8b, 0xb8, 0xf7, 0x1d, 0x87, 0x58, 0xdc, 0x1d, - 0x19, 0xa0, 0x5f, 0xa0, 0x8a, 0x0b, 0x04, 0x0b, 0x6c, 0x6f, 0xa0, 0x60, 0xbe, 0x1a, 0x71, 0x3b, - 0x71, 0x10, 0xe0, 0x13, 0xbd, 0x2e, 0x1c, 0x20, 0x07, 0xe8, 0x23, 0xa8, 0xb9, 0x98, 0xaa, 0x46, - 0x77, 0x3d, 0x57, 0x1d, 0xca, 0x3c, 0xd0, 0x3e, 0xc4, 0x54, 0x76, 0x02, 0xbe, 0xac, 0xf5, 0x01, - 0xd4, 0x63, 0xc2, 0xd7, 0x82, 0x84, 0x5f, 0xc0, 0xa5, 0x5c, 0xf1, 0x41, 0x9f, 0xc3, 0x6a, 0x1a, - 0x51, 0x59, 0x85, 0x0a, 0x04, 0xbe, 0xf3, 0x52, 0xcb, 0xcc, 0x53, 0x04, 0x18, 0xcf, 0x60, 0x89, - 0x87, 0x8c, 0x48, 0xfc, 0x0b, 0xba, 0xda, 0x7c, 0x08, 0x8d, 0x44, 0x65, 0x69, 0xcc, 0xb4, 0xa0, - 0x7e, 0x1c, 0x3f, 0x91, 0xca, 0xbb, 0x4d, 0x32, 0x36, 0x76, 0x01, 0x65, 0xed, 0x55, 0x1d, 0xe8, - 0x46, 0x1e, 0x14, 0xaf, 0x14, 0xdb, 0x8d, 0x60, 0x8f, 0x31, 0xf1, 0xef, 0xaa, 0xb0, 0xb8, 0x6f, - 0x8b, 0x57, 0x8e, 0x0b, 0x2a, 0x72, 0xd7, 0xa1, 0x19, 0x46, 0x5d, 0xd7, 0xef, 0x45, 0x0e, 0x51, - 0xa0, 0x40, 0x75, 0xfa, 0x31, 0xfa, 0x59, 0xc5, 0x8f, 0x3b, 0x8b, 0x62, 0x36, 0x54, 0x37, 0x5c, - 0xf1, 0x8d, 0x3e, 0x82, 0xf5, 0x87, 0xe4, 0x4b, 0xb5, 0x9f, 0x7d, 0xc7, 0xef, 0x76, 0x6d, 0x6f, - 0x10, 0x2b, 0x99, 0x16, 0x4a, 0x4e, 0x67, 0x30, 0x7e, 0xad, 0x41, 0x33, 0xf5, 0x85, 0xf2, 0xe6, - 0x2d, 0x19, 0xf5, 0xd2, 0x97, 0x57, 0xb3, 0xbe, 0x2c, 0xb2, 0xfe, 0xef, 0x01, 0x3f, 0x9f, 0x0d, - 0xf8, 0x3f, 0x6b, 0xb0, 0xb2, 0x6f, 0xb3, 0xb8, 0xd4, 0xd8, 0xff, 0x67, 0xe7, 0x62, 0xb4, 0x61, - 0xb5, 0x68, 0xbe, 0x72, 0xe5, 0x32, 0x4c, 0xf3, 0x53, 0x8a, 0xef, 0xee, 0x72, 0xb0, 0xf3, 0x55, - 0x03, 0x96, 0xd2, 0xe6, 0xcb, 0xff, 0xb5, 0x2d, 0x82, 0x1e, 0x41, 0x73, 0x5f, 0xfd, 0x76, 0x16, - 0xbf, 0x99, 0xa0, 0xb3, 0x1e, 0x21, 0x5b, 0x57, 0xca, 0x27, 0xa5, 0x6a, 0xa3, 0x82, 0x2c, 0x58, - 0x2f, 0x0a, 0x4c, 0xdf, 0x3b, 0xbf, 0x7d, 0x86, 0xe4, 0x84, 0xeb, 0x65, 0x2a, 0xb6, 0x34, 0xf4, - 0x39, 0x2c, 0xe4, 0x5f, 0xe5, 0x50, 0xae, 0x1a, 0x95, 0x3e, 0x14, 0xb6, 0x8c, 0xb3, 0x58, 0x12, - 0xfb, 0x9f, 0x72, 0xe8, 0x9b, 0x7b, 0xa2, 0x42, 0x46, 0x1e, 0x98, 0x97, 0x3d, 0xe1, 0xb5, 0xbe, - 0x75, 0x26, 0x4f, 0x22, 0xfd, 0x43, 0xa8, 0xc7, 0x4f, 0x3a, 0x79, 0x37, 0x17, 0x1e, 0x7a, 0x5a, - 0xcd, 0xbc, 0xbc, 0x7e, 0x68, 0x54, 0xd0, 0xc7, 0x72, 0x31, 0xbf, 0xf2, 0x8f, 0x2f, 0xce, 0x3c, - 0x64, 0xb4, 0x2e, 0x97, 0x3c, 0x1e, 0x18, 0x15, 0xf4, 0x7d, 0x98, 0xe3, 0x5f, 0x47, 0xea, 0x57, - 0xab, 0xd5, 0xb6, 0xfc, 0x91, 0xb4, 0x1d, 0xff, 0x48, 0xda, 0xbe, 0xe3, 0x52, 0x76, 0xd2, 0x2a, - 0xb9, 0xdd, 0x2b, 0x01, 0x4f, 0xe1, 0xd2, 0x3e, 0x61, 0x29, 0x18, 0x47, 0x57, 0x5f, 0xe9, 0xca, - 0xd2, 0x32, 0x8a, 0x6c, 0xe3, 0x78, 0xde, 0xa8, 0xa0, 0xdf, 0x6b, 0x70, 0x79, 0x9f, 0xb0, 0x22, - 0xbc, 0x45, 0xef, 0x95, 0x2b, 0x39, 0x05, 0x06, 0xb7, 0x1e, 0x4e, 0x9a, 0xaf, 0x79, 0xb1, 0x46, - 0x05, 0xfd, 0x41, 0x83, 0xb5, 0x8c, 0x61, 0x59, 0xbc, 0x8a, 0xb6, 0xcf, 0x36, 0xae, 0x04, 0xdb, - 0xb6, 0x3e, 0x9b, 0xf0, 0xc7, 0xc8, 0x8c, 0x48, 0xa3, 0x82, 0x8e, 0xc4, 0x99, 0xa4, 0xed, 0x09, - 0xbd, 0x5d, 0xda, 0x87, 0x12, 0xed, 0x1b, 0xa7, 0x4d, 0x27, 0xe7, 0xf0, 0x19, 0xcc, 0xed, 0x13, - 0x16, 0x57, 0xdd, 0x7c, 0xa4, 0x15, 0x5a, 0x58, 0x3e, 0x55, 0x8b, 0x85, 0x5a, 0x44, 0xcc, 0x92, - 0x94, 0x95, 0xa9, 0x53, 0xf9, 0x5c, 0x2d, 0x2d, 0xc1, 0xf9, 0x88, 0x29, 0x2f, 0x73, 0x46, 0xe5, - 0x93, 0xdd, 0x7f, 0xbc, 0xd8, 0xd0, 0xbe, 0x7a, 0xb1, 0xa1, 0xfd, 0xfb, 0xc5, 0x86, 0xf6, 0x93, - 0x9b, 0x2f, 0xf9, 0x0b, 0x82, 0xcc, 0x1f, 0x25, 0x60, 0x6a, 0x5b, 0x8e, 0x4d, 0x3c, 0xd6, 0x9d, - 0x11, 0xc1, 0x7f, 0xf3, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x86, 0xe4, 0x0d, 0xb3, 0x20, - 0x00, 0x00, + 0xf5, 0xe7, 0x92, 0x94, 0x44, 0x1e, 0xd9, 0x12, 0x35, 0xd6, 0x65, 0xc5, 0x38, 0x82, 0xb2, 0xff, + 0xbf, 0x0d, 0xd5, 0x4e, 0x48, 0x48, 0x46, 0xe2, 0xc2, 0x49, 0x53, 0x28, 0x8a, 0x2d, 0x39, 0xb6, + 0x6c, 0x75, 0xed, 0xb6, 0x48, 0xeb, 0xb6, 0x18, 0x2e, 0x87, 0xe4, 0x86, 0x7b, 0x19, 0xef, 0xce, + 0x2a, 0x90, 0x81, 0x3e, 0x14, 0x2d, 0xfa, 0x11, 0xfa, 0xd0, 0xaf, 0x51, 0x14, 0x7d, 0xec, 0x53, + 0x2f, 0x8f, 0x41, 0xbf, 0x40, 0x0b, 0xbf, 0x14, 0xe8, 0xa7, 0x28, 0xe6, 0xb2, 0x57, 0xae, 0x64, + 0xa7, 0x94, 0x15, 0xb4, 0x2f, 0xf6, 0xce, 0x99, 0x33, 0xe7, 0x9c, 0x39, 0x73, 0x2e, 0xbf, 0x19, + 0x0a, 0xae, 0x07, 0x84, 0xfa, 0x21, 0x09, 0x8e, 0x49, 0xd0, 0x15, 0x9f, 0x36, 0xf3, 0x83, 0x93, + 0xcc, 0x67, 0x87, 0x06, 0x3e, 0xf3, 0x11, 0xa4, 0x94, 0xf6, 0xc3, 0xa1, 0xcd, 0x46, 0x51, 0xaf, + 0x63, 0xf9, 0x6e, 0x17, 0x07, 0x43, 0x9f, 0x06, 0xfe, 0x17, 0xe2, 0xe3, 0x3d, 0xab, 0xdf, 0x3d, + 0xde, 0xe9, 0xd2, 0xf1, 0xb0, 0x8b, 0xa9, 0x1d, 0x76, 0x31, 0xa5, 0x8e, 0x6d, 0x61, 0x66, 0xfb, + 0x5e, 0xf7, 0x78, 0x1b, 0x3b, 0x74, 0x84, 0xb7, 0xbb, 0x43, 0xe2, 0x91, 0x00, 0x33, 0xd2, 0x97, + 0x92, 0xdb, 0x6f, 0x0d, 0x7d, 0x7f, 0xe8, 0x90, 0xae, 0x18, 0xf5, 0xa2, 0x41, 0x97, 0xb8, 0x94, + 0x29, 0xb5, 0xc6, 0xbf, 0x2e, 0xc1, 0xe2, 0x21, 0xf6, 0xec, 0x01, 0x09, 0x99, 0x49, 0x9e, 0x47, + 0x24, 0x64, 0xe8, 0x19, 0xd4, 0xb9, 0x31, 0xba, 0xb6, 0xa9, 0x6d, 0xcd, 0xef, 0x1c, 0x74, 0x52, + 0x6b, 0x3a, 0xb1, 0x35, 0xe2, 0xe3, 0x67, 0x56, 0xbf, 0x73, 0xbc, 0xd3, 0xa1, 0xe3, 0x61, 0x87, + 0x5b, 0xd3, 0xc9, 0x58, 0xd3, 0x89, 0xad, 0xe9, 0x98, 0xc9, 0xb6, 0x4c, 0x21, 0x15, 0xb5, 0xa1, + 0x11, 0x90, 0x63, 0x3b, 0xb4, 0x7d, 0x4f, 0xaf, 0x6e, 0x6a, 0x5b, 0x4d, 0x33, 0x19, 0x23, 0x1d, + 0xe6, 0x3c, 0x7f, 0x0f, 0x5b, 0x23, 0xa2, 0xd7, 0x36, 0xb5, 0xad, 0x86, 0x19, 0x0f, 0xd1, 0x26, + 0xcc, 0x63, 0x4a, 0x1f, 0xe2, 0x1e, 0x71, 0x1e, 0x90, 0x13, 0xbd, 0x2e, 0x16, 0x66, 0x49, 0x7c, + 0x2d, 0xa6, 0xf4, 0x11, 0x76, 0x89, 0x3e, 0x23, 0x66, 0xe3, 0x21, 0xba, 0x0a, 0x4d, 0x0f, 0xbb, + 0x24, 0xa4, 0xd8, 0x22, 0x7a, 0x43, 0xcc, 0xa5, 0x04, 0xf4, 0x73, 0x58, 0xca, 0x18, 0xfe, 0xc4, + 0x8f, 0x02, 0x8b, 0xe8, 0x20, 0xb6, 0xfe, 0x78, 0xba, 0xad, 0xef, 0x16, 0xc5, 0x9a, 0x93, 0x9a, + 0xd0, 0x4f, 0x61, 0x46, 0x9c, 0xbc, 0x3e, 0xbf, 0x59, 0x3b, 0x57, 0x6f, 0x4b, 0xb1, 0xc8, 0x83, + 0x39, 0xea, 0x44, 0x43, 0xdb, 0x0b, 0xf5, 0x4b, 0x42, 0xc3, 0xd3, 0xe9, 0x34, 0xec, 0xf9, 0xde, + 0xc0, 0x1e, 0x1e, 0x62, 0x0f, 0x0f, 0x89, 0x4b, 0x3c, 0x76, 0x24, 0x84, 0x9b, 0xb1, 0x12, 0xf4, + 0x02, 0x5a, 0xe3, 0x28, 0x64, 0xbe, 0x6b, 0xbf, 0x20, 0x8f, 0x29, 0x5f, 0x1b, 0xea, 0x97, 0x85, + 0x37, 0x1f, 0x4d, 0xa7, 0xf8, 0x41, 0x41, 0xaa, 0x39, 0xa1, 0x87, 0x07, 0xc9, 0x38, 0xea, 0x91, + 0x1f, 0x90, 0x40, 0x44, 0xd7, 0x82, 0x0c, 0x92, 0x0c, 0x49, 0x86, 0x91, 0xad, 0x46, 0xa1, 0xbe, + 0xb8, 0x59, 0x93, 0x61, 0x94, 0x90, 0xd0, 0x16, 0x2c, 0x1e, 0x93, 0xc0, 0x1e, 0x9c, 0x3c, 0xb1, + 0x87, 0x1e, 0x66, 0x51, 0x40, 0xf4, 0x96, 0x08, 0xc5, 0x22, 0x19, 0xb9, 0x70, 0x79, 0x44, 0x1c, + 0x97, 0xbb, 0x7c, 0x2f, 0x20, 0xfd, 0x50, 0x5f, 0x12, 0xfe, 0xdd, 0x9f, 0xfe, 0x04, 0x85, 0x38, + 0x33, 0x2f, 0x9d, 0x1b, 0xe6, 0xf9, 0xa6, 0xca, 0x14, 0x99, 0x23, 0x48, 0x1a, 0x56, 0x20, 0xa3, + 0xeb, 0xb0, 0xc0, 0x02, 0x6c, 0x8d, 0x6d, 0x6f, 0x78, 0x48, 0xd8, 0xc8, 0xef, 0xeb, 0x57, 0x84, + 0x27, 0x0a, 0x54, 0x64, 0x01, 0x22, 0x1e, 0xee, 0x39, 0xa4, 0x2f, 0x63, 0xf1, 0xe9, 0x09, 0x25, + 0xa1, 0xbe, 0x2c, 0x76, 0x71, 0xab, 0x93, 0xa9, 0x50, 0x85, 0x02, 0xd1, 0xb9, 0x3b, 0xb1, 0xea, + 0xae, 0xc7, 0x82, 0x13, 0xb3, 0x44, 0x1c, 0x1a, 0xc3, 0x3c, 0xdf, 0x47, 0x1c, 0x0a, 0x2b, 0x22, + 0x14, 0xee, 0x4f, 0xe7, 0xa3, 0x83, 0x54, 0xa0, 0x99, 0x95, 0x8e, 0x3a, 0x80, 0x46, 0x38, 0x3c, + 0x8c, 0x1c, 0x66, 0x53, 0x87, 0x48, 0x33, 0x42, 0x7d, 0x55, 0xb8, 0xa9, 0x64, 0x06, 0x3d, 0x00, + 0x08, 0xc8, 0x20, 0xe6, 0x5b, 0x13, 0x3b, 0xbf, 0x79, 0xd6, 0xce, 0xcd, 0x84, 0x5b, 0xee, 0x38, + 0xb3, 0x9c, 0x2b, 0xe7, 0xdb, 0x20, 0x16, 0x53, 0xd9, 0x2e, 0xd2, 0x5a, 0x17, 0x21, 0x56, 0x32, + 0xc3, 0x63, 0x51, 0x51, 0x45, 0xd1, 0x5a, 0x97, 0xd1, 0x9a, 0x21, 0xb5, 0xef, 0xc2, 0xda, 0x29, + 0xae, 0x46, 0x2d, 0xa8, 0x8d, 0xc9, 0x89, 0x28, 0xd1, 0x4d, 0x93, 0x7f, 0xa2, 0x65, 0x98, 0x39, + 0xc6, 0x4e, 0x44, 0x44, 0x51, 0x6d, 0x98, 0x72, 0x70, 0xa7, 0xfa, 0x6d, 0xad, 0xfd, 0x6b, 0x0d, + 0x16, 0x0b, 0x86, 0x97, 0xac, 0xff, 0x49, 0x76, 0xfd, 0x39, 0x84, 0xf1, 0xe0, 0x29, 0x0e, 0x86, + 0x84, 0x65, 0x0c, 0x31, 0xfe, 0xa6, 0x81, 0x5e, 0xf0, 0xe8, 0x0f, 0x6d, 0x36, 0xba, 0x67, 0x3b, + 0x24, 0x44, 0xb7, 0x61, 0x2e, 0x90, 0x34, 0xd5, 0x78, 0xde, 0x3a, 0xe3, 0x20, 0x0e, 0x2a, 0x66, + 0xcc, 0x8d, 0x3e, 0x86, 0x86, 0x4b, 0x18, 0xee, 0x63, 0x86, 0x95, 0xed, 0x9b, 0x65, 0x2b, 0xb9, + 0x96, 0x43, 0xc5, 0x77, 0x50, 0x31, 0x93, 0x35, 0xe8, 0x7d, 0x98, 0xb1, 0x46, 0x91, 0x37, 0x16, + 0x2d, 0x67, 0x7e, 0xe7, 0xed, 0xd3, 0x16, 0xef, 0x71, 0xa6, 0x83, 0x8a, 0x29, 0xb9, 0x3f, 0x99, + 0x85, 0x3a, 0xc5, 0x01, 0x33, 0xee, 0xc1, 0x72, 0x99, 0x0a, 0xde, 0xe7, 0xac, 0x11, 0xb1, 0xc6, + 0x61, 0xe4, 0x2a, 0x37, 0x27, 0x63, 0x84, 0xa0, 0x1e, 0xda, 0x2f, 0xa4, 0xab, 0x6b, 0xa6, 0xf8, + 0x36, 0xbe, 0x05, 0x4b, 0x13, 0xda, 0xf8, 0xa1, 0x4a, 0xdb, 0xb8, 0x84, 0x4b, 0x4a, 0xb5, 0x11, + 0xc1, 0xca, 0x53, 0xe1, 0x8b, 0xa4, 0xd8, 0x5f, 0x44, 0xe7, 0x36, 0x0e, 0x60, 0xb5, 0xa8, 0x36, + 0xa4, 0xbe, 0x17, 0x12, 0x1e, 0xfa, 0xa2, 0x3a, 0xda, 0xa4, 0x9f, 0xce, 0x0a, 0x2b, 0x1a, 0x66, + 0xc9, 0x8c, 0xf1, 0x8b, 0x2a, 0xac, 0x9a, 0x24, 0xf4, 0x9d, 0x63, 0x12, 0x97, 0xae, 0x8b, 0x01, + 0x1f, 0x3f, 0x86, 0x1a, 0xa6, 0x54, 0x85, 0xc9, 0xfd, 0x73, 0x6b, 0xef, 0x26, 0x97, 0x8a, 0xde, + 0x85, 0x25, 0xec, 0xf6, 0xec, 0x61, 0xe4, 0x47, 0x61, 0xbc, 0x2d, 0x11, 0x54, 0x4d, 0x73, 0x72, + 0xc2, 0xb0, 0x60, 0x6d, 0xc2, 0x05, 0xca, 0x9d, 0x59, 0x88, 0xa4, 0x15, 0x20, 0x52, 0xa9, 0x92, + 0xea, 0x69, 0x4a, 0xfe, 0xac, 0x41, 0x2b, 0x4d, 0x1d, 0x25, 0xfe, 0x2a, 0x34, 0x5d, 0x45, 0x0b, + 0x75, 0x4d, 0xd4, 0xa7, 0x94, 0x90, 0x47, 0x4b, 0xd5, 0x22, 0x5a, 0x5a, 0x85, 0x59, 0x09, 0x66, + 0xd5, 0xc6, 0xd4, 0x28, 0x67, 0x72, 0xbd, 0x60, 0xf2, 0x06, 0x40, 0x98, 0xd4, 0x2f, 0x7d, 0x56, + 0xcc, 0x66, 0x28, 0xc8, 0x80, 0x4b, 0xb2, 0xb7, 0x9a, 0x24, 0x8c, 0x1c, 0xa6, 0xcf, 0x09, 0x8e, + 0x1c, 0xcd, 0xf0, 0x61, 0xf1, 0xa1, 0xcd, 0xf7, 0x30, 0x08, 0x2f, 0x26, 0xd8, 0x3f, 0x80, 0x3a, + 0x57, 0xc6, 0x37, 0xd6, 0x0b, 0xb0, 0x67, 0x8d, 0x48, 0xec, 0xab, 0x64, 0xcc, 0xd3, 0x98, 0xe1, + 0x61, 0xa8, 0x57, 0x05, 0x5d, 0x7c, 0x1b, 0x7f, 0xa8, 0x4a, 0x4b, 0x77, 0x29, 0x0d, 0xbf, 0x79, + 0x40, 0x5d, 0xde, 0xe2, 0x6b, 0x93, 0x2d, 0xbe, 0x60, 0xf2, 0xd7, 0x69, 0xf1, 0xe7, 0xd4, 0xa6, + 0x8c, 0x08, 0xe6, 0x76, 0x29, 0xe5, 0x86, 0xa0, 0x6d, 0xa8, 0x63, 0x4a, 0xa5, 0xc3, 0x0b, 0x15, + 0x59, 0xb1, 0xf0, 0xff, 0x95, 0x49, 0x82, 0xb5, 0x7d, 0x1b, 0x9a, 0x09, 0xe9, 0x55, 0x6a, 0x9b, + 0x59, 0xb5, 0x9b, 0x00, 0x12, 0xc3, 0xde, 0xf7, 0x06, 0x3e, 0x3f, 0x52, 0x1e, 0xec, 0x6a, 0xa9, + 0xf8, 0x36, 0xee, 0xc4, 0x1c, 0xc2, 0xb6, 0x77, 0x61, 0xc6, 0x66, 0xc4, 0x8d, 0x8d, 0x5b, 0xcd, + 0x1a, 0x97, 0x0a, 0x32, 0x25, 0x93, 0xf1, 0x97, 0x06, 0xac, 0xf3, 0x13, 0x7b, 0x22, 0xd2, 0x64, + 0x97, 0xd2, 0x4f, 0x09, 0xc3, 0xb6, 0x13, 0x7e, 0x2f, 0x22, 0xc1, 0xc9, 0x1b, 0x0e, 0x8c, 0x21, + 0xcc, 0xca, 0x2c, 0x53, 0xf5, 0xee, 0xdc, 0xaf, 0x33, 0x4a, 0x7c, 0x7a, 0x87, 0xa9, 0xbd, 0x99, + 0x3b, 0x4c, 0xd9, 0x9d, 0xa2, 0x7e, 0x41, 0x77, 0x8a, 0xd3, 0xaf, 0x95, 0x99, 0xcb, 0xea, 0x6c, + 0xfe, 0xb2, 0x5a, 0x02, 0xd5, 0xe7, 0x5e, 0x17, 0xaa, 0x37, 0x4a, 0xa1, 0xba, 0x5b, 0x9a, 0xc7, + 0x4d, 0xe1, 0xee, 0xef, 0x64, 0x23, 0xf0, 0xd4, 0x58, 0x9b, 0x06, 0xb4, 0xc3, 0x1b, 0x05, 0xed, + 0xdf, 0xcf, 0x81, 0x70, 0x79, 0x0d, 0x7e, 0xff, 0xf5, 0xf6, 0x74, 0x06, 0x1c, 0xff, 0x9f, 0x03, + 0xcf, 0xbf, 0x12, 0x98, 0x89, 0xfa, 0xa9, 0x0f, 0x92, 0x86, 0xce, 0xfb, 0x10, 0x6f, 0xad, 0xaa, + 0x68, 0xf1, 0x6f, 0x74, 0x13, 0xea, 0xdc, 0xc9, 0x0a, 0xd4, 0xae, 0x65, 0xfd, 0xc9, 0x4f, 0x62, + 0x97, 0xd2, 0x27, 0x94, 0x58, 0xa6, 0x60, 0x42, 0x77, 0xa0, 0x99, 0x04, 0xbe, 0xca, 0xac, 0xab, + 0xd9, 0x15, 0x49, 0x9e, 0xc4, 0xcb, 0x52, 0x76, 0xbe, 0xb6, 0x6f, 0x07, 0xc4, 0x12, 0x90, 0x6f, + 0x66, 0x72, 0xed, 0xa7, 0xf1, 0x64, 0xb2, 0x36, 0x61, 0x47, 0xdb, 0x30, 0x2b, 0xdf, 0x0d, 0x44, + 0x06, 0xcd, 0xef, 0xac, 0x4f, 0x16, 0xd3, 0x78, 0x95, 0x62, 0x34, 0xfe, 0xa4, 0xc1, 0x3b, 0x69, + 0x40, 0xc4, 0xd9, 0x14, 0xa3, 0xee, 0x6f, 0xbe, 0xe3, 0x5e, 0x87, 0x05, 0x01, 0xf3, 0xd3, 0xe7, + 0x03, 0xf9, 0x92, 0x55, 0xa0, 0x1a, 0xbf, 0xd7, 0xe0, 0xda, 0xe4, 0x3e, 0xf6, 0x46, 0x38, 0x60, + 0xc9, 0xf1, 0x5e, 0xc4, 0x5e, 0xe2, 0x86, 0x57, 0x4d, 0x1b, 0x5e, 0x6e, 0x7f, 0xb5, 0xfc, 0xfe, + 0x8c, 0x3f, 0x56, 0x61, 0x3e, 0x13, 0x40, 0x65, 0x0d, 0x93, 0x03, 0x3e, 0x11, 0xb7, 0xe2, 0x62, + 0x27, 0x9a, 0x42, 0xd3, 0xcc, 0x50, 0xd0, 0x18, 0x80, 0xe2, 0x00, 0xbb, 0x84, 0x91, 0x80, 0x57, + 0x72, 0x9e, 0xf1, 0x0f, 0xa6, 0xaf, 0x2e, 0x47, 0xb1, 0x4c, 0x33, 0x23, 0x9e, 0x23, 0x56, 0xa1, + 0x3a, 0x54, 0xf5, 0x5b, 0x8d, 0xd0, 0x97, 0xb0, 0x30, 0xb0, 0x1d, 0x72, 0x94, 0x1a, 0x32, 0x2b, + 0x0c, 0x79, 0x3c, 0xbd, 0x21, 0xf7, 0xb2, 0x72, 0xcd, 0x82, 0x1a, 0xe3, 0x06, 0xb4, 0x8a, 0xf9, + 0xc4, 0x8d, 0xb4, 0x5d, 0x3c, 0x4c, 0xbc, 0xa5, 0x46, 0x06, 0x82, 0x56, 0x31, 0x7f, 0x8c, 0xbf, + 0x57, 0x61, 0x25, 0x11, 0xb7, 0xeb, 0x79, 0x7e, 0xe4, 0x59, 0xe2, 0x29, 0xae, 0xf4, 0x2c, 0x96, + 0x61, 0x86, 0xd9, 0xcc, 0x49, 0x80, 0x8f, 0x18, 0xf0, 0xde, 0xc5, 0x7c, 0xdf, 0x61, 0x36, 0x55, + 0x07, 0x1c, 0x0f, 0xe5, 0xd9, 0x3f, 0x8f, 0xec, 0x80, 0xf4, 0x45, 0x25, 0x68, 0x98, 0xc9, 0x98, + 0xcf, 0x71, 0x54, 0x23, 0x60, 0xbc, 0x74, 0x66, 0x32, 0x16, 0x71, 0xef, 0x3b, 0x0e, 0xb1, 0xb8, + 0x3b, 0x32, 0x40, 0xbf, 0x40, 0x15, 0x17, 0x08, 0x16, 0xd8, 0xde, 0x50, 0xc1, 0x7c, 0x35, 0xe2, + 0x76, 0xe2, 0x20, 0xc0, 0x27, 0x7a, 0x43, 0x38, 0x40, 0x0e, 0xd0, 0x47, 0x50, 0x73, 0x31, 0x55, + 0x8d, 0xee, 0x46, 0xae, 0x3a, 0x94, 0x79, 0xa0, 0x73, 0x88, 0xa9, 0xec, 0x04, 0x7c, 0x59, 0xfb, + 0x03, 0x68, 0xc4, 0x84, 0xaf, 0x05, 0x09, 0xbf, 0x80, 0xcb, 0xb9, 0xe2, 0x83, 0x3e, 0x87, 0xd5, + 0x34, 0xa2, 0xb2, 0x0a, 0x15, 0x08, 0x7c, 0xe7, 0x95, 0x96, 0x99, 0xa7, 0x08, 0x30, 0x9e, 0xc3, + 0x12, 0x0f, 0x19, 0x91, 0xf8, 0x17, 0x74, 0xb5, 0xf9, 0x10, 0x9a, 0x89, 0xca, 0xd2, 0x98, 0x69, + 0x43, 0xe3, 0x38, 0x7e, 0x22, 0x95, 0x77, 0x9b, 0x64, 0x6c, 0xec, 0x02, 0xca, 0xda, 0xab, 0x3a, + 0xd0, 0xcd, 0x3c, 0x28, 0x5e, 0x29, 0xb6, 0x1b, 0xc1, 0x1e, 0x63, 0xe2, 0xdf, 0x55, 0x61, 0x71, + 0xdf, 0x16, 0xaf, 0x1c, 0x17, 0x54, 0xe4, 0x6e, 0x40, 0x2b, 0x8c, 0x7a, 0xae, 0xdf, 0x8f, 0x1c, + 0xa2, 0x40, 0x81, 0xea, 0xf4, 0x13, 0xf4, 0xb3, 0x8a, 0x1f, 0x77, 0x16, 0xc5, 0x6c, 0xa4, 0x6e, + 0xb8, 0xe2, 0x1b, 0x7d, 0x04, 0xeb, 0x8f, 0xc8, 0x97, 0x6a, 0x3f, 0xfb, 0x8e, 0xdf, 0xeb, 0xd9, + 0xde, 0x30, 0x56, 0x32, 0x23, 0x94, 0x9c, 0xce, 0x50, 0x06, 0x15, 0x67, 0x4b, 0xa1, 0xa2, 0xf1, + 0x4b, 0x0d, 0x5a, 0xa9, 0xd7, 0x94, 0xdf, 0x6f, 0xcb, 0xfc, 0x90, 0x5e, 0xbf, 0x96, 0xf5, 0x7a, + 0x91, 0xf5, 0x3f, 0x4f, 0x8d, 0x4b, 0xd9, 0xd4, 0xf8, 0xa7, 0x06, 0x2b, 0xfb, 0x36, 0x8b, 0x8b, + 0x92, 0xfd, 0xdf, 0x76, 0x82, 0x25, 0xfe, 0xae, 0x97, 0xfb, 0xbb, 0x03, 0xab, 0xc5, 0x8d, 0x2a, + 0xa7, 0x2f, 0xc3, 0x0c, 0x3f, 0xf9, 0xf8, 0x3d, 0x40, 0x0e, 0x76, 0xbe, 0x6a, 0xc2, 0x52, 0xda, + 0xd0, 0xf9, 0xbf, 0xb6, 0x45, 0xd0, 0x63, 0x68, 0xed, 0xab, 0xdf, 0xe3, 0xe2, 0x77, 0x18, 0x74, + 0xd6, 0xc3, 0x66, 0xfb, 0x6a, 0xf9, 0xa4, 0x54, 0x6d, 0x54, 0x90, 0x05, 0xeb, 0x45, 0x81, 0xe9, + 0x1b, 0xea, 0xff, 0x9f, 0x21, 0x39, 0xe1, 0x7a, 0x95, 0x8a, 0x2d, 0x0d, 0x7d, 0x0e, 0x0b, 0xf9, + 0x97, 0x3e, 0x94, 0xab, 0x70, 0xa5, 0x8f, 0x8f, 0x6d, 0xe3, 0x2c, 0x96, 0xc4, 0xfe, 0x67, 0x1c, + 0x4e, 0xe7, 0x9e, 0xbd, 0x90, 0x91, 0x07, 0xfb, 0x65, 0xcf, 0x82, 0xed, 0xff, 0x3b, 0x93, 0x27, + 0x91, 0xfe, 0x21, 0x34, 0xe2, 0x67, 0xa2, 0xbc, 0x9b, 0x0b, 0x8f, 0x47, 0xed, 0x56, 0x5e, 0xde, + 0x20, 0x34, 0x2a, 0xe8, 0x63, 0xb9, 0x78, 0x97, 0xd2, 0x92, 0xc5, 0x99, 0xc7, 0x91, 0xf6, 0x95, + 0x92, 0x07, 0x09, 0xa3, 0x82, 0xbe, 0x0b, 0xf3, 0xfc, 0xeb, 0x48, 0xfd, 0x12, 0xb6, 0xda, 0x91, + 0x3f, 0xbc, 0x76, 0xe2, 0x1f, 0x5e, 0x3b, 0x77, 0x5d, 0xca, 0x4e, 0xda, 0x25, 0x2f, 0x06, 0x4a, + 0xc0, 0x33, 0xb8, 0xbc, 0x4f, 0x58, 0x0a, 0xf0, 0xd1, 0xb5, 0xd7, 0xba, 0x06, 0xb5, 0x8d, 0x22, + 0xdb, 0xe4, 0x1d, 0xc1, 0xa8, 0xa0, 0xdf, 0x68, 0x70, 0x65, 0x9f, 0xb0, 0x22, 0x64, 0x46, 0xef, + 0x95, 0x2b, 0x39, 0x05, 0x5a, 0xb7, 0x1f, 0x4d, 0x9b, 0xd9, 0x79, 0xb1, 0x46, 0x05, 0xfd, 0x56, + 0x83, 0xb5, 0x8c, 0x61, 0x59, 0x0c, 0x8c, 0xb6, 0xcf, 0x36, 0xae, 0x04, 0x2f, 0xb7, 0x3f, 0x9b, + 0xf2, 0x07, 0xce, 0x8c, 0x48, 0xa3, 0x82, 0x8e, 0xc4, 0x99, 0xa4, 0x2d, 0x0f, 0xbd, 0x5d, 0xda, + 0xdb, 0x12, 0xed, 0x1b, 0xa7, 0x4d, 0x27, 0xe7, 0xf0, 0x19, 0xcc, 0xef, 0x13, 0x16, 0xd7, 0xe7, + 0x7c, 0xa4, 0x15, 0xda, 0x62, 0x3e, 0x55, 0x8b, 0x25, 0x5d, 0x44, 0xcc, 0x92, 0x94, 0x95, 0xa9, + 0x53, 0xf9, 0x5c, 0x2d, 0x2d, 0xd6, 0xf9, 0x88, 0x29, 0x2f, 0x73, 0x46, 0xe5, 0x93, 0xdd, 0xbf, + 0xbe, 0xdc, 0xd0, 0xbe, 0x7a, 0xb9, 0xa1, 0xfd, 0xe3, 0xe5, 0x86, 0xf6, 0xa3, 0x5b, 0xaf, 0xf8, + 0xab, 0x84, 0xcc, 0x1f, 0x3a, 0x60, 0x6a, 0x5b, 0x8e, 0x4d, 0x3c, 0xd6, 0x9b, 0x15, 0xc1, 0x7f, + 0xeb, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf2, 0x91, 0xe2, 0xd9, 0x07, 0x21, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -4679,6 +4695,16 @@ func (m *GitFilesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.NoRevisionCache { + i-- + if m.NoRevisionCache { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } if m.NewGitFileGlobbingEnabled { i-- if m.NewGitFileGlobbingEnabled { @@ -4800,6 +4826,16 @@ func (m *GitDirectoriesRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if m.NoRevisionCache { + i-- + if m.NoRevisionCache { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x20 + } if len(m.Revision) > 0 { i -= len(m.Revision) copy(dAtA[i:], m.Revision) @@ -5686,6 +5722,9 @@ func (m *GitFilesRequest) Size() (n int) { if m.NewGitFileGlobbingEnabled { n += 2 } + if m.NoRevisionCache { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -5733,6 +5772,9 @@ func (m *GitDirectoriesRequest) Size() (n int) { if l > 0 { n += 1 + l + sovRepository(uint64(l)) } + if m.NoRevisionCache { + n += 2 + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -10874,6 +10916,26 @@ func (m *GitFilesRequest) Unmarshal(dAtA []byte) error { } } m.NewGitFileGlobbingEnabled = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NoRevisionCache = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) @@ -11192,6 +11254,26 @@ func (m *GitDirectoriesRequest) Unmarshal(dAtA []byte) error { } m.Revision = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NoRevisionCache", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowRepository + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.NoRevisionCache = bool(v != 0) default: iNdEx = preIndex skippy, err := skipRepository(dAtA[iNdEx:]) diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index f5a934ee12c5c..67c1d24e072d4 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -2506,6 +2506,7 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ repo := request.GetRepo() revision := request.GetRevision() gitPath := request.GetPath() + noRevisionCache := request.GetNoRevisionCache() enableNewGitFileGlobbing := request.GetNewGitFileGlobbingEnabled() if gitPath == "" { gitPath = "." @@ -2515,7 +2516,7 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ return nil, status.Error(codes.InvalidArgument, "must pass a valid repo") } - gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, true)) + gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, !noRevisionCache)) if err != nil { return nil, status.Errorf(codes.Internal, "unable to resolve git revision %s: %v", revision, err) } @@ -2568,12 +2569,12 @@ func (s *Service) GetGitFiles(_ context.Context, request *apiclient.GitFilesRequ func (s *Service) GetGitDirectories(_ context.Context, request *apiclient.GitDirectoriesRequest) (*apiclient.GitDirectoriesResponse, error) { repo := request.GetRepo() revision := request.GetRevision() - + noRevisionCache := request.GetNoRevisionCache() if repo == nil { return nil, status.Error(codes.InvalidArgument, "must pass a valid repo") } - gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, true)) + gitClient, revision, err := s.newClientResolveRevision(repo, revision, git.WithCache(s.cache, !noRevisionCache)) if err != nil { return nil, status.Errorf(codes.Internal, "unable to resolve git revision %s: %v", revision, err) } diff --git a/reposerver/repository/repository.proto b/reposerver/repository/repository.proto index 8e4b69000f7e1..de061122e2586 100644 --- a/reposerver/repository/repository.proto +++ b/reposerver/repository/repository.proto @@ -236,6 +236,7 @@ message GitFilesRequest { string revision = 3; string path = 4; bool NewGitFileGlobbingEnabled = 5; + bool noRevisionCache = 6; } message GitFilesResponse { @@ -247,6 +248,7 @@ message GitDirectoriesRequest { github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1; bool submoduleEnabled = 2; string revision = 3; + bool noRevisionCache = 4; } message GitDirectoriesResponse { From 30b92b246da8649a6c230a253ed4d751536faaf2 Mon Sep 17 00:00:00 2001 From: Geoffrey MUSELLI Date: Mon, 4 Dec 2023 10:59:18 -0500 Subject: [PATCH 139/269] fix(doc): Fix documentation templatePatch (#16522) Signed-off-by: gmuselli --- docs/operator-manual/applicationset/Template.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/applicationset/Template.md b/docs/operator-manual/applicationset/Template.md index 76ff9132802d5..573e297bff2e2 100644 --- a/docs/operator-manual/applicationset/Template.md +++ b/docs/operator-manual/applicationset/Template.md @@ -157,12 +157,12 @@ spec: helm: valueFiles: {{- range $valueFile := .valueFiles }} - - {{ $valueFile | toJson }} + - {{ $valueFile }} {{- end }} {{- if .autoSync }} syncPolicy: automated: - prune: {{ .prune | toJson }} + prune: {{ .prune }} {{- end }} ``` From 888687452fded683dfbef2f86ff818b4c5aff95a Mon Sep 17 00:00:00 2001 From: Chris Murray Date: Mon, 4 Dec 2023 19:42:33 +0000 Subject: [PATCH 140/269] fix: cert-manager.io/certificate health.lua for consistent issuing (Issue #16523) (#16520) * Update cert-manager.opcertificate health.lua Signed-off-by: Chris Murray * adding test case for cert issuing Signed-off-by: Chris Murray * fixing typo Signed-off-by: Chris Murray --------- Signed-off-by: Chris Murray --- .../cert-manager.io/Certificate/health.lua | 5 +++ .../Certificate/health_test.yaml | 4 +++ .../testdata/progressing_issuing_last.yaml | 36 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml diff --git a/resource_customizations/cert-manager.io/Certificate/health.lua b/resource_customizations/cert-manager.io/Certificate/health.lua index ddecb2631b39a..fce5bcbe3d1d0 100644 --- a/resource_customizations/cert-manager.io/Certificate/health.lua +++ b/resource_customizations/cert-manager.io/Certificate/health.lua @@ -1,12 +1,17 @@ local hs = {} if obj.status ~= nil then if obj.status.conditions ~= nil then + + -- Always Handle Issuing First to ensure consistent behaviour for i, condition in ipairs(obj.status.conditions) do if condition.type == "Issuing" and condition.status == "True" then hs.status = "Progressing" hs.message = condition.message return hs end + end + + for i, condition in ipairs(obj.status.conditions) do if condition.type == "Ready" and condition.status == "False" then hs.status = "Degraded" hs.message = condition.message diff --git a/resource_customizations/cert-manager.io/Certificate/health_test.yaml b/resource_customizations/cert-manager.io/Certificate/health_test.yaml index ebf8e75e89064..1af7b1a759a60 100644 --- a/resource_customizations/cert-manager.io/Certificate/health_test.yaml +++ b/resource_customizations/cert-manager.io/Certificate/health_test.yaml @@ -7,6 +7,10 @@ tests: status: Progressing message: Issuing certificate as Secret does not exist inputPath: testdata/progressing_issuing.yaml +- healthStatus: + status: Progressing + message: Issuing certificate as Secret does not exist + inputPath: testdata/progressing_issuing_last.yaml - healthStatus: status: Degraded message: 'Resource validation failed: spec.acme.config: Required value: no ACME diff --git a/resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml b/resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml new file mode 100644 index 0000000000000..4d21a9b3610f1 --- /dev/null +++ b/resource_customizations/cert-manager.io/Certificate/testdata/progressing_issuing_last.yaml @@ -0,0 +1,36 @@ +apiVersion: cert-manager.io/v1alpha2 +kind: Certificate +metadata: + creationTimestamp: '2018-11-07T00:06:12Z' + generation: 1 + name: test-cert + namespace: argocd + resourceVersion: '64763033' + selfLink: /apis/cert-manager.io/v1alpha2/namespaces/argocd/certificates/test-cert + uid: e6cfba50-314d-11e9-be3f-42010a800011 +spec: + acme: + config: + - domains: + - cd.apps.argoproj.io + http01: + ingress: http01 + commonName: cd.apps.argoproj.io + dnsNames: + - cd.apps.argoproj.io + issuerRef: + kind: Issuer + name: argo-cd-issuer + secretName: test-secret +status: + conditions: + - lastTransitionTime: '2021-09-15T02:10:00Z' + message: Issuing certificate as Secret does not exist + reason: DoesNotExist + status: 'False' + type: Ready + - lastTransitionTime: '2021-09-15T02:10:00Z' + message: Issuing certificate as Secret does not exist + reason: DoesNotExist + status: 'True' + type: Issuing From 99c2859560817b4ca514613d3417cc1a93565844 Mon Sep 17 00:00:00 2001 From: Ondrej Sika Date: Mon, 4 Dec 2023 23:14:32 +0100 Subject: [PATCH 141/269] fix: Use math.MaxInt (instead of math.MaxInt64) to fix builds on 32bit platforms (#16065) Signed-off-by: Ondrej Sika From 7484f1df6549d188d4edcc234511d33947af4c45 Mon Sep 17 00:00:00 2001 From: ffppmm Date: Tue, 5 Dec 2023 05:26:58 +0100 Subject: [PATCH 142/269] Added missing 'alias:' prefix for repository name as described here: (#15902) --- reposerver/repository/repository.go | 4 ++++ reposerver/repository/repository_test.go | 17 +++++++++++++++++ .../helm-with-dependencies-alias/Chart.yaml | 7 +++++++ 3 files changed, 28 insertions(+) create mode 100644 reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 67c1d24e072d4..155ff8c6f8653 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -1022,6 +1022,10 @@ func getHelmDependencyRepos(appPath string) ([]*v1alpha1.Repository, error) { repos = append(repos, &v1alpha1.Repository{ Name: r.Repository[1:], }) + } else if strings.HasPrefix(r.Repository, "alias:") { + repos = append(repos, &v1alpha1.Repository{ + Name: strings.TrimPrefix(r.Repository, "alias:"), + }) } else if u, err := url.Parse(r.Repository); err == nil && (u.Scheme == "https" || u.Scheme == "oci") { repo := &v1alpha1.Repository{ // trimming oci:// prefix since it is currently not supported by Argo CD (OCI repos just have no scheme) diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index 74d09dd6f86b8..ab2225b6e778d 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -1440,6 +1440,7 @@ func TestListApps(t *testing.T) { "out-of-bounds-values-file-link": "Helm", "values-files": "Helm", "helm-with-dependencies": "Helm", + "helm-with-dependencies-alias": "Helm", } assert.Equal(t, expectedApps, res.Apps) } @@ -2949,6 +2950,22 @@ func TestGetHelmRepo_NamedRepos(t *testing.T) { assert.Equal(t, helmRepos[0].Repo, "https://example.com") } +func TestGetHelmRepo_NamedReposAlias(t *testing.T) { + src := argoappv1.ApplicationSource{Path: "."} + q := apiclient.ManifestRequest{Repo: &argoappv1.Repository{}, ApplicationSource: &src, Repos: []*argoappv1.Repository{{ + Name: "custom-repo-alias", + Repo: "https://example.com", + Username: "test-alias", + }}} + + helmRepos, err := getHelmRepos("./testdata/helm-with-dependencies-alias", q.Repos, q.HelmRepoCreds) + assert.Nil(t, err) + + assert.Equal(t, len(helmRepos), 1) + assert.Equal(t, helmRepos[0].Username, "test-alias") + assert.Equal(t, helmRepos[0].Repo, "https://example.com") +} + func Test_getResolvedValueFiles(t *testing.T) { tempDir := t.TempDir() paths := io.NewRandomizedTempPaths(tempDir) diff --git a/reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml b/reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml new file mode 100644 index 0000000000000..8a38d551070c7 --- /dev/null +++ b/reposerver/repository/testdata/helm-with-dependencies-alias/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: helm-with-dependencies-alias +version: v1.0.0 +dependencies: + - name: helm + repository: "alias:custom-repo-alias" + version: v1.0.0 From 5c51dcb6a1c76cb346990d14fb650dc56b054c88 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:00:39 -0500 Subject: [PATCH 143/269] fix(ui): use background delete to match k8s terminology (#15579) Signed-off-by: Josh Soref Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- ui/src/app/applications/components/utils.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/applications/components/utils.tsx b/ui/src/app/applications/components/utils.tsx index f11ca2a916307..cd39470bfb25b 100644 --- a/ui/src/app/applications/components/utils.tsx +++ b/ui/src/app/applications/components/utils.tsx @@ -361,7 +361,7 @@ export const deletePopup = async (ctx: ContextApis, resource: ResourceTreeNode, handleStateChange('force')} style={{marginRight: '5px'}} id='force-delete-radio' /> handleStateChange('orphan')} style={{marginRight: '5px'}} id='cascade-delete-radio' /> From 07a2e643239da9f80fbf56a04443741ec4611c3e Mon Sep 17 00:00:00 2001 From: Elouan Keryell-Even Date: Tue, 5 Dec 2023 22:04:55 +0100 Subject: [PATCH 144/269] docs: Fix format issue in rbac.md (#16521) Wrongly placed horizontal line (`----`) was formatting code-block as a header. Fixed it with a necessary line break Signed-off-by: Elouan Keryell-Even --- docs/operator-manual/rbac.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/operator-manual/rbac.md b/docs/operator-manual/rbac.md index 0f15a18be1973..b1d386fb5eb8e 100644 --- a/docs/operator-manual/rbac.md +++ b/docs/operator-manual/rbac.md @@ -159,6 +159,7 @@ data: g, your-github-org:your-team, role:org-admin ``` + ---- Another `policy.csv` example might look as follows: From 86f79ecd741d1bccdec31fe5819de48023479e25 Mon Sep 17 00:00:00 2001 From: Phil Nichol <35630607+philnichol@users.noreply.github.com> Date: Wed, 6 Dec 2023 16:37:14 +0800 Subject: [PATCH 145/269] docs: Fix minor typo in Declarative Setup (#16550) Signed-off-by: Phil Nichol <35630607+philnichol@users.noreply.github.com> --- docs/operator-manual/declarative-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index a156f27589dbd..ee216a7118f7f 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -490,7 +490,7 @@ stringData: ### Legacy behaviour -In Argo CD version 2.0 and earlier, repositories where stored as part of the `argocd-cm` config map. For +In Argo CD version 2.0 and earlier, repositories were stored as part of the `argocd-cm` config map. For backward-compatibility, Argo CD will still honor repositories in the config map, but this style of repository configuration is deprecated and support for it will be removed in a future version. From 710777e261f359fe8e4f69b0a97bfb6d070938b6 Mon Sep 17 00:00:00 2001 From: Jesse Suen Date: Wed, 6 Dec 2023 11:49:40 -0800 Subject: [PATCH 146/269] chore: update PR template to suggest cherry-pick releases (#16560) Signed-off-by: Jesse Suen --- .github/pull_request_template.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 406306bbeca2e..c1a3f42508aaa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -13,11 +13,12 @@ Checklist: * [ ] I've updated both the CLI and UI to expose my feature, or I plan to submit a second PR with them. * [ ] Does this PR require documentation updates? * [ ] I've updated documentation as required by this PR. -* [ ] Optional. My organization is added to USERS.md. * [ ] I have signed off all my commits as required by [DCO](https://github.com/argoproj/argoproj/blob/master/community/CONTRIBUTING.md#legal) * [ ] I have written unit and/or e2e tests for my change. PRs without these are unlikely to be merged. * [ ] My build is green ([troubleshooting builds](https://argo-cd.readthedocs.io/en/latest/developer-guide/ci/)). * [ ] My new feature complies with the [feature status](https://github.com/argoproj/argoproj/blob/master/community/feature-status.md) guidelines. * [ ] I have added a brief description of why this PR is necessary and/or what this PR solves. +* [ ] Optional. My organization is added to USERS.md. +* [ ] Optional. For bug fixes, I've indicated what older releases this fix should be cherry-picked into (this may or may not happen depending on risk/complexity). From 35f1ee78448aa36f0560686df880da1a14a33ee3 Mon Sep 17 00:00:00 2001 From: Rotem Tamir Date: Thu, 7 Dec 2023 13:11:07 +0200 Subject: [PATCH 147/269] resource_customizations/db.atlasgo.io: atlas operator resources (#16364) Signed-off-by: Rotem Tamir --- .../db.atlasgo.io/AtlasMigration/health.lua | 37 ++++++++++++++++++ .../AtlasMigration/health_test.yaml | 13 +++++++ .../AtlasMigration/testdata/degraded.yaml | 29 ++++++++++++++ .../AtlasMigration/testdata/healthy.yaml | 30 ++++++++++++++ .../AtlasMigration/testdata/progressing.yaml | 30 ++++++++++++++ .../db.atlasgo.io/AtlasSchema/health.lua | 37 ++++++++++++++++++ .../AtlasSchema/health_test.yaml | 13 +++++++ .../AtlasSchema/testdata/degraded.yaml | 38 ++++++++++++++++++ .../AtlasSchema/testdata/healthy.yaml | 39 +++++++++++++++++++ .../AtlasSchema/testdata/progressing.yaml | 35 +++++++++++++++++ 10 files changed, 301 insertions(+) create mode 100644 resource_customizations/db.atlasgo.io/AtlasMigration/health.lua create mode 100644 resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasSchema/health.lua create mode 100644 resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml create mode 100644 resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/health.lua b/resource_customizations/db.atlasgo.io/AtlasMigration/health.lua new file mode 100644 index 0000000000000..332b43ec21314 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/health.lua @@ -0,0 +1,37 @@ +hs = {} + +local function readyCond(obj) + if obj.status ~= nil and obj.status.conditions ~= nil then + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + return condition + end + end + end + return nil +end + +local ready = readyCond(obj) + +if ready == nil then + hs.status = "Progressing" + hs.message = "Waiting for Atlas Operator" + return hs +end + +if ready.status == "True" then + hs.status = "Healthy" + hs.message = ready.reason + return hs +end + +if ready.reason == "Reconciling" then + hs.status = "Progressing" +else + hs.status = "Degraded" +end + +hs.message = ready.reason + +return hs + diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml new file mode 100644 index 0000000000000..b827f89c0bdf2 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Reconciling" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Degraded + message: "Migrating" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Healthy + message: "Applied" + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml new file mode 100644 index 0000000000000..ee51f15e48241 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/degraded.yaml @@ -0,0 +1,29 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasMigration +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasMigration","metadata":{"annotations":{},"name":"atlasmigration-sample","namespace":"default"},"spec":{"dir":{"configMapRef":{"name":"migration-dir"}},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-16T08:37:23Z" + generation: 1 + name: atlasmigration-sample + namespace: default + resourceVersion: "49923" + uid: 0d5bc3d6-750e-4f5a-82a3-8b9173106ef4 +spec: + dir: + configMapRef: + name: migration-dir + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-16T08:37:23Z" + message: 'Error: checksum mismatch' + reason: Migrating + status: "False" + type: Ready + lastApplied: 0 + observed_hash: "" diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml new file mode 100644 index 0000000000000..4a7a91324d196 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/healthy.yaml @@ -0,0 +1,30 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasMigration +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasMigration","metadata":{"annotations":{},"name":"atlasmigration-sample","namespace":"default"},"spec":{"dir":{"configMapRef":{"name":"migration-dir"}},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-16T08:37:23Z" + generation: 1 + name: atlasmigration-sample + namespace: default + resourceVersion: "50387" + uid: 0d5bc3d6-750e-4f5a-82a3-8b9173106ef4 +spec: + dir: + configMapRef: + name: migration-dir + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-16T08:46:27Z" + message: "" + reason: Applied + status: "True" + type: Ready + lastApplied: 1700124387 + lastAppliedVersion: "20230316085611" + observed_hash: 4969b3c84c097ff61a9f9722b595a66c1a4473bd85fdd282107b98a92db8a43b diff --git a/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml new file mode 100644 index 0000000000000..024f9f7558d78 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasMigration/testdata/progressing.yaml @@ -0,0 +1,30 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasMigration +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasMigration","metadata":{"annotations":{},"name":"atlasmigration-sample","namespace":"default"},"spec":{"dir":{"configMapRef":{"name":"migration-dir"}},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-16T08:37:23Z" + generation: 1 + name: atlasmigration-sample + namespace: default + resourceVersion: "50387" + uid: 0d5bc3d6-750e-4f5a-82a3-8b9173106ef4 +spec: + dir: + configMapRef: + name: migration-dir + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-16T08:46:27Z" + message: "Current migration data has changed" + reason: "Reconciling" + status: "False" + type: Ready + lastApplied: 1700124387 + lastAppliedVersion: "20230316085611" + observed_hash: 4969b3c84c097ff61a9f9722b595a66c1a4473bd85fdd282107b98a92db8a43b diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/health.lua b/resource_customizations/db.atlasgo.io/AtlasSchema/health.lua new file mode 100644 index 0000000000000..c66d66d15b5a8 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/health.lua @@ -0,0 +1,37 @@ +hs = {} + +local function readyCond(obj) + if obj.status ~= nil and obj.status.conditions ~= nil then + for _, condition in ipairs(obj.status.conditions) do + if condition.type == "Ready" then + return condition + end + end + end + return nil +end + +local ready = readyCond(obj) + +if ready == nil then + hs.status = "Progressing" + hs.message = "Waiting for Atlas Operator" + return hs +end + +if ready.status == "True" then + hs.status = "Healthy" + hs.message = ready.reason + return hs +end + +if ready.message == "Reconciling" or ready.message == "GettingDevDB" then + hs.status = "Progressing" +else + hs.status = "Degraded" +end + +hs.message = ready.reason + +return hs + diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml new file mode 100644 index 0000000000000..0fe102f299138 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/health_test.yaml @@ -0,0 +1,13 @@ +tests: +- healthStatus: + status: Progressing + message: "Reconciling" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Degraded + message: "ApplyingSchema" + inputPath: testdata/degraded.yaml +- healthStatus: + status: Healthy + message: "Applied" + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml new file mode 100644 index 0000000000000..08383988e996a --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/degraded.yaml @@ -0,0 +1,38 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasSchema","metadata":{"annotations":{},"name":"atlasschema-mysql","namespace":"default"},"spec":{"schema":{"sql":"create table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);\n"},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-15T14:33:18Z" + generation: 2 + name: atlasschema-mysql + namespace: default + resourceVersion: "46659" + uid: 54a4cdfc-e4f9-4c3d-934c-e08b6122e38a +spec: + schema: + sql: | + xcreate table users ( + id int not null auto_increment, + name varchar(255) not null, + email varchar(255) unique not null, + short_bio varchar(255) not null, + primary key (id) + ); + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-15T14:38:41Z" + message: |- + Error: sql/migrate: read migration directory state: sql/migrate: execute: executing statement "xcreate table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);" from version "schema": Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xcreate table users ( + id int not null auto_increment, + name varchar(255) not ' at line 1 + reason: ApplyingSchema + status: "False" + type: Ready + last_applied: 1700058814 + observed_hash: ddfe666707ddf5c2cc7625c2a0de89da51e54fc7caa6403db307146430d20d85 diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml new file mode 100644 index 0000000000000..eca8ec497f09a --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/healthy.yaml @@ -0,0 +1,39 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasSchema","metadata":{"annotations":{},"name":"atlasschema-mysql","namespace":"default"},"spec":{"schema":{"sql":"create table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);\n"},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-15T14:33:18Z" + generation: 1 + name: atlasschema-mysql + namespace: default + resourceVersion: "46390" + uid: 54a4cdfc-e4f9-4c3d-934c-e08b6122e38a +spec: + schema: + sql: | + create table users ( + id int not null auto_increment, + name varchar(255) not null, + email varchar(255) unique not null, + short_bio varchar(255) not null, + primary key (id) + ); + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-15T14:33:34Z" + message: 'The schema has been applied successfully. Apply response: {"Driver":"mysql","URL":{"Scheme":"mysql","Opaque":"","User":{},"Host":"mysql.default:3306","Path":"/myapp","RawPath":"","OmitHost":false,"ForceQuery":false,"RawQuery":"parseTime=true","Fragment":"","RawFragment":"","Schema":"myapp"},"Changes":{"Applied":["CREATE + TABLE `users` (\n `id` int NOT NULL AUTO_INCREMENT,\n `name` varchar(255) + NOT NULL,\n `email` varchar(255) NOT NULL,\n `short_bio` varchar(255) NOT + NULL,\n PRIMARY KEY (`id`),\n UNIQUE INDEX `email` (`email`)\n) CHARSET utf8mb4 + COLLATE utf8mb4_0900_ai_ci"]}}' + reason: Applied + status: "True" + type: Ready + last_applied: 1700058814 + observed_hash: ddfe666707ddf5c2cc7625c2a0de89da51e54fc7caa6403db307146430d20d85 diff --git a/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml new file mode 100644 index 0000000000000..79d59ca768141 --- /dev/null +++ b/resource_customizations/db.atlasgo.io/AtlasSchema/testdata/progressing.yaml @@ -0,0 +1,35 @@ +apiVersion: db.atlasgo.io/v1alpha1 +kind: AtlasSchema +metadata: + annotations: + kubectl.kubernetes.io/last-applied-configuration: | + {"apiVersion":"db.atlasgo.io/v1alpha1","kind":"AtlasSchema","metadata":{"annotations":{},"name":"atlasschema-mysql","namespace":"default"},"spec":{"schema":{"sql":"create table users (\n id int not null auto_increment,\n name varchar(255) not null,\n email varchar(255) unique not null,\n short_bio varchar(255) not null,\n primary key (id)\n);\n"},"urlFrom":{"secretKeyRef":{"key":"url","name":"mysql-credentials"}}}} + creationTimestamp: "2023-11-15T14:33:18Z" + generation: 1 + name: atlasschema-mysql + namespace: default + resourceVersion: "46390" + uid: 54a4cdfc-e4f9-4c3d-934c-e08b6122e38a +spec: + schema: + sql: | + create table users ( + id int not null auto_increment, + name varchar(255) not null, + email varchar(255) unique not null, + short_bio varchar(255) not null, + primary key (id) + ); + urlFrom: + secretKeyRef: + key: url + name: mysql-credentials +status: + conditions: + - lastTransitionTime: "2023-11-15T14:33:34Z" + message: 'Reconciling' + reason: Reconciling + status: "False" + type: Ready + last_applied: 1700058814 + observed_hash: ddfe666707ddf5c2cc7625c2a0de89da51e54fc7caa6403db307146430d20d85 From 9179835ec1995d089a0c6938f459b8c637906eef Mon Sep 17 00:00:00 2001 From: Takumi Sue <23391543+mikutas@users.noreply.github.com> Date: Fri, 8 Dec 2023 23:20:01 +0900 Subject: [PATCH 148/269] fix(appset): Always remove ownerReferences when appset policy doesn't allow app's deletion (#12172) (#16506) * fix(appset): remove unnecessary condition Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> * docs: update explanation about policy Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> --------- Signed-off-by: mikutas <23391543+mikutas@users.noreply.github.com> --- .../controllers/applicationset_controller.go | 18 ++++++++---------- .../Controlling-Resource-Modification.md | 6 ++---- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/applicationset/controllers/applicationset_controller.go b/applicationset/controllers/applicationset_controller.go index 527a4ae1e3883..4f5ac66fc016d 100644 --- a/applicationset/controllers/applicationset_controller.go +++ b/applicationset/controllers/applicationset_controller.go @@ -108,16 +108,14 @@ func (r *ApplicationSetReconciler) Reconcile(ctx context.Context, req ctrl.Reque // Do not attempt to further reconcile the ApplicationSet if it is being deleted. if applicationSetInfo.ObjectMeta.DeletionTimestamp != nil { - if controllerutil.ContainsFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) { - deleteAllowed := utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete() - if !deleteAllowed { - if err := r.removeOwnerReferencesOnDeleteAppSet(ctx, applicationSetInfo); err != nil { - return ctrl.Result{}, err - } - controllerutil.RemoveFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) - if err := r.Update(ctx, &applicationSetInfo); err != nil { - return ctrl.Result{}, err - } + deleteAllowed := utils.DefaultPolicy(applicationSetInfo.Spec.SyncPolicy, r.Policy, r.EnablePolicyOverride).AllowDelete() + if !deleteAllowed { + if err := r.removeOwnerReferencesOnDeleteAppSet(ctx, applicationSetInfo); err != nil { + return ctrl.Result{}, err + } + controllerutil.RemoveFinalizer(&applicationSetInfo, argov1alpha1.ResourcesFinalizerName) + if err := r.Update(ctx, &applicationSetInfo); err != nil { + return ctrl.Result{}, err } } return ctrl.Result{}, nil diff --git a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md index 44b6797b24d11..d72cee60ad401 100644 --- a/docs/operator-manual/applicationset/Controlling-Resource-Modification.md +++ b/docs/operator-manual/applicationset/Controlling-Resource-Modification.md @@ -32,15 +32,13 @@ spec: ``` -- Policy `create-only`: Prevents ApplicationSet controller from modifying or deleting Applications. -- Policy `create-update`: Prevents ApplicationSet controller from deleting Applications. Update is allowed. +- Policy `create-only`: Prevents ApplicationSet controller from modifying or deleting Applications. Prevents Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/). +- Policy `create-update`: Prevents ApplicationSet controller from deleting Applications. Update is allowed. Prevents Application controller from deleting Applications according to [ownerReferences](https://kubernetes.io/docs/concepts/overview/working-with-objects/owners-dependents/). - Policy `create-delete`: Prevents ApplicationSet controller from modifying Applications. Delete is allowed. - Policy `sync`: Update and Delete are allowed. If the controller parameter `--policy` is set, it takes precedence on the field `applicationsSync`. It is possible to allow per ApplicationSet sync policy by setting variable `ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_POLICY_OVERRIDE` to argocd-cmd-params-cm `applicationsetcontroller.enable.policy.override` or directly with controller parameter `--enable-policy-override` (default to `false`). -This does not prevent deletion of Applications if the ApplicationSet is deleted - ### Controller parameter To allow the ApplicationSet controller to *create* `Application` resources, but prevent any further modification, such as deletion, or modification of Application fields, add this parameter in the ApplicationSet controller: From f67dcac945ab2364071c4a4e9966807be480c672 Mon Sep 17 00:00:00 2001 From: Jay Shah Date: Fri, 8 Dec 2023 12:40:34 -0500 Subject: [PATCH 149/269] docs: Add Kong Inc. as a user (#16582) Signed-off-by: Jay Shah --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 431a5ef3944f4..cc1c22e3d9d7b 100644 --- a/USERS.md +++ b/USERS.md @@ -148,6 +148,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Kinguin](https://www.kinguin.net/) 1. [KintoHub](https://www.kintohub.com/) 1. [KompiTech GmbH](https://www.kompitech.com/) +1. [Kong Inc.](https://konghq.com/) 1. [KPMG](https://kpmg.com/uk) 1. [KubeSphere](https://github.com/kubesphere) 1. [Kurly](https://www.kurly.com/) From a761a495f16d76c0a8e50359eda50f605e329aba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Reegn?= Date: Fri, 8 Dec 2023 21:01:05 +0100 Subject: [PATCH 150/269] chore: upgrade kubernetes dependencies from 0.26.4 to 0.26.11 (#16581) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: upgrade kubernetes dependencies from 0.26.4 to 0.26.11 Fixes some vulnerabilities trivy is reporting on (not necessarily vulnerabe, trivy tends to have a lot of false positives when it comes to golang projects): * CVE-2023-3676 * CVE-2023-3955 * CVE-2023-5528 * CVE-2023-2431 * CVE-2023-2727 * CVE-2023-2728 Signed-off-by: Zoltán Reegn * go mod tidy Signed-off-by: Zoltán Reegn * Add go mod tidy to kubernetes updater script Signed-off-by: Zoltán Reegn --------- Signed-off-by: Zoltán Reegn --- go.mod | 80 +++++++++++++++---------------- go.sum | 60 ++++++++++++----------- hack/update-kubernetes-version.sh | 22 +++++++++ 3 files changed, 93 insertions(+), 69 deletions(-) create mode 100755 hack/update-kubernetes-version.sh diff --git a/go.mod b/go.mod index 8b91fe20eef1b..03283f5c61f09 100644 --- a/go.mod +++ b/go.mod @@ -91,12 +91,12 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 - k8s.io/api v0.26.4 + k8s.io/api v0.26.11 k8s.io/apiextensions-apiserver v0.26.4 - k8s.io/apimachinery v0.26.4 - k8s.io/apiserver v0.26.4 - k8s.io/client-go v0.26.4 - k8s.io/code-generator v0.26.4 + k8s.io/apimachinery v0.26.11 + k8s.io/apiserver v0.26.11 + k8s.io/client-go v0.26.11 + k8s.io/code-generator v0.26.11 k8s.io/klog/v2 v2.100.1 k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f k8s.io/kubectl v0.26.4 @@ -267,12 +267,12 @@ require ( go.opentelemetry.io/otel/trace v1.21.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect - golang.org/x/mod v0.9.0 // indirect + golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 golang.org/x/sys v0.14.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.12.0 // indirect gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect gomodules.xyz/notify v0.1.1 // indirect @@ -281,12 +281,12 @@ require ( gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - k8s.io/cli-runtime v0.26.4 // indirect - k8s.io/component-base v0.26.4 // indirect - k8s.io/component-helpers v0.26.4 // indirect + k8s.io/cli-runtime v0.26.11 // indirect + k8s.io/component-base v0.26.11 // indirect + k8s.io/component-helpers v0.26.11 // indirect k8s.io/gengo v0.0.0-20220902162205-c0856e24416d // indirect k8s.io/kube-aggregator v0.26.4 // indirect - k8s.io/kubernetes v1.26.4 // indirect + k8s.io/kubernetes v1.26.11 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/kustomize/api v0.12.1 // indirect sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect @@ -305,34 +305,34 @@ replace ( // Avoid CVE-2022-28948 gopkg.in/yaml.v3 => gopkg.in/yaml.v3 v3.0.1 - k8s.io/api => k8s.io/api v0.26.4 - k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.4 - k8s.io/apimachinery => k8s.io/apimachinery v0.26.4 - k8s.io/apiserver => k8s.io/apiserver v0.26.4 - k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.4 - k8s.io/client-go => k8s.io/client-go v0.26.4 - k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.4 - k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.4 - k8s.io/code-generator => k8s.io/code-generator v0.26.4 - k8s.io/component-base => k8s.io/component-base v0.26.4 - k8s.io/component-helpers => k8s.io/component-helpers v0.26.4 - k8s.io/controller-manager => k8s.io/controller-manager v0.26.4 - k8s.io/cri-api => k8s.io/cri-api v0.26.4 - k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.4 - k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.26.4 - k8s.io/kms => k8s.io/kms v0.26.4 - k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.4 - k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.4 - k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.4 - k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.4 - k8s.io/kubectl => k8s.io/kubectl v0.26.4 - k8s.io/kubelet => k8s.io/kubelet v0.26.4 - k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.4 - k8s.io/metrics => k8s.io/metrics v0.26.4 - k8s.io/mount-utils => k8s.io/mount-utils v0.26.4 - k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.4 - k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.4 - k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.26.4 - k8s.io/sample-controller => k8s.io/sample-controller v0.26.4 + k8s.io/api => k8s.io/api v0.26.11 + k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.26.11 + k8s.io/apimachinery => k8s.io/apimachinery v0.26.11 + k8s.io/apiserver => k8s.io/apiserver v0.26.11 + k8s.io/cli-runtime => k8s.io/cli-runtime v0.26.11 + k8s.io/client-go => k8s.io/client-go v0.26.11 + k8s.io/cloud-provider => k8s.io/cloud-provider v0.26.11 + k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.26.11 + k8s.io/code-generator => k8s.io/code-generator v0.26.11 + k8s.io/component-base => k8s.io/component-base v0.26.11 + k8s.io/component-helpers => k8s.io/component-helpers v0.26.11 + k8s.io/controller-manager => k8s.io/controller-manager v0.26.11 + k8s.io/cri-api => k8s.io/cri-api v0.26.11 + k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.26.11 + k8s.io/dynamic-resource-allocation => k8s.io/dynamic-resource-allocation v0.26.11 + k8s.io/kms => k8s.io/kms v0.26.11 + k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.26.11 + k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.26.11 + k8s.io/kube-proxy => k8s.io/kube-proxy v0.26.11 + k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.26.11 + k8s.io/kubectl => k8s.io/kubectl v0.26.11 + k8s.io/kubelet => k8s.io/kubelet v0.26.11 + k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.26.11 + k8s.io/metrics => k8s.io/metrics v0.26.11 + k8s.io/mount-utils => k8s.io/mount-utils v0.26.11 + k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.26.11 + k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.26.11 + k8s.io/sample-cli-plugin => k8s.io/sample-cli-plugin v0.26.11 + k8s.io/sample-controller => k8s.io/sample-controller v0.26.11 ) diff --git a/go.sum b/go.sum index dbe7107f59cba..9f0d3f9a0976e 100644 --- a/go.sum +++ b/go.sum @@ -1596,8 +1596,8 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= @@ -1878,8 +1878,9 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2132,6 +2133,7 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2173,7 +2175,6 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb 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= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= @@ -2258,8 +2259,9 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= +golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -2616,24 +2618,24 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -k8s.io/api v0.26.4 h1:qSG2PmtcD23BkYiWfoYAcak870eF/hE7NNYBYavTT94= -k8s.io/api v0.26.4/go.mod h1:WwKEXU3R1rgCZ77AYa7DFksd9/BAIKyOmRlbVxgvjCk= -k8s.io/apiextensions-apiserver v0.26.4 h1:9D2RTxYGxrG5uYg6D7QZRcykXvavBvcA59j5kTaedQI= -k8s.io/apiextensions-apiserver v0.26.4/go.mod h1:cd4uGFGIgzEqUghWpRsr9KE8j2KNTjY8Ji8pnMMazyw= -k8s.io/apimachinery v0.26.4 h1:rZccKdBLg9vP6J09JD+z8Yr99Ce8gk3Lbi9TCx05Jzs= -k8s.io/apimachinery v0.26.4/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= -k8s.io/apiserver v0.26.4 h1:3Oq4mnJv0mzVX7BR/Nod+8KjlELf/3Ljvu9ZWDyLUoA= -k8s.io/apiserver v0.26.4/go.mod h1:yAY3O1vBM4/0OIGAGeWcdfzQvgdwJ188VirLcuSAVnw= -k8s.io/cli-runtime v0.26.4 h1:MgSU871KDzBDX7V9GtuqS6Ai9lhQCHgRzkurnXOWtZ0= -k8s.io/cli-runtime v0.26.4/go.mod h1:MjJ2DXMChw2zcG0/agzm17xwKpfVxOfuoCdfY9iOCOE= -k8s.io/client-go v0.26.4 h1:/7P/IbGBuT73A+G97trf44NTPSNqvuBREpOfdLbHvD4= -k8s.io/client-go v0.26.4/go.mod h1:6qOItWm3EwxJdl/8p5t7FWtWUOwyMdA8N9ekbW4idpI= -k8s.io/code-generator v0.26.4 h1:zgDD0qX13p/jtrAoYRRiYeQ5ibnriwmo2cMkMZAtJxc= -k8s.io/code-generator v0.26.4/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= -k8s.io/component-base v0.26.4 h1:Bg2xzyXNKL3eAuiTEu3XE198d6z22ENgFgGQv2GGOUk= -k8s.io/component-base v0.26.4/go.mod h1:lTuWL1Xz/a4e80gmIC3YZG2JCO4xNwtKWHJWeJmsq20= -k8s.io/component-helpers v0.26.4 h1:qbZrh8QmfL+Yn7lWEI/BPrvITGgkBy33djP5Tzsu2hA= -k8s.io/component-helpers v0.26.4/go.mod h1:2Siz5eWmaKu0khASXMTCfJuASZAbCPX9mtjlCe5IWRs= +k8s.io/api v0.26.11 h1:hLhTZRdYc3vBBOY4wbEyTLWgMyieOAk2Ws9NG57QqO4= +k8s.io/api v0.26.11/go.mod h1:bSr/A0TKRt5W2OMDdexkM/ER1NxOxiQqNNFXW2nMZrM= +k8s.io/apiextensions-apiserver v0.26.11 h1:6/T0Jm9c+Aw1AYUflPOz2sAsty304/DDSkciTr8+HuE= +k8s.io/apiextensions-apiserver v0.26.11/go.mod h1:xMqWxAB+AvSTdmFRVWlpavY9bJl/3g6yWiPn/fwZbT0= +k8s.io/apimachinery v0.26.11 h1:w//840HHdwSRKqD15j9YX9HLlU6RPlfrvW0xEhLk2+0= +k8s.io/apimachinery v0.26.11/go.mod h1:2/HZp0l6coXtS26du1Bk36fCuAEr/lVs9Q9NbpBtd1Y= +k8s.io/apiserver v0.26.11 h1:JcrlATLu5xQVLV7/rfRFFl9ivvNLmZH0dM3DFFdFp+w= +k8s.io/apiserver v0.26.11/go.mod h1:htEG/Q3sI3+6Is3Z26QzBjaCGICsz/kFj+IhIP4oJuE= +k8s.io/cli-runtime v0.26.11 h1:HO3Sgf06XkT8/8wWnhskfz4+LMKrChRz+A13vDJSQrE= +k8s.io/cli-runtime v0.26.11/go.mod h1:D98GjQtDmqn7WDuKBgWivd6R8qEs3yzT19EmCM5pqBs= +k8s.io/client-go v0.26.11 h1:RjfZr5+vQjjTRmk4oCqHyC0cgrZXPjw+X+ge35sk4GI= +k8s.io/client-go v0.26.11/go.mod h1:+emNszw9va/uRJIM5ALTBtFnlZMTjwBrNjRfEh0iuw8= +k8s.io/code-generator v0.26.11 h1:S0PJxapUhG6LWYezYB/FVE5Gf4BxGY0fCwnLrwfQ/70= +k8s.io/code-generator v0.26.11/go.mod h1:Hjxj7hpvSxcNnYIWzCSuEdwN0/9aHlezQRKJXr0Kv8U= +k8s.io/component-base v0.26.11 h1:1/JmB6fexefGByfFyIK6aHksZZVtaDskttzXOzmZ6zA= +k8s.io/component-base v0.26.11/go.mod h1:jYNisnoM6iWFRUg51pxaQabzL5fBYTr5CMpsLjUYGp0= +k8s.io/component-helpers v0.26.11 h1:XD2/2lik/5n1WFepDvgHzIGL0tix/EU3GaxGJHdsgkA= +k8s.io/component-helpers v0.26.11/go.mod h1:lw3bchkI0NHMPmb+CE73GznPW0Mvqd/Y9UVMEqBkysE= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20220902162205-c0856e24416d h1:U9tB195lKdzwqicbJvyJeOXV7Klv+wNAWENRnXEGi08= k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= @@ -2645,15 +2647,15 @@ k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-aggregator v0.26.4 h1:iGljhq5exQkbuc3bnkwUx95RPCBDExg7DkX9XaYhg6w= -k8s.io/kube-aggregator v0.26.4/go.mod h1:eWfg4tU0+l57ebWiS5THOANIJUrKRxudSVDJ+63bqvQ= +k8s.io/kube-aggregator v0.26.11 h1:P46aQPWOE+8bTbK2cqxUFP1XwH4ShZEHnlk1T5QFT8U= +k8s.io/kube-aggregator v0.26.11/go.mod h1:XNGLFzn4Ex7qFVqpCnvLUr354EM4QhMFuFSoB6JHmL4= k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= -k8s.io/kubectl v0.26.4 h1:A0Oa0u/po4KxXnXsNCOwLojAe9cQR3TJNJabEIf7U1w= -k8s.io/kubectl v0.26.4/go.mod h1:cWtp/+I4p+h5En3s2zO1zCry9v3/6h37EQ2tF3jNRnM= -k8s.io/kubernetes v1.26.4 h1:/c00/JjOltBwhNOBs+hO433Q3fRyeWWtyYF6z2xtmag= -k8s.io/kubernetes v1.26.4/go.mod h1:NxzR7U7mS+OGa3J/qweI86Pek//mlfHqDgt6NNGdz8g= +k8s.io/kubectl v0.26.11 h1:cVPzYA4HKefU3tPiVK7hZpJ+5Lm04XoyvCCY5ODznpQ= +k8s.io/kubectl v0.26.11/go.mod h1:xjEX/AHtEQrGj2AGqVopyHr/JU1hLy1k7Yn48JuK9LQ= +k8s.io/kubernetes v1.26.11 h1:g3r1IAUqsaHnOG2jdpoagJ5W9UCXkR2ljQ/7BmCzPNg= +k8s.io/kubernetes v1.26.11/go.mod h1:z1URAaBJ+XnOTr3Q/l4umxRUxn/OyD2fbkUgS0Bl7u4= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= diff --git a/hack/update-kubernetes-version.sh b/hack/update-kubernetes-version.sh new file mode 100755 index 0000000000000..8d52033a601fc --- /dev/null +++ b/hack/update-kubernetes-version.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ -z "${1:-}" ]; then + echo "Example usage: ./hack/update-kubernetes-version.sh v1.26.11" + exit 1 +fi +VERSION=${1#"v"} +MODS=($( + curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod | + sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' +)) +for MOD in "${MODS[@]}"; do + echo "Updating $MOD..." >&2 + V=$( + go mod download -json "${MOD}@kubernetes-${VERSION}" | + sed -n 's|.*"Version": "\(.*\)".*|\1|p' + ) + go mod edit "-replace=${MOD}=${MOD}@${V}" +done +go get "k8s.io/kubernetes@v${VERSION}" +go mod tidy From 10bb8b0f6865309c4ae578a6d0d31d9fcee30d94 Mon Sep 17 00:00:00 2001 From: Elouan Keryell-Even Date: Mon, 11 Dec 2023 13:03:13 +0100 Subject: [PATCH 151/269] docs: fix broken link in secret-management.md (#16588) Signed-off-by: Elouan Keryell-Even --- docs/operator-manual/secret-management.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/secret-management.md b/docs/operator-manual/secret-management.md index ab06a46014b20..aa224e20ff742 100644 --- a/docs/operator-manual/secret-management.md +++ b/docs/operator-manual/secret-management.md @@ -10,7 +10,7 @@ Here are some ways people are doing GitOps secrets: * [Bitnami Sealed Secrets](https://github.com/bitnami-labs/sealed-secrets) * [External Secrets Operator](https://github.com/external-secrets/external-secrets) * [Hashicorp Vault](https://www.vaultproject.io) -* [Bank-Vaults]((https://bank-vaults.dev/)) +* [Bank-Vaults](https://bank-vaults.dev/) * [Helm Secrets](https://github.com/jkroepke/helm-secrets) * [Kustomize secret generator plugins](https://github.com/kubernetes-sigs/kustomize/blob/fd7a353df6cece4629b8e8ad56b71e30636f38fc/examples/kvSourceGoPlugin.md#secret-values-from-anywhere) * [aws-secret-operator](https://github.com/mumoshu/aws-secret-operator) From d70f9a49b139872e5540e9bdf60e78867112d78c Mon Sep 17 00:00:00 2001 From: John Date: Wed, 13 Dec 2023 08:48:20 +0100 Subject: [PATCH 152/269] docs(monitoring): add new ServiceMonitors for redis, dex, notifications (#16534) Signed-off-by: dmpe --- docs/operator-manual/metrics.md | 48 ++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/operator-manual/metrics.md b/docs/operator-manual/metrics.md index 2bde146a786a2..cfd2a8a8093ac 100644 --- a/docs/operator-manual/metrics.md +++ b/docs/operator-manual/metrics.md @@ -86,7 +86,7 @@ Scraped at the `argocd-repo-server:8084/metrics` endpoint. ## Prometheus Operator If using Prometheus Operator, the following ServiceMonitor example manifests can be used. -Change `metadata.labels.release` to the name of label selected by your Prometheus. +Add a namespace where Argo CD is installed and change `metadata.labels.release` to the name of label selected by your Prometheus. ```yaml apiVersion: monitoring.coreos.com/v1 @@ -148,6 +148,52 @@ spec: - port: metrics ``` +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: argocd-dex-server + labels: + release: prometheus-operator +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-dex-server + endpoints: + - port: metrics +``` + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: argocd-redis-haproxy-metrics +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-redis-ha-haproxy + endpoints: + - port: http-exporter-port +``` + +For notifications controller, you need to additionally add following: + +```yaml +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: argocd-notifications-controller + labels: + release: prometheus-operator +spec: + selector: + matchLabels: + app.kubernetes.io/name: argocd-notifications-controller-metrics + endpoints: + - port: metrics +``` + + ## Dashboards You can find an example Grafana dashboard [here](https://github.com/argoproj/argo-cd/blob/master/examples/dashboard.json) or check demo instance From cde68e0691dd23d184ead6b90b71ce10b94eb068 Mon Sep 17 00:00:00 2001 From: Jason Wang <7304774+jasonwzm@users.noreply.github.com> Date: Thu, 14 Dec 2023 00:36:12 -0800 Subject: [PATCH 153/269] Add Statsig as a user (#16604) Signed-off-by: Jason Wang <7304774+jasonwzm@users.noreply.github.com> --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index cc1c22e3d9d7b..ea0c44ae1ff4b 100644 --- a/USERS.md +++ b/USERS.md @@ -266,6 +266,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Spendesk](https://spendesk.com/) 1. [Splunk](https://splunk.com/) 1. [Spores Labs](https://spores.app) +1. [Statsig](https://statsig.com) 1. [StreamNative](https://streamnative.io) 1. [Stuart](https://stuart.com/) 1. [Sumo Logic](https://sumologic.com/) From ecef174301214c9d2ebbb487aaa33f14783e287d Mon Sep 17 00:00:00 2001 From: yedayak <43016107+yedayak@users.noreply.github.com> Date: Thu, 14 Dec 2023 13:18:30 +0200 Subject: [PATCH 154/269] docs: fix indentation for preserve file mode (#16598) The preserveFileMode isn't under parameters, it should be right under spec. It's correct in the other example here. Signed-off-by: yedayak --- docs/operator-manual/config-management-plugins.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/operator-manual/config-management-plugins.md b/docs/operator-manual/config-management-plugins.md index 5a831dc5e7c47..7c86075ff2f7f 100644 --- a/docs/operator-manual/config-management-plugins.md +++ b/docs/operator-manual/config-management-plugins.md @@ -110,9 +110,9 @@ spec: # static parameter announcements list. command: [echo, '[{"name": "example-param", "string": "default-string-value"}]'] - # If set to `true` then the plugin receives repository files with original file mode. Dangerous since the repository - # might have executable files. Set to true only if you trust the CMP plugin authors. - preserveFileMode: false + # If set to `true` then the plugin receives repository files with original file mode. Dangerous since the repository + # might have executable files. Set to true only if you trust the CMP plugin authors. + preserveFileMode: false ``` !!! note From 2ad419bf63cdb32166422591d3b1e005d0df1946 Mon Sep 17 00:00:00 2001 From: Nathan Romriell Date: Thu, 14 Dec 2023 03:35:55 -0800 Subject: [PATCH 155/269] fix(repo-server): excess git requests, short-circuit GenerateManifests ref only (#16501) * fix(repo-server): excess git requests part 2, short-circuit GenerateManifests ref only Signed-off-by: nromriell * chore(logging): pr feedback, add debug log to short circuit Signed-off-by: nromriell * chore: pr feedback, add ref to debug statement Signed-off-by: nromriell --------- Signed-off-by: nromriell --- reposerver/repository/repository.go | 11 +++++ reposerver/repository/repository_test.go | 58 +++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 155ff8c6f8653..41f26b1f434b8 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -507,6 +507,17 @@ func resolveReferencedSources(hasMultipleSources bool, source *v1alpha1.Applicat func (s *Service) GenerateManifest(ctx context.Context, q *apiclient.ManifestRequest) (*apiclient.ManifestResponse, error) { var res *apiclient.ManifestResponse var err error + + // Skip this path for ref only sources + if q.HasMultipleSources && q.ApplicationSource.Path == "" && q.ApplicationSource.Chart == "" && q.ApplicationSource.Ref != "" { + log.Debugf("Skipping manifest generation for ref only source for application: %s and ref %s", q.AppName, q.ApplicationSource.Ref) + _, revision, err := s.newClientResolveRevision(q.Repo, q.Revision, git.WithCache(s.cache, !q.NoRevisionCache && !q.NoCache)) + res = &apiclient.ManifestResponse{ + Revision: revision, + } + return res, err + } + cacheFn := func(cacheKey string, refSourceCommitSHAs cache.ResolvedRevisions, firstInvocation bool) (bool, error) { ok, resp, err := s.getManifestCacheEntry(cacheKey, q, refSourceCommitSHAs, firstInvocation) res = resp diff --git a/reposerver/repository/repository_test.go b/reposerver/repository/repository_test.go index ab2225b6e778d..3f2f74c4e5ae0 100644 --- a/reposerver/repository/repository_test.go +++ b/reposerver/repository/repository_test.go @@ -337,6 +337,62 @@ func TestGenerateManifests_EmptyCache(t *testing.T) { gitMocks.AssertCalled(t, "Fetch", mock.Anything) } +// Test that when Generate manifest is called with a source that is ref only it does not try to generate manifests or hit the manifest cache +// but it does resolve and cache the revision +func TestGenerateManifest_RefOnlyShortCircuit(t *testing.T) { + lsremoteCalled := false + dir := t.TempDir() + repopath := fmt.Sprintf("%s/tmprepo", dir) + repoRemote := fmt.Sprintf("file://%s", repopath) + cacheMocks := newCacheMocks() + t.Cleanup(cacheMocks.mockCache.StopRedisCallback) + service := NewService(metrics.NewMetricsServer(), cacheMocks.cache, RepoServerInitConstants{ParallelismLimit: 1}, argo.NewResourceTracking(), &git.NoopCredsStore{}, repopath) + service.newGitClient = func(rawRepoURL string, root string, creds git.Creds, insecure bool, enableLfs bool, proxy string, opts ...git.ClientOpts) (client git.Client, e error) { + opts = append(opts, git.WithEventHandlers(git.EventHandlers{ + // Primary check, we want to make sure ls-remote is not called when the item is in cache + OnLsRemote: func(repo string) func() { + return func() { + lsremoteCalled = true + } + }, + OnFetch: func(repo string) func() { + return func() { + assert.Fail(t, "Fetch should not be called from GenerateManifest when the source is ref only") + } + }, + })) + gitClient, err := git.NewClientExt(rawRepoURL, root, creds, insecure, enableLfs, proxy, opts...) + return gitClient, err + } + revision := initGitRepo(t, newGitRepoOptions{ + path: repopath, + createPath: true, + remote: repoRemote, + addEmptyCommit: true, + }) + src := argoappv1.ApplicationSource{RepoURL: repoRemote, TargetRevision: "HEAD", Ref: "test-ref"} + repo := &argoappv1.Repository{ + Repo: repoRemote, + } + q := apiclient.ManifestRequest{ + Repo: repo, + Revision: "HEAD", + HasMultipleSources: true, + ApplicationSource: &src, + ProjectName: "default", + ProjectSourceRepos: []string{"*"}, + } + _, err := service.GenerateManifest(context.Background(), &q) + assert.NoError(t, err) + cacheMocks.mockCache.AssertCacheCalledTimes(t, &repositorymocks.CacheCallCounts{ + ExternalSets: 1, + ExternalGets: 1}) + assert.True(t, lsremoteCalled, "ls-remote should be called when the source is ref only") + var revisions [][2]string + assert.NoError(t, cacheMocks.cacheutilCache.GetItem(fmt.Sprintf("git-refs|%s", repoRemote), &revisions)) + assert.ElementsMatch(t, [][2]string{{"refs/heads/main", revision}, {"HEAD", "ref: refs/heads/main"}}, revisions) +} + // Test that calling manifest generation on source helm reference helm files that when the revision is cached it does not call ls-remote func TestGenerateManifestsHelmWithRefs_CachedNoLsRemote(t *testing.T) { dir := t.TempDir() @@ -2758,7 +2814,7 @@ func initGitRepo(t *testing.T, options newGitRepoOptions) (revision string) { assert.NoError(t, os.Mkdir(options.path, 0755)) } - cmd := exec.Command("git", "init", options.path) + cmd := exec.Command("git", "init", "-b", "main", options.path) cmd.Dir = options.path assert.NoError(t, cmd.Run()) From 23959ca1f739cb53e3841d119a9f7678aa799f4d Mon Sep 17 00:00:00 2001 From: flux-ricky <42919858+flux-ricky@users.noreply.github.com> Date: Fri, 15 Dec 2023 00:57:21 +1300 Subject: [PATCH 156/269] fix(cli): `argocd admin settings resource-overrides health` to not ignore wildard customizations (#16461) Signed-off-by: Ricky McMillen --- cmd/argocd/commands/admin/settings.go | 22 +++++------- cmd/argocd/commands/admin/settings_test.go | 39 ++++++++++++++++++---- 2 files changed, 42 insertions(+), 19 deletions(-) diff --git a/cmd/argocd/commands/admin/settings.go b/cmd/argocd/commands/admin/settings.go index 281d9875691c4..0274b4a422f09 100644 --- a/cmd/argocd/commands/admin/settings.go +++ b/cmd/argocd/commands/admin/settings.go @@ -373,11 +373,7 @@ func executeResourceOverrideCommand(ctx context.Context, cmdCtx commandContext, if gvk.Group != "" { key = fmt.Sprintf("%s/%s", gvk.Group, gvk.Kind) } - override, hasOverride := overrides[key] - if !hasOverride { - _, _ = fmt.Printf("No overrides configured for '%s/%s'\n", gvk.Group, gvk.Kind) - return - } + override := overrides[key] callback(res, override, overrides) } @@ -519,16 +515,16 @@ argocd admin settings resource-overrides health ./deploy.yaml --argocd-cm-path . executeResourceOverrideCommand(ctx, cmdCtx, args, func(res unstructured.Unstructured, override v1alpha1.ResourceOverride, overrides map[string]v1alpha1.ResourceOverride) { gvk := res.GroupVersionKind() - if override.HealthLua == "" { - _, _ = fmt.Printf("Health script is not configured for '%s/%s'\n", gvk.Group, gvk.Kind) - return - } - resHealth, err := healthutil.GetResourceHealth(&res, lua.ResourceHealthOverrides(overrides)) - errors.CheckError(err) - _, _ = fmt.Printf("STATUS: %s\n", resHealth.Status) - _, _ = fmt.Printf("MESSAGE: %s\n", resHealth.Message) + if err != nil { + errors.CheckError(err) + } else if resHealth == nil { + fmt.Printf("Health script is not configured for '%s/%s'\n", gvk.Group, gvk.Kind) + } else { + _, _ = fmt.Printf("STATUS: %s\n", resHealth.Status) + _, _ = fmt.Printf("MESSAGE: %s\n", resHealth.Message) + } }) }, } diff --git a/cmd/argocd/commands/admin/settings_test.go b/cmd/argocd/commands/admin/settings_test.go index adb18c80ee84e..ff817017f4be5 100644 --- a/cmd/argocd/commands/admin/settings_test.go +++ b/cmd/argocd/commands/admin/settings_test.go @@ -226,6 +226,18 @@ spec: replicas: 0` ) +const ( + testCustomResourceYAML = `apiVersion: v1 +apiVersion: example.com/v1alpha1 +kind: ExampleResource +metadata: + name: example-resource + labels: + app: example +spec: + replicas: 0` +) + const ( testCronJobYAML = `apiVersion: batch/v1 kind: CronJob @@ -285,7 +297,7 @@ func TestResourceOverrideIgnoreDifferences(t *testing.T) { assert.NoError(t, err) }) assert.NoError(t, err) - assert.Contains(t, out, "No overrides configured") + assert.Contains(t, out, "Ignore differences are not configured for 'apps/Deployment'\n") }) t.Run("DataIgnored", func(t *testing.T) { @@ -305,7 +317,7 @@ func TestResourceOverrideIgnoreDifferences(t *testing.T) { } func TestResourceOverrideHealth(t *testing.T) { - f, closer, err := tempFile(testDeploymentYAML) + f, closer, err := tempFile(testCustomResourceYAML) if !assert.NoError(t, err) { return } @@ -313,19 +325,34 @@ func TestResourceOverrideHealth(t *testing.T) { t.Run("NoHealthAssessment", func(t *testing.T) { cmd := NewResourceOverridesCommand(newCmdContext(map[string]string{ - "resource.customizations": `apps/Deployment: {}`})) + "resource.customizations": `example.com/ExampleResource: {}`})) out, err := captureStdout(func() { cmd.SetArgs([]string{"health", f}) err := cmd.Execute() assert.NoError(t, err) }) assert.NoError(t, err) - assert.Contains(t, out, "Health script is not configured") + assert.Contains(t, out, "Health script is not configured for 'example.com/ExampleResource'\n") }) t.Run("HealthAssessmentConfigured", func(t *testing.T) { cmd := NewResourceOverridesCommand(newCmdContext(map[string]string{ - "resource.customizations": `apps/Deployment: + "resource.customizations": `example.com/ExampleResource: + health.lua: | + return { status = "Progressing" } +`})) + out, err := captureStdout(func() { + cmd.SetArgs([]string{"health", f}) + err := cmd.Execute() + assert.NoError(t, err) + }) + assert.NoError(t, err) + assert.Contains(t, out, "Progressing") + }) + + t.Run("HealthAssessmentConfiguredWildcard", func(t *testing.T) { + cmd := NewResourceOverridesCommand(newCmdContext(map[string]string{ + "resource.customizations": `example.com/*: health.lua: | return { status = "Progressing" } `})) @@ -412,7 +439,7 @@ resume false action.lua: | job1 = {} job1.apiVersion = "batch/v1" - job1.kind = "Job" + job1.kind = "Job" job1.metadata = {} job1.metadata.name = "hello-1" job1.metadata.namespace = "obj.metadata.namespace" From a7d0da941cc9d92f3aef19acc0c898a43fee3b16 Mon Sep 17 00:00:00 2001 From: Matthew Hughes <34972397+matthewhughes934@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:03:33 +0000 Subject: [PATCH 157/269] Add meta.Duration as known type for diffing (#16587) So that this can be used for custom resources. The motivation for this is issue #6008: with this change one should be able to use the known type to ensure equal durations don't present a diff, e,g. via adding to `argocd-cm`: data: resource.customizations.knownTypeFields.cert-manager.io_Certificate: | - field: spec.duration type: meta/v1/Duration This change is based on 5b464c996bd5ebc1d39bb013af3bed34415d77d2, though I've included the API version in the type path to be consistent with the generated type (i.e. `meta/v1/Duration` and not `meta/Duration`). For documentation I've just manually listed the extra types that aren't auto-generated, though this requires having to keep this list and the code in-sync but this is probably not a big issue since the number of extra types is not frequently changed. In the tests I've used `require.*` methods since I find this simpler than `if !assert.Blah(...) { return }` which the other tests in this file are using. Signed-off-by: Matthew Hughes --- docs/user-guide/diffing.md | 5 +++- .../argo/normalizers/knowntypes_normalizer.go | 4 +++ .../normalizers/knowntypes_normalizer_test.go | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/user-guide/diffing.md b/docs/user-guide/diffing.md index 5a056b9c3769b..61f799e514d6a 100644 --- a/docs/user-guide/diffing.md +++ b/docs/user-guide/diffing.md @@ -181,4 +181,7 @@ data: type: core/v1/PodSpec ``` -The list of supported Kubernetes types is available in [diffing_known_types.txt](https://raw.githubusercontent.com/argoproj/argo-cd/master/util/argo/normalizers/diffing_known_types.txt) +The list of supported Kubernetes types is available in [diffing_known_types.txt](https://raw.githubusercontent.com/argoproj/argo-cd/master/util/argo/normalizers/diffing_known_types.txt) and additionally: + +* `core/Quantity` +* `meta/v1/duration` diff --git a/util/argo/normalizers/knowntypes_normalizer.go b/util/argo/normalizers/knowntypes_normalizer.go index 403065c58a6df..f96a366a75d6a 100644 --- a/util/argo/normalizers/knowntypes_normalizer.go +++ b/util/argo/normalizers/knowntypes_normalizer.go @@ -8,6 +8,7 @@ import ( log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -32,6 +33,9 @@ func init() { knownTypes["core/Quantity"] = func() interface{} { return &resource.Quantity{} } + knownTypes["meta/v1/Duration"] = func() interface{} { + return &metav1.Duration{} + } } // NewKnownTypesNormalizer create a normalizer that re-format custom resource fields using built-in Kubernetes types. diff --git a/util/argo/normalizers/knowntypes_normalizer_test.go b/util/argo/normalizers/knowntypes_normalizer_test.go index 57e436195f890..37c34d37509b3 100644 --- a/util/argo/normalizers/knowntypes_normalizer_test.go +++ b/util/argo/normalizers/knowntypes_normalizer_test.go @@ -11,6 +11,7 @@ import ( "github.com/argoproj/pkg/errors" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/yaml" @@ -228,6 +229,33 @@ spec: assert.Equal(t, "1250M", ram) } +func TestNormalize_Duration(t *testing.T) { + cert := mustUnmarshalYAML(` +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: my-cert +spec: + duration: 8760h +`) + normalizer, err := NewKnownTypesNormalizer(map[string]v1alpha1.ResourceOverride{ + "cert-manager.io/Certificate": { + KnownTypeFields: []v1alpha1.KnownTypeField{{ + Type: "meta/v1/Duration", + Field: "spec.duration", + }}, + }, + }) + require.NoError(t, err) + + require.NoError(t, normalizer.Normalize(cert)) + + duration, ok, err := unstructured.NestedFieldNoCopy(cert.Object, "spec", "duration") + require.NoError(t, err) + require.True(t, ok) + require.Equal(t, "8760h0m0s", duration) +} + func TestFieldDoesNotExist(t *testing.T) { rollout := mustUnmarshalYAML(someCRDYaml) normalizer, err := NewKnownTypesNormalizer(map[string]v1alpha1.ResourceOverride{ From a6d8a01c0725dad431a69d28671d8f7ce41d4404 Mon Sep 17 00:00:00 2001 From: afrancis101 <64639952+afrancis101@users.noreply.github.com> Date: Thu, 14 Dec 2023 16:49:18 +0000 Subject: [PATCH 158/269] fix(action): Add missing owner refs and annotation to create-job action (#16607) Signed-off-by: Arron Francis --- .../batch/CronJob/actions/create-job/action.lua | 6 ++++++ .../batch/CronJob/actions/testdata/job.yaml | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/resource_customizations/batch/CronJob/actions/create-job/action.lua b/resource_customizations/batch/CronJob/actions/create-job/action.lua index 8753144d404e7..a6f3253a5b757 100644 --- a/resource_customizations/batch/CronJob/actions/create-job/action.lua +++ b/resource_customizations/batch/CronJob/actions/create-job/action.lua @@ -38,12 +38,18 @@ if job.metadata == nil then end job.metadata.name = obj.metadata.name .. "-" ..os.date("!%Y%m%d%H%M") job.metadata.namespace = obj.metadata.namespace +if job.metadata.annotations == nil then + job.metadata.annotations = {} +end +job.metadata.annotations['cronjob.kubernetes.io/instantiate'] = "manual" local ownerRef = {} ownerRef.apiVersion = obj.apiVersion ownerRef.kind = obj.kind ownerRef.name = obj.metadata.name ownerRef.uid = obj.metadata.uid +ownerRef.blockOwnerDeletion = true +ownerRef.controller = true job.metadata.ownerReferences = {} job.metadata.ownerReferences[1] = ownerRef diff --git a/resource_customizations/batch/CronJob/actions/testdata/job.yaml b/resource_customizations/batch/CronJob/actions/testdata/job.yaml index 1ef281afdcdb4..322ab0480beb5 100644 --- a/resource_customizations/batch/CronJob/actions/testdata/job.yaml +++ b/resource_customizations/batch/CronJob/actions/testdata/job.yaml @@ -8,6 +8,7 @@ labels: my: label annotations: + cronjob.kubernetes.io/instantiate: manual my: annotation spec: ttlSecondsAfterFinished: 100 @@ -26,4 +27,4 @@ - /bin/sh - -c - date; echo Hello from the Kubernetes cluster - restartPolicy: OnFailure \ No newline at end of file + restartPolicy: OnFailure From 2f22a690e706c7c7746d6569d22aa345f7005362 Mon Sep 17 00:00:00 2001 From: Dennis Pan Date: Thu, 14 Dec 2023 23:48:26 -0800 Subject: [PATCH 159/269] docs: callout the need to restart pods to pickup service accounts (#16610) Signed-off-by: Dennis Pan --- docs/operator-manual/declarative-setup.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index ee216a7118f7f..c1f5ba2b2d3bd 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -676,8 +676,10 @@ extended to allow assumption of multiple roles, either as an explicit array of r } ``` -Example service account configs for `argocd-application-controller` and `argocd-server`. Note that once the annotations -have been set on the service accounts, both the application controller and server pods need to be restarted. +Example service account configs for `argocd-application-controller` and `argocd-server`. + +!!! warning + Once the annotations have been set on the service accounts, both the application controller and server pods need to be restarted. ```yaml apiVersion: v1 From bdf2c6a18c6572c0aa024e36d592b925f9836467 Mon Sep 17 00:00:00 2001 From: Robin Lieb Date: Fri, 15 Dec 2023 18:44:14 +0100 Subject: [PATCH 160/269] docs: update telepresence quickstart link (#16616) Signed-off-by: Robin Lieb --- docs/developer-guide/debugging-remote-environment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-guide/debugging-remote-environment.md b/docs/developer-guide/debugging-remote-environment.md index 7f8102a75c502..5548d3444af8c 100644 --- a/docs/developer-guide/debugging-remote-environment.md +++ b/docs/developer-guide/debugging-remote-environment.md @@ -45,7 +45,7 @@ And uninstall telepresence from your cluster: telepresence helm uninstall ``` -See [this quickstart](https://www.telepresence.io/docs/latest/howtos/intercepts/) for more information on how to intercept services using Telepresence. +See [this quickstart](https://www.telepresence.io/docs/latest/quick-start/) for more information on how to intercept services using Telepresence. ### Connect (telepresence v1) Use the following command instead: From 0b35e2f1fe27f395e6106a7466d58911c4f7ec9c Mon Sep 17 00:00:00 2001 From: morre Date: Fri, 15 Dec 2023 18:51:42 +0100 Subject: [PATCH 161/269] docs: add documentation for the argocd cluster commands (#16555) * docs: add documentation for the argocd cluster commands This adds initial non-reference documentation for the `argocd cluster` commands as part of #14531. The main goal here is to bootstrap that page and point users wanting to remove the `in-cluster` cluster to the right setting. Signed-off-by: Maurice Meyer * fixup! docs: add documentation for the argocd cluster commands Signed-off-by: Morre * fixup! docs: add documentation for the argocd cluster commands Signed-off-by: Maurice Meyer --------- Signed-off-by: Maurice Meyer Signed-off-by: Morre --- docs/operator-manual/cluster-management.md | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 docs/operator-manual/cluster-management.md diff --git a/docs/operator-manual/cluster-management.md b/docs/operator-manual/cluster-management.md new file mode 100644 index 0000000000000..bd0d28e08dba7 --- /dev/null +++ b/docs/operator-manual/cluster-management.md @@ -0,0 +1,23 @@ +# Cluster Management + +This guide is for operators looking to manage clusters on the CLI. If you want to use Kubernetes resources for this, check out [Declarative Setup](./declarative-setup.md#clusters). + +Not all commands are described here, see the [argocd cluster Command Reference](../user-guide/commands/argocd_cluster.md) for all available commands. + +## Adding a cluster + +Run `argocd cluster add context-name`. + +If you're unsure about the context names, run `kubectl config get-contexts` to get them all listed. + +This will connect to the cluster and install the necessary resources for ArgoCD to connect to it. +Note that you will need privileged access to the cluster. + +## Removing a cluster + +Run `argocd cluster rm context-name`. + +This removes the cluster with the specified name. + +!!!note "in-cluster cannot be removed" + The `in-cluster` cluster cannot be removed with this. If you want to disable the `in-cluster` configuration, you need to update your `argocd-cm` ConfigMap. Set [`cluster.inClusterEnabled`](./argocd-cm-yaml.md) to `"false"` From c5d5cdb31a4b5df312dd4e21aa20fdf26ccf2168 Mon Sep 17 00:00:00 2001 From: Sam Greening <2552620+SG60@users.noreply.github.com> Date: Sun, 17 Dec 2023 18:07:25 +0000 Subject: [PATCH 162/269] fix(appset): Use case insensitive comparison of repo details in appset webhook handler (#16503) (#16504) * fix: case insensitive comparison of repo details in appset webhook handler Signed-off-by: Sam Greening <2552620+SG60@users.noreply.github.com> * chore(appset test): test case-insensitivity of appset github webhooks Signed-off-by: Sam Greening <2552620+SG60@users.noreply.github.com> * chore(appset test): test case for PR labeled event And fix a couple of spelling errors Signed-off-by: Sam Greening <2552620+SG60@users.noreply.github.com> --------- Signed-off-by: Sam Greening <2552620+SG60@users.noreply.github.com> Co-authored-by: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> --- .../github-pull-request-labeled-event.json | 473 ++++++++++++++++++ applicationset/webhook/webhook.go | 6 +- applicationset/webhook/webhook_test.go | 17 +- 3 files changed, 490 insertions(+), 6 deletions(-) create mode 100644 applicationset/webhook/testdata/github-pull-request-labeled-event.json diff --git a/applicationset/webhook/testdata/github-pull-request-labeled-event.json b/applicationset/webhook/testdata/github-pull-request-labeled-event.json new file mode 100644 index 0000000000000..f912a2fdb4a97 --- /dev/null +++ b/applicationset/webhook/testdata/github-pull-request-labeled-event.json @@ -0,0 +1,473 @@ +{ + "action": "labeled", + "number": 2, + "label": { + "id": 6129306173, + "node_id": "LA_kwDOIqudU88AAAABbVXKPQ", + "url": "https://api.github.com/repos/SG60/backstage/labels/deploy-preview", + "name": "deploy-preview", + "color": "bfd4f2", + "default": false, + "description": "" + }, + "pull_request": { + "url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2", + "id": 279147437, + "node_id": "MDExOlB1bGxSZXF1ZXN0Mjc5MTQ3NDM3", + "html_url": "https://github.com/Codertocat/Hello-World/pull/2", + "diff_url": "https://github.com/Codertocat/Hello-World/pull/2.diff", + "patch_url": "https://github.com/Codertocat/Hello-World/pull/2.patch", + "issue_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/2", + "number": 2, + "state": "open", + "locked": false, + "title": "Update the README with new information.", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "body": "This is a pretty simple change that we need to pull into master.", + "created_at": "2019-05-15T15:20:33Z", + "updated_at": "2019-05-15T15:20:33Z", + "closed_at": null, + "merged_at": null, + "merge_commit_sha": null, + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [ + { + "id": 6129306173, + "node_id": "LA_kwDOIqudU88AAAABbVXKPQ", + "url": "https://api.github.com/repos/Codertocat/Hello-World/labels/deploy-preview", + "name": "deploy-preview", + "color": "bfd4f2", + "default": false, + "description": "" + } + ], + "milestone": null, + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/commits", + "review_comments_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/comments", + "review_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/2/comments", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/ec26c3e57ca3a959ca5aad62de7213c562f8c821", + "head": { + "label": "Codertocat:changes", + "ref": "changes", + "sha": "ec26c3e57ca3a959ca5aad62de7213c562f8c821", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 186853002, + "node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "private": false, + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2019-05-15T15:19:25Z", + "updated_at": "2019-05-15T15:19:27Z", + "pushed_at": "2019-05-15T15:20:32Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": null, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "delete_branch_on_merge": false + } + }, + "base": { + "label": "Codertocat:master", + "ref": "master", + "sha": "f95f852bd8fca8fcc58a9a2d6c842781e32a215e", + "user": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "repo": { + "id": 186853002, + "node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "private": false, + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2019-05-15T15:19:25Z", + "updated_at": "2019-05-15T15:19:27Z", + "pushed_at": "2019-05-15T15:20:32Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": null, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master", + "allow_squash_merge": true, + "allow_merge_commit": true, + "allow_rebase_merge": true, + "delete_branch_on_merge": false + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2" + }, + "html": { + "href": "https://github.com/Codertocat/Hello-World/pull/2" + }, + "issue": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/2" + }, + "comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/issues/2/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/pulls/2/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/Codertocat/Hello-World/statuses/ec26c3e57ca3a959ca5aad62de7213c562f8c821" + } + }, + "author_association": "OWNER", + "draft": false, + "merged": false, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": null, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 1, + "additions": 1, + "deletions": 1, + "changed_files": 1 + }, + "repository": { + "id": 186853002, + "node_id": "MDEwOlJlcG9zaXRvcnkxODY4NTMwMDI=", + "name": "Hello-World", + "full_name": "Codertocat/Hello-World", + "private": false, + "owner": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + }, + "html_url": "https://github.com/Codertocat/Hello-World", + "description": null, + "fork": false, + "url": "https://api.github.com/repos/Codertocat/Hello-World", + "forks_url": "https://api.github.com/repos/Codertocat/Hello-World/forks", + "keys_url": "https://api.github.com/repos/Codertocat/Hello-World/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/Codertocat/Hello-World/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/Codertocat/Hello-World/teams", + "hooks_url": "https://api.github.com/repos/Codertocat/Hello-World/hooks", + "issue_events_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/events{/number}", + "events_url": "https://api.github.com/repos/Codertocat/Hello-World/events", + "assignees_url": "https://api.github.com/repos/Codertocat/Hello-World/assignees{/user}", + "branches_url": "https://api.github.com/repos/Codertocat/Hello-World/branches{/branch}", + "tags_url": "https://api.github.com/repos/Codertocat/Hello-World/tags", + "blobs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/Codertocat/Hello-World/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/Codertocat/Hello-World/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/Codertocat/Hello-World/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/Codertocat/Hello-World/statuses/{sha}", + "languages_url": "https://api.github.com/repos/Codertocat/Hello-World/languages", + "stargazers_url": "https://api.github.com/repos/Codertocat/Hello-World/stargazers", + "contributors_url": "https://api.github.com/repos/Codertocat/Hello-World/contributors", + "subscribers_url": "https://api.github.com/repos/Codertocat/Hello-World/subscribers", + "subscription_url": "https://api.github.com/repos/Codertocat/Hello-World/subscription", + "commits_url": "https://api.github.com/repos/Codertocat/Hello-World/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/Codertocat/Hello-World/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/Codertocat/Hello-World/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/Codertocat/Hello-World/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/Codertocat/Hello-World/contents/{+path}", + "compare_url": "https://api.github.com/repos/Codertocat/Hello-World/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/Codertocat/Hello-World/merges", + "archive_url": "https://api.github.com/repos/Codertocat/Hello-World/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/Codertocat/Hello-World/downloads", + "issues_url": "https://api.github.com/repos/Codertocat/Hello-World/issues{/number}", + "pulls_url": "https://api.github.com/repos/Codertocat/Hello-World/pulls{/number}", + "milestones_url": "https://api.github.com/repos/Codertocat/Hello-World/milestones{/number}", + "notifications_url": "https://api.github.com/repos/Codertocat/Hello-World/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/Codertocat/Hello-World/labels{/name}", + "releases_url": "https://api.github.com/repos/Codertocat/Hello-World/releases{/id}", + "deployments_url": "https://api.github.com/repos/Codertocat/Hello-World/deployments", + "created_at": "2019-05-15T15:19:25Z", + "updated_at": "2019-05-15T15:19:27Z", + "pushed_at": "2019-05-15T15:20:32Z", + "git_url": "git://github.com/Codertocat/Hello-World.git", + "ssh_url": "git@github.com:Codertocat/Hello-World.git", + "clone_url": "https://github.com/Codertocat/Hello-World.git", + "svn_url": "https://github.com/Codertocat/Hello-World", + "homepage": null, + "size": 0, + "stargazers_count": 0, + "watchers_count": 0, + "language": null, + "has_issues": true, + "has_projects": true, + "has_downloads": true, + "has_wiki": true, + "has_pages": true, + "forks_count": 0, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 2, + "license": null, + "forks": 0, + "open_issues": 2, + "watchers": 0, + "default_branch": "master" + }, + "sender": { + "login": "Codertocat", + "id": 21031067, + "node_id": "MDQ6VXNlcjIxMDMxMDY3", + "avatar_url": "https://avatars1.githubusercontent.com/u/21031067?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/Codertocat", + "html_url": "https://github.com/Codertocat", + "followers_url": "https://api.github.com/users/Codertocat/followers", + "following_url": "https://api.github.com/users/Codertocat/following{/other_user}", + "gists_url": "https://api.github.com/users/Codertocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/Codertocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/Codertocat/subscriptions", + "organizations_url": "https://api.github.com/users/Codertocat/orgs", + "repos_url": "https://api.github.com/users/Codertocat/repos", + "events_url": "https://api.github.com/users/Codertocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/Codertocat/received_events", + "type": "User", + "site_admin": false + } +} diff --git a/applicationset/webhook/webhook.go b/applicationset/webhook/webhook.go index ce099df35ea35..d55e63e064f5a 100644 --- a/applicationset/webhook/webhook.go +++ b/applicationset/webhook/webhook.go @@ -412,10 +412,12 @@ func shouldRefreshPRGenerator(gen *v1alpha1.PullRequestGenerator, info *prGenera } if gen.Github != nil && info.Github != nil { - if gen.Github.Owner != info.Github.Owner { + // repository owner and name are case-insensitive + // See https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-pull-requests + if !strings.EqualFold(gen.Github.Owner, info.Github.Owner) { return false } - if gen.Github.Repo != info.Github.Repo { + if !strings.EqualFold(gen.Github.Repo, info.Github.Repo) { return false } api := gen.Github.API diff --git a/applicationset/webhook/webhook_test.go b/applicationset/webhook/webhook_test.go index 349d275948aee..d22b1a07ca6f2 100644 --- a/applicationset/webhook/webhook_test.go +++ b/applicationset/webhook/webhook_test.go @@ -111,7 +111,7 @@ func TestWebhookHandler(t *testing.T) { expectedRefresh: false, }, { - desc: "WebHook from a GitHub repository via pull_reqeuest opened event", + desc: "WebHook from a GitHub repository via pull_request opened event", headerKey: "X-GitHub-Event", headerValue: "pull_request", payloadFile: "github-pull-request-opened-event.json", @@ -120,7 +120,7 @@ func TestWebhookHandler(t *testing.T) { expectedRefresh: true, }, { - desc: "WebHook from a GitHub repository via pull_reqeuest assigned event", + desc: "WebHook from a GitHub repository via pull_request assigned event", headerKey: "X-GitHub-Event", headerValue: "pull_request", payloadFile: "github-pull-request-assigned-event.json", @@ -128,6 +128,15 @@ func TestWebhookHandler(t *testing.T) { expectedStatusCode: http.StatusOK, expectedRefresh: false, }, + { + desc: "WebHook from a GitHub repository via pull_request labeled event", + headerKey: "X-GitHub-Event", + headerValue: "pull_request", + payloadFile: "github-pull-request-labeled-event.json", + effectedAppSets: []string{"pull-request-github", "matrix-pull-request-github", "matrix-scm-pull-request-github", "merge-pull-request-github", "plugin", "matrix-pull-request-github-plugin"}, + expectedStatusCode: http.StatusOK, + expectedRefresh: true, + }, { desc: "WebHook from a GitLab repository via open merge request event", headerKey: "X-Gitlab-Event", @@ -180,7 +189,7 @@ func TestWebhookHandler(t *testing.T) { fakeAppWithGitGenerator("git-github", namespace, "https://github.com/org/repo"), fakeAppWithGitGenerator("git-gitlab", namespace, "https://gitlab/group/name"), fakeAppWithGitGenerator("git-azure-devops", namespace, "https://dev.azure.com/fabrikam-fiber-inc/DefaultCollection/_git/Fabrikam-Fiber-Git"), - fakeAppWithGithubPullRequestGenerator("pull-request-github", namespace, "Codertocat", "Hello-World"), + fakeAppWithGithubPullRequestGenerator("pull-request-github", namespace, "CodErTOcat", "Hello-World"), fakeAppWithGitlabPullRequestGenerator("pull-request-gitlab", namespace, "100500"), fakeAppWithAzureDevOpsPullRequestGenerator("pull-request-azure-devops", namespace, "DefaultCollection", "Fabrikam"), fakeAppWithPluginGenerator("plugin", namespace), @@ -189,7 +198,7 @@ func TestWebhookHandler(t *testing.T) { fakeAppWithMatrixAndScmWithGitGenerator("matrix-scm-git-github", namespace, "org"), fakeAppWithMatrixAndScmWithPullRequestGenerator("matrix-scm-pull-request-github", namespace, "Codertocat"), fakeAppWithMatrixAndNestedGitGenerator("matrix-nested-git-github", namespace, "https://github.com/org/repo"), - fakeAppWithMatrixAndPullRequestGeneratorWithPluginGenerator("matrix-pull-request-github-plugin", namespace, "Codertocat", "Hello-World", "plugin-cm"), + fakeAppWithMatrixAndPullRequestGeneratorWithPluginGenerator("matrix-pull-request-github-plugin", namespace, "coDErtoCat", "HeLLO-WorLD", "plugin-cm"), fakeAppWithMergeAndGitGenerator("merge-git-github", namespace, "https://github.com/org/repo"), fakeAppWithMergeAndPullRequestGenerator("merge-pull-request-github", namespace, "Codertocat", "Hello-World"), fakeAppWithMergeAndNestedGitGenerator("merge-nested-git-github", namespace, "https://github.com/org/repo"), From 23e0d527e17f21b78c50765bed5e37f7e4c54597 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Mon, 18 Dec 2023 09:41:32 -0500 Subject: [PATCH 163/269] feat(security): log user when access is blocked (#16558) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- server/application/application.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/server/application/application.go b/server/application/application.go index 23d4d79a767cf..8ee16b93494c8 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -152,7 +152,12 @@ func NewServer( // If the user does provide a "project," we can respond more specifically. If the user does not have access to the given // app name in the given project, we return "permission denied." If the app exists, but the project is different from func (s *Server) getAppEnforceRBAC(ctx context.Context, action, project, namespace, name string, getApp func() (*appv1.Application, error)) (*appv1.Application, error) { + user := session.Username(ctx) + if user == "" { + user = "Unknown user" + } logCtx := log.WithFields(map[string]interface{}{ + "user": user, "application": name, "namespace": namespace, }) From dcc17f70bf7db973fe480b8b613189b2c5ac4b4b Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Mon, 18 Dec 2023 08:40:23 -0800 Subject: [PATCH 164/269] feat: PostDelete hook support (#16595) * feat: PostDelete hooks support Signed-off-by: Alexander Matyushentsev --------- Signed-off-by: Alexander Matyushentsev --- controller/appcontroller.go | 150 +++++++++----- controller/appcontroller_test.go | 183 +++++++++++++++++- controller/hook.go | 158 +++++++++++++++ controller/state.go | 23 ++- controller/sync.go | 1 + docs/user-guide/helm.md | 4 +- docs/user-guide/resource_hooks.md | 2 + .../v1alpha1/application_defaults.go | 3 + pkg/apis/application/v1alpha1/types.go | 12 ++ test/e2e/hook_test.go | 20 ++ test/e2e/testdata/post-delete-hook/hook.yaml | 14 ++ 11 files changed, 501 insertions(+), 69 deletions(-) create mode 100644 controller/hook.go create mode 100644 test/e2e/testdata/post-delete-hook/hook.yaml diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 964bcc1aa0dec..b98334b8fa567 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -15,7 +15,6 @@ import ( "sync" "time" - "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" clustercache "github.com/argoproj/gitops-engine/pkg/cache" "github.com/argoproj/gitops-engine/pkg/diff" "github.com/argoproj/gitops-engine/pkg/health" @@ -59,6 +58,7 @@ import ( kubeerrors "k8s.io/apimachinery/pkg/api/errors" + "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" "github.com/argoproj/argo-cd/v2/util/db" "github.com/argoproj/argo-cd/v2/util/errors" @@ -884,11 +884,10 @@ func (ctrl *ApplicationController) processAppOperationQueueItem() (processNext b if app.Operation != nil { ctrl.processRequestedAppOperation(app) - } else if app.DeletionTimestamp != nil && app.CascadedDeletion() { - _, err = ctrl.finalizeApplicationDeletion(app, func(project string) ([]*appv1.Cluster, error) { + } else if app.DeletionTimestamp != nil { + if err = ctrl.finalizeApplicationDeletion(app, func(project string) ([]*appv1.Cluster, error) { return ctrl.db.GetProjectClusters(context.Background(), project) - }) - if err != nil { + }); err != nil { ctrl.setAppCondition(app, appv1.ApplicationCondition{ Type: appv1.ApplicationConditionDeletionError, Message: err.Error(), @@ -1023,57 +1022,63 @@ func (ctrl *ApplicationController) getPermittedAppLiveObjects(app *appv1.Applica return objsMap, nil } -func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Application, projectClusters func(project string) ([]*appv1.Cluster, error)) ([]*unstructured.Unstructured, error) { +func (ctrl *ApplicationController) isValidDestination(app *appv1.Application) (bool, *argov1alpha.Cluster) { + // Validate the cluster using the Application destination's `name` field, if applicable, + // and set the Server field, if needed. + if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { + log.Warnf("Unable to validate destination of the Application being deleted: %v", err) + return false, nil + } + + cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server) + if err != nil { + log.Warnf("Unable to locate cluster URL for Application being deleted: %v", err) + return false, nil + } + return true, cluster +} + +func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Application, projectClusters func(project string) ([]*appv1.Cluster, error)) error { logCtx := log.WithField("application", app.QualifiedName()) - logCtx.Infof("Deleting resources") // Get refreshed application info, since informer app copy might be stale app, err := ctrl.applicationClientset.ArgoprojV1alpha1().Applications(app.Namespace).Get(context.Background(), app.Name, metav1.GetOptions{}) if err != nil { if !apierr.IsNotFound(err) { logCtx.Errorf("Unable to get refreshed application info prior deleting resources: %v", err) } - return nil, nil + return nil } proj, err := ctrl.getAppProj(app) if err != nil { - return nil, err + return err } - // validDestination is true if the Application destination points to a cluster that is managed by Argo CD - // (and thus either a cluster secret exists for it, or it's local); validDestination is false otherwise. - validDestination := true - - // Validate the cluster using the Application destination's `name` field, if applicable, - // and set the Server field, if needed. - if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { - log.Warnf("Unable to validate destination of the Application being deleted: %v", err) - validDestination = false - } - - objs := make([]*unstructured.Unstructured, 0) - var cluster *appv1.Cluster - - // Attempt to validate the destination via its URL - if validDestination { - if cluster, err = ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server); err != nil { - log.Warnf("Unable to locate cluster URL for Application being deleted: %v", err) - validDestination = false + isValid, cluster := ctrl.isValidDestination(app) + if !isValid { + app.UnSetCascadedDeletion() + app.UnSetPostDeleteFinalizer() + if err := ctrl.updateFinalizers(app); err != nil { + return err } + logCtx.Infof("Resource entries removed from undefined cluster") + return nil } + config := metrics.AddMetricsTransportWrapper(ctrl.metricsServer, app, cluster.RESTConfig()) - if validDestination { + if app.CascadedDeletion() { + logCtx.Infof("Deleting resources") // ApplicationDestination points to a valid cluster, so we may clean up the live objects - + objs := make([]*unstructured.Unstructured, 0) objsMap, err := ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) if err != nil { - return nil, err + return err } for k := range objsMap { // Wait for objects pending deletion to complete before proceeding with next sync wave if objsMap[k].GetDeletionTimestamp() != nil { logCtx.Infof("%d objects remaining for deletion", len(objsMap)) - return objs, nil + return nil } if ctrl.shouldBeDeleted(app, objsMap[k]) { @@ -1081,8 +1086,6 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic } } - config := metrics.AddMetricsTransportWrapper(ctrl.metricsServer, app, cluster.RESTConfig()) - filteredObjs := FilterObjectsForDeletion(objs) propagationPolicy := metav1.DeletePropagationForeground @@ -1096,12 +1099,12 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic return ctrl.kubectl.DeleteResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), metav1.DeleteOptions{PropagationPolicy: &propagationPolicy}) }) if err != nil { - return objs, err + return err } objsMap, err = ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) if err != nil { - return nil, err + return err } for k, obj := range objsMap { @@ -1111,38 +1114,67 @@ func (ctrl *ApplicationController) finalizeApplicationDeletion(app *appv1.Applic } if len(objsMap) > 0 { logCtx.Infof("%d objects remaining for deletion", len(objsMap)) - return objs, nil + return nil } + logCtx.Infof("Successfully deleted %d resources", len(objs)) + app.UnSetCascadedDeletion() + return ctrl.updateFinalizers(app) } - if err := ctrl.cache.SetAppManagedResources(app.Name, nil); err != nil { - return objs, err - } + if app.HasPostDeleteFinalizer() { + objsMap, err := ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) + if err != nil { + return err + } - if err := ctrl.cache.SetAppResourcesTree(app.Name, nil); err != nil { - return objs, err + done, err := ctrl.executePostDeleteHooks(app, proj, objsMap, config, logCtx) + if err != nil { + return err + } + if !done { + return nil + } + app.UnSetPostDeleteFinalizer() + return ctrl.updateFinalizers(app) } - if err := ctrl.removeCascadeFinalizer(app); err != nil { - return objs, err + if app.HasPostDeleteFinalizer("cleanup") { + objsMap, err := ctrl.getPermittedAppLiveObjects(app, proj, projectClusters) + if err != nil { + return err + } + + done, err := ctrl.cleanupPostDeleteHooks(objsMap, config, logCtx) + if err != nil { + return err + } + if !done { + return nil + } + app.UnSetPostDeleteFinalizer("cleanup") + return ctrl.updateFinalizers(app) } - if validDestination { - logCtx.Infof("Successfully deleted %d resources", len(objs)) - } else { - logCtx.Infof("Resource entries removed from undefined cluster") + if !app.CascadedDeletion() && !app.HasPostDeleteFinalizer() { + if err := ctrl.cache.SetAppManagedResources(app.Name, nil); err != nil { + return err + } + + if err := ctrl.cache.SetAppResourcesTree(app.Name, nil); err != nil { + return err + } + ctrl.projectRefreshQueue.Add(fmt.Sprintf("%s/%s", ctrl.namespace, app.Spec.GetProject())) } - ctrl.projectRefreshQueue.Add(fmt.Sprintf("%s/%s", ctrl.namespace, app.Spec.GetProject())) - return objs, nil + return nil } -func (ctrl *ApplicationController) removeCascadeFinalizer(app *appv1.Application) error { +func (ctrl *ApplicationController) updateFinalizers(app *appv1.Application) error { _, err := ctrl.getAppProj(app) if err != nil { return fmt.Errorf("error getting project: %w", err) } - app.UnSetCascadedDeletion() + var patch []byte patch, _ = json.Marshal(map[string]interface{}{ "metadata": map[string]interface{}{ @@ -1566,6 +1598,20 @@ func (ctrl *ApplicationController) processAppRefreshQueueItem() (processNext boo app.Status.SourceTypes = compareResult.appSourceTypes app.Status.ControllerNamespace = ctrl.namespace patchMs = ctrl.persistAppStatus(origApp, &app.Status) + if (compareResult.hasPostDeleteHooks != app.HasPostDeleteFinalizer() || compareResult.hasPostDeleteHooks != app.HasPostDeleteFinalizer("cleanup")) && + app.GetDeletionTimestamp() == nil { + if compareResult.hasPostDeleteHooks { + app.SetPostDeleteFinalizer() + app.SetPostDeleteFinalizer("cleanup") + } else { + app.UnSetPostDeleteFinalizer() + app.UnSetPostDeleteFinalizer("cleanup") + } + + if err := ctrl.updateFinalizers(app); err != nil { + logCtx.Errorf("Failed to update finalizers: %v", err) + } + } return } diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 9c2933feeb6df..2efc7ac723bc7 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -7,8 +7,11 @@ import ( "testing" "time" + "github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest" "github.com/sirupsen/logrus" + "github.com/stretchr/testify/require" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/client-go/rest" clustercache "github.com/argoproj/gitops-engine/pkg/cache" @@ -18,7 +21,6 @@ import ( "github.com/argoproj/gitops-engine/pkg/cache/mocks" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" - "github.com/argoproj/gitops-engine/pkg/utils/kube/kubetest" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" corev1 "k8s.io/api/core/v1" @@ -59,6 +61,23 @@ type fakeData struct { applicationNamespaces []string } +type MockKubectl struct { + kube.Kubectl + + DeletedResources []kube.ResourceKey + CreatedResources []*unstructured.Unstructured +} + +func (m *MockKubectl) CreateResource(ctx context.Context, config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, obj *unstructured.Unstructured, createOptions metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error) { + m.CreatedResources = append(m.CreatedResources, obj) + return m.Kubectl.CreateResource(ctx, config, gvk, name, namespace, obj, createOptions, subresources...) +} + +func (m *MockKubectl) DeleteResource(ctx context.Context, config *rest.Config, gvk schema.GroupVersionKind, name string, namespace string, deleteOptions metav1.DeleteOptions) error { + m.DeletedResources = append(m.DeletedResources, kube.NewResourceKey(gvk.Group, gvk.Kind, namespace, name)) + return m.Kubectl.DeleteResource(ctx, config, gvk, name, namespace, deleteOptions) +} + func newFakeController(data *fakeData, repoErr error) *ApplicationController { var clust corev1.Secret err := yaml.Unmarshal([]byte(fakeCluster), &clust) @@ -109,7 +128,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { } kubeClient := fake.NewSimpleClientset(&clust, &cm, &secret) settingsMgr := settings.NewSettingsManager(context.Background(), kubeClient, test.FakeArgoCDNamespace) - kubectl := &kubetest.MockKubectlCmd{} + kubectl := &MockKubectl{Kubectl: &kubetest.MockKubectlCmd{}} ctrl, err := NewApplicationController( test.FakeArgoCDNamespace, settingsMgr, @@ -337,6 +356,38 @@ metadata: data: ` +var fakePostDeleteHook = ` +{ + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "post-delete-hook", + "namespace": "default", + "labels": { + "app.kubernetes.io/instance": "my-app" + }, + "annotations": { + "argocd.argoproj.io/hook": "PostDelete", + "argocd.argoproj.io/hook-delete-policy": "HookSucceeded" + } + }, + "spec": { + "containers": [ + { + "name": "post-delete-hook", + "image": "busybox", + "restartPolicy": "Never", + "command": [ + "/bin/sh", + "-c", + "sleep 5 && echo hello from the post-delete-hook pod" + ] + } + ] + } +} +` + func newFakeApp() *v1alpha1.Application { return createFakeApp(fakeApp) } @@ -371,6 +422,15 @@ func newFakeCM() map[string]interface{} { return cm } +func newFakePostDeleteHook() map[string]interface{} { + var cm map[string]interface{} + err := yaml.Unmarshal([]byte(fakePostDeleteHook), &cm) + if err != nil { + panic(err) + } + return cm +} + func TestAutoSync(t *testing.T) { app := newFakeApp() ctrl := newFakeController(&fakeData{apps: []runtime.Object{app}}, nil) @@ -619,6 +679,7 @@ func TestFinalizeAppDeletion(t *testing.T) { // Ensure app can be deleted cascading t.Run("CascadingDelete", func(t *testing.T) { app := newFakeApp() + app.SetCascadedDeletion(v1alpha1.ResourcesFinalizerName) app.Spec.Destination.Namespace = test.FakeArgoCDNamespace appObj := kube.MustToUnstructured(&app) ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ @@ -636,7 +697,7 @@ func TestFinalizeAppDeletion(t *testing.T) { patched = true return true, &v1alpha1.Application{}, nil }) - _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) assert.NoError(t, err) @@ -662,6 +723,7 @@ func TestFinalizeAppDeletion(t *testing.T) { }, } app := newFakeApp() + app.SetCascadedDeletion(v1alpha1.ResourcesFinalizerName) app.Spec.Destination.Namespace = test.FakeArgoCDNamespace app.Spec.Project = "restricted" appObj := kube.MustToUnstructured(&app) @@ -686,7 +748,7 @@ func TestFinalizeAppDeletion(t *testing.T) { patched = true return true, &v1alpha1.Application{}, nil }) - objs, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) assert.NoError(t, err) @@ -697,14 +759,16 @@ func TestFinalizeAppDeletion(t *testing.T) { } // Managed objects must be empty assert.Empty(t, objsMap) + // Loop through all deleted objects, ensure that test-cm is none of them - for _, o := range objs { - assert.NotEqual(t, "test-cm", o.GetName()) + for _, o := range ctrl.kubectl.(*MockKubectl).DeletedResources { + assert.NotEqual(t, "test-cm", o.Name) } }) t.Run("DeleteWithDestinationClusterName", func(t *testing.T) { app := newFakeAppWithDestName() + app.SetCascadedDeletion(v1alpha1.ResourcesFinalizerName) appObj := kube.MustToUnstructured(&app) ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(appObj): appObj, @@ -720,7 +784,7 @@ func TestFinalizeAppDeletion(t *testing.T) { patched = true return true, &v1alpha1.Application{}, nil }) - _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) assert.NoError(t, err) @@ -745,7 +809,7 @@ func TestFinalizeAppDeletion(t *testing.T) { fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { return defaultReactor.React(action) }) - _, err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { return []*v1alpha1.Cluster{}, nil }) assert.NoError(t, err) @@ -766,6 +830,109 @@ func TestFinalizeAppDeletion(t *testing.T) { }) + t.Run("PostDelete_HookIsCreated", func(t *testing.T) { + app := newFakeApp() + app.SetPostDeleteFinalizer() + app.Spec.Destination.Namespace = test.FakeArgoCDNamespace + ctrl := newFakeController(&fakeData{ + manifestResponses: []*apiclient.ManifestResponse{{ + Manifests: []string{fakePostDeleteHook}, + }}, + apps: []runtime.Object{app, &defaultProj}, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{}}, nil) + + patched := false + fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) + defaultReactor := fakeAppCs.ReactionChain[0] + fakeAppCs.ReactionChain = nil + fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return defaultReactor.React(action) + }) + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + patched = true + return true, &v1alpha1.Application{}, nil + }) + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + return []*v1alpha1.Cluster{}, nil + }) + assert.NoError(t, err) + // finalizer is not deleted + assert.False(t, patched) + // post-delete hook is created + require.Len(t, ctrl.kubectl.(*MockKubectl).CreatedResources, 1) + require.Equal(t, "post-delete-hook", ctrl.kubectl.(*MockKubectl).CreatedResources[0].GetName()) + }) + + t.Run("PostDelete_HookIsExecuted", func(t *testing.T) { + app := newFakeApp() + app.SetPostDeleteFinalizer() + app.Spec.Destination.Namespace = test.FakeArgoCDNamespace + liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()} + require.NoError(t, unstructured.SetNestedField(liveHook.Object, "Succeeded", "status", "phase")) + ctrl := newFakeController(&fakeData{ + manifestResponses: []*apiclient.ManifestResponse{{ + Manifests: []string{fakePostDeleteHook}, + }}, + apps: []runtime.Object{app, &defaultProj}, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(liveHook): liveHook, + }}, nil) + + patched := false + fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) + defaultReactor := fakeAppCs.ReactionChain[0] + fakeAppCs.ReactionChain = nil + fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return defaultReactor.React(action) + }) + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + patched = true + return true, &v1alpha1.Application{}, nil + }) + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + return []*v1alpha1.Cluster{}, nil + }) + assert.NoError(t, err) + // finalizer is removed + assert.True(t, patched) + }) + + t.Run("PostDelete_HookIsDeleted", func(t *testing.T) { + app := newFakeApp() + app.SetPostDeleteFinalizer("cleanup") + app.Spec.Destination.Namespace = test.FakeArgoCDNamespace + liveHook := &unstructured.Unstructured{Object: newFakePostDeleteHook()} + require.NoError(t, unstructured.SetNestedField(liveHook.Object, "Succeeded", "status", "phase")) + ctrl := newFakeController(&fakeData{ + manifestResponses: []*apiclient.ManifestResponse{{ + Manifests: []string{fakePostDeleteHook}, + }}, + apps: []runtime.Object{app, &defaultProj}, + managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ + kube.GetResourceKey(liveHook): liveHook, + }}, nil) + + patched := false + fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) + defaultReactor := fakeAppCs.ReactionChain[0] + fakeAppCs.ReactionChain = nil + fakeAppCs.AddReactor("get", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + return defaultReactor.React(action) + }) + fakeAppCs.AddReactor("patch", "*", func(action kubetesting.Action) (handled bool, ret runtime.Object, err error) { + patched = true + return true, &v1alpha1.Application{}, nil + }) + err := ctrl.finalizeApplicationDeletion(app, func(project string) ([]*v1alpha1.Cluster, error) { + return []*v1alpha1.Cluster{}, nil + }) + assert.NoError(t, err) + // post-delete hook is deleted + require.Len(t, ctrl.kubectl.(*MockKubectl).DeletedResources, 1) + require.Equal(t, "post-delete-hook", ctrl.kubectl.(*MockKubectl).DeletedResources[0].Name) + // finalizer is not removed + assert.False(t, patched) + }) } // TestNormalizeApplication verifies we normalize an application during reconciliation diff --git a/controller/hook.go b/controller/hook.go new file mode 100644 index 0000000000000..0c019ac6a1e08 --- /dev/null +++ b/controller/hook.go @@ -0,0 +1,158 @@ +package controller + +import ( + "context" + + "github.com/argoproj/gitops-engine/pkg/health" + "github.com/argoproj/gitops-engine/pkg/sync/common" + "github.com/argoproj/gitops-engine/pkg/sync/hook" + "github.com/argoproj/gitops-engine/pkg/utils/kube" + log "github.com/sirupsen/logrus" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/rest" + + "github.com/argoproj/argo-cd/v2/util/lua" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" +) + +var ( + postDeleteHook = "PostDelete" + postDeleteHooks = map[string]string{ + "argocd.argoproj.io/hook": postDeleteHook, + "helm.sh/hook": "post-delete", + } +) + +func isHook(obj *unstructured.Unstructured) bool { + return hook.IsHook(obj) || isPostDeleteHook(obj) +} + +func isPostDeleteHook(obj *unstructured.Unstructured) bool { + if obj == nil || obj.GetAnnotations() == nil { + return false + } + for k, v := range postDeleteHooks { + if val, ok := obj.GetAnnotations()[k]; ok && val == v { + return true + } + } + return false +} + +func (ctrl *ApplicationController) executePostDeleteHooks(app *v1alpha1.Application, proj *v1alpha1.AppProject, liveObjs map[kube.ResourceKey]*unstructured.Unstructured, config *rest.Config, logCtx *log.Entry) (bool, error) { + appLabelKey, err := ctrl.settingsMgr.GetAppInstanceLabelKey() + if err != nil { + return false, err + } + var revisions []string + for _, src := range app.Spec.GetSources() { + revisions = append(revisions, src.TargetRevision) + } + + targets, _, err := ctrl.appStateManager.GetRepoObjs(app, app.Spec.GetSources(), appLabelKey, revisions, false, false, false, proj) + if err != nil { + return false, err + } + runningHooks := map[kube.ResourceKey]*unstructured.Unstructured{} + for key, obj := range liveObjs { + if isPostDeleteHook(obj) { + runningHooks[key] = obj + } + } + + expectedHook := map[kube.ResourceKey]*unstructured.Unstructured{} + for _, obj := range targets { + if obj.GetNamespace() == "" { + obj.SetNamespace(app.Spec.Destination.Namespace) + } + if !isPostDeleteHook(obj) { + continue + } + if runningHook := runningHooks[kube.GetResourceKey(obj)]; runningHook == nil { + expectedHook[kube.GetResourceKey(obj)] = obj + } + } + createdCnt := 0 + for _, obj := range expectedHook { + _, err = ctrl.kubectl.CreateResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), obj, v1.CreateOptions{}) + if err != nil { + return false, err + } + createdCnt++ + } + if createdCnt > 0 { + logCtx.Infof("Created %d post-delete hooks", createdCnt) + return false, nil + } + resourceOverrides, err := ctrl.settingsMgr.GetResourceOverrides() + if err != nil { + return false, err + } + healthOverrides := lua.ResourceHealthOverrides(resourceOverrides) + + progressingHooksCnt := 0 + for _, obj := range runningHooks { + hookHealth, err := health.GetResourceHealth(obj, healthOverrides) + if err != nil { + return false, err + } + if hookHealth.Status == health.HealthStatusProgressing { + progressingHooksCnt++ + } + } + if progressingHooksCnt > 0 { + logCtx.Infof("Waiting for %d post-delete hooks to complete", progressingHooksCnt) + return false, nil + } + + return true, nil +} + +func (ctrl *ApplicationController) cleanupPostDeleteHooks(liveObjs map[kube.ResourceKey]*unstructured.Unstructured, config *rest.Config, logCtx *log.Entry) (bool, error) { + resourceOverrides, err := ctrl.settingsMgr.GetResourceOverrides() + if err != nil { + return false, err + } + healthOverrides := lua.ResourceHealthOverrides(resourceOverrides) + + pendingDeletionCount := 0 + aggregatedHealth := health.HealthStatusHealthy + var hooks []*unstructured.Unstructured + for _, obj := range liveObjs { + if !isPostDeleteHook(obj) { + continue + } + hookHealth, err := health.GetResourceHealth(obj, healthOverrides) + if err != nil { + return false, err + } + if health.IsWorse(aggregatedHealth, hookHealth.Status) { + aggregatedHealth = hookHealth.Status + } + hooks = append(hooks, obj) + } + + for _, obj := range hooks { + for _, policy := range hook.DeletePolicies(obj) { + if policy == common.HookDeletePolicyHookFailed && aggregatedHealth == health.HealthStatusDegraded || policy == common.HookDeletePolicyHookSucceeded && aggregatedHealth == health.HealthStatusHealthy { + pendingDeletionCount++ + if obj.GetDeletionTimestamp() != nil { + continue + } + logCtx.Infof("Deleting post-delete hook %s/%s", obj.GetNamespace(), obj.GetName()) + err = ctrl.kubectl.DeleteResource(context.Background(), config, obj.GroupVersionKind(), obj.GetName(), obj.GetNamespace(), v1.DeleteOptions{}) + if err != nil { + return false, err + } + } + } + + } + if pendingDeletionCount > 0 { + logCtx.Infof("Waiting for %d post-delete hooks to be deleted", pendingDeletionCount) + return false, nil + } + return true, nil +} diff --git a/controller/state.go b/controller/state.go index 59e7fa31248ae..ccd17bf532643 100644 --- a/controller/state.go +++ b/controller/state.go @@ -71,6 +71,7 @@ type managedResource struct { type AppStateManager interface { CompareAppState(app *v1alpha1.Application, project *v1alpha1.AppProject, revisions []string, sources []v1alpha1.ApplicationSource, noCache bool, noRevisionCache bool, localObjects []string, hasMultipleSources bool) (*comparisonResult, error) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) + GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) } // comparisonResult holds the state of an application after the reconciliation @@ -85,8 +86,9 @@ type comparisonResult struct { // appSourceTypes stores the SourceType for each application source under sources field appSourceTypes []v1alpha1.ApplicationSourceType // timings maps phases of comparison to the duration it took to complete (for statistical purposes) - timings map[string]time.Duration - diffResultList *diff.DiffResultList + timings map[string]time.Duration + diffResultList *diff.DiffResultList + hasPostDeleteHooks bool } func (res *comparisonResult) GetSyncStatus() *v1alpha1.SyncStatus { @@ -116,11 +118,11 @@ type appStateManager struct { repoErrorGracePeriod time.Duration } -// getRepoObjs will generate the manifests for the given application delegating the +// GetRepoObjs will generate the manifests for the given application delegating the // task to the repo-server. It returns the list of generated manifests as unstructured // objects. It also returns the full response from all calls to the repo server as the // second argument. -func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) { +func (m *appStateManager) GetRepoObjs(app *v1alpha1.Application, sources []v1alpha1.ApplicationSource, appLabelKey string, revisions []string, noCache, noRevisionCache, verifySignature bool, proj *v1alpha1.AppProject) ([]*unstructured.Unstructured, []*apiclient.ManifestResponse, error) { ts := stats.NewTimingStats() helmRepos, err := m.db.ListHelmRepositories(context.Background()) if err != nil { @@ -236,7 +238,7 @@ func (m *appStateManager) getRepoObjs(app *v1alpha1.Application, sources []v1alp logCtx = logCtx.WithField(k, v.Milliseconds()) } logCtx = logCtx.WithField("time_ms", time.Since(ts.StartTime).Milliseconds()) - logCtx.Info("getRepoObjs stats") + logCtx.Info("GetRepoObjs stats") return targetObjs, manifestInfos, nil } @@ -415,7 +417,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } } - targetObjs, manifestInfos, err = m.getRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project) + targetObjs, manifestInfos, err = m.GetRepoObjs(app, sources, appLabelKey, revisions, noCache, noRevisionCache, verifySignature, project) if err != nil { targetObjs = make([]*unstructured.Unstructured, 0) msg := fmt.Sprintf("Failed to load target state: %s", err.Error()) @@ -569,6 +571,12 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 } } } + hasPostDeleteHooks := false + for _, obj := range targetObjs { + if isPostDeleteHook(obj) { + hasPostDeleteHooks = true + } + } reconciliation := sync.Reconcile(targetObjs, liveObjByKey, app.Spec.Destination.Namespace, infoProvider) ts.AddCheckpoint("live_ms") @@ -643,7 +651,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 Kind: gvk.Kind, Version: gvk.Version, Group: gvk.Group, - Hook: hookutil.IsHook(obj), + Hook: isHook(obj), RequiresPruning: targetObj == nil && liveObj != nil && isSelfReferencedObj, } if targetObj != nil { @@ -776,6 +784,7 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 reconciliationResult: reconciliation, diffConfig: diffConfig, diffResultList: diffResults, + hasPostDeleteHooks: hasPostDeleteHooks, } if hasMultipleSources { diff --git a/controller/sync.go b/controller/sync.go index 2b925b7782b9e..435f62e587c34 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -283,6 +283,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha sync.WithInitialState(state.Phase, state.Message, initialResourcesRes, state.StartedAt), sync.WithResourcesFilter(func(key kube.ResourceKey, target *unstructured.Unstructured, live *unstructured.Unstructured) bool { return (len(syncOp.Resources) == 0 || + isPostDeleteHook(target) || argo.ContainsSyncResource(key.Name, key.Namespace, schema.GroupVersionKind{Kind: key.Kind, Group: key.Group}, syncOp.Resources)) && m.isSelfReferencedObj(live, target, app.GetName(), appLabelKey, trackingMethod) }), diff --git a/docs/user-guide/helm.md b/docs/user-guide/helm.md index 76853480a6def..866f9c6d935aa 100644 --- a/docs/user-guide/helm.md +++ b/docs/user-guide/helm.md @@ -210,7 +210,7 @@ is any normal Kubernetes resource annotated with the `helm.sh/hook` annotation. Argo CD supports many (most?) Helm hooks by mapping the Helm annotations onto Argo CD's own hook annotations: | Helm Annotation | Notes | -| ------------------------------- | --------------------------------------------------------------------------------------------- | +| ------------------------------- |-----------------------------------------------------------------------------------------------| | `helm.sh/hook: crd-install` | Supported as equivalent to `argocd.argoproj.io/hook: PreSync`. | | `helm.sh/hook: pre-delete` | Not supported. In Helm stable there are 3 cases used to clean up CRDs and 3 to clean-up jobs. | | `helm.sh/hook: pre-rollback` | Not supported. Never used in Helm stable. | @@ -218,7 +218,7 @@ Argo CD supports many (most?) Helm hooks by mapping the Helm annotations onto Ar | `helm.sh/hook: pre-upgrade` | Supported as equivalent to `argocd.argoproj.io/hook: PreSync`. | | `helm.sh/hook: post-upgrade` | Supported as equivalent to `argocd.argoproj.io/hook: PostSync`. | | `helm.sh/hook: post-install` | Supported as equivalent to `argocd.argoproj.io/hook: PostSync`. | -| `helm.sh/hook: post-delete` | Not supported. Never used in Helm stable. | +| `helm.sh/hook: post-delete` | Supported as equivalent to `argocd.argoproj.io/hook: PostDelete`. | | `helm.sh/hook: post-rollback` | Not supported. Never used in Helm stable. | | `helm.sh/hook: test-success` | Not supported. No equivalent in Argo CD. | | `helm.sh/hook: test-failure` | Not supported. No equivalent in Argo CD. | diff --git a/docs/user-guide/resource_hooks.md b/docs/user-guide/resource_hooks.md index d705f8d21423d..74098b1810011 100644 --- a/docs/user-guide/resource_hooks.md +++ b/docs/user-guide/resource_hooks.md @@ -9,6 +9,8 @@ and after a Sync operation. Hooks can also be run if a Sync operation fails at a Kubernetes rolling update strategy. * Using a `PostSync` hook to run integration and health checks after a deployment. * Using a `SyncFail` hook to run clean-up or finalizer logic if a Sync operation fails. _`SyncFail` hooks are only available starting in v1.2_ +* Using a `PostDelete` hook to run clean-up or finalizer logic after an all Application resources are deleted. Please note that + `PostDelete` hooks are only deleted if delete policy matches to the aggregated deletion hooks status and not garbage collected after the application is deleted. ## Usage diff --git a/pkg/apis/application/v1alpha1/application_defaults.go b/pkg/apis/application/v1alpha1/application_defaults.go index 2bc9b1bd0d744..ad8112af8c88d 100644 --- a/pkg/apis/application/v1alpha1/application_defaults.go +++ b/pkg/apis/application/v1alpha1/application_defaults.go @@ -9,6 +9,9 @@ const ( // ResourcesFinalizerName is the finalizer value which we inject to finalize deletion of an application ResourcesFinalizerName string = "resources-finalizer.argocd.argoproj.io" + // PostDeleteFinalizerName is the finalizer that controls post-delete hooks execution + PostDeleteFinalizerName string = "post-delete-finalizer.argocd.argoproj.io" + // ForegroundPropagationPolicyFinalizer is the finalizer we inject to delete application with foreground propagation policy ForegroundPropagationPolicyFinalizer string = "resources-finalizer.argocd.argoproj.io/foreground" diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index dc6a73f05dee5..49be82a443bc4 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -2651,6 +2651,18 @@ func (app *Application) IsRefreshRequested() (RefreshType, bool) { return refreshType, true } +func (app *Application) HasPostDeleteFinalizer(stage ...string) bool { + return getFinalizerIndex(app.ObjectMeta, strings.Join(append([]string{PostDeleteFinalizerName}, stage...), "/")) > -1 +} + +func (app *Application) SetPostDeleteFinalizer(stage ...string) { + setFinalizer(&app.ObjectMeta, strings.Join(append([]string{PostDeleteFinalizerName}, stage...), "/"), true) +} + +func (app *Application) UnSetPostDeleteFinalizer(stage ...string) { + setFinalizer(&app.ObjectMeta, strings.Join(append([]string{PostDeleteFinalizerName}, stage...), "/"), false) +} + // SetCascadedDeletion will enable cascaded deletion by setting the propagation policy finalizer func (app *Application) SetCascadedDeletion(finalizer string) { setFinalizer(&app.ObjectMeta, finalizer, true) diff --git a/test/e2e/hook_test.go b/test/e2e/hook_test.go index f6bb1be872ac6..2db8ff87795ad 100644 --- a/test/e2e/hook_test.go +++ b/test/e2e/hook_test.go @@ -1,12 +1,14 @@ package e2e import ( + "context" "fmt" "testing" "time" "github.com/stretchr/testify/assert" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" @@ -48,6 +50,24 @@ func testHookSuccessful(t *testing.T, hookType HookType) { Expect(ResourceResultIs(ResourceResult{Version: "v1", Kind: "Pod", Namespace: DeploymentNamespace(), Name: "hook", Message: "pod/hook created", HookType: hookType, HookPhase: OperationSucceeded, SyncPhase: SyncPhase(hookType)})) } +func TestPostDeleteHook(t *testing.T) { + Given(t). + Path("post-delete-hook"). + When(). + CreateApp(). + Refresh(RefreshTypeNormal). + Delete(true). + Then(). + Expect(DoesNotExist()). + AndAction(func() { + hooks, err := KubeClientset.CoreV1().Pods(DeploymentNamespace()).List(context.Background(), metav1.ListOptions{}) + CheckError(err) + assert.Len(t, hooks.Items, 1) + assert.Equal(t, "hook", hooks.Items[0].Name) + }) + +} + // make sure that that hooks do not appear in "argocd app diff" func TestHookDiff(t *testing.T) { Given(t). diff --git a/test/e2e/testdata/post-delete-hook/hook.yaml b/test/e2e/testdata/post-delete-hook/hook.yaml new file mode 100644 index 0000000000000..5631db681f1d0 --- /dev/null +++ b/test/e2e/testdata/post-delete-hook/hook.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + argocd.argoproj.io/hook: PostDelete + name: hook +spec: + containers: + - command: + - "true" + image: quay.io/argoprojlabs/argocd-e2e-container:0.1 + imagePullPolicy: IfNotPresent + name: main + restartPolicy: Never \ No newline at end of file From 9abc1cc8372a44b001da45e6196af17fbce35b32 Mon Sep 17 00:00:00 2001 From: AS <11219262+ashutosh16@users.noreply.github.com> Date: Mon, 18 Dec 2023 12:15:42 -0800 Subject: [PATCH 165/269] feat(ui): Show prompt when every resource requires pruning (#16603) * fix(ui): show prompt when using prune option Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * fix(ui): show prompt when using prune option Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * fix(ui): show prompt when using prune option Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> fix(ui): show prompt when using prune option Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> * chore: update message and simplify code Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * don't warn on partial sync Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix(ui): lint Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> --------- Signed-off-by: ashutosh16 <11219262+ashutosh16@users.noreply.github.com> Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .../application-sync-options.tsx | 1 + .../application-sync-panel.tsx | 34 +++++++++++++++---- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx b/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx index 538d74455fea0..7cc24173cd36a 100644 --- a/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx +++ b/ui/src/app/applications/components/application-sync-options/application-sync-options.tsx @@ -7,6 +7,7 @@ import './application-sync-options.scss'; export const REPLACE_WARNING = `The resources will be synced using 'kubectl replace/create' command that is a potentially destructive action and might cause resources recreation.`; export const FORCE_WARNING = `The resources will be synced using '--force' that is a potentially destructive action and will immediately remove resources from the API and bypasses graceful deletion. Immediate deletion of some resources may result in inconsistency or data loss.`; +export const PRUNE_ALL_WARNING = `The resources will be synced using '--prune', and all resources are marked to be pruned. Only continue if you want to delete all of the Application's resources.`; export interface ApplicationSyncOptionProps { options: string[]; diff --git a/ui/src/app/applications/components/application-sync-panel/application-sync-panel.tsx b/ui/src/app/applications/components/application-sync-panel/application-sync-panel.tsx index 884cdd4eb85ff..c1a4505eeeba0 100644 --- a/ui/src/app/applications/components/application-sync-panel/application-sync-panel.tsx +++ b/ui/src/app/applications/components/application-sync-panel/application-sync-panel.tsx @@ -7,7 +7,14 @@ import {Consumer} from '../../../shared/context'; import * as models from '../../../shared/models'; import {services} from '../../../shared/services'; import {ApplicationRetryOptions} from '../application-retry-options/application-retry-options'; -import {ApplicationManualSyncFlags, ApplicationSyncOptions, FORCE_WARNING, SyncFlags, REPLACE_WARNING} from '../application-sync-options/application-sync-options'; +import { + ApplicationManualSyncFlags, + ApplicationSyncOptions, + FORCE_WARNING, + SyncFlags, + REPLACE_WARNING, + PRUNE_ALL_WARNING +} from '../application-sync-options/application-sync-options'; import {ComparisonStatusIcon, getAppDefaultSource, nodeKey} from '../utils'; import './application-sync-panel.scss'; @@ -57,9 +64,25 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app })} onSubmit={async (params: any) => { setPending(true); - let resources = appResources.filter((_, i) => params.resources[i]); - if (resources.length === appResources.length) { - resources = null; + let selectedResources = appResources.filter((_, i) => params.resources[i]); + const allResourcesAreSelected = selectedResources.length === appResources.length; + const syncFlags = {...params.syncFlags} as SyncFlags; + + const allRequirePruning = !selectedResources.some(resource => !resource?.requiresPruning); + if (syncFlags.Prune && allRequirePruning && allResourcesAreSelected) { + const confirmed = await ctx.popup.confirm('Prune all resources?', () => ( +
    + + {PRUNE_ALL_WARNING} Are you sure you want to continue? +
    + )); + if (!confirmed) { + setPending(false); + return; + } + } + if (allResourcesAreSelected) { + selectedResources = null; } const replace = params.syncOptions?.findIndex((opt: string) => opt === 'Replace=true') > -1; if (replace) { @@ -74,7 +97,6 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app } } - const syncFlags = {...params.syncFlags} as SyncFlags; const force = syncFlags.Force || false; if (syncFlags.ApplyOnly) { @@ -102,7 +124,7 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app syncFlags.Prune || false, syncFlags.DryRun || false, syncStrategy, - resources, + selectedResources, params.syncOptions, params.retryStrategy ); From 82ca7a7f9c5df24de5e78970716d01d13b008410 Mon Sep 17 00:00:00 2001 From: Leonardo Luz Almeida Date: Mon, 18 Dec 2023 15:37:13 -0500 Subject: [PATCH 166/269] feat: Implement Server-Side Diff (#13663) * feat: Implement Server-Side Diff Signed-off-by: Leonardo Luz Almeida * propagate the refreshtype to the diff config Signed-off-by: Leonardo Luz Almeida * Create the serverSideDiff config Signed-off-by: Leonardo Luz Almeida * chore: add featureflag utility package Signed-off-by: Leonardo Luz Almeida * remove featureflag package Signed-off-by: Leonardo Luz Almeida * add param Signed-off-by: Leonardo Luz Almeida * make ssd configurable with app annotation Signed-off-by: Leonardo Luz Almeida * add server-side-diff flags Signed-off-by: Leonardo Luz Almeida * apply the same logic regardless of the refresh type Signed-off-by: Leonardo Luz Almeida * fix gitops-engine reference Signed-off-by: Leonardo Luz Almeida * address review comments Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida * docs: add docs related to server-side-diff Signed-off-by: Leonardo Luz Almeida * docs: update doc Signed-off-by: Leonardo Luz Almeida * Add config to include mutation webhooks Signed-off-by: Leonardo Luz Almeida * Address review comments Signed-off-by: Leonardo Luz Almeida * go mod update Signed-off-by: Leonardo Luz Almeida * Add sdd cache test case Signed-off-by: Leonardo Luz Almeida * fix ssd cache unit test Signed-off-by: Leonardo Luz Almeida * Update clidocs Signed-off-by: Leonardo Luz Almeida * update manifests Signed-off-by: Leonardo Luz Almeida * Fix procfile Signed-off-by: Leonardo Luz Almeida * additional doc changes Signed-off-by: Leonardo Luz Almeida * update gitops-engine version Signed-off-by: Leonardo Luz Almeida --------- Signed-off-by: Leonardo Luz Almeida --- Makefile | 1 + Procfile | 2 +- .../commands/argocd_application_controller.go | 3 + cmd/argocd/commands/admin/app.go | 7 +- cmd/argocd/commands/admin/app_test.go | 1 + common/common.go | 3 + controller/appcontroller.go | 3 +- controller/appcontroller_test.go | 1 + controller/state.go | 43 ++++- controller/state_test.go | 22 ++- controller/sync.go | 21 +++ .../operator-manual/argocd-cmd-params-cm.yaml | 4 + .../argocd-application-controller.md | 1 + .../argocd_admin_app_get-reconcile-results.md | 1 + docs/user-guide/diff-strategies.md | 125 ++++++++++++++ go.mod | 4 +- go.sum | 8 +- ...ocd-application-controller-deployment.yaml | 156 +++++++++--------- ...cd-application-controller-statefulset.yaml | 150 +++++++++-------- manifests/core-install.yaml | 6 + manifests/ha/install.yaml | 6 + manifests/ha/namespace-install.yaml | 6 + manifests/install.yaml | 6 + manifests/namespace-install.yaml | 6 + mkdocs.yml | 4 +- util/argo/diff/diff.go | 55 +++++- 26 files changed, 475 insertions(+), 170 deletions(-) create mode 100644 docs/user-guide/diff-strategies.md diff --git a/Makefile b/Makefile index d4df041fa58e1..880622e7279a9 100644 --- a/Makefile +++ b/Makefile @@ -492,6 +492,7 @@ start-local: mod-vendor-local dep-ui-local cli-local ARGOCD_ZJWT_FEATURE_FLAG=always \ ARGOCD_IN_CI=false \ ARGOCD_GPG_ENABLED=$(ARGOCD_GPG_ENABLED) \ + BIN_MODE=$(ARGOCD_BIN_MODE) \ ARGOCD_E2E_TEST=false \ ARGOCD_APPLICATION_NAMESPACES=$(ARGOCD_APPLICATION_NAMESPACES) \ goreman -f $(ARGOCD_PROCFILE) start ${ARGOCD_START} diff --git a/Procfile b/Procfile index 92f69ecf8ffbc..3bc2de5eca5e0 100644 --- a/Procfile +++ b/Procfile @@ -1,4 +1,4 @@ -controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" +controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'}" api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/cmd gendexcfg -o `pwd`/dist/dex.yaml && (test -f dist/dex.yaml || { echo 'Failed to generate dex configuration'; exit 1; }) && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:$(grep "image: ghcr.io/dexidp/dex" manifests/base/dex/argocd-dex-server-deployment.yaml | cut -d':' -f3) dex serve /dex.yaml" redis: bash -c "if [ \"$ARGOCD_REDIS_LOCAL\" = 'true' ]; then redis-server --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; else docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} docker.io/library/redis:$(grep "image: redis" manifests/base/redis/argocd-redis-deployment.yaml | cut -d':' -f3) --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi" diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 74d0af45c9d7a..796a645f03393 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -73,6 +73,7 @@ func NewCommand() *cobra.Command { persistResourceHealth bool shardingAlgorithm string enableDynamicClusterDistribution bool + serverSideDiff bool ) var command = cobra.Command{ Use: cliName, @@ -166,6 +167,7 @@ func NewCommand() *cobra.Command { clusterFilter, applicationNamespaces, &workqueueRateLimit, + serverSideDiff, ) errors.CheckError(err) cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer()) @@ -224,6 +226,7 @@ func NewCommand() *cobra.Command { command.Flags().DurationVar(&workqueueRateLimit.MaxDelay, "wq-maxdelay-ns", time.Duration(env.ParseInt64FromEnv("WORKQUEUE_MAX_DELAY_NS", time.Second.Nanoseconds(), 1*time.Millisecond.Nanoseconds(), (24*time.Hour).Nanoseconds())), "Set Workqueue Per Item Rate Limiter Max Delay duration in nanoseconds, default 1000000000 (1s)") command.Flags().Float64Var(&workqueueRateLimit.BackoffFactor, "wq-backoff-factor", env.ParseFloat64FromEnv("WORKQUEUE_BACKOFF_FACTOR", 1.5, 0, math.MaxFloat64), "Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5") command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.") + command.Flags().BoolVar(&serverSideDiff, "server-side-diff-enabled", env.ParseBoolFromEnv(common.EnvServerSideDiff, false), "Feature flag to enable ServerSide diff. Default (\"false\")") cacheSource = appstatecache.AddCacheFlagsToCmd(&command, func(client *redis.Client) { redisClient = client }) diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index 10e4effe8797a..096c92f9feb01 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -243,6 +243,7 @@ func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command repoServerAddress string outputFormat string refresh bool + serverSideDiff bool ) var command = &cobra.Command{ @@ -280,7 +281,7 @@ func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command appClientset := appclientset.NewForConfigOrDie(cfg) kubeClientset := kubernetes.NewForConfigOrDie(cfg) - result, err = reconcileApplications(ctx, kubeClientset, appClientset, namespace, repoServerClient, selector, newLiveStateCache) + result, err = reconcileApplications(ctx, kubeClientset, appClientset, namespace, repoServerClient, selector, newLiveStateCache, serverSideDiff) errors.CheckError(err) } else { appClientset := appclientset.NewForConfigOrDie(cfg) @@ -295,6 +296,7 @@ func NewReconcileCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command command.Flags().StringVar(&selector, "l", "", "Label selector") command.Flags().StringVar(&outputFormat, "o", "yaml", "Output format (yaml|json)") command.Flags().BoolVar(&refresh, "refresh", false, "If set to true then recalculates apps reconciliation") + command.Flags().BoolVar(&serverSideDiff, "server-side-diff", false, "If set to \"true\" will use server-side diff while comparing resources. Default (\"false\")") return command } @@ -344,6 +346,7 @@ func reconcileApplications( repoServerClient reposerverclient.Clientset, selector string, createLiveStateCache func(argoDB db.ArgoDB, appInformer kubecache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) cache.LiveStateCache, + serverSideDiff bool, ) ([]appReconcileResult, error) { settingsMgr := settings.NewSettingsManager(ctx, kubeClientset, namespace) argoDB := db.NewDB(namespace, settingsMgr, kubeClientset) @@ -384,7 +387,7 @@ func reconcileApplications( ) appStateManager := controller.NewAppStateManager( - argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false, 0) + argoDB, appClientset, repoServerClient, namespace, kubeutil.NewKubectl(), settingsMgr, stateCache, projInformer, server, cache, time.Second, argo.NewResourceTracking(), false, 0, serverSideDiff) appsList, err := appClientset.ArgoprojV1alpha1().Applications(namespace).List(ctx, v1.ListOptions{LabelSelector: selector}) if err != nil { diff --git a/cmd/argocd/commands/admin/app_test.go b/cmd/argocd/commands/admin/app_test.go index 0cad2485e6696..a0284fe8ffa09 100644 --- a/cmd/argocd/commands/admin/app_test.go +++ b/cmd/argocd/commands/admin/app_test.go @@ -113,6 +113,7 @@ func TestGetReconcileResults_Refresh(t *testing.T) { func(argoDB db.ArgoDB, appInformer cache.SharedIndexInformer, settingsMgr *settings.SettingsManager, server *metrics.MetricsServer) statecache.LiveStateCache { return &liveStateCache }, + false, ) if !assert.NoError(t, err) { diff --git a/common/common.go b/common/common.go index 5faedc2e344c4..c5b9362f7f943 100644 --- a/common/common.go +++ b/common/common.go @@ -260,6 +260,9 @@ const ( EnvRedisHaProxyName = "ARGOCD_REDIS_HAPROXY_NAME" // EnvGRPCKeepAliveMin defines the GRPCKeepAliveEnforcementMinimum, used in the grpc.KeepaliveEnforcementPolicy. Expects a "Duration" format (e.g. 10s). EnvGRPCKeepAliveMin = "ARGOCD_GRPC_KEEP_ALIVE_MIN" + // EnvServerSideDiff defines the env var used to enable ServerSide Diff feature. + // If defined, value must be "true" or "false". + EnvServerSideDiff = "ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF" ) // Config Management Plugin related constants diff --git a/controller/appcontroller.go b/controller/appcontroller.go index b98334b8fa567..0ded95de65d15 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -152,6 +152,7 @@ func NewApplicationController( clusterFilter func(cluster *appv1.Cluster) bool, applicationNamespaces []string, rateLimiterConfig *ratelimiter.AppControllerRateLimiterConfig, + serverSideDiff bool, ) (*ApplicationController, error) { log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v", appResyncPeriod, appHardResyncPeriod) db := db.NewDB(namespace, settingsMgr, kubeClientset) @@ -260,7 +261,7 @@ func NewApplicationController( } } stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterFilter, argo.NewResourceTracking()) - appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod) + appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod, serverSideDiff) ctrl.appInformer = appInformer ctrl.appLister = appLister ctrl.projInformer = projInformer diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 2efc7ac723bc7..bf3d8bb3a2e4c 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -152,6 +152,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { nil, data.applicationNamespaces, nil, + false, ) if err != nil { panic(err) diff --git a/controller/state.go b/controller/state.go index ccd17bf532643..5121fa68fcac9 100644 --- a/controller/state.go +++ b/controller/state.go @@ -116,6 +116,7 @@ type appStateManager struct { persistResourceHealth bool repoErrorCache goSync.Map repoErrorGracePeriod time.Duration + serverSideDiff bool } // GetRepoObjs will generate the manifests for the given application delegating the @@ -592,7 +593,16 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 manifestRevisions = append(manifestRevisions, manifestInfo.Revision) } - useDiffCache := useDiffCache(noCache, manifestInfos, sources, app, manifestRevisions, m.statusRefreshTimeout, logCtx) + serverSideDiff := m.serverSideDiff || + resourceutil.HasAnnotationOption(app, common.AnnotationCompareOptions, "ServerSideDiff=true") + + // This allows turning SSD off for a given app if it is enabled at the + // controller level + if resourceutil.HasAnnotationOption(app, common.AnnotationCompareOptions, "ServerSideDiff=false") { + serverSideDiff = false + } + + useDiffCache := useDiffCache(noCache, manifestInfos, sources, app, manifestRevisions, m.statusRefreshTimeout, serverSideDiff, logCtx) diffConfigBuilder := argodiff.NewDiffConfigBuilder(). WithDiffSettings(app.Spec.IgnoreDifferences, resourceOverrides, compareOptions.IgnoreAggregatedRoles). @@ -604,6 +614,10 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 diffConfigBuilder.WithNoCache() } + if resourceutil.HasAnnotationOption(app, common.AnnotationCompareOptions, "IncludeMutationWebhook=true") { + diffConfigBuilder.WithIgnoreMutationWebhook(false) + } + gvkParser, err := m.getGVKParser(app.Spec.Destination.Server) if err != nil { conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionUnknownError, Message: err.Error(), LastTransitionTime: &now}) @@ -611,6 +625,18 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 diffConfigBuilder.WithGVKParser(gvkParser) diffConfigBuilder.WithManager(common.ArgoCDSSAManager) + diffConfigBuilder.WithServerSideDiff(serverSideDiff) + + if serverSideDiff { + resourceOps, cleanup, err := m.getResourceOperations(app.Spec.Destination.Server) + if err != nil { + log.Errorf("CompareAppState error getting resource operations: %s", err) + conditions = append(conditions, v1alpha1.ApplicationCondition{Type: v1alpha1.ApplicationConditionUnknownError, Message: err.Error(), LastTransitionTime: &now}) + } + defer cleanup() + diffConfigBuilder.WithServerSideDryRunner(diff.NewK8sServerSideDryRunner(resourceOps)) + } + // enable structured merge diff if application syncs with server-side apply if app.Spec.SyncPolicy != nil && app.Spec.SyncPolicy.SyncOptions.HasOption("ServerSideApply=true") { diffConfigBuilder.WithStructuredMergeDiff(true) @@ -811,18 +837,23 @@ func (m *appStateManager) CompareAppState(app *v1alpha1.Application, project *v1 // useDiffCache will determine if the diff should be calculated based // on the existing live state cache or not. -func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sources []v1alpha1.ApplicationSource, app *v1alpha1.Application, manifestRevisions []string, statusRefreshTimeout time.Duration, log *log.Entry) bool { +func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sources []v1alpha1.ApplicationSource, app *v1alpha1.Application, manifestRevisions []string, statusRefreshTimeout time.Duration, serverSideDiff bool, log *log.Entry) bool { if noCache { log.WithField("useDiffCache", "false").Debug("noCache is true") return false } - _, refreshRequested := app.IsRefreshRequested() + refreshType, refreshRequested := app.IsRefreshRequested() if refreshRequested { - log.WithField("useDiffCache", "false").Debug("refreshRequested") + log.WithField("useDiffCache", "false").Debugf("refresh type %s requested", string(refreshType)) return false } - if app.Status.Expired(statusRefreshTimeout) { + // serverSideDiff should still use cache even if status is expired. + // This is an attempt to avoid hitting k8s API server too frequently during + // app refresh with serverSideDiff is enabled. If there are negative side + // effects identified with this approach, the serverSideDiff should be removed + // from this condition. + if app.Status.Expired(statusRefreshTimeout) && !serverSideDiff { log.WithField("useDiffCache", "false").Debug("app.status.expired") return false } @@ -903,6 +934,7 @@ func NewAppStateManager( resourceTracking argo.ResourceTracking, persistResourceHealth bool, repoErrorGracePeriod time.Duration, + serverSideDiff bool, ) AppStateManager { return &appStateManager{ liveStateCache: liveStateCache, @@ -919,6 +951,7 @@ func NewAppStateManager( resourceTracking: resourceTracking, persistResourceHealth: persistResourceHealth, repoErrorGracePeriod: repoErrorGracePeriod, + serverSideDiff: serverSideDiff, } } diff --git a/controller/state_test.go b/controller/state_test.go index a240b30d688df..5d2342b601a77 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -1407,6 +1407,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions []string statusRefreshTimeout time.Duration expectedUseCache bool + serverSideDiff bool } manifestInfos := func(revision string) []*apiclient.ManifestResponse { @@ -1505,6 +1506,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: true, + serverSideDiff: false, }, { testName: "will use diff cache for multisource", @@ -1548,6 +1550,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1", "rev2"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: true, + serverSideDiff: false, }, { testName: "will return false if nocache is true", @@ -1558,6 +1561,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: false, + serverSideDiff: false, }, { testName: "will return false if requested refresh", @@ -1568,6 +1572,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: false, + serverSideDiff: false, }, { testName: "will return false if status expired", @@ -1578,6 +1583,18 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1"}, statusRefreshTimeout: time.Minute, expectedUseCache: false, + serverSideDiff: false, + }, + { + testName: "will return true if status expired and server-side diff", + noCache: false, + manifestInfos: manifestInfos("rev1"), + sources: sources(), + app: app("httpbin", "rev1", false, nil), + manifestRevisions: []string{"rev1"}, + statusRefreshTimeout: time.Minute, + expectedUseCache: true, + serverSideDiff: true, }, { testName: "will return false if there is a new revision", @@ -1588,6 +1605,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev2"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: false, + serverSideDiff: false, }, { testName: "will return false if app spec repo changed", @@ -1604,6 +1622,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: false, + serverSideDiff: false, }, { testName: "will return false if app spec IgnoreDifferences changed", @@ -1626,6 +1645,7 @@ func TestUseDiffCache(t *testing.T) { manifestRevisions: []string{"rev1"}, statusRefreshTimeout: time.Hour * 24, expectedUseCache: false, + serverSideDiff: false, }, } @@ -1638,7 +1658,7 @@ func TestUseDiffCache(t *testing.T) { log := logrus.NewEntry(logger) // When - useDiffCache := useDiffCache(tc.noCache, tc.manifestInfos, tc.sources, tc.app, tc.manifestRevisions, tc.statusRefreshTimeout, log) + useDiffCache := useDiffCache(tc.noCache, tc.manifestInfos, tc.sources, tc.app, tc.manifestRevisions, tc.statusRefreshTimeout, tc.serverSideDiff, log) // Then assert.Equal(t, useDiffCache, tc.expectedUseCache) diff --git a/controller/sync.go b/controller/sync.go index 435f62e587c34..c33667a17a88d 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -57,6 +57,27 @@ func (m *appStateManager) getGVKParser(server string) (*managedfields.GvkParser, return cluster.GetGVKParser(), nil } +// getResourceOperations will return the kubectl implementation of the ResourceOperations +// interface that provides functionality to manage kubernetes resources. Returns a +// cleanup function that must be called to remove the generated kube config for this +// server. +func (m *appStateManager) getResourceOperations(server string) (kube.ResourceOperations, func(), error) { + clusterCache, err := m.liveStateCache.GetClusterCache(server) + if err != nil { + return nil, nil, fmt.Errorf("error getting cluster cache: %w", err) + } + + cluster, err := m.db.GetCluster(context.Background(), server) + if err != nil { + return nil, nil, fmt.Errorf("error getting cluster: %w", err) + } + ops, cleanup, err := m.kubectl.ManageResources(cluster.RawRestConfig(), clusterCache.GetOpenAPISchema()) + if err != nil { + return nil, nil, fmt.Errorf("error creating kubectl ResourceOperations: %w", err) + } + return ops, cleanup, nil +} + func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha1.OperationState) { // Sync requests might be requested with ambiguous revisions (e.g. master, HEAD, v1.2.3). // This can change meaning when resuming operations (e.g a hook sync). After calculating a diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index 5e8c04c7e50d6..dac955a9662de 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -68,6 +68,10 @@ data: controller.k8sclient.retry.base.backoff: "100" # Grace period in seconds for ignoring consecutive errors while communicating with repo server. controller.repo.error.grace.period.seconds: "180" + # Enables the server side diff feature at the application controller level. + # Diff calculation will be done by running a server side apply dryrun (when + # diff cache is unavailable). + controller.diff.server.side: "false" ## Server properties # Listen on given address for incoming connections (default "0.0.0.0") diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 434c30621b8bd..1d71fc6494445 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -67,6 +67,7 @@ argocd-application-controller [flags] --sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). --sentinelmaster string Redis sentinel master group name. (default "master") --server string The address and port of the Kubernetes API server + --server-side-diff-enabled Feature flag to enable ServerSide diff. Default ("false") --sharding-method string Enables choice of sharding method. Supported sharding methods are : [legacy, round-robin] (default "legacy") --status-processors int Number of application status processors (default 20) --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. diff --git a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md index 3290098999b7c..29fa5d54d9388 100644 --- a/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md +++ b/docs/user-guide/commands/argocd_admin_app_get-reconcile-results.md @@ -32,6 +32,7 @@ argocd admin app get-reconcile-results PATH [flags] --repo-server string Repo server address. --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") --server string The address and port of the Kubernetes API server + --server-side-diff If set to "true" will use server-side diff while comparing resources. Default ("false") --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use diff --git a/docs/user-guide/diff-strategies.md b/docs/user-guide/diff-strategies.md new file mode 100644 index 0000000000000..a7b3216fa7ec7 --- /dev/null +++ b/docs/user-guide/diff-strategies.md @@ -0,0 +1,125 @@ +# Diff Strategies + +Argo CD calculates the diff between the desired state and the live +state in order to define if an Application is out-of-sync. This same +logic is also used in Argo CD UI to display the differences between +live and desired states for all resources belonging to an application. + +Argo CD currently has 3 different strategies to calculate diffs: + +- **Legacy**: This is the main diff strategy used by default. It + applies a 3-way diff based on live state, desired state and + last-applied-configuration (annotation). +- **Structured-Merge Diff**: Strategy automatically applied when + enabling Server-Side Apply sync option. +- **Server-Side Diff**: New strategy that invokes a Server-Side Apply + in dryrun mode in order to generate the predicted live state. + +## Structured-Merge Diff +*Current Status: [Beta][1] (Since v2.5.0)* + +This is diff strategy is automatically used when Server-Side Apply +sync option is enabled. It uses the [structured-merge-diff][2] library +used by Kubernetes to calculate diffs based on fields ownership. There +are some challenges using this strategy to calculate diffs for CRDs +that define default values. After different issues were identified by +the community, this strategy is being discontinued in favour of +Server-Side Diff. + +## Server-Side Diff +*Current Status: [Beta][1] (Since v2.10.0)* + +This diff strategy will execute a Server-Side Apply in dryrun mode for +each resource of the application. The response of this operation is then +compared with the live state in order to provide the diff results. The +diff results are cached and new Server-Side Apply requests to Kube API +are only triggered when: + +- An Application refresh or hard-refresh is requested. +- There is a new revision in the repo which the Argo CD Application is + targeting. +- The Argo CD Application spec changed. + +One advantage of Server-Side Diff is that Kubernetes Admission +Controllers will participate in the diff calculation. If for example +a validation webhook identifies a resource to be invalid, that will be +informed to Argo CD during the diff stage rather than during the sync +stage. + +### Enabling it + +Server-Side Diff can be enabled at the Argo CD Controller level or per +Application. + +**Enabling Server-Side Diff for all Applications** + +Add the following entry in the argocd-cmd-params-cm configmap: + +``` +controller.diff.server.side: "true" +``` + +Note: It is necessary to restart the `argocd-application-controller` +after applying this configuration. + +**Enabling Server-Side Diff for one application** + +Add the following annotation in the Argo CD Application resource: + +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/compare-options: ServerSideDiff=true +... +``` + +**Disabling Server-Side Diff for one application** + +If Server-Side Diff is enabled globally in your Argo CD instance, it +is possible to disable it at the application level. In order to do so, +add the following annotation in the Application resource: + +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/compare-options: ServerSideDiff=false +... +``` + +*Note: Please report any issues that forced you to disable the +Server-Side Diff feature* + +### Mutation Webhooks + +Server-Side Diff does not include changes made by mutation webhooks by +default. If you want to include mutation webhooks in Argo CD diffs add +the following annotation in the Argo CD Application resource: + +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/compare-options: IncludeMutationWebhook=true +... +``` + +Note: This annoation is only effective when Server-Side Diff is +enabled. To enable both options for a given application add the +following annotation in the Argo CD Application resource: + +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + annotations: + argocd.argoproj.io/compare-options: ServerSideDiff=true,IncludeMutationWebhook=true +... +``` + +[1]: https://github.com/argoproj/argoproj/blob/main/community/feature-status.md#beta +[2]: https://github.com/kubernetes-sigs/structured-merge-diff diff --git a/go.mod b/go.mod index 03283f5c61f09..734b312579e27 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 - github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 + github.com/argoproj/gitops-engine v0.7.1-0.20231218194513-aba38192fb16 github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 @@ -104,7 +104,7 @@ require ( layeh.com/gopher-json v0.0.0-20190114024228-97fed8db8427 oras.land/oras-go/v2 v2.3.0 sigs.k8s.io/controller-runtime v0.14.6 - sigs.k8s.io/structured-merge-diff/v4 v4.3.0 + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 9f0d3f9a0976e..3c9e5941366b4 100644 --- a/go.sum +++ b/go.sum @@ -696,8 +696,8 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48 h1:vnXMrNkBFC0H0KBkH1Jno31OVgJQR4KSd0ypEcfzQRA= -github.com/argoproj/gitops-engine v0.7.1-0.20231102154024-c0c2dd1f6f48/go.mod h1:1TchqKw9XmYYZluyEHa1dTJQoZgbV6PhabB/e8Wf3KY= +github.com/argoproj/gitops-engine v0.7.1-0.20231218194513-aba38192fb16 h1:kR15L8UsSVr7oitABKU88msQirMT0/RO/KRla1jkq/s= +github.com/argoproj/gitops-engine v0.7.1-0.20231218194513-aba38192fb16/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 h1:1lt0VXzmLK7Vv0kaeal3S6/JIfzPyBORkUWXhiqF3l0= github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9/go.mod h1:E/vv4+by868m0mmflaRfGBmKBtAupoF+mmyfekP8QCk= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= @@ -2715,8 +2715,8 @@ sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCY sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= -sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= -sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 4862721961f21..0fbf979809c97 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -34,24 +34,30 @@ spec: name: argocd-cm key: timeout.hard.reconciliation optional: true + - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.error.grace.period.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: repo.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.repo.server.timeout.seconds - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.timeout.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.status.processors - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.status.processors + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS valueFrom: configMapKeyRef: @@ -78,22 +84,22 @@ spec: optional: true - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.self.heal.timeout.seconds - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.timeout.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.repo.server.plaintext - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.plaintext + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.repo.server.strict.tls - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.strict.tls + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH valueFrom: configMapKeyRef: @@ -102,16 +108,16 @@ spec: optional: true - name: ARGOCD_APP_STATE_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.app.state.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.app.state.cache.expiration + optional: true - name: REDIS_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true - name: REDIS_COMPRESSION valueFrom: configMapKeyRef: @@ -120,70 +126,70 @@ spec: optional: true - name: REDISDB valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.db - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true - name: ARGOCD_DEFAULT_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.default.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.default.cache.expiration + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.address - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.insecure - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.headers - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: application.namespaces - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.sharding.algorithm - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.sharding.algorithm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT - valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.kubectl.parallelism.limit - optional: true - - name: ARGOCD_CONTROLLER_HEARTBEAT_TIME valueFrom: configMapKeyRef: name: argocd-cmd-params-cm - key: controller.heatbeat.time + key: controller.kubectl.parallelism.limit optional: true - name: ARGOCD_K8SCLIENT_RETRY_MAX valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.k8sclient.retry.max - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.max + optional: true - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.k8sclient.retry.base.backoff - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.base.backoff + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.diff.server.side + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index f5e5c759e0750..62f98a1449215 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -43,22 +43,22 @@ spec: optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: repo.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.repo.server.timeout.seconds - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.timeout.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.status.processors - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.status.processors + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS valueFrom: configMapKeyRef: @@ -85,22 +85,22 @@ spec: optional: true - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.self.heal.timeout.seconds - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.timeout.seconds + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.repo.server.plaintext - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.plaintext + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.repo.server.strict.tls - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.strict.tls + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH valueFrom: configMapKeyRef: @@ -109,16 +109,16 @@ spec: optional: true - name: ARGOCD_APP_STATE_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.app.state.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.app.state.cache.expiration + optional: true - name: REDIS_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true - name: REDIS_COMPRESSION valueFrom: configMapKeyRef: @@ -127,64 +127,70 @@ spec: optional: true - name: REDISDB valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.db - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true - name: ARGOCD_DEFAULT_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.default.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.default.cache.expiration + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.address - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.insecure - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.headers - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: application.namespaces - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true - name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.sharding.algorithm - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.sharding.algorithm + optional: true - name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.kubectl.parallelism.limit - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.kubectl.parallelism.limit + optional: true - name: ARGOCD_K8SCLIENT_RETRY_MAX valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.k8sclient.retry.max - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.max + optional: true - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: controller.k8sclient.retry.base.backoff - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.k8sclient.retry.base.backoff + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.diff.server.side + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 5d2d225473452..16cc132f23754 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21643,6 +21643,12 @@ spec: key: controller.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 19f8015b04945..bae1de52d5e6f 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -23476,6 +23476,12 @@ spec: key: controller.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 2ecd016092f1b..ad1a7baa8b017 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2861,6 +2861,12 @@ spec: key: controller.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/install.yaml b/manifests/install.yaml index 2f7da39bd9b12..22ba57873b694 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -22520,6 +22520,12 @@ spec: key: controller.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index d74ca00b88e4c..6fa2cdb2b6de0 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1905,6 +1905,12 @@ spec: key: controller.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF + valueFrom: + configMapKeyRef: + key: controller.diff.server.side + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always name: argocd-application-controller diff --git a/mkdocs.yml b/mkdocs.yml index 4a58580e29619..d4c206a01c4d1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -162,7 +162,9 @@ nav: - user-guide/multiple_sources.md - GnuPG verification: user-guide/gpg-verification.md - user-guide/auto_sync.md - - user-guide/diffing.md + - Diffing: + - Diff Strategies: user-guide/diff-strategies.md + - Diff Customization: user-guide/diffing.md - user-guide/orphaned-resources.md - user-guide/compare-options.md - user-guide/sync-options.md diff --git a/util/argo/diff/diff.go b/util/argo/diff/diff.go index 9b104719c5616..c99a04354c751 100644 --- a/util/argo/diff/diff.go +++ b/util/argo/diff/diff.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/go-logr/logr" + log "github.com/sirupsen/logrus" k8smanagedfields "k8s.io/apimachinery/pkg/util/managedfields" @@ -26,7 +27,9 @@ type DiffConfigBuilder struct { // NewDiffConfigBuilder create a new DiffConfigBuilder instance. func NewDiffConfigBuilder() *DiffConfigBuilder { return &DiffConfigBuilder{ - diffConfig: &diffConfig{}, + diffConfig: &diffConfig{ + ignoreMutationWebhook: true, + }, } } @@ -63,7 +66,6 @@ func (b *DiffConfigBuilder) WithNoCache() *DiffConfigBuilder { // WithCache sets the appstatecache.Cache and the appName in the diff config. Those the // are two objects necessary to retrieve a cached diff. func (b *DiffConfigBuilder) WithCache(s *appstatecache.Cache, appName string) *DiffConfigBuilder { - b.diffConfig.noCache = false b.diffConfig.stateCache = s b.diffConfig.appName = appName return b @@ -95,6 +97,21 @@ func (b *DiffConfigBuilder) WithManager(manager string) *DiffConfigBuilder { return b } +func (b *DiffConfigBuilder) WithServerSideDryRunner(ssdr diff.ServerSideDryRunner) *DiffConfigBuilder { + b.diffConfig.serverSideDryRunner = ssdr + return b +} + +func (b *DiffConfigBuilder) WithServerSideDiff(ssd bool) *DiffConfigBuilder { + b.diffConfig.serverSideDiff = ssd + return b +} + +func (b *DiffConfigBuilder) WithIgnoreMutationWebhook(m bool) *DiffConfigBuilder { + b.diffConfig.ignoreMutationWebhook = m + return b +} + // Build will first validate the current state of the diff config and return the // DiffConfig implementation if no errors are found. Will return nil and the error // details otherwise. @@ -140,6 +157,10 @@ type DiffConfig interface { // Manager returns the manager that should be used by the diff while // calculating the structured merge diff. Manager() string + + ServerSideDiff() bool + ServerSideDryRunner() diff.ServerSideDryRunner + IgnoreMutationWebhook() bool } // diffConfig defines the configurations used while applying diffs. @@ -156,6 +177,9 @@ type diffConfig struct { gvkParser *k8smanagedfields.GvkParser structuredMergeDiff bool manager string + serverSideDiff bool + serverSideDryRunner diff.ServerSideDryRunner + ignoreMutationWebhook bool } func (c *diffConfig) Ignores() []v1alpha1.ResourceIgnoreDifferences { @@ -194,6 +218,15 @@ func (c *diffConfig) StructuredMergeDiff() bool { func (c *diffConfig) Manager() string { return c.manager } +func (c *diffConfig) ServerSideDryRunner() diff.ServerSideDryRunner { + return c.serverSideDryRunner +} +func (c *diffConfig) ServerSideDiff() bool { + return c.serverSideDiff +} +func (c *diffConfig) IgnoreMutationWebhook() bool { + return c.ignoreMutationWebhook +} // Validate will check the current state of this diffConfig and return // error if it finds any required configuration missing. @@ -213,6 +246,9 @@ func (c *diffConfig) Validate() error { return fmt.Errorf("%s: StateCache must be set when retrieving from cache", msg) } } + if c.serverSideDiff && c.serverSideDryRunner == nil { + return fmt.Errorf("%s: serverSideDryRunner must be set when using server side diff", msg) + } return nil } @@ -254,6 +290,9 @@ func StateDiffs(lives, configs []*unstructured.Unstructured, diffConfig DiffConf diff.WithStructuredMergeDiff(diffConfig.StructuredMergeDiff()), diff.WithGVKParser(diffConfig.GVKParser()), diff.WithManager(diffConfig.Manager()), + diff.WithServerSideDiff(diffConfig.ServerSideDiff()), + diff.WithServerSideDryRunner(diffConfig.ServerSideDryRunner()), + diff.WithIgnoreMutationWebhook(diffConfig.IgnoreMutationWebhook()), } if diffConfig.Logger() != nil { @@ -282,9 +321,8 @@ func diffArrayCached(configArray []*unstructured.Unstructured, liveArray []*unst } diffByKey := map[kube.ResourceKey]*v1alpha1.ResourceDiff{} - for i := range cachedDiff { - res := cachedDiff[i] - diffByKey[kube.NewResourceKey(res.Group, res.Kind, res.Namespace, res.Name)] = cachedDiff[i] + for _, res := range cachedDiff { + diffByKey[kube.NewResourceKey(res.Group, res.Kind, res.Namespace, res.Name)] = res } diffResultList := diff.DiffResultList{ @@ -335,7 +373,12 @@ func (c *diffConfig) DiffFromCache(appName string) (bool, []*v1alpha1.ResourceDi return false, nil } cachedDiff := make([]*v1alpha1.ResourceDiff, 0) - if c.stateCache != nil && c.stateCache.GetAppManagedResources(appName, &cachedDiff) == nil { + if c.stateCache != nil { + err := c.stateCache.GetAppManagedResources(appName, &cachedDiff) + if err != nil { + log.Errorf("DiffFromCache error: error getting managed resources for app %s: %s", appName, err) + return false, nil + } return true, cachedDiff } return false, nil From 87e95b7485972cfc01b042302a37e037df7b63cc Mon Sep 17 00:00:00 2001 From: Alexy Mantha Date: Mon, 18 Dec 2023 15:38:53 -0500 Subject: [PATCH 167/269] feat(ui): add status panel extensions (#15780) * add extension Signed-off-by: Alexy Mantha * rename to status panel Signed-off-by: Alexy Mantha * wip Signed-off-by: Alexy Mantha * cleanup Signed-off-by: Alexy Mantha * add docs Signed-off-by: Alexy Mantha * add key Signed-off-by: Alexy Mantha * fix copy/paste Signed-off-by: Alexy Mantha * wip Signed-off-by: Alexy Mantha * flyout Signed-off-by: Alexy Mantha * cleanup Signed-off-by: Alexy Mantha * lint Signed-off-by: Alexy Mantha * document flyout Signed-off-by: Alexy Mantha * rename Signed-off-by: Alexy Mantha * linting Signed-off-by: Alexy Mantha --------- Signed-off-by: Alexy Mantha --- .../extensions/ui-extensions.md | 63 +++++++++++++++++++ .../application-details.tsx | 32 +++++++++- .../application-status-panel.tsx | 6 +- .../app/shared/services/extensions-service.ts | 33 +++++++++- 4 files changed, 129 insertions(+), 5 deletions(-) diff --git a/docs/developer-guide/extensions/ui-extensions.md b/docs/developer-guide/extensions/ui-extensions.md index ec1631038ad53..8d3d9dc4a3882 100644 --- a/docs/developer-guide/extensions/ui-extensions.md +++ b/docs/developer-guide/extensions/ui-extensions.md @@ -95,3 +95,66 @@ Below is an example of a simple system level extension: Since the Argo CD Application is a Kubernetes resource, application tabs can be the same as any other resource tab. Make sure to use 'argoproj.io'/'Application' as group/kind and an extension will be used to render the application-level tab. + +## Application Status Panel Extensions + +The status panel is the bar at the top of the application view where the sync status is displayed. Argo CD allows you to add new items to the status panel of an application. The extension should be registered using the `extensionsAPI.registerStatusPanelExtension` method: + +```typescript +registerStatusPanelExtension(component: StatusPanelExtensionComponent, title: string, id: string, flyout?: ExtensionComponent) +``` + +Below is an example of a simple extension: + +```typescript +((window) => { + const component = () => { + return React.createElement( + "div", + { style: { padding: "10px" } }, + "Hello World" + ); + }; + window.extensionsAPI.registerStatusPanelExtension( + component, + "My Extension", + "my_extension" + ); +})(window); +``` + +### Flyout widget + +It is also possible to add an optional flyout widget to your extension. It can be opened by calling `openFlyout()` from your extension's component. Your flyout component will then be rendered in a sliding panel, similar to the panel that opens when clicking on `History and rollback`. + +Below is an example of an extension using the flyout widget: + +```typescript +((window) => { + const component = (props: { + openFlyout: () => any + }) => { + return React.createElement( + "div", + { + style: { padding: "10px" }, + onClick: () => props.openFlyout() + }, + "Hello World" + ); + }; + const flyout = () => { + return React.createElement( + "div", + { style: { padding: "10px" } }, + "This is a flyout" + ); + }; + window.extensionsAPI.registerStatusPanelExtension( + component, + "My Extension", + "my_extension", + flyout + ); +})(window); +``` diff --git a/ui/src/app/applications/components/application-details/application-details.tsx b/ui/src/app/applications/components/application-details/application-details.tsx index 9b0a13f638c7b..a3e8175591dde 100644 --- a/ui/src/app/applications/components/application-details/application-details.tsx +++ b/ui/src/app/applications/components/application-details/application-details.tsx @@ -30,7 +30,7 @@ import {ApplicationsDetailsAppDropdown} from './application-details-app-dropdown import {useSidebarTarget} from '../../../sidebar/sidebar'; import './application-details.scss'; -import {AppViewExtension} from '../../../shared/services/extensions-service'; +import {AppViewExtension, StatusPanelExtension} from '../../../shared/services/extensions-service'; interface ApplicationDetailsState { page: number; @@ -42,6 +42,8 @@ interface ApplicationDetailsState { collapsedNodes?: string[]; extensions?: AppViewExtension[]; extensionsMap?: {[key: string]: AppViewExtension}; + statusExtensions?: StatusPanelExtension[]; + statusExtensionsMap?: {[key: string]: StatusPanelExtension}; } interface FilterInput { @@ -87,6 +89,11 @@ export class ApplicationDetails extends React.Component { extensionsMap[ext.title] = ext; }); + const statusExtensions = services.extensions.getStatusPanelExtensions(); + const statusExtensionsMap: {[key: string]: StatusPanelExtension} = {}; + statusExtensions.forEach(ext => { + statusExtensionsMap[ext.id] = ext; + }); this.state = { page: 0, groupedResources: [], @@ -95,7 +102,9 @@ export class ApplicationDetails extends React.Component this.selectNode(appFullName, 0, 'diff')} showOperation={() => this.setOperationStatusVisible(true)} showConditions={() => this.setConditionsStatusVisible(true)} + showExtension={id => this.setExtensionPanelVisible(id)} showMetadataInfo={revision => this.setState({...this.state, revision})} />
    @@ -732,6 +749,13 @@ export class ApplicationDetails extends React.Component ))} + this.setExtensionPanelVisible('')}> + {this.selectedExtension !== '' && activeExtension && activeExtension.flyout && ( + + )} +
    ); @@ -966,6 +990,10 @@ export class ApplicationDetails extends React.Component any; showOperation?: () => any; showConditions?: () => any; + showExtension?: (id: string) => any; showMetadataInfo?: (revision: string) => any; } @@ -45,7 +46,7 @@ const sectionHeader = (info: SectionInfo, hasMultipleSources: boolean, onClick?: ); }; -export const ApplicationStatusPanel = ({application, showDiff, showOperation, showConditions, showMetadataInfo}: Props) => { +export const ApplicationStatusPanel = ({application, showDiff, showOperation, showConditions, showExtension, showMetadataInfo}: Props) => { const today = new Date(); let daysSinceLastSynchronized = 0; @@ -63,6 +64,8 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh showOperation = null; } + const statusExtensions = services.extensions.getStatusPanelExtensions(); + const infos = cntByCategory.get('info'); const warnings = cntByCategory.get('warning'); const errors = cntByCategory.get('error'); @@ -203,6 +206,7 @@ export const ApplicationStatusPanel = ({application, showDiff, showOperation, sh )} + {statusExtensions && statusExtensions.map(ext => showExtension && showExtension(ext.id)} />)}
    ); }; diff --git a/ui/src/app/shared/services/extensions-service.ts b/ui/src/app/shared/services/extensions-service.ts index 3975fb1aec018..e26f3577b3487 100644 --- a/ui/src/app/shared/services/extensions-service.ts +++ b/ui/src/app/shared/services/extensions-service.ts @@ -6,7 +6,8 @@ import {Application, ApplicationTree, State} from '../models'; const extensions = { resourceExtentions: new Array(), systemLevelExtensions: new Array(), - appViewExtensions: new Array() + appViewExtensions: new Array(), + statusPanelExtensions: new Array() }; function registerResourceExtension(component: ExtensionComponent, group: string, kind: string, tabTitle: string, opts?: {icon: string}) { @@ -21,6 +22,10 @@ function registerAppViewExtension(component: ExtensionComponent, title: string, extensions.appViewExtensions.push({component, title, icon}); } +function registerStatusPanelExtension(component: StatusPanelExtensionComponent, title: string, id: string, flyout?: ExtensionComponent) { + extensions.statusPanelExtensions.push({component, flyout, title, id}); +} + let legacyInitialized = false; function initLegacyExtensions() { @@ -56,9 +61,18 @@ export interface AppViewExtension { icon?: string; } +export interface StatusPanelExtension { + component: StatusPanelExtensionComponent; + flyout?: StatusPanelExtensionFlyoutComponent; + title: string; + id: string; +} + export type ExtensionComponent = React.ComponentType; export type SystemExtensionComponent = React.ComponentType; export type AppViewExtensionComponent = React.ComponentType; +export type StatusPanelExtensionComponent = React.ComponentType; +export type StatusPanelExtensionFlyoutComponent = React.ComponentType; export interface Extension { component: ExtensionComponent; @@ -75,6 +89,16 @@ export interface AppViewComponentProps { tree: ApplicationTree; } +export interface StatusPanelComponentProps { + application: Application; + openFlyout: () => any; +} + +export interface StatusPanelFlyoutProps { + application: Application; + tree: ApplicationTree; +} + export class ExtensionsService { public getResourceTabs(group: string, kind: string): ResourceTabExtension[] { initLegacyExtensions(); @@ -89,6 +113,10 @@ export class ExtensionsService { public getAppViewExtensions(): AppViewExtension[] { return extensions.appViewExtensions.slice(); } + + public getStatusPanelExtensions(): StatusPanelExtension[] { + return extensions.statusPanelExtensions.slice(); + } } ((window: any) => { @@ -97,6 +125,7 @@ export class ExtensionsService { window.extensionsAPI = { registerResourceExtension, registerSystemLevelExtension, - registerAppViewExtension + registerAppViewExtension, + registerStatusPanelExtension }; })(window); From 3224102664b747e88e7330e59b3b44bc9c28cd66 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 00:25:22 +0000 Subject: [PATCH 168/269] chore(deps): bump golang.org/x/crypto from 0.14.0 to 0.17.0 (#16645) Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.14.0 to 0.17.0. - [Commits](https://github.com/golang/crypto/compare/v0.14.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/crypto dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 13 ++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 734b312579e27..377f5c2592d01 100644 --- a/go.mod +++ b/go.mod @@ -80,11 +80,11 @@ require ( go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 go.opentelemetry.io/otel/sdk v1.21.0 - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.17.0 golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/oauth2 v0.11.0 golang.org/x/sync v0.3.0 - golang.org/x/term v0.13.0 + golang.org/x/term v0.15.0 google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 @@ -269,8 +269,8 @@ require ( go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 golang.org/x/tools v0.12.0 // indirect gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect diff --git a/go.sum b/go.sum index 3c9e5941366b4..495bafe5b4053 100644 --- a/go.sum +++ b/go.sum @@ -1815,8 +1815,9 @@ golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0 golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -2134,8 +2135,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2149,8 +2150,9 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= 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= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2169,8 +2171,9 @@ 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.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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= From 7847e7f393c0f83a12d4733a3a887f0875dbb086 Mon Sep 17 00:00:00 2001 From: Abhishek Veeramalla Date: Thu, 21 Dec 2023 14:04:06 +0530 Subject: [PATCH 169/269] chore: fix typo in application controller description (#16671) Signed-off-by: iam-veeramalla --- docs/developer-guide/architecture/components.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-guide/architecture/components.md b/docs/developer-guide/architecture/components.md index eb2904b531ccb..e073751da4867 100644 --- a/docs/developer-guide/architecture/components.md +++ b/docs/developer-guide/architecture/components.md @@ -71,7 +71,7 @@ and the CLI functionalities. ### Application Controller The Application Controller is responsible for reconciling the -Application resource in Kubernetes syncronizing the desired +Application resource in Kubernetes synchronizing the desired application state (provided in Git) with the live state (in Kubernetes). The Application Controller is also responsible for reconciling the Project resource. From 0e67ed89acac213a0dc358001d1fda2804b2d46d Mon Sep 17 00:00:00 2001 From: Robin Lieb Date: Fri, 22 Dec 2023 17:50:33 +0100 Subject: [PATCH 170/269] feat: add initiated by in history and rollback view (#16654) Signed-off-by: Robin Lieb --- assets/swagger.json | 3 + controller/state.go | 13 +- controller/state_test.go | 5 +- controller/sync.go | 2 +- docs/operator-manual/upgrading/2.10-2.11.md | 5 + manifests/core-install.yaml | 13 + manifests/crds/application-crd.yaml | 13 + manifests/ha/install.yaml | 13 + manifests/install.yaml | 13 + mkdocs.yml | 1 + pkg/apis/application/v1alpha1/generated.pb.go | 1422 +++++++++-------- pkg/apis/application/v1alpha1/generated.proto | 3 + .../application/v1alpha1/openapi_generated.go | 9 +- pkg/apis/application/v1alpha1/types.go | 2 + .../v1alpha1/zz_generated.deepcopy.go | 1 + .../application-deployment-history.tsx | 7 + .../initiated-by.tsx | 6 + ui/src/app/shared/models.ts | 1 + 18 files changed, 839 insertions(+), 693 deletions(-) create mode 100644 docs/operator-manual/upgrading/2.10-2.11.md create mode 100644 ui/src/app/applications/components/application-deployment-history/initiated-by.tsx diff --git a/assets/swagger.json b/assets/swagger.json index 44e67d0b3923e..a9f45fcbb1956 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -8499,6 +8499,9 @@ "format": "int64", "title": "ID is an auto incrementing identifier of the RevisionHistory" }, + "initiatedBy": { + "$ref": "#/definitions/v1alpha1OperationInitiator" + }, "revision": { "type": "string", "title": "Revision holds the revision the sync was performed against" diff --git a/controller/state.go b/controller/state.go index 5121fa68fcac9..704411558669b 100644 --- a/controller/state.go +++ b/controller/state.go @@ -880,7 +880,16 @@ func useDiffCache(noCache bool, manifestInfos []*apiclient.ManifestResponse, sou return true } -func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revision string, source v1alpha1.ApplicationSource, revisions []string, sources []v1alpha1.ApplicationSource, hasMultipleSources bool, startedAt metav1.Time) error { +func (m *appStateManager) persistRevisionHistory( + app *v1alpha1.Application, + revision string, + source v1alpha1.ApplicationSource, + revisions []string, + sources []v1alpha1.ApplicationSource, + hasMultipleSources bool, + startedAt metav1.Time, + initiatedBy v1alpha1.OperationInitiator, +) error { var nextID int64 if len(app.Status.History) > 0 { nextID = app.Status.History.LastRevisionHistory().ID + 1 @@ -893,6 +902,7 @@ func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revi ID: nextID, Sources: sources, Revisions: revisions, + InitiatedBy: initiatedBy, }) } else { app.Status.History = append(app.Status.History, v1alpha1.RevisionHistory{ @@ -901,6 +911,7 @@ func (m *appStateManager) persistRevisionHistory(app *v1alpha1.Application, revi DeployStartedAt: &startedAt, ID: nextID, Source: source, + InitiatedBy: initiatedBy, }) } diff --git a/controller/state_test.go b/controller/state_test.go index 5d2342b601a77..1a55e25b262d1 100644 --- a/controller/state_test.go +++ b/controller/state_test.go @@ -23,6 +23,7 @@ import ( "k8s.io/apimachinery/pkg/runtime" "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" "github.com/argoproj/argo-cd/v2/test" @@ -838,7 +839,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { app.Spec.RevisionHistoryLimit = &i } addHistory := func() { - err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1.Time{}) + err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1.Time{}, v1alpha1.OperationInitiator{}) assert.NoError(t, err) } addHistory() @@ -874,7 +875,7 @@ func Test_appStateManager_persistRevisionHistory(t *testing.T) { assert.Len(t, app.Status.History, 9) metav1NowTime := metav1.NewTime(time.Now()) - err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1NowTime) + err := manager.persistRevisionHistory(app, "my-revision", argoappv1.ApplicationSource{}, []string{}, []argoappv1.ApplicationSource{}, false, metav1NowTime, v1alpha1.OperationInitiator{}) assert.NoError(t, err) assert.Equal(t, app.Status.History.LastRevisionHistory().DeployStartedAt, &metav1NowTime) } diff --git a/controller/sync.go b/controller/sync.go index c33667a17a88d..2d21bf1cb1190 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -391,7 +391,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha logEntry.WithField("duration", time.Since(start)).Info("sync/terminate complete") if !syncOp.DryRun && len(syncOp.Resources) == 0 && state.Phase.Successful() { - err := m.persistRevisionHistory(app, compareResult.syncStatus.Revision, source, compareResult.syncStatus.Revisions, compareResult.syncStatus.ComparedTo.Sources, app.Spec.HasMultipleSources(), state.StartedAt) + err := m.persistRevisionHistory(app, compareResult.syncStatus.Revision, source, compareResult.syncStatus.Revisions, compareResult.syncStatus.ComparedTo.Sources, app.Spec.HasMultipleSources(), state.StartedAt, state.Operation.InitiatedBy) if err != nil { state.Phase = common.OperationError state.Message = fmt.Sprintf("failed to record sync to history: %v", err) diff --git a/docs/operator-manual/upgrading/2.10-2.11.md b/docs/operator-manual/upgrading/2.10-2.11.md new file mode 100644 index 0000000000000..4cf5c8ed02b0b --- /dev/null +++ b/docs/operator-manual/upgrading/2.10-2.11.md @@ -0,0 +1,5 @@ +# v2.10 to 2.11 + +## initiatedBy added in Application CRD + +In order to address [argoproj/argo-cd#16612](https://github.com/argoproj/argo-cd/issues/16612), initiatedBy has been added in the Application CRD. \ No newline at end of file diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 16cc132f23754..c9028a44a1ae0 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -1726,6 +1726,19 @@ spec: description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object revision: description: Revision holds the revision the sync was performed against diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index 962543f80eb97..f325dda7da6f7 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -1725,6 +1725,19 @@ spec: description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object revision: description: Revision holds the revision the sync was performed against diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index bae1de52d5e6f..81f365bb8a86d 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -1726,6 +1726,19 @@ spec: description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object revision: description: Revision holds the revision the sync was performed against diff --git a/manifests/install.yaml b/manifests/install.yaml index 22ba57873b694..3d1bbf942afb5 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -1726,6 +1726,19 @@ spec: description: ID is an auto incrementing identifier of the RevisionHistory format: int64 type: integer + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object revision: description: Revision holds the revision the sync was performed against diff --git a/mkdocs.yml b/mkdocs.yml index d4c206a01c4d1..a7e8f86e216cc 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -128,6 +128,7 @@ nav: - operator-manual/server-commands/additional-configuration-method.md - Upgrading: - operator-manual/upgrading/overview.md + - operator-manual/upgrading/2.10-2.11.md - operator-manual/upgrading/2.9-2.10.md - operator-manual/upgrading/2.8-2.9.md - operator-manual/upgrading/2.7-2.8.md diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index 2a9c0f4789bb7..cccbc3f7f15a4 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4448,694 +4448,694 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 10983 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x70, 0x1c, 0xc9, - 0x75, 0x18, 0xae, 0xd9, 0x0f, 0x60, 0xf7, 0xe1, 0x83, 0x64, 0x93, 0xbc, 0x03, 0xa9, 0xbb, 0x03, - 0x3d, 0xf7, 0xf3, 0xe9, 0xfc, 0xd3, 0x1d, 0xe0, 0xa3, 0xef, 0xe4, 0x8b, 0xce, 0x96, 0x8c, 0x0f, - 0x12, 0x04, 0x09, 0x10, 0xb8, 0x06, 0x48, 0x4a, 0x27, 0x9f, 0x4e, 0x83, 0xdd, 0xc6, 0x62, 0x88, - 0xd9, 0x99, 0xb9, 0x99, 0x59, 0x10, 0x38, 0x4b, 0xb2, 0x64, 0xc9, 0xb6, 0x12, 0x7d, 0x9c, 0x22, - 0x25, 0xe5, 0x73, 0x12, 0x29, 0xb2, 0xe5, 0xa4, 0xec, 0x4a, 0x54, 0x71, 0x92, 0x3f, 0xe2, 0xc4, - 0x49, 0xb9, 0x6c, 0xa7, 0x52, 0x4a, 0x29, 0x29, 0xbb, 0x52, 0x2e, 0xcb, 0x49, 0x6c, 0x44, 0x62, - 0x2a, 0x95, 0x54, 0xaa, 0xe2, 0x2a, 0x27, 0xfe, 0x23, 0x61, 0xf2, 0x47, 0xaa, 0xbf, 0x7b, 0x66, - 0x67, 0x81, 0x05, 0x30, 0x20, 0x29, 0xe5, 0xfe, 0xdb, 0xed, 0xf7, 0xe6, 0xbd, 0x9e, 0x9e, 0xee, - 0xf7, 0x5e, 0xbf, 0x7e, 0xef, 0x35, 0x2c, 0xb4, 0xdc, 0x64, 0xa3, 0xb3, 0x36, 0xd1, 0x08, 0xda, - 0x93, 0x4e, 0xd4, 0x0a, 0xc2, 0x28, 0xb8, 0xcd, 0x7e, 0x3c, 0xdb, 0x68, 0x4e, 0x6e, 0x5d, 0x9c, - 0x0c, 0x37, 0x5b, 0x93, 0x4e, 0xe8, 0xc6, 0x93, 0x4e, 0x18, 0x7a, 0x6e, 0xc3, 0x49, 0xdc, 0xc0, - 0x9f, 0xdc, 0x7a, 0xce, 0xf1, 0xc2, 0x0d, 0xe7, 0xb9, 0xc9, 0x16, 0xf1, 0x49, 0xe4, 0x24, 0xa4, - 0x39, 0x11, 0x46, 0x41, 0x12, 0xa0, 0x1f, 0xd3, 0xd4, 0x26, 0x24, 0x35, 0xf6, 0xe3, 0xb5, 0x46, - 0x73, 0x62, 0xeb, 0xe2, 0x44, 0xb8, 0xd9, 0x9a, 0xa0, 0xd4, 0x26, 0x0c, 0x6a, 0x13, 0x92, 0xda, - 0xf9, 0x67, 0x8d, 0xbe, 0xb4, 0x82, 0x56, 0x30, 0xc9, 0x88, 0xae, 0x75, 0xd6, 0xd9, 0x3f, 0xf6, - 0x87, 0xfd, 0xe2, 0xcc, 0xce, 0xdb, 0x9b, 0x2f, 0xc6, 0x13, 0x6e, 0x40, 0xbb, 0x37, 0xd9, 0x08, - 0x22, 0x32, 0xb9, 0xd5, 0xd5, 0xa1, 0xf3, 0x57, 0x34, 0x0e, 0xd9, 0x4e, 0x88, 0x1f, 0xbb, 0x81, - 0x1f, 0x3f, 0x4b, 0xbb, 0x40, 0xa2, 0x2d, 0x12, 0x99, 0xaf, 0x67, 0x20, 0xe4, 0x51, 0x7a, 0x5e, - 0x53, 0x6a, 0x3b, 0x8d, 0x0d, 0xd7, 0x27, 0xd1, 0x8e, 0x7e, 0xbc, 0x4d, 0x12, 0x27, 0xef, 0xa9, - 0xc9, 0x5e, 0x4f, 0x45, 0x1d, 0x3f, 0x71, 0xdb, 0xa4, 0xeb, 0x81, 0xf7, 0xec, 0xf7, 0x40, 0xdc, - 0xd8, 0x20, 0x6d, 0xa7, 0xeb, 0xb9, 0x1f, 0xe9, 0xf5, 0x5c, 0x27, 0x71, 0xbd, 0x49, 0xd7, 0x4f, - 0xe2, 0x24, 0xca, 0x3e, 0x64, 0xbf, 0x0e, 0x23, 0x53, 0xb7, 0x56, 0xa6, 0x3a, 0xc9, 0xc6, 0x4c, - 0xe0, 0xaf, 0xbb, 0x2d, 0xf4, 0x02, 0x0c, 0x35, 0xbc, 0x4e, 0x9c, 0x90, 0xe8, 0xba, 0xd3, 0x26, - 0x63, 0xd6, 0x05, 0xeb, 0xe9, 0xfa, 0xf4, 0xe9, 0x6f, 0xee, 0x8e, 0xbf, 0xe3, 0xee, 0xee, 0xf8, - 0xd0, 0x8c, 0x06, 0x61, 0x13, 0x0f, 0xfd, 0x10, 0x0c, 0x46, 0x81, 0x47, 0xa6, 0xf0, 0xf5, 0xb1, - 0x12, 0x7b, 0xe4, 0x84, 0x78, 0x64, 0x10, 0xf3, 0x66, 0x2c, 0xe1, 0xf6, 0x1f, 0x96, 0x00, 0xa6, - 0xc2, 0x70, 0x39, 0x0a, 0x6e, 0x93, 0x46, 0x82, 0x3e, 0x02, 0x35, 0x3a, 0x74, 0x4d, 0x27, 0x71, - 0x18, 0xb7, 0xa1, 0x8b, 0x3f, 0x3c, 0xc1, 0xdf, 0x64, 0xc2, 0x7c, 0x13, 0x3d, 0x71, 0x28, 0xf6, - 0xc4, 0xd6, 0x73, 0x13, 0x4b, 0x6b, 0xf4, 0xf9, 0x45, 0x92, 0x38, 0xd3, 0x48, 0x30, 0x03, 0xdd, - 0x86, 0x15, 0x55, 0xe4, 0x43, 0x25, 0x0e, 0x49, 0x83, 0x75, 0x6c, 0xe8, 0xe2, 0xc2, 0xc4, 0x51, - 0x66, 0xe8, 0x84, 0xee, 0xf9, 0x4a, 0x48, 0x1a, 0xd3, 0xc3, 0x82, 0x73, 0x85, 0xfe, 0xc3, 0x8c, - 0x0f, 0xda, 0x82, 0x81, 0x38, 0x71, 0x92, 0x4e, 0x3c, 0x56, 0x66, 0x1c, 0xaf, 0x17, 0xc6, 0x91, - 0x51, 0x9d, 0x1e, 0x15, 0x3c, 0x07, 0xf8, 0x7f, 0x2c, 0xb8, 0xd9, 0x7f, 0x62, 0xc1, 0xa8, 0x46, - 0x5e, 0x70, 0xe3, 0x04, 0xfd, 0x64, 0xd7, 0xe0, 0x4e, 0xf4, 0x37, 0xb8, 0xf4, 0x69, 0x36, 0xb4, - 0x27, 0x05, 0xb3, 0x9a, 0x6c, 0x31, 0x06, 0xb6, 0x0d, 0x55, 0x37, 0x21, 0xed, 0x78, 0xac, 0x74, - 0xa1, 0xfc, 0xf4, 0xd0, 0xc5, 0x2b, 0x45, 0xbd, 0xe7, 0xf4, 0x88, 0x60, 0x5a, 0x9d, 0xa7, 0xe4, - 0x31, 0xe7, 0x62, 0xff, 0xda, 0xb0, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x73, 0x30, 0x14, 0x07, 0x9d, - 0xa8, 0x41, 0x30, 0x09, 0x83, 0x78, 0xcc, 0xba, 0x50, 0xa6, 0x53, 0x8f, 0xce, 0xd4, 0x15, 0xdd, - 0x8c, 0x4d, 0x1c, 0xf4, 0x05, 0x0b, 0x86, 0x9b, 0x24, 0x4e, 0x5c, 0x9f, 0xf1, 0x97, 0x9d, 0x5f, - 0x3d, 0x72, 0xe7, 0x65, 0xe3, 0xac, 0x26, 0x3e, 0x7d, 0x46, 0xbc, 0xc8, 0xb0, 0xd1, 0x18, 0xe3, - 0x14, 0x7f, 0xba, 0xe2, 0x9a, 0x24, 0x6e, 0x44, 0x6e, 0x48, 0xff, 0xb3, 0x39, 0x63, 0xac, 0xb8, - 0x59, 0x0d, 0xc2, 0x26, 0x1e, 0xf2, 0xa1, 0x4a, 0x57, 0x54, 0x3c, 0x56, 0x61, 0xfd, 0x9f, 0x3f, - 0x5a, 0xff, 0xc5, 0xa0, 0xd2, 0xc5, 0xaa, 0x47, 0x9f, 0xfe, 0x8b, 0x31, 0x67, 0x83, 0x3e, 0x6f, - 0xc1, 0x98, 0x58, 0xf1, 0x98, 0xf0, 0x01, 0xbd, 0xb5, 0xe1, 0x26, 0xc4, 0x73, 0xe3, 0x64, 0xac, - 0xca, 0xfa, 0x30, 0xd9, 0xdf, 0xdc, 0x9a, 0x8b, 0x82, 0x4e, 0x78, 0xcd, 0xf5, 0x9b, 0xd3, 0x17, - 0x04, 0xa7, 0xb1, 0x99, 0x1e, 0x84, 0x71, 0x4f, 0x96, 0xe8, 0xcb, 0x16, 0x9c, 0xf7, 0x9d, 0x36, - 0x89, 0x43, 0x87, 0x7e, 0x5a, 0x0e, 0x9e, 0xf6, 0x9c, 0xc6, 0x26, 0xeb, 0xd1, 0xc0, 0xe1, 0x7a, - 0x64, 0x8b, 0x1e, 0x9d, 0xbf, 0xde, 0x93, 0x34, 0xde, 0x83, 0x2d, 0xfa, 0xba, 0x05, 0xa7, 0x82, - 0x28, 0xdc, 0x70, 0x7c, 0xd2, 0x94, 0xd0, 0x78, 0x6c, 0x90, 0x2d, 0xbd, 0x0f, 0x1f, 0xed, 0x13, - 0x2d, 0x65, 0xc9, 0x2e, 0x06, 0xbe, 0x9b, 0x04, 0xd1, 0x0a, 0x49, 0x12, 0xd7, 0x6f, 0xc5, 0xd3, - 0x67, 0xef, 0xee, 0x8e, 0x9f, 0xea, 0xc2, 0xc2, 0xdd, 0xfd, 0x41, 0x3f, 0x05, 0x43, 0xf1, 0x8e, - 0xdf, 0xb8, 0xe5, 0xfa, 0xcd, 0xe0, 0x4e, 0x3c, 0x56, 0x2b, 0x62, 0xf9, 0xae, 0x28, 0x82, 0x62, - 0x01, 0x6a, 0x06, 0xd8, 0xe4, 0x96, 0xff, 0xe1, 0xf4, 0x54, 0xaa, 0x17, 0xfd, 0xe1, 0xf4, 0x64, - 0xda, 0x83, 0x2d, 0xfa, 0x79, 0x0b, 0x46, 0x62, 0xb7, 0xe5, 0x3b, 0x49, 0x27, 0x22, 0xd7, 0xc8, - 0x4e, 0x3c, 0x06, 0xac, 0x23, 0x57, 0x8f, 0x38, 0x2a, 0x06, 0xc9, 0xe9, 0xb3, 0xa2, 0x8f, 0x23, - 0x66, 0x6b, 0x8c, 0xd3, 0x7c, 0xf3, 0x16, 0x9a, 0x9e, 0xd6, 0x43, 0xc5, 0x2e, 0x34, 0x3d, 0xa9, - 0x7b, 0xb2, 0x44, 0x3f, 0x01, 0x27, 0x79, 0x93, 0x1a, 0xd9, 0x78, 0x6c, 0x98, 0x09, 0xda, 0x33, - 0x77, 0x77, 0xc7, 0x4f, 0xae, 0x64, 0x60, 0xb8, 0x0b, 0x1b, 0xbd, 0x0e, 0xe3, 0x21, 0x89, 0xda, - 0x6e, 0xb2, 0xe4, 0x7b, 0x3b, 0x52, 0x7c, 0x37, 0x82, 0x90, 0x34, 0x45, 0x77, 0xe2, 0xb1, 0x91, - 0x0b, 0xd6, 0xd3, 0xb5, 0xe9, 0x77, 0x89, 0x6e, 0x8e, 0x2f, 0xef, 0x8d, 0x8e, 0xf7, 0xa3, 0x67, - 0xff, 0xcb, 0x12, 0x9c, 0xcc, 0x2a, 0x4e, 0xf4, 0xb7, 0x2d, 0x38, 0x71, 0xfb, 0x4e, 0xb2, 0x1a, - 0x6c, 0x12, 0x3f, 0x9e, 0xde, 0xa1, 0xe2, 0x8d, 0xa9, 0x8c, 0xa1, 0x8b, 0x8d, 0x62, 0x55, 0xf4, - 0xc4, 0xd5, 0x34, 0x97, 0x4b, 0x7e, 0x12, 0xed, 0x4c, 0x3f, 0x2a, 0xde, 0xee, 0xc4, 0xd5, 0x5b, - 0xab, 0x26, 0x14, 0x67, 0x3b, 0x75, 0xfe, 0xb3, 0x16, 0x9c, 0xc9, 0x23, 0x81, 0x4e, 0x42, 0x79, - 0x93, 0xec, 0x70, 0xab, 0x0c, 0xd3, 0x9f, 0xe8, 0x55, 0xa8, 0x6e, 0x39, 0x5e, 0x87, 0x08, 0xeb, - 0x66, 0xee, 0x68, 0x2f, 0xa2, 0x7a, 0x86, 0x39, 0xd5, 0xf7, 0x96, 0x5e, 0xb4, 0xec, 0xdf, 0x2b, - 0xc3, 0x90, 0xa1, 0xdf, 0xee, 0x83, 0xc5, 0x16, 0xa4, 0x2c, 0xb6, 0xc5, 0xc2, 0x54, 0x73, 0x4f, - 0x93, 0xed, 0x4e, 0xc6, 0x64, 0x5b, 0x2a, 0x8e, 0xe5, 0x9e, 0x36, 0x1b, 0x4a, 0xa0, 0x1e, 0x84, - 0xd4, 0x22, 0xa7, 0xaa, 0xbf, 0x52, 0xc4, 0x27, 0x5c, 0x92, 0xe4, 0xa6, 0x47, 0xee, 0xee, 0x8e, - 0xd7, 0xd5, 0x5f, 0xac, 0x19, 0xd9, 0xdf, 0xb6, 0xe0, 0x8c, 0xd1, 0xc7, 0x99, 0xc0, 0x6f, 0xba, - 0xec, 0xd3, 0x5e, 0x80, 0x4a, 0xb2, 0x13, 0x4a, 0xb3, 0x5f, 0x8d, 0xd4, 0xea, 0x4e, 0x48, 0x30, - 0x83, 0x50, 0x43, 0xbf, 0x4d, 0xe2, 0xd8, 0x69, 0x91, 0xac, 0xa1, 0xbf, 0xc8, 0x9b, 0xb1, 0x84, - 0xa3, 0x08, 0x90, 0xe7, 0xc4, 0xc9, 0x6a, 0xe4, 0xf8, 0x31, 0x23, 0xbf, 0xea, 0xb6, 0x89, 0x18, - 0xe0, 0xff, 0xbf, 0xbf, 0x19, 0x43, 0x9f, 0x98, 0x7e, 0xe4, 0xee, 0xee, 0x38, 0x5a, 0xe8, 0xa2, - 0x84, 0x73, 0xa8, 0xdb, 0x5f, 0xb6, 0xe0, 0x91, 0x7c, 0x5b, 0x0c, 0x3d, 0x05, 0x03, 0x7c, 0xcb, - 0x27, 0xde, 0x4e, 0x7f, 0x12, 0xd6, 0x8a, 0x05, 0x14, 0x4d, 0x42, 0x5d, 0xe9, 0x09, 0xf1, 0x8e, - 0xa7, 0x04, 0x6a, 0x5d, 0x2b, 0x17, 0x8d, 0x43, 0x07, 0x8d, 0xfe, 0x11, 0x96, 0x9b, 0x1a, 0x34, - 0xb6, 0x49, 0x62, 0x10, 0xfb, 0x3f, 0x58, 0x70, 0xc2, 0xe8, 0xd5, 0x7d, 0x30, 0xcd, 0xfd, 0xb4, - 0x69, 0x3e, 0x5f, 0xd8, 0x7c, 0xee, 0x61, 0x9b, 0x7f, 0xde, 0x82, 0xf3, 0x06, 0xd6, 0xa2, 0x93, - 0x34, 0x36, 0x2e, 0x6d, 0x87, 0x11, 0x89, 0xe9, 0x76, 0x1a, 0x3d, 0x6e, 0xc8, 0xad, 0xe9, 0x21, - 0x41, 0xa1, 0x7c, 0x8d, 0xec, 0x70, 0x21, 0xf6, 0x0c, 0xd4, 0xf8, 0xe4, 0x0c, 0x22, 0x31, 0xe2, - 0xea, 0xdd, 0x96, 0x44, 0x3b, 0x56, 0x18, 0xc8, 0x86, 0x01, 0x26, 0x9c, 0xe8, 0x62, 0xa5, 0x6a, - 0x08, 0xe8, 0x47, 0xbc, 0xc9, 0x5a, 0xb0, 0x80, 0xd8, 0x71, 0xaa, 0x3b, 0xcb, 0x11, 0x61, 0x1f, - 0xb7, 0x79, 0xd9, 0x25, 0x5e, 0x33, 0xa6, 0xdb, 0x06, 0xc7, 0xf7, 0x83, 0x44, 0xec, 0x00, 0x8c, - 0x6d, 0xc3, 0x94, 0x6e, 0xc6, 0x26, 0x0e, 0x65, 0xea, 0x39, 0x6b, 0xc4, 0xe3, 0x23, 0x2a, 0x98, - 0x2e, 0xb0, 0x16, 0x2c, 0x20, 0xf6, 0xdd, 0x12, 0xdb, 0xa0, 0xa8, 0xa5, 0x4f, 0xee, 0xc7, 0xee, - 0x36, 0x4a, 0xc9, 0xca, 0xe5, 0xe2, 0x04, 0x17, 0xe9, 0xbd, 0xc3, 0x7d, 0x23, 0x23, 0x2e, 0x71, - 0xa1, 0x5c, 0xf7, 0xde, 0xe5, 0xfe, 0x76, 0x09, 0xc6, 0xd3, 0x0f, 0x74, 0x49, 0x5b, 0xba, 0xa5, - 0x32, 0x18, 0x65, 0x9d, 0x18, 0x06, 0x3e, 0x36, 0xf1, 0x7a, 0x08, 0xac, 0xd2, 0x71, 0x0a, 0x2c, - 0x53, 0x9e, 0x96, 0xf7, 0x91, 0xa7, 0x4f, 0xa9, 0x51, 0xaf, 0x64, 0x04, 0x58, 0x5a, 0xa7, 0x5c, - 0x80, 0x4a, 0x9c, 0x90, 0x70, 0xac, 0x9a, 0x96, 0x47, 0x2b, 0x09, 0x09, 0x31, 0x83, 0xd8, 0xff, - 0xb5, 0x04, 0x8f, 0xa6, 0xc7, 0x50, 0xab, 0x80, 0xf7, 0xa7, 0x54, 0xc0, 0xbb, 0x4d, 0x15, 0x70, - 0x6f, 0x77, 0xfc, 0x9d, 0x3d, 0x1e, 0xfb, 0x9e, 0xd1, 0x10, 0x68, 0x2e, 0x33, 0x8a, 0x93, 0xe9, - 0x51, 0xbc, 0xb7, 0x3b, 0xfe, 0x78, 0x8f, 0x77, 0xcc, 0x0c, 0xf3, 0x53, 0x30, 0x10, 0x11, 0x27, - 0x0e, 0x7c, 0x31, 0xd0, 0xea, 0x73, 0x60, 0xd6, 0x8a, 0x05, 0xd4, 0xfe, 0x37, 0xf5, 0xec, 0x60, - 0xcf, 0x71, 0x27, 0x5c, 0x10, 0x21, 0x17, 0x2a, 0xcc, 0xac, 0xe7, 0xa2, 0xe1, 0xda, 0xd1, 0x96, - 0x11, 0x55, 0x03, 0x8a, 0xf4, 0x74, 0x8d, 0x7e, 0x35, 0xda, 0x84, 0x19, 0x0b, 0xb4, 0x0d, 0xb5, - 0x86, 0xb4, 0xb6, 0x4b, 0x45, 0xf8, 0xa5, 0x84, 0xad, 0xad, 0x39, 0x0e, 0x53, 0x79, 0xad, 0x4c, - 0x74, 0xc5, 0x0d, 0x11, 0x28, 0xb7, 0xdc, 0x44, 0x7c, 0xd6, 0x23, 0xee, 0xa7, 0xe6, 0x5c, 0xe3, - 0x15, 0x07, 0xa9, 0x12, 0x99, 0x73, 0x13, 0x4c, 0xe9, 0xa3, 0x9f, 0xb5, 0x60, 0x28, 0x6e, 0xb4, - 0x97, 0xa3, 0x60, 0xcb, 0x6d, 0x92, 0x48, 0x58, 0x53, 0x47, 0x14, 0x4d, 0x2b, 0x33, 0x8b, 0x92, - 0xa0, 0xe6, 0xcb, 0xf7, 0xb7, 0x1a, 0x82, 0x4d, 0xbe, 0x74, 0x97, 0xf1, 0xa8, 0x78, 0xf7, 0x59, - 0xd2, 0x70, 0xa9, 0xfe, 0x93, 0x9b, 0x2a, 0x36, 0x53, 0x8e, 0x6c, 0x5d, 0xce, 0x76, 0x1a, 0x9b, - 0x74, 0xbd, 0xe9, 0x0e, 0xbd, 0xf3, 0xee, 0xee, 0xf8, 0xa3, 0x33, 0xf9, 0x3c, 0x71, 0xaf, 0xce, - 0xb0, 0x01, 0x0b, 0x3b, 0x9e, 0x87, 0xc9, 0xeb, 0x1d, 0xc2, 0x5c, 0x26, 0x05, 0x0c, 0xd8, 0xb2, - 0x26, 0x98, 0x19, 0x30, 0x03, 0x82, 0x4d, 0xbe, 0xe8, 0x75, 0x18, 0x68, 0x3b, 0x49, 0xe4, 0x6e, - 0x0b, 0x3f, 0xc9, 0x11, 0xed, 0xfd, 0x45, 0x46, 0x4b, 0x33, 0x67, 0x9a, 0x9a, 0x37, 0x62, 0xc1, - 0x08, 0xb5, 0xa1, 0xda, 0x26, 0x51, 0x8b, 0x8c, 0xd5, 0x8a, 0xf0, 0x09, 0x2f, 0x52, 0x52, 0x9a, - 0x61, 0x9d, 0x5a, 0x47, 0xac, 0x0d, 0x73, 0x2e, 0xe8, 0x55, 0xa8, 0xc5, 0xc4, 0x23, 0x0d, 0x6a, - 0xdf, 0xd4, 0x19, 0xc7, 0x1f, 0xe9, 0xd3, 0xd6, 0xa3, 0x86, 0xc5, 0x8a, 0x78, 0x94, 0x2f, 0x30, - 0xf9, 0x0f, 0x2b, 0x92, 0x74, 0x00, 0x43, 0xaf, 0xd3, 0x72, 0xfd, 0x31, 0x28, 0x62, 0x00, 0x97, - 0x19, 0xad, 0xcc, 0x00, 0xf2, 0x46, 0x2c, 0x18, 0xd9, 0xff, 0xc9, 0x02, 0x94, 0x16, 0x6a, 0xf7, - 0xc1, 0xa8, 0x7d, 0x3d, 0x6d, 0xd4, 0x2e, 0x14, 0x69, 0x75, 0xf4, 0xb0, 0x6b, 0x7f, 0xb3, 0x0e, - 0x19, 0x75, 0x70, 0x9d, 0xc4, 0x09, 0x69, 0xbe, 0x2d, 0xc2, 0xdf, 0x16, 0xe1, 0x6f, 0x8b, 0x70, - 0x25, 0xc2, 0xd7, 0x32, 0x22, 0xfc, 0x7d, 0xc6, 0xaa, 0xd7, 0x87, 0xaa, 0xaf, 0xa9, 0x53, 0x57, - 0xb3, 0x07, 0x06, 0x02, 0x95, 0x04, 0x57, 0x57, 0x96, 0xae, 0xe7, 0xca, 0xec, 0xd7, 0xd2, 0x32, - 0xfb, 0xa8, 0x2c, 0xfe, 0x5f, 0x90, 0xd2, 0xff, 0xc2, 0x82, 0x77, 0xa5, 0xa5, 0x97, 0x9c, 0x39, - 0xf3, 0x2d, 0x3f, 0x88, 0xc8, 0xac, 0xbb, 0xbe, 0x4e, 0x22, 0xe2, 0x37, 0x48, 0xac, 0xbc, 0x18, - 0x56, 0x2f, 0x2f, 0x06, 0x7a, 0x1e, 0x86, 0x6f, 0xc7, 0x81, 0xbf, 0x1c, 0xb8, 0xbe, 0x10, 0x41, - 0x74, 0x23, 0x7c, 0xf2, 0xee, 0xee, 0xf8, 0x30, 0x1d, 0x51, 0xd9, 0x8e, 0x53, 0x58, 0x68, 0x06, - 0x4e, 0xdd, 0x7e, 0x7d, 0xd9, 0x49, 0x0c, 0x77, 0x80, 0xdc, 0xb8, 0xb3, 0x03, 0x8b, 0xab, 0x2f, - 0x67, 0x80, 0xb8, 0x1b, 0xdf, 0xfe, 0xeb, 0x25, 0x38, 0x97, 0x79, 0x91, 0xc0, 0xf3, 0x82, 0x4e, - 0x42, 0x37, 0x35, 0xe8, 0xab, 0x16, 0x9c, 0x6c, 0xa7, 0x3d, 0x0e, 0xb1, 0x70, 0xec, 0x7e, 0xa0, - 0x30, 0x1d, 0x91, 0x71, 0x69, 0x4c, 0x8f, 0x89, 0x11, 0x3a, 0x99, 0x01, 0xc4, 0xb8, 0xab, 0x2f, - 0xe8, 0x55, 0xa8, 0xb7, 0x9d, 0xed, 0x1b, 0x61, 0xd3, 0x49, 0xe4, 0x7e, 0xb2, 0xb7, 0x1b, 0xa0, - 0x93, 0xb8, 0xde, 0x04, 0x3f, 0xae, 0x9f, 0x98, 0xf7, 0x93, 0xa5, 0x68, 0x25, 0x89, 0x5c, 0xbf, - 0xc5, 0xdd, 0x79, 0x8b, 0x92, 0x0c, 0xd6, 0x14, 0xed, 0xaf, 0x58, 0x59, 0x25, 0xa5, 0x46, 0x27, - 0x72, 0x12, 0xd2, 0xda, 0x41, 0x1f, 0x85, 0x2a, 0xdd, 0xf8, 0xc9, 0x51, 0xb9, 0x55, 0xa4, 0xe6, - 0x34, 0xbe, 0x84, 0x56, 0xa2, 0xf4, 0x5f, 0x8c, 0x39, 0x53, 0xfb, 0xab, 0xf5, 0xac, 0xb1, 0xc0, - 0x0e, 0x6f, 0x2f, 0x02, 0xb4, 0x82, 0x55, 0xd2, 0x0e, 0x3d, 0x3a, 0x2c, 0x16, 0x3b, 0x01, 0x50, - 0xbe, 0x8e, 0x39, 0x05, 0xc1, 0x06, 0x16, 0xfa, 0x8b, 0x16, 0x40, 0x4b, 0xce, 0x79, 0x69, 0x08, - 0xdc, 0x28, 0xf2, 0x75, 0xf4, 0x8a, 0xd2, 0x7d, 0x51, 0x0c, 0xb1, 0xc1, 0x1c, 0xfd, 0x8c, 0x05, - 0xb5, 0x44, 0x76, 0x9f, 0xab, 0xc6, 0xd5, 0x22, 0x7b, 0x22, 0x5f, 0x5a, 0xdb, 0x44, 0x6a, 0x48, - 0x14, 0x5f, 0xf4, 0x73, 0x16, 0x40, 0xbc, 0xe3, 0x37, 0x96, 0x03, 0xcf, 0x6d, 0xec, 0x08, 0x8d, - 0x79, 0xb3, 0x50, 0x7f, 0x8c, 0xa2, 0x3e, 0x3d, 0x4a, 0x47, 0x43, 0xff, 0xc7, 0x06, 0x67, 0xf4, - 0x71, 0xa8, 0xc5, 0x62, 0xba, 0x09, 0x1d, 0xb9, 0x5a, 0xac, 0x57, 0x88, 0xd3, 0x16, 0xe2, 0x55, - 0xfc, 0xc3, 0x8a, 0x27, 0xfa, 0x05, 0x0b, 0x4e, 0x84, 0x69, 0x3f, 0x9f, 0x50, 0x87, 0xc5, 0xc9, - 0x80, 0x8c, 0x1f, 0x71, 0xfa, 0xf4, 0xdd, 0xdd, 0xf1, 0x13, 0x99, 0x46, 0x9c, 0xed, 0x05, 0x95, - 0x80, 0x7a, 0x06, 0x2f, 0x85, 0xdc, 0xe7, 0x38, 0xa8, 0x25, 0xe0, 0x5c, 0x16, 0x88, 0xbb, 0xf1, - 0xd1, 0x32, 0x9c, 0xa1, 0xbd, 0xdb, 0xe1, 0xe6, 0xa7, 0x54, 0x2f, 0x31, 0x53, 0x86, 0xb5, 0xe9, - 0xc7, 0xc4, 0x0c, 0x61, 0x5e, 0xfd, 0x2c, 0x0e, 0xce, 0x7d, 0x12, 0xfd, 0x9e, 0x05, 0x8f, 0xb9, - 0x4c, 0x0d, 0x98, 0x0e, 0x73, 0xad, 0x11, 0xc4, 0x49, 0x2c, 0x29, 0x54, 0x56, 0xf4, 0x52, 0x3f, - 0xd3, 0xff, 0x9f, 0x78, 0x83, 0xc7, 0xe6, 0xf7, 0xe8, 0x12, 0xde, 0xb3, 0xc3, 0xe8, 0x47, 0x61, - 0x44, 0xae, 0x8b, 0x65, 0x2a, 0x82, 0x99, 0xa2, 0xad, 0x4f, 0x9f, 0xba, 0xbb, 0x3b, 0x3e, 0xb2, - 0x6a, 0x02, 0x70, 0x1a, 0xcf, 0xfe, 0x56, 0x29, 0x75, 0x1e, 0xa2, 0x9c, 0x90, 0x4c, 0xdc, 0x34, - 0xa4, 0xff, 0x47, 0x4a, 0xcf, 0x42, 0xc5, 0x8d, 0xf2, 0x2e, 0x69, 0x71, 0xa3, 0x9a, 0x62, 0x6c, - 0x30, 0xa7, 0x46, 0xe9, 0x29, 0x27, 0xeb, 0xea, 0x14, 0x12, 0xf0, 0xd5, 0x22, 0xbb, 0xd4, 0x7d, - 0x7a, 0x75, 0x4e, 0x74, 0xed, 0x54, 0x17, 0x08, 0x77, 0x77, 0xc9, 0xfe, 0x56, 0xfa, 0x0c, 0xc6, - 0x58, 0xbc, 0x7d, 0x9c, 0x2f, 0x7d, 0xc1, 0x82, 0xa1, 0x28, 0xf0, 0x3c, 0xd7, 0x6f, 0x51, 0x41, - 0x23, 0xb4, 0xe5, 0x87, 0x8e, 0x45, 0x61, 0x09, 0x89, 0xc2, 0x4c, 0x5b, 0xac, 0x79, 0x62, 0xb3, - 0x03, 0xf6, 0x9f, 0x58, 0x30, 0xd6, 0x4b, 0x20, 0x22, 0x02, 0xef, 0x94, 0xab, 0x5d, 0x45, 0x57, - 0x2c, 0xf9, 0xb3, 0xc4, 0x23, 0xca, 0xf1, 0x5c, 0x9b, 0x7e, 0x52, 0xbc, 0xe6, 0x3b, 0x97, 0x7b, - 0xa3, 0xe2, 0xbd, 0xe8, 0xa0, 0x57, 0xe0, 0xa4, 0xf1, 0x5e, 0xb1, 0x1a, 0x98, 0xfa, 0xf4, 0x04, - 0xb5, 0x40, 0xa6, 0x32, 0xb0, 0x7b, 0xbb, 0xe3, 0x8f, 0x64, 0xdb, 0x84, 0xc4, 0xee, 0xa2, 0x63, - 0xff, 0x4a, 0x29, 0xfb, 0xb5, 0x94, 0xb2, 0x7d, 0xcb, 0xea, 0xda, 0xce, 0x7f, 0xe0, 0x38, 0x14, - 0x1c, 0xdb, 0xf8, 0xab, 0x00, 0x8e, 0xde, 0x38, 0x0f, 0xf0, 0x84, 0xd8, 0xfe, 0x57, 0x15, 0xd8, - 0xa3, 0x67, 0x7d, 0x58, 0xcf, 0x07, 0x3e, 0x56, 0xfc, 0x9c, 0xa5, 0x8e, 0x9c, 0xca, 0x6c, 0x91, - 0x37, 0x8f, 0x6b, 0xec, 0xf9, 0x06, 0x26, 0xe6, 0x51, 0x0a, 0xca, 0x8d, 0x9d, 0x3e, 0xdc, 0x42, - 0x5f, 0xb3, 0xd2, 0x87, 0x66, 0x3c, 0xec, 0xcc, 0x3d, 0xb6, 0x3e, 0x19, 0x27, 0x71, 0xbc, 0x63, - 0xfa, 0xfc, 0xa6, 0xd7, 0x19, 0xdd, 0x04, 0xc0, 0xba, 0xeb, 0x3b, 0x9e, 0xfb, 0x06, 0xdd, 0x9e, - 0x54, 0x99, 0x86, 0x65, 0x26, 0xcb, 0x65, 0xd5, 0x8a, 0x0d, 0x8c, 0xf3, 0x7f, 0x01, 0x86, 0x8c, - 0x37, 0xcf, 0x09, 0xae, 0x38, 0x63, 0x06, 0x57, 0xd4, 0x8d, 0x98, 0x88, 0xf3, 0xef, 0x83, 0x93, - 0xd9, 0x0e, 0x1e, 0xe4, 0x79, 0xfb, 0x7f, 0x0e, 0x66, 0x4f, 0xb1, 0x56, 0x49, 0xd4, 0xa6, 0x5d, - 0x7b, 0xdb, 0xb3, 0xf4, 0xb6, 0x67, 0xe9, 0x6d, 0xcf, 0x92, 0x79, 0x38, 0x20, 0xbc, 0x26, 0x83, - 0xf7, 0xc9, 0x6b, 0x92, 0xf2, 0x03, 0xd5, 0x0a, 0xf7, 0x03, 0xd9, 0x77, 0xab, 0x90, 0xb2, 0xa3, - 0xf8, 0x78, 0xff, 0x10, 0x0c, 0x46, 0x24, 0x0c, 0x6e, 0xe0, 0x05, 0xa1, 0x43, 0x74, 0x00, 0x3d, - 0x6f, 0xc6, 0x12, 0x4e, 0x75, 0x4d, 0xe8, 0x24, 0x1b, 0x42, 0x89, 0x28, 0x5d, 0xb3, 0xec, 0x24, - 0x1b, 0x98, 0x41, 0xd0, 0xfb, 0x60, 0x34, 0x71, 0xa2, 0x16, 0xb5, 0xb7, 0xb7, 0xd8, 0x67, 0x15, - 0x67, 0x9d, 0x8f, 0x08, 0xdc, 0xd1, 0xd5, 0x14, 0x14, 0x67, 0xb0, 0xd1, 0xeb, 0x50, 0xd9, 0x20, - 0x5e, 0x5b, 0x0c, 0xf9, 0x4a, 0x71, 0x32, 0x9e, 0xbd, 0xeb, 0x15, 0xe2, 0xb5, 0xb9, 0x04, 0xa2, - 0xbf, 0x30, 0x63, 0x45, 0xe7, 0x5b, 0x7d, 0xb3, 0x13, 0x27, 0x41, 0xdb, 0x7d, 0x43, 0xba, 0xf8, - 0x3e, 0x50, 0x30, 0xe3, 0x6b, 0x92, 0x3e, 0xf7, 0xa5, 0xa8, 0xbf, 0x58, 0x73, 0x66, 0xfd, 0x68, - 0xba, 0x11, 0xfb, 0x54, 0x3b, 0xc2, 0x53, 0x57, 0x74, 0x3f, 0x66, 0x25, 0x7d, 0xde, 0x0f, 0xf5, - 0x17, 0x6b, 0xce, 0x68, 0x47, 0xcd, 0xfb, 0x21, 0xd6, 0x87, 0x1b, 0x05, 0xf7, 0x81, 0xcf, 0xf9, - 0xdc, 0xf9, 0xff, 0x24, 0x54, 0x1b, 0x1b, 0x4e, 0x94, 0x8c, 0x0d, 0xb3, 0x49, 0xa3, 0x7c, 0x3a, - 0x33, 0xb4, 0x11, 0x73, 0x18, 0x7a, 0x1c, 0xca, 0x11, 0x59, 0x67, 0x71, 0x9b, 0x46, 0x44, 0x0f, - 0x26, 0xeb, 0x98, 0xb6, 0xdb, 0xbf, 0x54, 0x4a, 0x9b, 0x4b, 0xe9, 0xf7, 0xe6, 0xb3, 0xbd, 0xd1, - 0x89, 0x62, 0xe9, 0xf7, 0x31, 0x66, 0x3b, 0x6b, 0xc6, 0x12, 0x8e, 0x3e, 0x69, 0xc1, 0xe0, 0xed, - 0x38, 0xf0, 0x7d, 0x92, 0x08, 0xd5, 0x74, 0xb3, 0xe0, 0xa1, 0xb8, 0xca, 0xa9, 0xeb, 0x3e, 0x88, - 0x06, 0x2c, 0xf9, 0xd2, 0xee, 0x92, 0xed, 0x86, 0xd7, 0x69, 0x76, 0x05, 0x69, 0x5c, 0xe2, 0xcd, - 0x58, 0xc2, 0x29, 0xaa, 0xeb, 0x73, 0xd4, 0x4a, 0x1a, 0x75, 0xde, 0x17, 0xa8, 0x02, 0x6e, 0xff, - 0xd5, 0x01, 0x38, 0x9b, 0xbb, 0x38, 0xa8, 0x21, 0xc3, 0x4c, 0x85, 0xcb, 0xae, 0x47, 0x64, 0x78, - 0x12, 0x33, 0x64, 0x6e, 0xaa, 0x56, 0x6c, 0x60, 0xa0, 0x9f, 0x06, 0x08, 0x9d, 0xc8, 0x69, 0x13, - 0xe5, 0x97, 0x3d, 0xb2, 0xbd, 0x40, 0xfb, 0xb1, 0x2c, 0x69, 0xea, 0xbd, 0xa9, 0x6a, 0x8a, 0xb1, - 0xc1, 0x12, 0xbd, 0x00, 0x43, 0x11, 0xf1, 0x88, 0x13, 0xb3, 0xb0, 0xdf, 0x6c, 0x0e, 0x03, 0xd6, - 0x20, 0x6c, 0xe2, 0xa1, 0xa7, 0x54, 0x24, 0x57, 0x26, 0xa2, 0x25, 0x1d, 0xcd, 0x85, 0xde, 0xb4, - 0x60, 0x74, 0xdd, 0xf5, 0x88, 0xe6, 0x2e, 0x32, 0x0e, 0x96, 0x8e, 0xfe, 0x92, 0x97, 0x4d, 0xba, - 0x5a, 0x42, 0xa6, 0x9a, 0x63, 0x9c, 0x61, 0x4f, 0x3f, 0xf3, 0x16, 0x89, 0x98, 0x68, 0x1d, 0x48, - 0x7f, 0xe6, 0x9b, 0xbc, 0x19, 0x4b, 0x38, 0x9a, 0x82, 0x13, 0xa1, 0x13, 0xc7, 0x33, 0x11, 0x69, - 0x12, 0x3f, 0x71, 0x1d, 0x8f, 0xe7, 0x03, 0xd4, 0x74, 0x3c, 0xf0, 0x72, 0x1a, 0x8c, 0xb3, 0xf8, - 0xe8, 0x83, 0xf0, 0x28, 0x77, 0x7c, 0x2c, 0xba, 0x71, 0xec, 0xfa, 0x2d, 0x3d, 0x0d, 0x84, 0xff, - 0x67, 0x5c, 0x90, 0x7a, 0x74, 0x3e, 0x1f, 0x0d, 0xf7, 0x7a, 0x1e, 0x3d, 0x03, 0xb5, 0x78, 0xd3, - 0x0d, 0x67, 0xa2, 0x66, 0xcc, 0x0e, 0x3d, 0x6a, 0xda, 0xdb, 0xb8, 0x22, 0xda, 0xb1, 0xc2, 0x40, - 0x0d, 0x18, 0xe6, 0x9f, 0x84, 0x87, 0xa2, 0x09, 0xf9, 0xf8, 0x6c, 0x4f, 0xf5, 0x28, 0x52, 0xd6, - 0x26, 0xb0, 0x73, 0xe7, 0x92, 0x3c, 0x82, 0xe1, 0x27, 0x06, 0x37, 0x0d, 0x32, 0x38, 0x45, 0xd4, - 0xfe, 0xc5, 0x52, 0x7a, 0xc7, 0x6d, 0x2e, 0x52, 0x14, 0xd3, 0xa5, 0x98, 0xdc, 0x74, 0x22, 0xe9, - 0x8d, 0x39, 0x62, 0xda, 0x82, 0xa0, 0x7b, 0xd3, 0x89, 0xcc, 0x45, 0xcd, 0x18, 0x60, 0xc9, 0x09, - 0xdd, 0x86, 0x4a, 0xe2, 0x39, 0x05, 0xe5, 0x39, 0x19, 0x1c, 0xb5, 0x03, 0x64, 0x61, 0x2a, 0xc6, - 0x8c, 0x07, 0x7a, 0x8c, 0x5a, 0xfd, 0x6b, 0xf2, 0x88, 0x44, 0x18, 0xea, 0x6b, 0x31, 0x66, 0xad, - 0xf6, 0xaf, 0x42, 0x8e, 0x5c, 0x55, 0x8a, 0x0c, 0x5d, 0x04, 0xa0, 0x1b, 0xc8, 0xe5, 0x88, 0xac, - 0xbb, 0xdb, 0xc2, 0x90, 0x50, 0x6b, 0xf7, 0xba, 0x82, 0x60, 0x03, 0x4b, 0x3e, 0xb3, 0xd2, 0x59, - 0xa7, 0xcf, 0x94, 0xba, 0x9f, 0xe1, 0x10, 0x6c, 0x60, 0xa1, 0xe7, 0x61, 0xc0, 0x6d, 0x3b, 0x2d, - 0x15, 0x82, 0xf9, 0x18, 0x5d, 0xb4, 0xf3, 0xac, 0xe5, 0xde, 0xee, 0xf8, 0xa8, 0xea, 0x10, 0x6b, - 0xc2, 0x02, 0x17, 0xfd, 0x8a, 0x05, 0xc3, 0x8d, 0xa0, 0xdd, 0x0e, 0x7c, 0xbe, 0xed, 0x12, 0x7b, - 0xc8, 0xdb, 0xc7, 0xa5, 0xe6, 0x27, 0x66, 0x0c, 0x66, 0x7c, 0x13, 0xa9, 0x12, 0xb2, 0x4c, 0x10, - 0x4e, 0xf5, 0xca, 0x5c, 0xdb, 0xd5, 0x7d, 0xd6, 0xf6, 0x6f, 0x58, 0x70, 0x8a, 0x3f, 0x6b, 0xec, - 0x06, 0x45, 0xee, 0x51, 0x70, 0xcc, 0xaf, 0xd5, 0xb5, 0x41, 0x56, 0x5e, 0xba, 0x2e, 0x38, 0xee, - 0xee, 0x24, 0x9a, 0x83, 0x53, 0xeb, 0x41, 0xd4, 0x20, 0xe6, 0x40, 0x08, 0xc1, 0xa4, 0x08, 0x5d, - 0xce, 0x22, 0xe0, 0xee, 0x67, 0xd0, 0x4d, 0x78, 0xc4, 0x68, 0x34, 0xc7, 0x81, 0xcb, 0xa6, 0x27, - 0x04, 0xb5, 0x47, 0x2e, 0xe7, 0x62, 0xe1, 0x1e, 0x4f, 0xa7, 0x1d, 0x26, 0xf5, 0x3e, 0x1c, 0x26, - 0xaf, 0xc1, 0xb9, 0x46, 0xf7, 0xc8, 0x6c, 0xc5, 0x9d, 0xb5, 0x98, 0x4b, 0xaa, 0xda, 0xf4, 0x0f, - 0x08, 0x02, 0xe7, 0x66, 0x7a, 0x21, 0xe2, 0xde, 0x34, 0xd0, 0x47, 0xa1, 0x16, 0x11, 0xf6, 0x55, - 0x62, 0x91, 0x88, 0x73, 0xc4, 0x5d, 0xb2, 0xb6, 0x40, 0x39, 0x59, 0x2d, 0x7b, 0x45, 0x43, 0x8c, - 0x15, 0x47, 0x74, 0x07, 0x06, 0x43, 0x27, 0x69, 0x6c, 0x88, 0xf4, 0x9b, 0x23, 0xc7, 0xbf, 0x28, - 0xe6, 0xcc, 0x07, 0xae, 0x27, 0xf9, 0x32, 0x67, 0x82, 0x25, 0x37, 0x6a, 0x8d, 0x34, 0x82, 0x76, - 0x18, 0xf8, 0xc4, 0x4f, 0xe2, 0xb1, 0x11, 0x6d, 0x8d, 0xcc, 0xa8, 0x56, 0x6c, 0x60, 0x9c, 0x7f, - 0x3f, 0x9c, 0xea, 0x5a, 0x78, 0x07, 0x72, 0xae, 0xcc, 0xc2, 0x23, 0xf9, 0x53, 0xfc, 0x40, 0x2e, - 0x96, 0x7f, 0x98, 0x09, 0x72, 0x35, 0xcc, 0xde, 0x3e, 0xdc, 0x75, 0x0e, 0x94, 0x89, 0xbf, 0x25, - 0x24, 0xfe, 0xe5, 0xa3, 0x8d, 0xf4, 0x25, 0x7f, 0x8b, 0xaf, 0x50, 0xe6, 0x93, 0xb8, 0xe4, 0x6f, - 0x61, 0x4a, 0x1b, 0x7d, 0xc9, 0x4a, 0x99, 0x6d, 0xdc, 0xc9, 0xf7, 0xe1, 0x63, 0xb1, 0xf3, 0xfb, - 0xb6, 0xe4, 0xec, 0x7f, 0x5d, 0x82, 0x0b, 0xfb, 0x11, 0xe9, 0x63, 0xf8, 0x9e, 0x84, 0x81, 0x98, - 0x1d, 0x5b, 0x0b, 0x11, 0x3a, 0x44, 0x67, 0x16, 0x3f, 0xc8, 0x7e, 0x0d, 0x0b, 0x10, 0xf2, 0xa0, - 0xdc, 0x76, 0x42, 0xe1, 0xfb, 0x99, 0x3f, 0x6a, 0xda, 0x0b, 0xfd, 0xef, 0x78, 0x8b, 0x4e, 0xc8, - 0x3d, 0x0a, 0x46, 0x03, 0xa6, 0x6c, 0x50, 0x02, 0x55, 0x27, 0x8a, 0x1c, 0x79, 0x46, 0x7a, 0xad, - 0x18, 0x7e, 0x53, 0x94, 0x24, 0x3f, 0x62, 0x4a, 0x35, 0x61, 0xce, 0xcc, 0xfe, 0xdc, 0x60, 0x2a, - 0xf5, 0x83, 0x1d, 0x7c, 0xc7, 0x30, 0x20, 0x5c, 0x3e, 0x56, 0xd1, 0xd9, 0x46, 0x3c, 0x77, 0x8f, - 0xed, 0xea, 0x44, 0x06, 0xb4, 0x60, 0x85, 0x3e, 0x6b, 0xb1, 0x3c, 0x63, 0x99, 0x0e, 0x23, 0xf6, - 0x52, 0xc7, 0x93, 0xf6, 0x6c, 0x66, 0x2f, 0xcb, 0x46, 0x6c, 0x72, 0xa7, 0x3a, 0x36, 0xe4, 0x19, - 0x73, 0xd9, 0x1d, 0x95, 0xcc, 0x44, 0x96, 0x70, 0xb4, 0x9d, 0x73, 0xc0, 0x5d, 0x40, 0xae, 0x6a, - 0x1f, 0x47, 0xda, 0x5f, 0xb3, 0xe0, 0x94, 0x9b, 0x3d, 0xa9, 0x14, 0x3b, 0x8f, 0x23, 0x86, 0x50, - 0xf4, 0x3e, 0x08, 0x55, 0xca, 0xb7, 0x0b, 0x84, 0xbb, 0x3b, 0x83, 0x9a, 0x50, 0x71, 0xfd, 0xf5, - 0x40, 0x98, 0x1c, 0xd3, 0x47, 0xeb, 0xd4, 0xbc, 0xbf, 0x1e, 0xe8, 0xd5, 0x4c, 0xff, 0x61, 0x46, - 0x1d, 0x2d, 0xc0, 0x99, 0x48, 0xf8, 0x86, 0xae, 0xb8, 0x31, 0xdd, 0xc1, 0x2f, 0xb8, 0x6d, 0x37, - 0x61, 0xe6, 0x42, 0x79, 0x7a, 0xec, 0xee, 0xee, 0xf8, 0x19, 0x9c, 0x03, 0xc7, 0xb9, 0x4f, 0xa1, - 0x37, 0x60, 0x50, 0x26, 0x46, 0xd7, 0x8a, 0xd8, 0xc5, 0x75, 0xcf, 0x7f, 0x35, 0x99, 0x56, 0x44, - 0x0e, 0xb4, 0x64, 0x68, 0xbf, 0x39, 0x04, 0xdd, 0x87, 0x98, 0xe8, 0x63, 0x50, 0x8f, 0x54, 0xb2, - 0xb6, 0x55, 0x84, 0x72, 0x95, 0xdf, 0x57, 0x1c, 0xa0, 0x2a, 0xc3, 0x45, 0xa7, 0x65, 0x6b, 0x8e, - 0x74, 0x7b, 0x11, 0xeb, 0xb3, 0xce, 0x02, 0xe6, 0xb6, 0xe0, 0xaa, 0xcf, 0xb1, 0x76, 0xfc, 0x06, - 0x66, 0x3c, 0x50, 0x04, 0x03, 0x1b, 0xc4, 0xf1, 0x92, 0x8d, 0x62, 0x5c, 0xee, 0x57, 0x18, 0xad, - 0x6c, 0xca, 0x0e, 0x6f, 0xc5, 0x82, 0x13, 0xda, 0x86, 0xc1, 0x0d, 0x3e, 0x01, 0x84, 0xc5, 0xbf, - 0x78, 0xd4, 0xc1, 0x4d, 0xcd, 0x2a, 0xfd, 0xb9, 0x45, 0x03, 0x96, 0xec, 0x58, 0x74, 0x8c, 0x71, - 0x7e, 0xcf, 0x97, 0x6e, 0x71, 0xd9, 0x4a, 0xfd, 0x1f, 0xde, 0x7f, 0x04, 0x86, 0x23, 0xd2, 0x08, - 0xfc, 0x86, 0xeb, 0x91, 0xe6, 0x94, 0x74, 0xa7, 0x1f, 0x24, 0xc7, 0x85, 0xed, 0x9a, 0xb1, 0x41, - 0x03, 0xa7, 0x28, 0xa2, 0xcf, 0x58, 0x30, 0xaa, 0x32, 0x3c, 0xe9, 0x07, 0x21, 0xc2, 0x7d, 0xbb, - 0x50, 0x50, 0x3e, 0x29, 0xa3, 0x39, 0x8d, 0xee, 0xee, 0x8e, 0x8f, 0xa6, 0xdb, 0x70, 0x86, 0x2f, - 0x7a, 0x05, 0x20, 0x58, 0xe3, 0x21, 0x30, 0x53, 0x89, 0xf0, 0xe5, 0x1e, 0xe4, 0x55, 0x47, 0x79, - 0xb2, 0x9b, 0xa4, 0x80, 0x0d, 0x6a, 0xe8, 0x1a, 0x00, 0x5f, 0x36, 0xab, 0x3b, 0xa1, 0xdc, 0x16, - 0xc8, 0x24, 0x25, 0x58, 0x51, 0x90, 0x7b, 0xbb, 0xe3, 0xdd, 0xbe, 0x35, 0x16, 0x66, 0x60, 0x3c, - 0x8e, 0x7e, 0x0a, 0x06, 0xe3, 0x4e, 0xbb, 0xed, 0x28, 0x4f, 0x6f, 0x81, 0xe9, 0x73, 0x9c, 0xae, - 0x21, 0x8a, 0x78, 0x03, 0x96, 0x1c, 0xd1, 0x6d, 0x2a, 0x54, 0x63, 0xe1, 0xf4, 0x63, 0xab, 0x88, - 0xdb, 0x04, 0x43, 0xec, 0x9d, 0xde, 0x23, 0x23, 0x7a, 0x70, 0x0e, 0xce, 0xbd, 0xdd, 0xf1, 0x47, - 0xd2, 0xed, 0x0b, 0x81, 0x48, 0x68, 0xcb, 0xa5, 0x89, 0xae, 0xca, 0x3a, 0x29, 0xf4, 0xb5, 0x65, - 0xfa, 0xfe, 0xd3, 0xba, 0x4e, 0x0a, 0x6b, 0xee, 0x3d, 0x66, 0xe6, 0xc3, 0x68, 0x11, 0x4e, 0x37, - 0x02, 0x3f, 0x89, 0x02, 0xcf, 0xe3, 0xc5, 0x7f, 0xf8, 0x0e, 0x8d, 0x7b, 0x82, 0xdf, 0x29, 0xba, - 0x7d, 0x7a, 0xa6, 0x1b, 0x05, 0xe7, 0x3d, 0x67, 0xfb, 0xe9, 0xd8, 0x40, 0x31, 0x38, 0xcf, 0xc3, - 0x30, 0xd9, 0x4e, 0x48, 0xe4, 0x3b, 0xde, 0x0d, 0xbc, 0x20, 0x7d, 0xa0, 0x6c, 0x0d, 0x5c, 0x32, - 0xda, 0x71, 0x0a, 0x0b, 0xd9, 0xca, 0x2d, 0x61, 0x24, 0x69, 0x72, 0xb7, 0x84, 0x74, 0x42, 0xd8, - 0xff, 0xab, 0x94, 0x32, 0xc8, 0x56, 0x23, 0x42, 0x50, 0x00, 0x55, 0x3f, 0x68, 0x2a, 0xd9, 0x7f, - 0xb5, 0x18, 0xd9, 0x7f, 0x3d, 0x68, 0x1a, 0xc5, 0x54, 0xe8, 0xbf, 0x18, 0x73, 0x3e, 0xac, 0xda, - 0x84, 0x2c, 0xcb, 0xc1, 0x00, 0x62, 0xa3, 0x51, 0x24, 0x67, 0x55, 0x6d, 0x62, 0xc9, 0x64, 0x84, - 0xd3, 0x7c, 0xd1, 0x26, 0x54, 0x37, 0x82, 0x38, 0x91, 0xdb, 0x8f, 0x23, 0xee, 0x74, 0xae, 0x04, - 0x71, 0xc2, 0xac, 0x08, 0xf5, 0xda, 0xb4, 0x25, 0xc6, 0x9c, 0x87, 0xfd, 0x9f, 0xad, 0x94, 0xc7, - 0xfb, 0x16, 0x8b, 0x93, 0xdd, 0x22, 0x3e, 0x5d, 0xd6, 0x66, 0x60, 0xd0, 0x8f, 0x66, 0xb2, 0x0e, - 0xdf, 0xd5, 0xab, 0xb4, 0xd5, 0x1d, 0x4a, 0x61, 0x82, 0x91, 0x30, 0x62, 0x88, 0x3e, 0x61, 0xa5, - 0xf3, 0x3f, 0x4b, 0x45, 0x6c, 0x30, 0xcc, 0x1c, 0xe8, 0x7d, 0x53, 0x49, 0xed, 0x2f, 0x59, 0x30, - 0x38, 0xed, 0x34, 0x36, 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0xd4, 0x9a, 0x9d, 0xc8, 0x4c, 0x45, 0x55, - 0xdb, 0xfc, 0x59, 0xd1, 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x66, 0x42, 0x97, 0xf9, - 0x1c, 0xbe, 0xcc, 0x5a, 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xa8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, - 0xf6, 0x45, 0x0d, 0xc2, 0x26, 0x9e, 0xfd, 0xcf, 0x2d, 0x18, 0x9b, 0x76, 0x62, 0xb7, 0x31, 0xd5, - 0x49, 0x36, 0xa6, 0xdd, 0x64, 0xad, 0xd3, 0xd8, 0x24, 0x09, 0x4f, 0x7f, 0xa7, 0xbd, 0xec, 0xc4, - 0x74, 0x29, 0xa9, 0x7d, 0x9d, 0xea, 0xe5, 0x0d, 0xd1, 0x8e, 0x15, 0x06, 0x7a, 0x03, 0x86, 0x42, - 0x27, 0x8e, 0xef, 0x04, 0x51, 0x13, 0x93, 0xf5, 0x62, 0x8a, 0x4f, 0xac, 0x90, 0x46, 0x44, 0x12, - 0x4c, 0xd6, 0xc5, 0x91, 0xb0, 0xa6, 0x8f, 0x4d, 0x66, 0xf6, 0x17, 0x2c, 0x38, 0x37, 0x4d, 0x9c, - 0x88, 0x44, 0xac, 0x56, 0x85, 0x7a, 0x91, 0x19, 0x2f, 0xe8, 0x34, 0xd1, 0xeb, 0x50, 0x4b, 0x68, - 0x33, 0xed, 0x96, 0x55, 0x6c, 0xb7, 0xd8, 0x89, 0xee, 0xaa, 0x20, 0x8e, 0x15, 0x1b, 0xfb, 0xaf, - 0x59, 0x30, 0xcc, 0x0e, 0xc7, 0x66, 0x49, 0xe2, 0xb8, 0x5e, 0x57, 0x49, 0x27, 0xab, 0xcf, 0x92, - 0x4e, 0x17, 0xa0, 0xb2, 0x11, 0xb4, 0x49, 0xf6, 0x60, 0xf7, 0x4a, 0x40, 0xb7, 0xd5, 0x14, 0x82, - 0x9e, 0xa3, 0x1f, 0xde, 0xf5, 0x13, 0x87, 0x2e, 0x01, 0xe9, 0x7c, 0x3d, 0xc1, 0x3f, 0xba, 0x6a, - 0xc6, 0x26, 0x8e, 0xfd, 0xdb, 0x75, 0x18, 0x14, 0xa7, 0xff, 0x7d, 0x97, 0x40, 0x90, 0xfb, 0xfb, - 0x52, 0xcf, 0xfd, 0x7d, 0x0c, 0x03, 0x0d, 0x56, 0x30, 0x4e, 0x98, 0x91, 0xd7, 0x0a, 0x09, 0x17, - 0xe1, 0x35, 0xe8, 0x74, 0xb7, 0xf8, 0x7f, 0x2c, 0x58, 0xa1, 0x2f, 0x5a, 0x70, 0xa2, 0x11, 0xf8, - 0x3e, 0x69, 0x68, 0x1b, 0xa7, 0x52, 0x44, 0x54, 0xc0, 0x4c, 0x9a, 0xa8, 0x3e, 0x99, 0xc9, 0x00, - 0x70, 0x96, 0x3d, 0x7a, 0x09, 0x46, 0xf8, 0x98, 0xdd, 0x4c, 0x79, 0x8c, 0x75, 0xa5, 0x1f, 0x13, - 0x88, 0xd3, 0xb8, 0x68, 0x82, 0x7b, 0xde, 0x45, 0x4d, 0x9d, 0x01, 0xed, 0x58, 0x33, 0xaa, 0xe9, - 0x18, 0x18, 0x28, 0x02, 0x14, 0x91, 0xf5, 0x88, 0xc4, 0x1b, 0x22, 0x3a, 0x82, 0xd9, 0x57, 0x83, - 0x87, 0x4b, 0x97, 0xc6, 0x5d, 0x94, 0x70, 0x0e, 0x75, 0xb4, 0x29, 0x36, 0x98, 0xb5, 0x22, 0x64, - 0xa8, 0xf8, 0xcc, 0x3d, 0xf7, 0x99, 0xe3, 0x50, 0x8d, 0x37, 0x9c, 0xa8, 0xc9, 0xec, 0xba, 0x32, - 0x4f, 0xd1, 0x59, 0xa1, 0x0d, 0x98, 0xb7, 0xa3, 0x59, 0x38, 0x99, 0xa9, 0x53, 0x14, 0x0b, 0xcf, - 0xae, 0x4a, 0xc7, 0xc8, 0x54, 0x38, 0x8a, 0x71, 0xd7, 0x13, 0xa6, 0xf3, 0x61, 0x68, 0x1f, 0xe7, - 0xc3, 0x8e, 0x8a, 0xc1, 0xe3, 0x3e, 0xd7, 0x97, 0x0b, 0x19, 0x80, 0xbe, 0x02, 0xee, 0x3e, 0x9f, - 0x09, 0xb8, 0x1b, 0x61, 0x1d, 0xb8, 0x59, 0x4c, 0x07, 0x0e, 0x1e, 0x5d, 0xf7, 0x20, 0xa3, 0xe5, - 0xfe, 0xdc, 0x02, 0xf9, 0x5d, 0x67, 0x9c, 0xc6, 0x06, 0xa1, 0x53, 0x06, 0xbd, 0x0f, 0x46, 0xd5, - 0x16, 0x7a, 0x26, 0xe8, 0xf8, 0x3c, 0x50, 0xae, 0xac, 0x8f, 0x70, 0x71, 0x0a, 0x8a, 0x33, 0xd8, - 0x68, 0x12, 0xea, 0x74, 0x9c, 0xf8, 0xa3, 0x5c, 0xd7, 0xaa, 0x6d, 0xfa, 0xd4, 0xf2, 0xbc, 0x78, - 0x4a, 0xe3, 0xa0, 0x00, 0x4e, 0x79, 0x4e, 0x9c, 0xb0, 0x1e, 0xd0, 0x1d, 0xf5, 0x21, 0x8b, 0x15, - 0xb0, 0x98, 0xff, 0x85, 0x2c, 0x21, 0xdc, 0x4d, 0xdb, 0xfe, 0x76, 0x05, 0x46, 0x52, 0x92, 0xf1, - 0x80, 0x4a, 0xfa, 0x19, 0xa8, 0x49, 0xbd, 0x99, 0x2d, 0xab, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, - 0x6b, 0x4d, 0x6b, 0xd5, 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, - 0x8c, 0xe7, 0x12, 0x3f, 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, - 0xce, 0x00, 0x70, 0x96, 0x3d, 0xfa, 0xb4, 0x05, 0x23, 0xce, 0x9d, 0x58, 0x57, 0x35, 0x15, 0xa1, - 0x75, 0x47, 0x54, 0x52, 0xa9, 0x42, 0xa9, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, - 0x0b, 0x10, 0xd9, 0x26, 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x50, 0xc4, 0x4e, 0xf3, 0x52, 0x17, - 0x5d, 0x2e, 0xd5, 0xbb, 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x52, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, - 0x3a, 0x46, 0xdc, 0x9b, 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0x03, 0x99, 0x4a, 0x99, - 0x2a, 0x3d, 0xa0, 0x94, 0xa9, 0x9f, 0xb1, 0x52, 0x05, 0x84, 0x86, 0x2e, 0xbe, 0x52, 0x6c, 0xac, - 0xeb, 0x04, 0x8f, 0x6d, 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, - 0xe1, 0xbf, 0x2b, 0xc3, 0x90, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, - 0x30, 0x8b, 0x7e, 0x1a, 0xea, 0x0d, 0x29, 0xe5, 0x8b, 0x29, 0xa1, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, - 0xab, 0x26, 0xac, 0x79, 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x15, 0xa6, 0x21, 0xf2, 0x32, - 0x61, 0x84, 0xa6, 0xe8, 0x7e, 0x86, 0xd5, 0x99, 0x0a, 0x5d, 0xf1, 0x5e, 0x32, 0x22, 0x9d, 0xd7, - 0x99, 0x5a, 0x9e, 0x97, 0xcd, 0xd8, 0xc4, 0xb1, 0xbf, 0x6d, 0xa9, 0x8f, 0x7b, 0x1f, 0x2a, 0x2a, - 0xdc, 0x4e, 0x57, 0x54, 0xb8, 0x54, 0xc8, 0x30, 0xf7, 0x28, 0xa5, 0x70, 0x1d, 0x06, 0x67, 0x82, - 0x76, 0xdb, 0xf1, 0x9b, 0xe8, 0x07, 0x61, 0xb0, 0xc1, 0x7f, 0x0a, 0xc7, 0x0e, 0x3b, 0x1e, 0x14, - 0x50, 0x2c, 0x61, 0xe8, 0x31, 0xa8, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x54, 0xd4, - 0x8a, 0x31, 0x6b, 0xb5, 0xff, 0x41, 0x05, 0xd8, 0x09, 0xb4, 0x13, 0x91, 0xe6, 0x6a, 0xc0, 0x4a, - 0xf8, 0x1d, 0xeb, 0xa1, 0x9a, 0xde, 0x2c, 0x3d, 0xcc, 0x07, 0x6b, 0xc6, 0xe1, 0x4a, 0xf9, 0x3e, - 0x1f, 0xae, 0xf4, 0x38, 0x2f, 0xab, 0x3c, 0x44, 0xe7, 0x65, 0xf6, 0xe7, 0x2c, 0x40, 0x2a, 0x6c, - 0x41, 0x1f, 0x68, 0x4f, 0x42, 0x5d, 0x05, 0x30, 0x08, 0xc3, 0x4a, 0x8b, 0x08, 0x09, 0xc0, 0x1a, - 0xa7, 0x8f, 0x1d, 0xf2, 0x93, 0x52, 0x7e, 0x97, 0xd3, 0x51, 0xb4, 0x4c, 0xea, 0x0b, 0x71, 0x6e, - 0xff, 0x4e, 0x09, 0x1e, 0xe1, 0x2a, 0x79, 0xd1, 0xf1, 0x9d, 0x16, 0x69, 0xd3, 0x5e, 0xf5, 0x1b, - 0xa2, 0xd0, 0xa0, 0x5b, 0x33, 0x57, 0x46, 0xc5, 0x1e, 0x75, 0xed, 0xf2, 0x35, 0xc7, 0x57, 0xd9, - 0xbc, 0xef, 0x26, 0x98, 0x11, 0x47, 0x31, 0xd4, 0x64, 0xcd, 0x78, 0x21, 0x8b, 0x0b, 0x62, 0xa4, - 0xc4, 0x92, 0xd0, 0x9b, 0x04, 0x2b, 0x46, 0xd4, 0x70, 0xf5, 0x82, 0xc6, 0x26, 0x26, 0x61, 0xc0, - 0xe4, 0xae, 0x11, 0x94, 0xb8, 0x20, 0xda, 0xb1, 0xc2, 0xb0, 0x7f, 0xc7, 0x82, 0xac, 0x46, 0x32, - 0x6a, 0xa5, 0x59, 0x7b, 0xd6, 0x4a, 0x3b, 0x40, 0xb1, 0xb2, 0x9f, 0x84, 0x21, 0x27, 0xa1, 0x46, - 0x04, 0xdf, 0x76, 0x97, 0x0f, 0x77, 0xac, 0xb1, 0x18, 0x34, 0xdd, 0x75, 0x97, 0x6d, 0xb7, 0x4d, - 0x72, 0xf6, 0x7f, 0xaf, 0xc0, 0xa9, 0xae, 0xdc, 0x0d, 0xf4, 0x22, 0x0c, 0x37, 0xc4, 0xf4, 0x08, - 0xa5, 0x43, 0xab, 0x6e, 0x06, 0xb1, 0x69, 0x18, 0x4e, 0x61, 0xf6, 0x31, 0x41, 0xe7, 0xe1, 0x74, - 0x44, 0x37, 0xfa, 0x1d, 0x32, 0xb5, 0x9e, 0x90, 0x68, 0x85, 0x34, 0x02, 0xbf, 0xc9, 0x2b, 0xfa, - 0x95, 0xa7, 0x1f, 0xbd, 0xbb, 0x3b, 0x7e, 0x1a, 0x77, 0x83, 0x71, 0xde, 0x33, 0x28, 0x84, 0x11, - 0xcf, 0xb4, 0x01, 0xc5, 0x06, 0xe0, 0x50, 0xe6, 0xa3, 0xb2, 0x11, 0x52, 0xcd, 0x38, 0xcd, 0x20, - 0x6d, 0x48, 0x56, 0x1f, 0x90, 0x21, 0xf9, 0x29, 0x6d, 0x48, 0xf2, 0xf3, 0xf7, 0x0f, 0x15, 0x9c, - 0xbb, 0x73, 0xdc, 0x96, 0xe4, 0xcb, 0x50, 0x93, 0xb1, 0x49, 0x7d, 0xc5, 0xf4, 0x98, 0x74, 0x7a, - 0x48, 0xb4, 0x7b, 0x25, 0xc8, 0xd9, 0x84, 0xd0, 0x75, 0xa6, 0x35, 0x7e, 0x6a, 0x9d, 0x1d, 0x4c, - 0xeb, 0xa3, 0x6d, 0x1e, 0x97, 0xc5, 0x75, 0xdb, 0x07, 0x8b, 0xde, 0x44, 0xe9, 0x50, 0x2d, 0x95, - 0xd2, 0xa0, 0xc2, 0xb5, 0x2e, 0x02, 0x68, 0x43, 0x4d, 0x04, 0xac, 0xab, 0x63, 0x5f, 0x6d, 0xcf, - 0x61, 0x03, 0x8b, 0xee, 0xa9, 0x5d, 0x3f, 0x4e, 0x1c, 0xcf, 0xbb, 0xe2, 0xfa, 0x89, 0x70, 0x0e, - 0x2a, 0x25, 0x3e, 0xaf, 0x41, 0xd8, 0xc4, 0x3b, 0xff, 0x1e, 0xe3, 0xbb, 0x1c, 0xe4, 0x7b, 0x6e, - 0xc0, 0xb9, 0x39, 0x37, 0x51, 0x69, 0x16, 0x6a, 0x1e, 0x51, 0x3b, 0x4c, 0xa5, 0x0d, 0x59, 0x3d, - 0xd3, 0x86, 0x8c, 0x34, 0x87, 0x52, 0x3a, 0x2b, 0x23, 0x9b, 0xe6, 0x60, 0xbf, 0x08, 0x67, 0xe6, - 0xdc, 0xe4, 0xb2, 0xeb, 0x91, 0x03, 0x32, 0xb1, 0x7f, 0x6b, 0x00, 0x86, 0xcd, 0x44, 0xbd, 0x83, - 0x64, 0x3e, 0x7d, 0x81, 0x9a, 0x5a, 0xe2, 0xed, 0x5c, 0x75, 0x68, 0x76, 0xeb, 0xc8, 0x59, 0x83, - 0xf9, 0x23, 0x66, 0x58, 0x5b, 0x9a, 0x27, 0x36, 0x3b, 0x80, 0xee, 0x40, 0x75, 0x9d, 0x85, 0xe1, - 0x97, 0x8b, 0x88, 0x2c, 0xc8, 0x1b, 0x51, 0xbd, 0xcc, 0x78, 0x20, 0x3f, 0xe7, 0x47, 0x35, 0x64, - 0x94, 0xce, 0xed, 0x32, 0x42, 0x47, 0x45, 0x56, 0x97, 0xc2, 0xe8, 0x25, 0xea, 0xab, 0x87, 0x10, - 0xf5, 0x29, 0xc1, 0x3b, 0xf0, 0x80, 0x04, 0x2f, 0x4b, 0xa9, 0x48, 0x36, 0x98, 0xfd, 0x26, 0x62, - 0xdd, 0x07, 0xd9, 0x20, 0x18, 0x29, 0x15, 0x29, 0x30, 0xce, 0xe2, 0xa3, 0x8f, 0x2b, 0xd1, 0x5d, - 0x2b, 0xc2, 0xaf, 0x6a, 0xce, 0xe8, 0xe3, 0x96, 0xda, 0x9f, 0x2b, 0xc1, 0xe8, 0x9c, 0xdf, 0x59, - 0x9e, 0x5b, 0xee, 0xac, 0x79, 0x6e, 0xe3, 0x1a, 0xd9, 0xa1, 0xa2, 0x79, 0x93, 0xec, 0xcc, 0xcf, - 0x8a, 0x15, 0xa4, 0xe6, 0xcc, 0x35, 0xda, 0x88, 0x39, 0x8c, 0x0a, 0xa3, 0x75, 0xd7, 0x6f, 0x91, - 0x28, 0x8c, 0x5c, 0xe1, 0xf2, 0x34, 0x84, 0xd1, 0x65, 0x0d, 0xc2, 0x26, 0x1e, 0xa5, 0x1d, 0xdc, - 0xf1, 0x49, 0x94, 0x35, 0x64, 0x97, 0x68, 0x23, 0xe6, 0x30, 0x8a, 0x94, 0x44, 0x9d, 0x38, 0x11, - 0x93, 0x51, 0x21, 0xad, 0xd2, 0x46, 0xcc, 0x61, 0x74, 0xa5, 0xc7, 0x9d, 0x35, 0x16, 0xb8, 0x91, - 0x09, 0xac, 0x5f, 0xe1, 0xcd, 0x58, 0xc2, 0x29, 0xea, 0x26, 0xd9, 0x99, 0xa5, 0xbb, 0xde, 0x4c, - 0x7e, 0xcd, 0x35, 0xde, 0x8c, 0x25, 0x9c, 0x95, 0x22, 0x4c, 0x0f, 0xc7, 0xf7, 0x5c, 0x29, 0xc2, - 0x74, 0xf7, 0x7b, 0xec, 0x9f, 0x7f, 0xd9, 0x82, 0x61, 0x33, 0xdc, 0x0a, 0xb5, 0x32, 0x36, 0xee, - 0x52, 0x57, 0x25, 0xdb, 0x1f, 0xcf, 0xbb, 0xda, 0xab, 0xe5, 0x26, 0x41, 0x18, 0x3f, 0x4b, 0xfc, - 0x96, 0xeb, 0x13, 0x76, 0x8a, 0xce, 0xc3, 0xb4, 0x52, 0xb1, 0x5c, 0x33, 0x41, 0x93, 0x1c, 0xc2, - 0x48, 0xb6, 0x6f, 0xc1, 0xa9, 0xae, 0xa4, 0xaa, 0x3e, 0x4c, 0x8b, 0x7d, 0x53, 0x5a, 0x6d, 0x0c, - 0x43, 0x94, 0xb0, 0x2c, 0x87, 0x33, 0x03, 0xa7, 0xf8, 0x42, 0xa2, 0x9c, 0x56, 0x1a, 0x1b, 0xa4, - 0xad, 0x12, 0xe5, 0x98, 0x7f, 0xfd, 0x66, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0xcf, 0x5b, 0x30, 0x92, - 0xca, 0x73, 0x2b, 0xc8, 0x08, 0x62, 0x2b, 0x2d, 0x60, 0xd1, 0x7f, 0x2c, 0x04, 0xba, 0xcc, 0x94, - 0xa9, 0x5e, 0x69, 0x1a, 0x84, 0x4d, 0x3c, 0xfb, 0x4b, 0x25, 0xa8, 0xc9, 0x08, 0x8a, 0x3e, 0xba, - 0xf2, 0x59, 0x0b, 0x46, 0xd4, 0x99, 0x06, 0x73, 0x96, 0x95, 0x8a, 0x48, 0x4a, 0xa0, 0x3d, 0x50, - 0xdb, 0x6d, 0x7f, 0x3d, 0xd0, 0x16, 0x39, 0x36, 0x99, 0xe1, 0x34, 0x6f, 0x74, 0x13, 0x20, 0xde, - 0x89, 0x13, 0xd2, 0x36, 0xdc, 0x76, 0xb6, 0xb1, 0xe2, 0x26, 0x1a, 0x41, 0x44, 0xe8, 0xfa, 0xba, - 0x1e, 0x34, 0xc9, 0x8a, 0xc2, 0xd4, 0x26, 0x94, 0x6e, 0xc3, 0x06, 0x25, 0xfb, 0xef, 0x95, 0xe0, - 0x64, 0xb6, 0x4b, 0xe8, 0x43, 0x30, 0x2c, 0xb9, 0x1b, 0xd7, 0x94, 0xc9, 0xb0, 0x91, 0x61, 0x6c, - 0xc0, 0xee, 0xed, 0x8e, 0x8f, 0x77, 0x5f, 0x13, 0x37, 0x61, 0xa2, 0xe0, 0x14, 0x31, 0x7e, 0xb0, - 0x24, 0x4e, 0x40, 0xa7, 0x77, 0xa6, 0xc2, 0x50, 0x9c, 0x0e, 0x19, 0x07, 0x4b, 0x26, 0x14, 0x67, - 0xb0, 0xd1, 0x32, 0x9c, 0x31, 0x5a, 0xae, 0x13, 0xb7, 0xb5, 0xb1, 0x16, 0x44, 0x72, 0x67, 0xf5, - 0x98, 0x0e, 0xec, 0xea, 0xc6, 0xc1, 0xb9, 0x4f, 0x52, 0x6d, 0xdf, 0x70, 0x42, 0xa7, 0xe1, 0x26, - 0x3b, 0xc2, 0x0f, 0xa9, 0x64, 0xd3, 0x8c, 0x68, 0xc7, 0x0a, 0xc3, 0x5e, 0x84, 0x4a, 0x9f, 0x33, - 0xa8, 0x2f, 0x8b, 0xfe, 0x65, 0xa8, 0x51, 0x72, 0xd2, 0xbc, 0x2b, 0x82, 0x64, 0x00, 0x35, 0x79, - 0xd3, 0x08, 0xb2, 0xa1, 0xec, 0x3a, 0xf2, 0xec, 0x4e, 0xbd, 0xd6, 0x7c, 0x1c, 0x77, 0xd8, 0x26, - 0x99, 0x02, 0xd1, 0x93, 0x50, 0x26, 0xdb, 0x61, 0xf6, 0x90, 0xee, 0xd2, 0x76, 0xe8, 0x46, 0x24, - 0xa6, 0x48, 0x64, 0x3b, 0x44, 0xe7, 0xa1, 0xe4, 0x36, 0x85, 0x92, 0x02, 0x81, 0x53, 0x9a, 0x9f, - 0xc5, 0x25, 0xb7, 0x69, 0x6f, 0x43, 0x5d, 0x5d, 0x6d, 0x82, 0x36, 0xa5, 0xec, 0xb6, 0x8a, 0x08, - 0x79, 0x92, 0x74, 0x7b, 0x48, 0xed, 0x0e, 0x80, 0x4e, 0xf8, 0x2b, 0x4a, 0xbe, 0x5c, 0x80, 0x4a, - 0x23, 0x10, 0xc9, 0xc8, 0x35, 0x4d, 0x86, 0x09, 0x6d, 0x06, 0xb1, 0x6f, 0xc1, 0xe8, 0x35, 0x3f, - 0xb8, 0xc3, 0xea, 0xb2, 0xb3, 0x32, 0x64, 0x94, 0xf0, 0x3a, 0xfd, 0x91, 0x35, 0x11, 0x18, 0x14, - 0x73, 0x98, 0xaa, 0xcf, 0x54, 0xea, 0x55, 0x9f, 0xc9, 0xfe, 0x84, 0x05, 0xc3, 0x2a, 0x73, 0x68, - 0x6e, 0x6b, 0x93, 0xd2, 0x6d, 0x45, 0x41, 0x27, 0xcc, 0xd2, 0x65, 0x97, 0x0f, 0x61, 0x0e, 0x33, - 0x53, 0xea, 0x4a, 0xfb, 0xa4, 0xd4, 0x5d, 0x80, 0xca, 0xa6, 0xeb, 0x37, 0xb3, 0xb7, 0x69, 0x5c, - 0x73, 0xfd, 0x26, 0x66, 0x10, 0xda, 0x85, 0x93, 0xaa, 0x0b, 0x52, 0x21, 0xbc, 0x08, 0xc3, 0x6b, - 0x1d, 0xd7, 0x6b, 0xca, 0xfa, 0x6a, 0x19, 0x4f, 0xc9, 0xb4, 0x01, 0xc3, 0x29, 0x4c, 0xba, 0xaf, - 0x5b, 0x73, 0x7d, 0x27, 0xda, 0x59, 0xd6, 0x1a, 0x48, 0x09, 0xa5, 0x69, 0x05, 0xc1, 0x06, 0x96, - 0xfd, 0x66, 0x19, 0x46, 0xd3, 0xf9, 0x53, 0x7d, 0x6c, 0xaf, 0x9e, 0x84, 0x2a, 0x4b, 0xa9, 0xca, - 0x7e, 0x5a, 0x5e, 0x92, 0x8c, 0xc3, 0x50, 0x0c, 0x03, 0xbc, 0x18, 0x43, 0x31, 0x37, 0xd1, 0xa8, - 0x4e, 0x2a, 0xff, 0x0a, 0x8b, 0x27, 0x13, 0xf5, 0x1f, 0x04, 0x2b, 0xf4, 0x69, 0x0b, 0x06, 0x83, - 0xd0, 0xac, 0xeb, 0xf3, 0xc1, 0x22, 0x73, 0xcb, 0x44, 0xb2, 0x8c, 0xb0, 0x88, 0xd5, 0xa7, 0x97, - 0x9f, 0x43, 0xb2, 0x3e, 0xff, 0x5e, 0x18, 0x36, 0x31, 0xf7, 0x33, 0x8a, 0x6b, 0xa6, 0x51, 0xfc, - 0x59, 0x73, 0x52, 0x88, 0xec, 0xb9, 0x3e, 0x96, 0xdb, 0x0d, 0xa8, 0x36, 0x54, 0x00, 0xc0, 0xa1, - 0xaa, 0x72, 0xaa, 0xea, 0x08, 0xec, 0x10, 0x88, 0x53, 0xb3, 0xbf, 0x6d, 0x19, 0xf3, 0x03, 0x93, - 0x78, 0xbe, 0x89, 0x22, 0x28, 0xb7, 0xb6, 0x36, 0x85, 0x29, 0x7a, 0xb5, 0xa0, 0xe1, 0x9d, 0xdb, - 0xda, 0xd4, 0x73, 0xdc, 0x6c, 0xc5, 0x94, 0x59, 0x1f, 0x4e, 0xc0, 0x54, 0x92, 0x65, 0x79, 0xff, - 0x24, 0x4b, 0xfb, 0xad, 0x12, 0x9c, 0xea, 0x9a, 0x54, 0xe8, 0x0d, 0xa8, 0x46, 0xf4, 0x2d, 0xc5, - 0xeb, 0x2d, 0x14, 0x96, 0x16, 0x19, 0xcf, 0x37, 0xb5, 0xde, 0x4d, 0xb7, 0x63, 0xce, 0x12, 0x5d, - 0x05, 0xa4, 0xc3, 0x54, 0x94, 0x07, 0x92, 0xbf, 0xf2, 0x79, 0xf1, 0x28, 0x9a, 0xea, 0xc2, 0xc0, - 0x39, 0x4f, 0xa1, 0x97, 0xb2, 0x8e, 0xcc, 0x72, 0xfa, 0xdc, 0x72, 0x2f, 0x9f, 0xa4, 0xfd, 0x4f, - 0x4b, 0x30, 0x92, 0x2a, 0xb3, 0x84, 0x3c, 0xa8, 0x11, 0x8f, 0x39, 0xf5, 0xa5, 0xb2, 0x39, 0x6a, - 0xd5, 0x62, 0xa5, 0x20, 0x2f, 0x09, 0xba, 0x58, 0x71, 0x78, 0x38, 0x0e, 0xd7, 0x5f, 0x84, 0x61, - 0xd9, 0xa1, 0x0f, 0x3a, 0x6d, 0x4f, 0x0c, 0xa0, 0x9a, 0xa3, 0x97, 0x0c, 0x18, 0x4e, 0x61, 0xda, - 0xbf, 0x5b, 0x86, 0x31, 0x7e, 0x0a, 0xd2, 0x54, 0x33, 0x6f, 0x51, 0xee, 0xb7, 0xfe, 0x92, 0x2e, - 0x86, 0xc6, 0x07, 0x72, 0xed, 0xa8, 0x97, 0x04, 0xe4, 0x33, 0xea, 0x2b, 0x32, 0xeb, 0xab, 0x99, - 0xc8, 0x2c, 0x6e, 0x76, 0xb7, 0x8e, 0xa9, 0x47, 0xdf, 0x5b, 0xa1, 0x5a, 0xbf, 0x5a, 0x82, 0x13, - 0x99, 0x1b, 0x18, 0xd0, 0x9b, 0xe9, 0xa2, 0xbd, 0x56, 0x11, 0xbe, 0xf2, 0x3d, 0x8b, 0xf2, 0x1f, - 0xac, 0x74, 0xef, 0x03, 0x5a, 0x2a, 0xf6, 0x1f, 0x94, 0x60, 0x34, 0x7d, 0x75, 0xc4, 0x43, 0x38, - 0x52, 0xef, 0x86, 0x3a, 0xab, 0x8e, 0xce, 0xae, 0xc4, 0xe4, 0x2e, 0x79, 0x5e, 0x88, 0x5a, 0x36, - 0x62, 0x0d, 0x7f, 0x28, 0x2a, 0x22, 0xdb, 0x7f, 0xc7, 0x82, 0xb3, 0xfc, 0x2d, 0xb3, 0xf3, 0xf0, - 0x2f, 0xe7, 0x8d, 0xee, 0xab, 0xc5, 0x76, 0x30, 0x53, 0xc4, 0x6f, 0xbf, 0xf1, 0x65, 0x57, 0xf1, - 0x89, 0xde, 0xa6, 0xa7, 0xc2, 0x43, 0xd8, 0xd9, 0x03, 0x4d, 0x06, 0xfb, 0x0f, 0xca, 0xa0, 0x6f, - 0x1f, 0x44, 0xae, 0xc8, 0x71, 0x2c, 0xa4, 0x98, 0xe1, 0xca, 0x8e, 0xdf, 0xd0, 0xf7, 0x1c, 0xd6, - 0x32, 0x29, 0x8e, 0x3f, 0x6f, 0xc1, 0x90, 0xeb, 0xbb, 0x89, 0xeb, 0xb0, 0x6d, 0x74, 0x31, 0x37, - 0xa3, 0x29, 0x76, 0xf3, 0x9c, 0x72, 0x10, 0x99, 0xe7, 0x38, 0x8a, 0x19, 0x36, 0x39, 0xa3, 0x8f, - 0x88, 0xe0, 0xe9, 0x72, 0x61, 0xd9, 0xb9, 0xb5, 0x4c, 0xc4, 0x74, 0x48, 0x0d, 0xaf, 0x24, 0x2a, - 0x28, 0xa9, 0x1d, 0x53, 0x52, 0xaa, 0x2e, 0xae, 0xbe, 0x07, 0x9a, 0x36, 0x63, 0xce, 0xc8, 0x8e, - 0x01, 0x75, 0x8f, 0xc5, 0x01, 0x03, 0x53, 0x27, 0xa1, 0xee, 0x74, 0x92, 0xa0, 0x4d, 0x87, 0x49, - 0x1c, 0x35, 0xe9, 0xd0, 0x5b, 0x09, 0xc0, 0x1a, 0xc7, 0x7e, 0xb3, 0x0a, 0x99, 0xa4, 0x43, 0xb4, - 0x6d, 0xde, 0x9c, 0x69, 0x15, 0x7b, 0x73, 0xa6, 0xea, 0x4c, 0xde, 0xed, 0x99, 0xa8, 0x05, 0xd5, - 0x70, 0xc3, 0x89, 0xa5, 0x59, 0xfd, 0xb2, 0xda, 0xc7, 0xd1, 0xc6, 0x7b, 0xbb, 0xe3, 0x3f, 0xd1, - 0x9f, 0xd7, 0x95, 0xce, 0xd5, 0x49, 0x5e, 0x6c, 0x44, 0xb3, 0x66, 0x34, 0x30, 0xa7, 0x7f, 0x90, - 0xbb, 0xe1, 0x3e, 0x29, 0xca, 0xc0, 0x63, 0x12, 0x77, 0xbc, 0x44, 0xcc, 0x86, 0x97, 0x0b, 0x5c, - 0x65, 0x9c, 0xb0, 0x4e, 0x97, 0xe7, 0xff, 0xb1, 0xc1, 0x14, 0x7d, 0x08, 0xea, 0x71, 0xe2, 0x44, - 0xc9, 0x21, 0x13, 0x5c, 0xd5, 0xa0, 0xaf, 0x48, 0x22, 0x58, 0xd3, 0x43, 0xaf, 0xb0, 0xda, 0xae, - 0x6e, 0xbc, 0x71, 0xc8, 0x9c, 0x07, 0x59, 0x07, 0x56, 0x50, 0xc0, 0x06, 0x35, 0x74, 0x11, 0x80, - 0xcd, 0x6d, 0x1e, 0xe8, 0x57, 0x63, 0x5e, 0x26, 0x25, 0x0a, 0xb1, 0x82, 0x60, 0x03, 0xcb, 0xfe, - 0x61, 0x48, 0xd7, 0x7b, 0x40, 0xe3, 0xb2, 0xbc, 0x04, 0xf7, 0x42, 0xb3, 0xdc, 0x85, 0x54, 0x25, - 0x88, 0xdf, 0xb0, 0xc0, 0x2c, 0x4a, 0x81, 0x5e, 0xe7, 0xd5, 0x2f, 0xac, 0x22, 0x4e, 0x0e, 0x0d, - 0xba, 0x13, 0x8b, 0x4e, 0x98, 0x39, 0xc2, 0x96, 0x25, 0x30, 0xce, 0xbf, 0x07, 0x6a, 0x12, 0x7a, - 0x20, 0xa3, 0xee, 0xe3, 0x70, 0x3a, 0x7b, 0xaf, 0xb8, 0x38, 0x75, 0xda, 0xdf, 0xf5, 0x23, 0xfd, - 0x39, 0xa5, 0x5e, 0xfe, 0x9c, 0x3e, 0xee, 0x4f, 0xfd, 0x4d, 0x0b, 0x2e, 0xec, 0x77, 0xfd, 0x39, - 0x7a, 0x0c, 0x2a, 0x77, 0x9c, 0x48, 0x16, 0xdd, 0x66, 0x82, 0xf2, 0x96, 0x13, 0xf9, 0x98, 0xb5, - 0xa2, 0x1d, 0x18, 0xe0, 0xd1, 0x60, 0xc2, 0x5a, 0x7f, 0xb9, 0xd8, 0xcb, 0xd8, 0xaf, 0x11, 0x63, - 0xbb, 0xc0, 0x23, 0xd1, 0xb0, 0x60, 0x68, 0x7f, 0xc7, 0x02, 0xb4, 0xb4, 0x45, 0xa2, 0xc8, 0x6d, - 0x1a, 0xf1, 0x6b, 0xec, 0x3a, 0x15, 0xe3, 0xda, 0x14, 0x33, 0xc5, 0x35, 0x73, 0x9d, 0x8a, 0xf1, - 0x2f, 0xff, 0x3a, 0x95, 0xd2, 0xc1, 0xae, 0x53, 0x41, 0x4b, 0x70, 0xb6, 0xcd, 0xb7, 0x1b, 0xfc, - 0x8a, 0x02, 0xbe, 0xf7, 0x50, 0x09, 0x65, 0xe7, 0xee, 0xee, 0x8e, 0x9f, 0x5d, 0xcc, 0x43, 0xc0, - 0xf9, 0xcf, 0xd9, 0xef, 0x01, 0xc4, 0xc3, 0xd6, 0x66, 0xf2, 0x62, 0x90, 0x7a, 0xba, 0x5f, 0xec, - 0xaf, 0x54, 0xe1, 0x44, 0xa6, 0x24, 0x2b, 0xdd, 0xea, 0x75, 0x07, 0x3d, 0x1d, 0x59, 0x7f, 0x77, - 0x77, 0xaf, 0xaf, 0x30, 0x2a, 0x1f, 0xaa, 0xae, 0x1f, 0x76, 0x92, 0x62, 0x72, 0x48, 0x79, 0x27, - 0xe6, 0x29, 0x41, 0xc3, 0x5d, 0x4c, 0xff, 0x62, 0xce, 0xa6, 0xc8, 0xa0, 0xac, 0x94, 0x31, 0x5e, - 0x79, 0x40, 0xee, 0x80, 0x4f, 0xea, 0x10, 0xa9, 0x6a, 0x11, 0x8e, 0xc5, 0xcc, 0x64, 0x39, 0xee, - 0xa3, 0xf6, 0x5f, 0x2f, 0xc1, 0x90, 0xf1, 0xd1, 0xd0, 0x2f, 0xa5, 0x4b, 0x36, 0x59, 0xc5, 0xbd, - 0x12, 0xa3, 0x3f, 0xa1, 0x8b, 0x32, 0xf1, 0x57, 0x7a, 0xaa, 0xbb, 0x5a, 0xd3, 0xbd, 0xdd, 0xf1, - 0x93, 0x99, 0x7a, 0x4c, 0xa9, 0x0a, 0x4e, 0xe7, 0x3f, 0x06, 0x27, 0x32, 0x64, 0x72, 0x5e, 0x79, - 0x35, 0x7d, 0x6d, 0xfc, 0x11, 0xdd, 0x52, 0xe6, 0x90, 0x7d, 0x83, 0x0e, 0x99, 0x48, 0xa3, 0x0b, - 0x3c, 0xd2, 0x87, 0x0f, 0x36, 0x93, 0x2d, 0x5b, 0xea, 0x33, 0x5b, 0xf6, 0x69, 0xa8, 0x85, 0x81, - 0xe7, 0x36, 0x5c, 0x55, 0x85, 0x90, 0xe5, 0xe7, 0x2e, 0x8b, 0x36, 0xac, 0xa0, 0xe8, 0x0e, 0xd4, - 0xd5, 0x0d, 0xfb, 0xc2, 0xbf, 0x5d, 0xd4, 0xa1, 0x8f, 0x32, 0x5a, 0xf4, 0xcd, 0xf9, 0x9a, 0x17, - 0xb2, 0x61, 0x80, 0x29, 0x41, 0x19, 0xfa, 0xcf, 0x7c, 0xef, 0x4c, 0x3b, 0xc6, 0x58, 0x40, 0xec, - 0xaf, 0xd7, 0xe1, 0x4c, 0x5e, 0x5d, 0x6c, 0xf4, 0x51, 0x18, 0xe0, 0x7d, 0x2c, 0xe6, 0xea, 0x85, - 0x3c, 0x1e, 0x73, 0x8c, 0xa0, 0xe8, 0x16, 0xfb, 0x8d, 0x05, 0x4f, 0xc1, 0xdd, 0x73, 0xd6, 0xc4, - 0x0c, 0x39, 0x1e, 0xee, 0x0b, 0x8e, 0xe6, 0xbe, 0xe0, 0x70, 0xee, 0x9e, 0xb3, 0x86, 0xb6, 0xa1, - 0xda, 0x72, 0x13, 0xe2, 0x08, 0x27, 0xc2, 0xad, 0x63, 0x61, 0x4e, 0x1c, 0x6e, 0xa5, 0xb1, 0x9f, - 0x98, 0x33, 0x44, 0x5f, 0xb3, 0xe0, 0xc4, 0x5a, 0x3a, 0x35, 0x5e, 0x08, 0x4f, 0xe7, 0x18, 0x6a, - 0x9f, 0xa7, 0x19, 0xf1, 0xfb, 0x84, 0x32, 0x8d, 0x38, 0xdb, 0x1d, 0xf4, 0x29, 0x0b, 0x06, 0xd7, - 0x5d, 0xcf, 0x28, 0x83, 0x7b, 0x0c, 0x1f, 0xe7, 0x32, 0x63, 0xa0, 0x77, 0x1c, 0xfc, 0x7f, 0x8c, - 0x25, 0xe7, 0x5e, 0x9a, 0x6a, 0xe0, 0xa8, 0x9a, 0x6a, 0xf0, 0x01, 0x69, 0xaa, 0xcf, 0x58, 0x50, - 0x57, 0x23, 0x2d, 0xd2, 0x9d, 0x3f, 0x74, 0x8c, 0x9f, 0x9c, 0x7b, 0x4e, 0xd4, 0x5f, 0xac, 0x99, - 0xa3, 0x2f, 0x5a, 0x30, 0xe4, 0xbc, 0xd1, 0x89, 0x48, 0x93, 0x6c, 0x05, 0x61, 0x2c, 0x2e, 0x23, - 0x7c, 0xb5, 0xf8, 0xce, 0x4c, 0x51, 0x26, 0xb3, 0x64, 0x6b, 0x29, 0x8c, 0x45, 0x5a, 0x92, 0x6e, - 0xc0, 0x66, 0x17, 0xec, 0xdd, 0x12, 0x8c, 0xef, 0x43, 0x01, 0xbd, 0x08, 0xc3, 0x41, 0xd4, 0x72, - 0x7c, 0xf7, 0x0d, 0xb3, 0xd6, 0x85, 0xb2, 0xb2, 0x96, 0x0c, 0x18, 0x4e, 0x61, 0x9a, 0x09, 0xd9, - 0xa5, 0x7d, 0x12, 0xb2, 0x2f, 0x40, 0x25, 0x22, 0x61, 0x90, 0xdd, 0x2c, 0xb0, 0x94, 0x00, 0x06, - 0x41, 0x8f, 0x43, 0xd9, 0x09, 0x5d, 0x11, 0x88, 0xa6, 0xf6, 0x40, 0x53, 0xcb, 0xf3, 0x98, 0xb6, - 0xa7, 0xea, 0x43, 0x54, 0xef, 0x4b, 0x7d, 0x08, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0x80, 0x56, 0x03, - 0xe9, 0x33, 0x05, 0xfb, 0xad, 0x32, 0x3c, 0xbe, 0xe7, 0x7c, 0xd1, 0x71, 0x78, 0xd6, 0x1e, 0x71, - 0x78, 0x72, 0x78, 0x4a, 0xfb, 0x0d, 0x4f, 0xb9, 0xc7, 0xf0, 0x7c, 0x8a, 0x2e, 0x03, 0x59, 0x23, - 0xa4, 0x98, 0xeb, 0xe4, 0x7a, 0x95, 0x1c, 0x11, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, - 0xa9, 0x64, 0xe4, 0x6a, 0x11, 0x6a, 0xa0, 0x67, 0xcd, 0x10, 0x3e, 0xf7, 0x7b, 0x65, 0x38, 0xdb, - 0xbf, 0x50, 0x82, 0x27, 0xfb, 0x90, 0xde, 0xe6, 0x2c, 0xb6, 0xfa, 0x9c, 0xc5, 0xdf, 0xdb, 0x9f, - 0xc9, 0xfe, 0x2b, 0x16, 0x9c, 0xef, 0xad, 0x3c, 0xd0, 0x73, 0x30, 0xb4, 0x16, 0x39, 0x7e, 0x63, - 0x83, 0x5d, 0x91, 0x29, 0x07, 0x85, 0x8d, 0xb5, 0x6e, 0xc6, 0x26, 0x0e, 0xdd, 0xde, 0xf2, 0x98, - 0x04, 0x03, 0x43, 0x26, 0x8f, 0xd2, 0xed, 0xed, 0x6a, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x3f, 0x2b, - 0xe5, 0x77, 0x8b, 0x1b, 0x19, 0x07, 0xf9, 0x4e, 0xe2, 0x2b, 0x94, 0xfa, 0x90, 0x25, 0xe5, 0xfb, - 0x2d, 0x4b, 0x2a, 0xbd, 0x64, 0x09, 0x9a, 0x85, 0x93, 0xc6, 0x15, 0x2a, 0x3c, 0x21, 0x98, 0x07, - 0xdc, 0xaa, 0x2a, 0x19, 0xcb, 0x19, 0x38, 0xee, 0x7a, 0x02, 0x3d, 0x03, 0x35, 0xd7, 0x8f, 0x49, - 0xa3, 0x13, 0xf1, 0x40, 0x6f, 0x23, 0x09, 0x6b, 0x5e, 0xb4, 0x63, 0x85, 0x61, 0xff, 0x72, 0x09, - 0xce, 0xf5, 0xb4, 0xb3, 0xee, 0x93, 0xec, 0x32, 0x3f, 0x47, 0xe5, 0xfe, 0x7c, 0x0e, 0x73, 0x90, - 0xaa, 0xfb, 0x0e, 0xd2, 0x1f, 0xf6, 0x9e, 0x98, 0xd4, 0xe6, 0xfe, 0xbe, 0x1d, 0xa5, 0x97, 0x60, - 0xc4, 0x09, 0x43, 0x8e, 0xc7, 0xe2, 0x35, 0x33, 0x55, 0x72, 0xa6, 0x4c, 0x20, 0x4e, 0xe3, 0xf6, - 0xa5, 0x3d, 0xff, 0xd8, 0x82, 0x3a, 0x26, 0xeb, 0x5c, 0x3a, 0xa0, 0xdb, 0x62, 0x88, 0xac, 0x22, - 0xea, 0x69, 0xd2, 0x81, 0x8d, 0x5d, 0x56, 0x67, 0x32, 0x6f, 0xb0, 0xbb, 0xaf, 0xda, 0x29, 0x1d, - 0xe8, 0xaa, 0x1d, 0x75, 0xd9, 0x4a, 0xb9, 0xf7, 0x65, 0x2b, 0xf6, 0x37, 0x06, 0xe9, 0xeb, 0x85, - 0xc1, 0x4c, 0x44, 0x9a, 0x31, 0xfd, 0xbe, 0x9d, 0xc8, 0x13, 0x93, 0x44, 0x7d, 0xdf, 0x1b, 0x78, - 0x01, 0xd3, 0xf6, 0xd4, 0x51, 0x4c, 0xe9, 0x40, 0x35, 0x42, 0xca, 0xfb, 0xd6, 0x08, 0x79, 0x09, - 0x46, 0xe2, 0x78, 0x63, 0x39, 0x72, 0xb7, 0x9c, 0x84, 0x5c, 0x23, 0x3b, 0xc2, 0xca, 0xd2, 0x79, - 0xfd, 0x2b, 0x57, 0x34, 0x10, 0xa7, 0x71, 0xd1, 0x1c, 0x9c, 0xd2, 0x95, 0x3a, 0x48, 0x94, 0xb0, - 0xe8, 0x7e, 0x3e, 0x13, 0x54, 0x12, 0xaf, 0xae, 0xed, 0x21, 0x10, 0x70, 0xf7, 0x33, 0x54, 0xbe, - 0xa5, 0x1a, 0x69, 0x47, 0x06, 0xd2, 0xf2, 0x2d, 0x45, 0x87, 0xf6, 0xa5, 0xeb, 0x09, 0xb4, 0x08, - 0xa7, 0xf9, 0xc4, 0x98, 0x0a, 0x43, 0xe3, 0x8d, 0x06, 0xd3, 0x75, 0x0c, 0xe7, 0xba, 0x51, 0x70, - 0xde, 0x73, 0xe8, 0x05, 0x18, 0x52, 0xcd, 0xf3, 0xb3, 0xe2, 0x14, 0x41, 0x79, 0x31, 0x14, 0x99, - 0xf9, 0x26, 0x36, 0xf1, 0xd0, 0x07, 0xe1, 0x51, 0xfd, 0x97, 0xa7, 0x80, 0xf1, 0xa3, 0xb5, 0x59, - 0x51, 0x04, 0x49, 0x5d, 0xed, 0x31, 0x97, 0x8b, 0xd6, 0xc4, 0xbd, 0x9e, 0x47, 0x6b, 0x70, 0x5e, - 0x81, 0x2e, 0xf9, 0x09, 0xcb, 0xe7, 0x88, 0xc9, 0xb4, 0x13, 0x93, 0x1b, 0x91, 0x27, 0xee, 0x46, - 0x55, 0xb7, 0x2e, 0xce, 0xb9, 0xc9, 0x95, 0x3c, 0x4c, 0xbc, 0x80, 0xf7, 0xa0, 0x82, 0x26, 0xa1, - 0x4e, 0x7c, 0x67, 0xcd, 0x23, 0x4b, 0x33, 0xf3, 0xac, 0x98, 0x92, 0x71, 0x92, 0x77, 0x49, 0x02, - 0xb0, 0xc6, 0x51, 0x11, 0xa6, 0xc3, 0x3d, 0x6f, 0x00, 0x5d, 0x86, 0x33, 0xad, 0x46, 0x48, 0x6d, - 0x0f, 0xb7, 0x41, 0xa6, 0x1a, 0x2c, 0xa0, 0x8e, 0x7e, 0x18, 0x5e, 0x60, 0x52, 0x85, 0x4f, 0xcf, - 0xcd, 0x2c, 0x77, 0xe1, 0xe0, 0xdc, 0x27, 0x59, 0xe0, 0x65, 0x14, 0x6c, 0xef, 0x8c, 0x9d, 0xce, - 0x04, 0x5e, 0xd2, 0x46, 0xcc, 0x61, 0xe8, 0x2a, 0x20, 0x16, 0x8b, 0x7f, 0x25, 0x49, 0x42, 0x65, - 0xec, 0x8c, 0x9d, 0x61, 0xaf, 0xa4, 0xc2, 0xc8, 0x2e, 0x77, 0x61, 0xe0, 0x9c, 0xa7, 0xec, 0x7f, - 0x6f, 0xc1, 0x88, 0x5a, 0xaf, 0xf7, 0x21, 0x1b, 0xc5, 0x4b, 0x67, 0xa3, 0xcc, 0x1d, 0x5d, 0xe2, - 0xb1, 0x9e, 0xf7, 0x08, 0x69, 0xfe, 0xd9, 0x21, 0x00, 0x2d, 0x15, 0x95, 0x42, 0xb2, 0x7a, 0x2a, - 0xa4, 0x87, 0x56, 0x22, 0xe5, 0x55, 0x4e, 0xa9, 0x3e, 0xd8, 0xca, 0x29, 0x2b, 0x70, 0x56, 0x9a, - 0x0b, 0xfc, 0xac, 0xe8, 0x4a, 0x10, 0x2b, 0x01, 0x57, 0x9b, 0x7e, 0x5c, 0x10, 0x3a, 0x3b, 0x9f, - 0x87, 0x84, 0xf3, 0x9f, 0x4d, 0x59, 0x29, 0x83, 0xfb, 0x59, 0x29, 0x7a, 0x4d, 0x2f, 0xac, 0xcb, - 0x3b, 0x3c, 0x32, 0x6b, 0x7a, 0xe1, 0xf2, 0x0a, 0xd6, 0x38, 0xf9, 0x82, 0xbd, 0x5e, 0x90, 0x60, - 0x87, 0x03, 0x0b, 0x76, 0x29, 0x62, 0x86, 0x7a, 0x8a, 0x18, 0xe9, 0x93, 0x1e, 0xee, 0xe9, 0x93, - 0x7e, 0x1f, 0x8c, 0xba, 0xfe, 0x06, 0x89, 0xdc, 0x84, 0x34, 0xd9, 0x5a, 0x60, 0xe2, 0xa7, 0xa6, - 0xd5, 0xfa, 0x7c, 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0xb9, 0x38, 0xda, 0x87, 0x5c, 0xec, 0xa1, 0x8d, - 0x4e, 0x14, 0xa3, 0x8d, 0x4e, 0x1e, 0x5d, 0x1b, 0x9d, 0x3a, 0x56, 0x6d, 0x84, 0x0a, 0xd1, 0x46, - 0x7d, 0x09, 0x7a, 0x63, 0xfb, 0x77, 0x66, 0x9f, 0xed, 0x5f, 0x2f, 0x55, 0x74, 0xf6, 0xd0, 0xaa, - 0x28, 0x5f, 0xcb, 0x3c, 0x72, 0x28, 0x2d, 0xf3, 0x99, 0x12, 0x9c, 0xd5, 0x72, 0x98, 0xce, 0x7e, - 0x77, 0x9d, 0x4a, 0x22, 0x76, 0x0d, 0x14, 0x3f, 0xb7, 0x31, 0x92, 0xa3, 0x74, 0x9e, 0x95, 0x82, - 0x60, 0x03, 0x8b, 0xe5, 0x18, 0x91, 0x88, 0x95, 0xd1, 0xcd, 0x0a, 0xe9, 0x19, 0xd1, 0x8e, 0x15, - 0x06, 0x9d, 0x5f, 0xf4, 0xb7, 0xc8, 0xdb, 0xcc, 0x16, 0x8b, 0x9b, 0xd1, 0x20, 0x6c, 0xe2, 0xa1, - 0xa7, 0x39, 0x13, 0x26, 0x20, 0xa8, 0xa0, 0x1e, 0x16, 0xf7, 0xc2, 0x4a, 0x99, 0xa0, 0xa0, 0xb2, - 0x3b, 0x2c, 0x99, 0xac, 0xda, 0xdd, 0x1d, 0x16, 0x02, 0xa5, 0x30, 0xec, 0xff, 0x61, 0xc1, 0xb9, - 0xdc, 0xa1, 0xb8, 0x0f, 0xca, 0x77, 0x3b, 0xad, 0x7c, 0x57, 0x8a, 0xda, 0x6e, 0x18, 0x6f, 0xd1, - 0x43, 0x11, 0xff, 0x5b, 0x0b, 0x46, 0x35, 0xfe, 0x7d, 0x78, 0x55, 0x37, 0xfd, 0xaa, 0xc5, 0xed, - 0xac, 0xea, 0x5d, 0xef, 0xf6, 0xbb, 0x25, 0x50, 0x05, 0x1c, 0xa7, 0x1a, 0xb2, 0x3c, 0xee, 0x3e, - 0x27, 0x89, 0x3b, 0x30, 0xc0, 0x0e, 0x42, 0xe3, 0x62, 0x82, 0x3c, 0xd2, 0xfc, 0xd9, 0xa1, 0xaa, - 0x3e, 0x64, 0x66, 0x7f, 0x63, 0x2c, 0x18, 0xb2, 0x22, 0xcf, 0x6e, 0x4c, 0xa5, 0x79, 0x53, 0xa4, - 0x65, 0xe9, 0x22, 0xcf, 0xa2, 0x1d, 0x2b, 0x0c, 0xaa, 0x1e, 0xdc, 0x46, 0xe0, 0xcf, 0x78, 0x4e, - 0x2c, 0xef, 0x3e, 0x54, 0xea, 0x61, 0x5e, 0x02, 0xb0, 0xc6, 0x61, 0x67, 0xa4, 0x6e, 0x1c, 0x7a, - 0xce, 0x8e, 0xb1, 0x7f, 0x36, 0xea, 0x13, 0x28, 0x10, 0x36, 0xf1, 0xec, 0x36, 0x8c, 0xa5, 0x5f, - 0x62, 0x96, 0xac, 0xb3, 0x00, 0xc5, 0xbe, 0x86, 0x73, 0x12, 0xea, 0x0e, 0x7b, 0x6a, 0xa1, 0xe3, - 0x64, 0xaf, 0x2c, 0x9f, 0x92, 0x00, 0xac, 0x71, 0xec, 0x5f, 0xb3, 0xe0, 0x74, 0xce, 0xa0, 0x15, - 0x98, 0xf6, 0x96, 0x68, 0x69, 0x93, 0xa7, 0xd8, 0x7f, 0x08, 0x06, 0x9b, 0x64, 0xdd, 0x91, 0x21, - 0x70, 0x86, 0x6c, 0x9f, 0xe5, 0xcd, 0x58, 0xc2, 0xed, 0xff, 0x66, 0xc1, 0x89, 0x74, 0x5f, 0x63, - 0x96, 0x4a, 0xc2, 0x87, 0xc9, 0x8d, 0x1b, 0xc1, 0x16, 0x89, 0x76, 0xe8, 0x9b, 0x5b, 0x99, 0x54, - 0x92, 0x2e, 0x0c, 0x9c, 0xf3, 0x14, 0x2b, 0xdf, 0xda, 0x54, 0xa3, 0x2d, 0x67, 0xe4, 0xcd, 0x22, - 0x67, 0xa4, 0xfe, 0x98, 0xe6, 0x71, 0xb9, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0x77, 0x2a, 0xa0, 0xf2, - 0x62, 0x59, 0xfc, 0x51, 0x41, 0xd1, 0x5b, 0x07, 0xcd, 0x20, 0x52, 0x93, 0xa1, 0xb2, 0x57, 0x40, - 0x00, 0xf7, 0x92, 0x98, 0xae, 0x4b, 0xf5, 0x86, 0xab, 0x1a, 0x84, 0x4d, 0x3c, 0xda, 0x13, 0xcf, - 0xdd, 0x22, 0xfc, 0xa1, 0x81, 0x74, 0x4f, 0x16, 0x24, 0x00, 0x6b, 0x1c, 0xda, 0x93, 0xa6, 0xbb, - 0xbe, 0x2e, 0xb6, 0xfc, 0xaa, 0x27, 0x74, 0x74, 0x30, 0x83, 0xf0, 0x8a, 0xdc, 0xc1, 0xa6, 0xb0, - 0x82, 0x8d, 0x8a, 0xdc, 0xc1, 0x26, 0x66, 0x10, 0x6a, 0xb7, 0xf9, 0x41, 0xd4, 0x66, 0x57, 0xca, - 0x37, 0x15, 0x17, 0x61, 0xfd, 0x2a, 0xbb, 0xed, 0x7a, 0x37, 0x0a, 0xce, 0x7b, 0x8e, 0xce, 0xc0, - 0x30, 0x22, 0x4d, 0xb7, 0x91, 0x98, 0xd4, 0x20, 0x3d, 0x03, 0x97, 0xbb, 0x30, 0x70, 0xce, 0x53, - 0x68, 0x0a, 0x4e, 0xc8, 0xbc, 0x66, 0x59, 0xb5, 0x66, 0x28, 0x5d, 0x25, 0x03, 0xa7, 0xc1, 0x38, - 0x8b, 0x4f, 0xa5, 0x5a, 0x5b, 0x14, 0xac, 0x62, 0xc6, 0xb2, 0x21, 0xd5, 0x64, 0x21, 0x2b, 0xac, - 0x30, 0xec, 0x4f, 0x96, 0xa9, 0x16, 0xee, 0x51, 0xa8, 0xed, 0xbe, 0x45, 0x0b, 0xa6, 0x67, 0x64, - 0xa5, 0x8f, 0x19, 0xf9, 0x3c, 0x0c, 0xdf, 0x8e, 0x03, 0x5f, 0x45, 0xe2, 0x55, 0x7b, 0x46, 0xe2, - 0x19, 0x58, 0xf9, 0x91, 0x78, 0x03, 0x45, 0x45, 0xe2, 0x0d, 0x1e, 0x32, 0x12, 0xef, 0x5b, 0x55, - 0x50, 0x57, 0x83, 0x5c, 0x27, 0xc9, 0x9d, 0x20, 0xda, 0x74, 0xfd, 0x16, 0xcb, 0x07, 0xff, 0x9a, - 0x05, 0xc3, 0x7c, 0xbd, 0x2c, 0x98, 0x99, 0x54, 0xeb, 0x05, 0xdd, 0x39, 0x91, 0x62, 0x36, 0xb1, - 0x6a, 0x30, 0xca, 0x5c, 0xbd, 0x69, 0x82, 0x70, 0xaa, 0x47, 0xe8, 0x63, 0x00, 0xd2, 0x3f, 0xba, - 0x2e, 0x45, 0xe6, 0x7c, 0x31, 0xfd, 0xc3, 0x64, 0x5d, 0xdb, 0xc0, 0xab, 0x8a, 0x09, 0x36, 0x18, - 0xa2, 0xcf, 0xe8, 0x2c, 0x33, 0x1e, 0xb2, 0xff, 0x91, 0x63, 0x19, 0x9b, 0x7e, 0x72, 0xcc, 0x30, - 0x0c, 0xba, 0x7e, 0x8b, 0xce, 0x13, 0x11, 0xb1, 0xf4, 0xae, 0xbc, 0x5a, 0x0a, 0x0b, 0x81, 0xd3, - 0x9c, 0x76, 0x3c, 0xc7, 0x6f, 0x90, 0x68, 0x9e, 0xa3, 0x9b, 0x17, 0x4e, 0xb3, 0x06, 0x2c, 0x09, - 0x75, 0x5d, 0xaa, 0x52, 0xed, 0xe7, 0x52, 0x95, 0xf3, 0xef, 0x87, 0x53, 0x5d, 0x1f, 0xf3, 0x40, - 0x29, 0x65, 0x87, 0xcf, 0x46, 0xb3, 0xff, 0xd9, 0x80, 0x56, 0x5a, 0xd7, 0x83, 0x26, 0xbf, 0xda, - 0x23, 0xd2, 0x5f, 0x54, 0xd8, 0xb8, 0x05, 0x4e, 0x11, 0xe3, 0xd2, 0x6a, 0xd5, 0x88, 0x4d, 0x96, - 0x74, 0x8e, 0x86, 0x4e, 0x44, 0xfc, 0xe3, 0x9e, 0xa3, 0xcb, 0x8a, 0x09, 0x36, 0x18, 0xa2, 0x8d, - 0x54, 0x4e, 0xc9, 0xe5, 0xa3, 0xe7, 0x94, 0xb0, 0x2a, 0x53, 0x79, 0xd5, 0xf8, 0xbf, 0x68, 0xc1, - 0xa8, 0x9f, 0x9a, 0xb9, 0xc5, 0x84, 0x91, 0xe6, 0xaf, 0x0a, 0x7e, 0xb3, 0x54, 0xba, 0x0d, 0x67, - 0xf8, 0xe7, 0xa9, 0xb4, 0xea, 0x01, 0x55, 0x9a, 0xbe, 0x23, 0x68, 0xa0, 0xd7, 0x1d, 0x41, 0xc8, - 0x57, 0x97, 0xa4, 0x0d, 0x16, 0x7e, 0x49, 0x1a, 0xe4, 0x5c, 0x90, 0x76, 0x0b, 0xea, 0x8d, 0x88, - 0x38, 0xc9, 0x21, 0xef, 0xcb, 0x62, 0x07, 0xf4, 0x33, 0x92, 0x00, 0xd6, 0xb4, 0xec, 0xff, 0x5d, - 0x81, 0x93, 0x72, 0x44, 0x64, 0x08, 0x3a, 0xd5, 0x8f, 0x9c, 0xaf, 0x36, 0x6e, 0x95, 0x7e, 0xbc, - 0x22, 0x01, 0x58, 0xe3, 0x50, 0x7b, 0xac, 0x13, 0x93, 0xa5, 0x90, 0xf8, 0x0b, 0xee, 0x5a, 0x2c, - 0xce, 0x39, 0xd5, 0x42, 0xb9, 0xa1, 0x41, 0xd8, 0xc4, 0xa3, 0xc6, 0x38, 0xb7, 0x8b, 0xe3, 0x6c, - 0xfa, 0x8a, 0xb0, 0xb7, 0xb1, 0x84, 0xa3, 0x5f, 0xcc, 0xad, 0x1c, 0x5b, 0x4c, 0xe2, 0x56, 0x57, - 0xe4, 0xfd, 0x01, 0xaf, 0x58, 0xfc, 0x5b, 0x16, 0x9c, 0xe5, 0xad, 0x72, 0x24, 0x6f, 0x84, 0x4d, - 0x27, 0x21, 0x71, 0x31, 0x95, 0xdc, 0x73, 0xfa, 0xa7, 0x9d, 0xbc, 0x79, 0x6c, 0x71, 0x7e, 0x6f, - 0xd0, 0x9b, 0x16, 0x9c, 0xd8, 0x4c, 0xd5, 0xfc, 0x90, 0xaa, 0xe3, 0xa8, 0xe9, 0xf8, 0x29, 0xa2, - 0x7a, 0xa9, 0xa5, 0xdb, 0x63, 0x9c, 0xe5, 0x6e, 0xff, 0x99, 0x05, 0xa6, 0x18, 0xbd, 0xff, 0xa5, - 0x42, 0x0e, 0x6e, 0x0a, 0x4a, 0xeb, 0xb2, 0xda, 0xd3, 0xba, 0x7c, 0x1c, 0xca, 0x1d, 0xb7, 0x29, - 0xf6, 0x17, 0xfa, 0xf4, 0x75, 0x7e, 0x16, 0xd3, 0x76, 0xfb, 0x1f, 0x57, 0xb5, 0xdf, 0x42, 0xe4, - 0x45, 0x7d, 0x5f, 0xbc, 0xf6, 0xba, 0x2a, 0x36, 0xc6, 0xdf, 0xfc, 0x7a, 0x57, 0xb1, 0xb1, 0x1f, - 0x3b, 0x78, 0xda, 0x1b, 0x1f, 0xa0, 0x5e, 0xb5, 0xc6, 0x06, 0xf7, 0xc9, 0x79, 0xbb, 0x0d, 0x35, - 0xba, 0x05, 0x63, 0x0e, 0xc8, 0x5a, 0xaa, 0x53, 0xb5, 0x2b, 0xa2, 0xfd, 0xde, 0xee, 0xf8, 0x7b, - 0x0f, 0xde, 0x2d, 0xf9, 0x34, 0x56, 0xf4, 0x51, 0x0c, 0x75, 0xfa, 0x9b, 0xa5, 0xe7, 0x89, 0xcd, - 0xdd, 0x0d, 0x25, 0x33, 0x25, 0xa0, 0x90, 0xdc, 0x3f, 0xcd, 0x07, 0xf9, 0x50, 0x67, 0xb7, 0xd1, - 0x32, 0xa6, 0x7c, 0x0f, 0xb8, 0xac, 0x92, 0xe4, 0x24, 0xe0, 0xde, 0xee, 0xf8, 0x4b, 0x07, 0x67, - 0xaa, 0x1e, 0xc7, 0x9a, 0x85, 0xfd, 0xa5, 0x8a, 0x9e, 0xbb, 0xa2, 0xc6, 0xdc, 0xf7, 0xc5, 0xdc, - 0x7d, 0x31, 0x33, 0x77, 0x2f, 0x74, 0xcd, 0xdd, 0x51, 0x7d, 0x6b, 0x6a, 0x6a, 0x36, 0xde, 0x6f, - 0x43, 0x60, 0x7f, 0x7f, 0x03, 0xb3, 0x80, 0x5e, 0xef, 0xb8, 0x11, 0x89, 0x97, 0xa3, 0x8e, 0xef, - 0xfa, 0x2d, 0x36, 0x1d, 0x6b, 0xa6, 0x05, 0x94, 0x02, 0xe3, 0x2c, 0x3e, 0xdd, 0xd4, 0xd3, 0x6f, - 0x7e, 0xcb, 0xd9, 0xe2, 0xb3, 0xca, 0x28, 0xbb, 0xb5, 0x22, 0xda, 0xb1, 0xc2, 0xb0, 0xbf, 0xc1, - 0xce, 0xb2, 0x8d, 0xbc, 0x60, 0x3a, 0x27, 0x3c, 0x76, 0xfd, 0x2f, 0xaf, 0xd9, 0xa5, 0xe6, 0x04, - 0xbf, 0xf3, 0x97, 0xc3, 0xd0, 0x1d, 0x18, 0x5c, 0xe3, 0xf7, 0xdf, 0x15, 0x53, 0x9f, 0x5c, 0x5c, - 0xa6, 0xc7, 0x6e, 0x39, 0x91, 0x37, 0xeb, 0xdd, 0xd3, 0x3f, 0xb1, 0xe4, 0x66, 0x7f, 0xb3, 0x02, - 0x27, 0x32, 0x17, 0xc4, 0xa6, 0xaa, 0xa5, 0x96, 0xf6, 0xad, 0x96, 0xfa, 0x61, 0x80, 0x26, 0x09, - 0xbd, 0x60, 0x87, 0x99, 0x63, 0x95, 0x03, 0x9b, 0x63, 0xca, 0x82, 0x9f, 0x55, 0x54, 0xb0, 0x41, - 0x51, 0x14, 0x2a, 0xe3, 0xc5, 0x57, 0x33, 0x85, 0xca, 0x8c, 0x5b, 0x0c, 0x06, 0xee, 0xef, 0x2d, - 0x06, 0x2e, 0x9c, 0xe0, 0x5d, 0x54, 0xd9, 0xb7, 0x87, 0x48, 0xb2, 0x65, 0xf9, 0x0b, 0xb3, 0x69, - 0x32, 0x38, 0x4b, 0xf7, 0x41, 0xde, 0xff, 0x8c, 0xde, 0x0d, 0x75, 0xf9, 0x9d, 0xe3, 0xb1, 0xba, - 0xae, 0x60, 0x20, 0xa7, 0x01, 0xbb, 0x97, 0x59, 0xfc, 0xb4, 0xbf, 0x50, 0xa2, 0xd6, 0x33, 0xff, - 0xa7, 0x2a, 0xd1, 0x3c, 0x05, 0x03, 0x4e, 0x27, 0xd9, 0x08, 0xba, 0xee, 0xd0, 0x9b, 0x62, 0xad, - 0x58, 0x40, 0xd1, 0x02, 0x54, 0x9a, 0xba, 0xba, 0xc8, 0x41, 0x46, 0x51, 0x3b, 0x22, 0x9d, 0x84, - 0x60, 0x46, 0x05, 0x3d, 0x06, 0x95, 0xc4, 0x69, 0xc9, 0x44, 0x27, 0x96, 0xdc, 0xba, 0xea, 0xb4, - 0x62, 0xcc, 0x5a, 0x4d, 0xa5, 0x59, 0xd9, 0x47, 0x69, 0xbe, 0x04, 0x23, 0xb1, 0xdb, 0xf2, 0x9d, - 0xa4, 0x13, 0x11, 0xe3, 0x70, 0x4d, 0xc7, 0x4b, 0x98, 0x40, 0x9c, 0xc6, 0xb5, 0x7f, 0x6b, 0x18, - 0xce, 0xac, 0xcc, 0x2c, 0xca, 0x9a, 0xd9, 0xc7, 0x96, 0xab, 0x94, 0xc7, 0xe3, 0xfe, 0xe5, 0x2a, - 0xf5, 0xe0, 0xee, 0x19, 0xb9, 0x4a, 0x9e, 0x91, 0xab, 0x94, 0x4e, 0x1c, 0x29, 0x17, 0x91, 0x38, - 0x92, 0xd7, 0x83, 0x7e, 0x12, 0x47, 0x8e, 0x2d, 0x79, 0x69, 0xcf, 0x0e, 0x1d, 0x28, 0x79, 0x49, - 0x65, 0x76, 0x15, 0x12, 0xd2, 0xdf, 0xe3, 0x53, 0xe5, 0x66, 0x76, 0xa9, 0xac, 0x1a, 0x9e, 0xae, - 0x22, 0x04, 0xec, 0xab, 0xc5, 0x77, 0xa0, 0x8f, 0xac, 0x1a, 0x91, 0x31, 0x63, 0x66, 0x72, 0x0d, - 0x16, 0x91, 0xc9, 0x95, 0xd7, 0x9d, 0x7d, 0x33, 0xb9, 0x5e, 0x82, 0x91, 0x86, 0x17, 0xf8, 0x64, - 0x39, 0x0a, 0x92, 0xa0, 0x11, 0x78, 0xc2, 0x98, 0x56, 0x22, 0x61, 0xc6, 0x04, 0xe2, 0x34, 0x6e, - 0xaf, 0x34, 0xb0, 0xfa, 0x51, 0xd3, 0xc0, 0xe0, 0x01, 0xa5, 0x81, 0xfd, 0x9c, 0x4e, 0x58, 0x1e, - 0x62, 0x5f, 0xe4, 0xc3, 0xc5, 0x7f, 0x91, 0x7e, 0xb2, 0x96, 0xd1, 0x5b, 0xfc, 0x12, 0x3b, 0x6a, - 0x8e, 0xce, 0x04, 0x6d, 0x6a, 0x6e, 0x0d, 0xb3, 0x21, 0x79, 0xed, 0x18, 0x26, 0xec, 0xad, 0x15, - 0xcd, 0x46, 0x5d, 0x6c, 0xa7, 0x9b, 0x70, 0xba, 0x23, 0x47, 0x49, 0xa8, 0xfe, 0x4a, 0x09, 0x7e, - 0x60, 0xdf, 0x2e, 0xa0, 0x3b, 0x00, 0x89, 0xd3, 0x12, 0x13, 0x55, 0x1c, 0x53, 0x1c, 0x31, 0xa8, - 0x71, 0x55, 0xd2, 0xe3, 0x95, 0x40, 0xd4, 0x5f, 0x76, 0x00, 0x20, 0x7f, 0xb3, 0x58, 0xc6, 0xc0, - 0xeb, 0x2a, 0x98, 0x88, 0x03, 0x8f, 0x60, 0x06, 0xa1, 0xea, 0x3f, 0x22, 0x2d, 0x7d, 0xeb, 0xb2, - 0xfa, 0x7c, 0x98, 0xb5, 0x62, 0x01, 0x45, 0x2f, 0xc0, 0x90, 0xe3, 0x79, 0x3c, 0x2b, 0x85, 0xc4, - 0xe2, 0x16, 0x1b, 0x5d, 0xb9, 0x4d, 0x83, 0xb0, 0x89, 0x67, 0xff, 0x69, 0x09, 0xc6, 0xf7, 0x91, - 0x29, 0x5d, 0x79, 0x76, 0xd5, 0xbe, 0xf3, 0xec, 0x44, 0x66, 0xc0, 0x40, 0x8f, 0xcc, 0x80, 0x17, - 0x60, 0x28, 0x21, 0x4e, 0x5b, 0x84, 0x41, 0x89, 0xfd, 0xb7, 0x3e, 0x77, 0xd5, 0x20, 0x6c, 0xe2, - 0x51, 0x29, 0x36, 0xea, 0x34, 0x1a, 0x24, 0x8e, 0x65, 0xe8, 0xbf, 0xf0, 0x61, 0x16, 0x96, 0x57, - 0xc0, 0x5c, 0xc3, 0x53, 0x29, 0x16, 0x38, 0xc3, 0x32, 0x3b, 0xe0, 0xf5, 0x3e, 0x07, 0xfc, 0xeb, - 0x25, 0x78, 0x7c, 0x4f, 0xed, 0xd6, 0x77, 0x56, 0x46, 0x27, 0x26, 0x51, 0x76, 0xe2, 0xdc, 0x88, - 0x49, 0x84, 0x19, 0x84, 0x8f, 0x52, 0x18, 0x1a, 0xb7, 0x5a, 0x17, 0x9d, 0x32, 0xc4, 0x47, 0x29, - 0xc5, 0x02, 0x67, 0x58, 0x1e, 0x76, 0x5a, 0xfe, 0xdd, 0x12, 0x3c, 0xd9, 0x87, 0x0d, 0x50, 0x60, - 0x6a, 0x55, 0x3a, 0xc1, 0xad, 0xfc, 0x80, 0xf2, 0x10, 0x0f, 0x39, 0x5c, 0xdf, 0x28, 0xc1, 0xf9, - 0xde, 0xaa, 0x18, 0xfd, 0x38, 0xdd, 0xc3, 0xcb, 0xd8, 0x27, 0x33, 0x37, 0xee, 0x34, 0xdf, 0xbf, - 0xa7, 0x40, 0x38, 0x8b, 0x8b, 0x26, 0x00, 0x42, 0x27, 0xd9, 0x88, 0x2f, 0x6d, 0xbb, 0x71, 0x22, - 0x6a, 0xbf, 0x8c, 0xf2, 0x13, 0x23, 0xd9, 0x8a, 0x0d, 0x0c, 0xca, 0x8e, 0xfd, 0x9b, 0x0d, 0xae, - 0x07, 0x09, 0x7f, 0x88, 0x6f, 0x23, 0x4e, 0xcb, 0x9b, 0x32, 0x0c, 0x10, 0xce, 0xe2, 0x52, 0x76, - 0xec, 0x4c, 0x92, 0x77, 0x94, 0xef, 0x2f, 0x18, 0xbb, 0x05, 0xd5, 0x8a, 0x0d, 0x8c, 0x6c, 0xd6, - 0x5f, 0x75, 0xff, 0xac, 0x3f, 0xfb, 0x1f, 0x95, 0xe0, 0x5c, 0x4f, 0x53, 0xae, 0xbf, 0x05, 0xf8, - 0xf0, 0x65, 0xea, 0x1d, 0x6e, 0xee, 0x1c, 0x30, 0xa3, 0xec, 0x8f, 0x7b, 0xcc, 0x34, 0x91, 0x51, - 0x76, 0xf8, 0x94, 0xec, 0x87, 0x6f, 0x3c, 0xbb, 0x92, 0xc8, 0x2a, 0x07, 0x48, 0x22, 0xcb, 0x7c, - 0x8c, 0x6a, 0x9f, 0x0b, 0xf9, 0xcf, 0xcb, 0x3d, 0x87, 0x97, 0x6e, 0xfd, 0xfa, 0xf2, 0x8e, 0xce, - 0xc2, 0x49, 0xd7, 0x67, 0xb7, 0x26, 0xad, 0x74, 0xd6, 0x44, 0x39, 0x90, 0x52, 0xfa, 0xce, 0xf2, - 0xf9, 0x0c, 0x1c, 0x77, 0x3d, 0xf1, 0x10, 0x26, 0xf5, 0x1d, 0x6e, 0x48, 0x0f, 0x96, 0x56, 0x8a, - 0x96, 0xe0, 0xac, 0x1c, 0x8a, 0x0d, 0x27, 0x22, 0x4d, 0xa1, 0x46, 0x62, 0x91, 0xc6, 0x70, 0x8e, - 0xa7, 0x42, 0xe4, 0x20, 0xe0, 0xfc, 0xe7, 0xd8, 0x45, 0x35, 0x41, 0xe8, 0x36, 0xc4, 0x26, 0x47, - 0x5f, 0x54, 0x43, 0x1b, 0x31, 0x87, 0xd9, 0x1f, 0x86, 0xba, 0x7a, 0x7f, 0x1e, 0x4c, 0xad, 0x26, - 0x5d, 0x57, 0x30, 0xb5, 0x9a, 0x71, 0x06, 0x16, 0xfd, 0x5a, 0xd4, 0x24, 0xce, 0xac, 0x9e, 0x6b, - 0x64, 0x87, 0xd9, 0xc7, 0xf6, 0x8f, 0xc0, 0xb0, 0xf2, 0xb3, 0xf4, 0x7b, 0x7d, 0x8f, 0xfd, 0xa5, - 0x01, 0x18, 0x49, 0x95, 0xe4, 0x4b, 0xb9, 0x35, 0xad, 0x7d, 0xdd, 0x9a, 0x2c, 0x38, 0xbe, 0xe3, - 0xcb, 0xbb, 0xbd, 0x8c, 0xe0, 0xf8, 0x8e, 0x4f, 0x30, 0x87, 0x51, 0xf3, 0xb6, 0x19, 0xed, 0xe0, - 0x8e, 0x2f, 0x82, 0x58, 0x95, 0x79, 0x3b, 0xcb, 0x5a, 0xb1, 0x80, 0xa2, 0x4f, 0x58, 0x30, 0x1c, - 0x33, 0x9f, 0x39, 0x77, 0x0a, 0x8b, 0x49, 0x77, 0xf5, 0xe8, 0x15, 0x07, 0x55, 0xf9, 0x49, 0x16, - 0x97, 0x62, 0xb6, 0xe0, 0x14, 0x47, 0xf4, 0x69, 0x0b, 0xea, 0xea, 0x0a, 0x12, 0x71, 0x01, 0xdf, - 0x4a, 0xb1, 0x15, 0x0f, 0xb9, 0x37, 0x51, 0x1d, 0x3f, 0xa8, 0xd2, 0x73, 0x58, 0x33, 0x46, 0xb1, - 0xf2, 0xd8, 0x0e, 0x1e, 0x8f, 0xc7, 0x16, 0x72, 0xbc, 0xb5, 0xef, 0x86, 0x7a, 0xdb, 0xf1, 0xdd, - 0x75, 0x12, 0x27, 0xdc, 0x89, 0x2a, 0x0b, 0xb1, 0xca, 0x46, 0xac, 0xe1, 0x54, 0x21, 0xc7, 0xec, - 0xc5, 0x12, 0xc3, 0xeb, 0xc9, 0x14, 0xf2, 0x8a, 0x6e, 0xc6, 0x26, 0x8e, 0xe9, 0xa2, 0x85, 0x07, - 0xea, 0xa2, 0x1d, 0xda, 0xc7, 0x45, 0xfb, 0xf7, 0x2d, 0x38, 0x9b, 0xfb, 0xd5, 0x1e, 0xde, 0x70, - 0x43, 0xfb, 0xcb, 0x55, 0x38, 0x9d, 0x53, 0x5b, 0x13, 0xed, 0x98, 0xf3, 0xd9, 0x2a, 0xe2, 0xe4, - 0x3e, 0x7d, 0x10, 0x2d, 0x87, 0x31, 0x67, 0x12, 0x1f, 0xec, 0x80, 0x44, 0x1f, 0x52, 0x94, 0xef, - 0xef, 0x21, 0x85, 0x31, 0x2d, 0x2b, 0x0f, 0x74, 0x5a, 0x56, 0xf7, 0x9e, 0x96, 0xe8, 0xd7, 0x2d, - 0x18, 0x6b, 0xf7, 0x28, 0xe8, 0x2e, 0x1c, 0x8f, 0x37, 0x8f, 0xa7, 0x5c, 0xfc, 0xf4, 0x63, 0x77, - 0x77, 0xc7, 0x7b, 0xd6, 0xd1, 0xc7, 0x3d, 0x7b, 0x65, 0x7f, 0xa7, 0x0c, 0xac, 0xb0, 0x2b, 0xab, - 0x9f, 0xb6, 0x83, 0x3e, 0x6e, 0x96, 0xe8, 0xb5, 0x8a, 0x2a, 0x27, 0xcb, 0x89, 0xab, 0x12, 0xbf, - 0x7c, 0x04, 0xf3, 0x2a, 0xfe, 0x66, 0x85, 0x56, 0xa9, 0x0f, 0xa1, 0xe5, 0xc9, 0x5a, 0xc8, 0xe5, - 0xe2, 0x6b, 0x21, 0xd7, 0xb3, 0x75, 0x90, 0xf7, 0xfe, 0xc4, 0x95, 0x87, 0xf2, 0x13, 0xff, 0x0d, - 0x8b, 0x0b, 0x9e, 0xcc, 0x57, 0xd0, 0x96, 0x81, 0xb5, 0x87, 0x65, 0xf0, 0x0c, 0xd4, 0x62, 0xe2, - 0xad, 0x5f, 0x21, 0x8e, 0x27, 0x2c, 0x08, 0x7d, 0x6a, 0x2c, 0xda, 0xb1, 0xc2, 0x60, 0x97, 0xa5, - 0x7a, 0x5e, 0x70, 0xe7, 0x52, 0x3b, 0x4c, 0x76, 0x84, 0x2d, 0xa1, 0x2f, 0x4b, 0x55, 0x10, 0x6c, - 0x60, 0xd9, 0x7f, 0xb3, 0xc4, 0x67, 0xa0, 0x08, 0x3d, 0x78, 0x31, 0x73, 0xbd, 0x5d, 0xff, 0xa7, - 0xf6, 0x1f, 0x05, 0x68, 0xa8, 0x8b, 0xe1, 0xc5, 0x99, 0xd0, 0x95, 0x23, 0xdf, 0x5a, 0x2d, 0xe8, - 0xe9, 0xd7, 0xd0, 0x6d, 0xd8, 0xe0, 0x97, 0x92, 0xa5, 0xe5, 0x7d, 0x65, 0x69, 0x4a, 0xac, 0x54, - 0xf6, 0xd1, 0x76, 0x7f, 0x6a, 0x41, 0xca, 0x22, 0x42, 0x21, 0x54, 0x69, 0x77, 0x77, 0x8a, 0xb9, - 0xf3, 0xde, 0x24, 0x4d, 0x45, 0xa3, 0x98, 0xf6, 0xec, 0x27, 0xe6, 0x8c, 0x90, 0x27, 0x22, 0x14, - 0xf8, 0xa8, 0x5e, 0x2f, 0x8e, 0xe1, 0x95, 0x20, 0xd8, 0xe4, 0x07, 0x9b, 0x3a, 0xda, 0xc1, 0x7e, - 0x11, 0x4e, 0x75, 0x75, 0x8a, 0xdd, 0x64, 0x15, 0xc8, 0x8b, 0xfe, 0x8d, 0xe9, 0xca, 0xd2, 0x26, - 0x31, 0x87, 0xd9, 0xdf, 0xb0, 0xe0, 0x64, 0x96, 0x3c, 0x7a, 0xcb, 0x82, 0x53, 0x71, 0x96, 0xde, - 0x71, 0x8d, 0x9d, 0x8a, 0x32, 0xec, 0x02, 0xe1, 0xee, 0x4e, 0xd8, 0xff, 0x47, 0x4c, 0xfe, 0x5b, - 0xae, 0xdf, 0x0c, 0xee, 0x28, 0xc3, 0xc4, 0xea, 0x69, 0x98, 0xd0, 0xf5, 0xd8, 0xd8, 0x20, 0xcd, - 0x8e, 0xd7, 0x95, 0xaf, 0xb9, 0x22, 0xda, 0xb1, 0xc2, 0x60, 0xe9, 0x69, 0x1d, 0x51, 0x2c, 0x3d, - 0x33, 0x29, 0x67, 0x45, 0x3b, 0x56, 0x18, 0xe8, 0x79, 0x18, 0x36, 0x5e, 0x52, 0xce, 0x4b, 0x66, - 0x90, 0x1b, 0x2a, 0x33, 0xc6, 0x29, 0x2c, 0x34, 0x01, 0xa0, 0x8c, 0x1c, 0xa9, 0x22, 0x99, 0xa3, - 0x48, 0x49, 0xa2, 0x18, 0x1b, 0x18, 0x2c, 0x19, 0xd4, 0xeb, 0xc4, 0xcc, 0xc7, 0x3f, 0xa0, 0x0b, - 0x78, 0xce, 0x88, 0x36, 0xac, 0xa0, 0x54, 0x9a, 0xb4, 0x1d, 0xbf, 0xe3, 0x78, 0x74, 0x84, 0xc4, - 0xd6, 0x4f, 0x2d, 0xc3, 0x45, 0x05, 0xc1, 0x06, 0x16, 0x7d, 0xe3, 0xc4, 0x6d, 0x93, 0x57, 0x02, - 0x5f, 0x46, 0x87, 0xe9, 0x63, 0x1f, 0xd1, 0x8e, 0x15, 0x86, 0xfd, 0x5f, 0x2c, 0x38, 0xa1, 0x53, - 0xcb, 0xf9, 0x9d, 0xd5, 0xe6, 0x4e, 0xd5, 0xda, 0x77, 0xa7, 0x9a, 0xce, 0xb9, 0x2d, 0xf5, 0x95, - 0x73, 0x6b, 0xa6, 0xc3, 0x96, 0xf7, 0x4c, 0x87, 0xfd, 0x41, 0x7d, 0x1f, 0x2a, 0xcf, 0x9b, 0x1d, - 0xca, 0xbb, 0x0b, 0x15, 0xd9, 0x30, 0xd0, 0x70, 0x54, 0x5d, 0x95, 0x61, 0xbe, 0x77, 0x98, 0x99, - 0x62, 0x48, 0x02, 0x62, 0x2f, 0x41, 0x5d, 0x9d, 0x7e, 0xc8, 0x8d, 0xaa, 0x95, 0xbf, 0x51, 0xed, - 0x2b, 0x2d, 0x6f, 0x7a, 0xed, 0x9b, 0xdf, 0x7d, 0xe2, 0x1d, 0xbf, 0xff, 0xdd, 0x27, 0xde, 0xf1, - 0x47, 0xdf, 0x7d, 0xe2, 0x1d, 0x9f, 0xb8, 0xfb, 0x84, 0xf5, 0xcd, 0xbb, 0x4f, 0x58, 0xbf, 0x7f, - 0xf7, 0x09, 0xeb, 0x8f, 0xee, 0x3e, 0x61, 0x7d, 0xe7, 0xee, 0x13, 0xd6, 0x17, 0xff, 0xe3, 0x13, - 0xef, 0x78, 0x25, 0x37, 0x3c, 0x90, 0xfe, 0x78, 0xb6, 0xd1, 0x9c, 0xdc, 0xba, 0xc8, 0x22, 0xd4, - 0xe8, 0xf2, 0x9a, 0x34, 0xe6, 0xd4, 0xa4, 0x5c, 0x5e, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0x90, - 0x85, 0x5a, 0x45, 0xa5, 0xe0, 0x00, 0x00, + // 10990 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x1c, 0xc9, + 0x75, 0x98, 0x66, 0x17, 0x0b, 0xec, 0x3e, 0x7c, 0x90, 0x6c, 0x92, 0x77, 0x20, 0x75, 0x77, 0xa0, + 0xe7, 0xe2, 0xd3, 0x39, 0xba, 0x03, 0x7c, 0xf4, 0x9d, 0x7c, 0xf1, 0xd9, 0x92, 0xb1, 0x00, 0x09, + 0x82, 0x04, 0x08, 0x5c, 0x03, 0x24, 0xa5, 0x93, 0x4f, 0xa7, 0xc1, 0x6e, 0x63, 0x31, 0xc4, 0xec, + 0xcc, 0xdc, 0xcc, 0x2c, 0x08, 0x9c, 0x25, 0x59, 0xb2, 0x64, 0x5b, 0x89, 0x3e, 0x4e, 0x91, 0x92, + 0xf2, 0x39, 0x89, 0x14, 0xd9, 0x72, 0x52, 0x76, 0x25, 0xaa, 0x38, 0xc9, 0x8f, 0x38, 0x71, 0x52, + 0x2e, 0xdb, 0xa9, 0x94, 0x52, 0x4a, 0xca, 0x2e, 0x97, 0xcb, 0x72, 0x12, 0x1b, 0x91, 0x98, 0x4a, + 0x25, 0x95, 0xaa, 0xb8, 0xca, 0x89, 0x7f, 0x24, 0x4c, 0x7e, 0xa4, 0xfa, 0xbb, 0x67, 0x76, 0x16, + 0x58, 0x00, 0x03, 0x92, 0x52, 0xee, 0xdf, 0x6e, 0xbf, 0x37, 0xef, 0xf5, 0xf4, 0x74, 0xbf, 0xf7, + 0xfa, 0xf5, 0x7b, 0xaf, 0x61, 0xa1, 0xe5, 0x26, 0x1b, 0x9d, 0xb5, 0xc9, 0x46, 0xd0, 0x9e, 0x72, + 0xa2, 0x56, 0x10, 0x46, 0xc1, 0x6d, 0xf6, 0xe3, 0xd9, 0x46, 0x73, 0x6a, 0xeb, 0xe2, 0x54, 0xb8, + 0xd9, 0x9a, 0x72, 0x42, 0x37, 0x9e, 0x72, 0xc2, 0xd0, 0x73, 0x1b, 0x4e, 0xe2, 0x06, 0xfe, 0xd4, + 0xd6, 0x73, 0x8e, 0x17, 0x6e, 0x38, 0xcf, 0x4d, 0xb5, 0x88, 0x4f, 0x22, 0x27, 0x21, 0xcd, 0xc9, + 0x30, 0x0a, 0x92, 0x00, 0xfd, 0xa8, 0xa6, 0x36, 0x29, 0xa9, 0xb1, 0x1f, 0xaf, 0x35, 0x9a, 0x93, + 0x5b, 0x17, 0x27, 0xc3, 0xcd, 0xd6, 0x24, 0xa5, 0x36, 0x69, 0x50, 0x9b, 0x94, 0xd4, 0xce, 0x3f, + 0x6b, 0xf4, 0xa5, 0x15, 0xb4, 0x82, 0x29, 0x46, 0x74, 0xad, 0xb3, 0xce, 0xfe, 0xb1, 0x3f, 0xec, + 0x17, 0x67, 0x76, 0xde, 0xde, 0x7c, 0x31, 0x9e, 0x74, 0x03, 0xda, 0xbd, 0xa9, 0x46, 0x10, 0x91, + 0xa9, 0xad, 0xae, 0x0e, 0x9d, 0xbf, 0xa2, 0x71, 0xc8, 0x76, 0x42, 0xfc, 0xd8, 0x0d, 0xfc, 0xf8, + 0x59, 0xda, 0x05, 0x12, 0x6d, 0x91, 0xc8, 0x7c, 0x3d, 0x03, 0x21, 0x8f, 0xd2, 0xf3, 0x9a, 0x52, + 0xdb, 0x69, 0x6c, 0xb8, 0x3e, 0x89, 0x76, 0xf4, 0xe3, 0x6d, 0x92, 0x38, 0x79, 0x4f, 0x4d, 0xf5, + 0x7a, 0x2a, 0xea, 0xf8, 0x89, 0xdb, 0x26, 0x5d, 0x0f, 0xbc, 0x67, 0xbf, 0x07, 0xe2, 0xc6, 0x06, + 0x69, 0x3b, 0x5d, 0xcf, 0xfd, 0x50, 0xaf, 0xe7, 0x3a, 0x89, 0xeb, 0x4d, 0xb9, 0x7e, 0x12, 0x27, + 0x51, 0xf6, 0x21, 0xfb, 0x75, 0x18, 0x9d, 0xbe, 0xb5, 0x32, 0xdd, 0x49, 0x36, 0x66, 0x02, 0x7f, + 0xdd, 0x6d, 0xa1, 0x17, 0x60, 0xb8, 0xe1, 0x75, 0xe2, 0x84, 0x44, 0xd7, 0x9d, 0x36, 0x19, 0xb7, + 0x2e, 0x58, 0x4f, 0xd7, 0xea, 0xa7, 0xbf, 0xb1, 0x3b, 0xf1, 0x8e, 0xbb, 0xbb, 0x13, 0xc3, 0x33, + 0x1a, 0x84, 0x4d, 0x3c, 0xf4, 0x03, 0x30, 0x14, 0x05, 0x1e, 0x99, 0xc6, 0xd7, 0xc7, 0x4b, 0xec, + 0x91, 0x13, 0xe2, 0x91, 0x21, 0xcc, 0x9b, 0xb1, 0x84, 0xdb, 0x7f, 0x58, 0x02, 0x98, 0x0e, 0xc3, + 0xe5, 0x28, 0xb8, 0x4d, 0x1a, 0x09, 0xfa, 0x30, 0x54, 0xe9, 0xd0, 0x35, 0x9d, 0xc4, 0x61, 0xdc, + 0x86, 0x2f, 0xfe, 0xe0, 0x24, 0x7f, 0x93, 0x49, 0xf3, 0x4d, 0xf4, 0xc4, 0xa1, 0xd8, 0x93, 0x5b, + 0xcf, 0x4d, 0x2e, 0xad, 0xd1, 0xe7, 0x17, 0x49, 0xe2, 0xd4, 0x91, 0x60, 0x06, 0xba, 0x0d, 0x2b, + 0xaa, 0xc8, 0x87, 0x81, 0x38, 0x24, 0x0d, 0xd6, 0xb1, 0xe1, 0x8b, 0x0b, 0x93, 0x47, 0x99, 0xa1, + 0x93, 0xba, 0xe7, 0x2b, 0x21, 0x69, 0xd4, 0x47, 0x04, 0xe7, 0x01, 0xfa, 0x0f, 0x33, 0x3e, 0x68, + 0x0b, 0x06, 0xe3, 0xc4, 0x49, 0x3a, 0xf1, 0x78, 0x99, 0x71, 0xbc, 0x5e, 0x18, 0x47, 0x46, 0xb5, + 0x3e, 0x26, 0x78, 0x0e, 0xf2, 0xff, 0x58, 0x70, 0xb3, 0xff, 0xc4, 0x82, 0x31, 0x8d, 0xbc, 0xe0, + 0xc6, 0x09, 0xfa, 0x89, 0xae, 0xc1, 0x9d, 0xec, 0x6f, 0x70, 0xe9, 0xd3, 0x6c, 0x68, 0x4f, 0x0a, + 0x66, 0x55, 0xd9, 0x62, 0x0c, 0x6c, 0x1b, 0x2a, 0x6e, 0x42, 0xda, 0xf1, 0x78, 0xe9, 0x42, 0xf9, + 0xe9, 0xe1, 0x8b, 0x57, 0x8a, 0x7a, 0xcf, 0xfa, 0xa8, 0x60, 0x5a, 0x99, 0xa7, 0xe4, 0x31, 0xe7, + 0x62, 0xff, 0xea, 0x88, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x73, 0x30, 0x1c, 0x07, 0x9d, 0xa8, 0x41, + 0x30, 0x09, 0x83, 0x78, 0xdc, 0xba, 0x50, 0xa6, 0x53, 0x8f, 0xce, 0xd4, 0x15, 0xdd, 0x8c, 0x4d, + 0x1c, 0xf4, 0x79, 0x0b, 0x46, 0x9a, 0x24, 0x4e, 0x5c, 0x9f, 0xf1, 0x97, 0x9d, 0x5f, 0x3d, 0x72, + 0xe7, 0x65, 0xe3, 0xac, 0x26, 0x5e, 0x3f, 0x23, 0x5e, 0x64, 0xc4, 0x68, 0x8c, 0x71, 0x8a, 0x3f, + 0x5d, 0x71, 0x4d, 0x12, 0x37, 0x22, 0x37, 0xa4, 0xff, 0xd9, 0x9c, 0x31, 0x56, 0xdc, 0xac, 0x06, + 0x61, 0x13, 0x0f, 0xf9, 0x50, 0xa1, 0x2b, 0x2a, 0x1e, 0x1f, 0x60, 0xfd, 0x9f, 0x3f, 0x5a, 0xff, + 0xc5, 0xa0, 0xd2, 0xc5, 0xaa, 0x47, 0x9f, 0xfe, 0x8b, 0x31, 0x67, 0x83, 0x3e, 0x67, 0xc1, 0xb8, + 0x58, 0xf1, 0x98, 0xf0, 0x01, 0xbd, 0xb5, 0xe1, 0x26, 0xc4, 0x73, 0xe3, 0x64, 0xbc, 0xc2, 0xfa, + 0x30, 0xd5, 0xdf, 0xdc, 0x9a, 0x8b, 0x82, 0x4e, 0x78, 0xcd, 0xf5, 0x9b, 0xf5, 0x0b, 0x82, 0xd3, + 0xf8, 0x4c, 0x0f, 0xc2, 0xb8, 0x27, 0x4b, 0xf4, 0x25, 0x0b, 0xce, 0xfb, 0x4e, 0x9b, 0xc4, 0xa1, + 0x43, 0x3f, 0x2d, 0x07, 0xd7, 0x3d, 0xa7, 0xb1, 0xc9, 0x7a, 0x34, 0x78, 0xb8, 0x1e, 0xd9, 0xa2, + 0x47, 0xe7, 0xaf, 0xf7, 0x24, 0x8d, 0xf7, 0x60, 0x8b, 0xbe, 0x66, 0xc1, 0xa9, 0x20, 0x0a, 0x37, + 0x1c, 0x9f, 0x34, 0x25, 0x34, 0x1e, 0x1f, 0x62, 0x4b, 0xef, 0x43, 0x47, 0xfb, 0x44, 0x4b, 0x59, + 0xb2, 0x8b, 0x81, 0xef, 0x26, 0x41, 0xb4, 0x42, 0x92, 0xc4, 0xf5, 0x5b, 0x71, 0xfd, 0xec, 0xdd, + 0xdd, 0x89, 0x53, 0x5d, 0x58, 0xb8, 0xbb, 0x3f, 0xe8, 0x27, 0x61, 0x38, 0xde, 0xf1, 0x1b, 0xb7, + 0x5c, 0xbf, 0x19, 0xdc, 0x89, 0xc7, 0xab, 0x45, 0x2c, 0xdf, 0x15, 0x45, 0x50, 0x2c, 0x40, 0xcd, + 0x00, 0x9b, 0xdc, 0xf2, 0x3f, 0x9c, 0x9e, 0x4a, 0xb5, 0xa2, 0x3f, 0x9c, 0x9e, 0x4c, 0x7b, 0xb0, + 0x45, 0x3f, 0x67, 0xc1, 0x68, 0xec, 0xb6, 0x7c, 0x27, 0xe9, 0x44, 0xe4, 0x1a, 0xd9, 0x89, 0xc7, + 0x81, 0x75, 0xe4, 0xea, 0x11, 0x47, 0xc5, 0x20, 0x59, 0x3f, 0x2b, 0xfa, 0x38, 0x6a, 0xb6, 0xc6, + 0x38, 0xcd, 0x37, 0x6f, 0xa1, 0xe9, 0x69, 0x3d, 0x5c, 0xec, 0x42, 0xd3, 0x93, 0xba, 0x27, 0x4b, + 0xf4, 0xe3, 0x70, 0x92, 0x37, 0xa9, 0x91, 0x8d, 0xc7, 0x47, 0x98, 0xa0, 0x3d, 0x73, 0x77, 0x77, + 0xe2, 0xe4, 0x4a, 0x06, 0x86, 0xbb, 0xb0, 0xd1, 0xeb, 0x30, 0x11, 0x92, 0xa8, 0xed, 0x26, 0x4b, + 0xbe, 0xb7, 0x23, 0xc5, 0x77, 0x23, 0x08, 0x49, 0x53, 0x74, 0x27, 0x1e, 0x1f, 0xbd, 0x60, 0x3d, + 0x5d, 0xad, 0xbf, 0x4b, 0x74, 0x73, 0x62, 0x79, 0x6f, 0x74, 0xbc, 0x1f, 0x3d, 0xfb, 0x5f, 0x97, + 0xe0, 0x64, 0x56, 0x71, 0xa2, 0xbf, 0x6b, 0xc1, 0x89, 0xdb, 0x77, 0x92, 0xd5, 0x60, 0x93, 0xf8, + 0x71, 0x7d, 0x87, 0x8a, 0x37, 0xa6, 0x32, 0x86, 0x2f, 0x36, 0x8a, 0x55, 0xd1, 0x93, 0x57, 0xd3, + 0x5c, 0x2e, 0xf9, 0x49, 0xb4, 0x53, 0x7f, 0x54, 0xbc, 0xdd, 0x89, 0xab, 0xb7, 0x56, 0x4d, 0x28, + 0xce, 0x76, 0xea, 0xfc, 0x67, 0x2c, 0x38, 0x93, 0x47, 0x02, 0x9d, 0x84, 0xf2, 0x26, 0xd9, 0xe1, + 0x56, 0x19, 0xa6, 0x3f, 0xd1, 0xab, 0x50, 0xd9, 0x72, 0xbc, 0x0e, 0x11, 0xd6, 0xcd, 0xdc, 0xd1, + 0x5e, 0x44, 0xf5, 0x0c, 0x73, 0xaa, 0x3f, 0x52, 0x7a, 0xd1, 0xb2, 0x7f, 0xb7, 0x0c, 0xc3, 0x86, + 0x7e, 0xbb, 0x0f, 0x16, 0x5b, 0x90, 0xb2, 0xd8, 0x16, 0x0b, 0x53, 0xcd, 0x3d, 0x4d, 0xb6, 0x3b, + 0x19, 0x93, 0x6d, 0xa9, 0x38, 0x96, 0x7b, 0xda, 0x6c, 0x28, 0x81, 0x5a, 0x10, 0x52, 0x8b, 0x9c, + 0xaa, 0xfe, 0x81, 0x22, 0x3e, 0xe1, 0x92, 0x24, 0x57, 0x1f, 0xbd, 0xbb, 0x3b, 0x51, 0x53, 0x7f, + 0xb1, 0x66, 0x64, 0x7f, 0xcb, 0x82, 0x33, 0x46, 0x1f, 0x67, 0x02, 0xbf, 0xe9, 0xb2, 0x4f, 0x7b, + 0x01, 0x06, 0x92, 0x9d, 0x50, 0x9a, 0xfd, 0x6a, 0xa4, 0x56, 0x77, 0x42, 0x82, 0x19, 0x84, 0x1a, + 0xfa, 0x6d, 0x12, 0xc7, 0x4e, 0x8b, 0x64, 0x0d, 0xfd, 0x45, 0xde, 0x8c, 0x25, 0x1c, 0x45, 0x80, + 0x3c, 0x27, 0x4e, 0x56, 0x23, 0xc7, 0x8f, 0x19, 0xf9, 0x55, 0xb7, 0x4d, 0xc4, 0x00, 0xff, 0xc5, + 0xfe, 0x66, 0x0c, 0x7d, 0xa2, 0xfe, 0xc8, 0xdd, 0xdd, 0x09, 0xb4, 0xd0, 0x45, 0x09, 0xe7, 0x50, + 0xb7, 0xbf, 0x64, 0xc1, 0x23, 0xf9, 0xb6, 0x18, 0x7a, 0x0a, 0x06, 0xf9, 0x96, 0x4f, 0xbc, 0x9d, + 0xfe, 0x24, 0xac, 0x15, 0x0b, 0x28, 0x9a, 0x82, 0x9a, 0xd2, 0x13, 0xe2, 0x1d, 0x4f, 0x09, 0xd4, + 0x9a, 0x56, 0x2e, 0x1a, 0x87, 0x0e, 0x1a, 0xfd, 0x23, 0x2c, 0x37, 0x35, 0x68, 0x6c, 0x93, 0xc4, + 0x20, 0xf6, 0x7f, 0xb4, 0xe0, 0x84, 0xd1, 0xab, 0xfb, 0x60, 0x9a, 0xfb, 0x69, 0xd3, 0x7c, 0xbe, + 0xb0, 0xf9, 0xdc, 0xc3, 0x36, 0xff, 0x9c, 0x05, 0xe7, 0x0d, 0xac, 0x45, 0x27, 0x69, 0x6c, 0x5c, + 0xda, 0x0e, 0x23, 0x12, 0xd3, 0xed, 0x34, 0x7a, 0xdc, 0x90, 0x5b, 0xf5, 0x61, 0x41, 0xa1, 0x7c, + 0x8d, 0xec, 0x70, 0x21, 0xf6, 0x0c, 0x54, 0xf9, 0xe4, 0x0c, 0x22, 0x31, 0xe2, 0xea, 0xdd, 0x96, + 0x44, 0x3b, 0x56, 0x18, 0xc8, 0x86, 0x41, 0x26, 0x9c, 0xe8, 0x62, 0xa5, 0x6a, 0x08, 0xe8, 0x47, + 0xbc, 0xc9, 0x5a, 0xb0, 0x80, 0xd8, 0x71, 0xaa, 0x3b, 0xcb, 0x11, 0x61, 0x1f, 0xb7, 0x79, 0xd9, + 0x25, 0x5e, 0x33, 0xa6, 0xdb, 0x06, 0xc7, 0xf7, 0x83, 0x44, 0xec, 0x00, 0x8c, 0x6d, 0xc3, 0xb4, + 0x6e, 0xc6, 0x26, 0x0e, 0x65, 0xea, 0x39, 0x6b, 0xc4, 0xe3, 0x23, 0x2a, 0x98, 0x2e, 0xb0, 0x16, + 0x2c, 0x20, 0xf6, 0xdd, 0x12, 0xdb, 0xa0, 0xa8, 0xa5, 0x4f, 0xee, 0xc7, 0xee, 0x36, 0x4a, 0xc9, + 0xca, 0xe5, 0xe2, 0x04, 0x17, 0xe9, 0xbd, 0xc3, 0x7d, 0x23, 0x23, 0x2e, 0x71, 0xa1, 0x5c, 0xf7, + 0xde, 0xe5, 0xfe, 0x56, 0x09, 0x26, 0xd2, 0x0f, 0x74, 0x49, 0x5b, 0xba, 0xa5, 0x32, 0x18, 0x65, + 0x9d, 0x18, 0x06, 0x3e, 0x36, 0xf1, 0x7a, 0x08, 0xac, 0xd2, 0x71, 0x0a, 0x2c, 0x53, 0x9e, 0x96, + 0xf7, 0x91, 0xa7, 0x4f, 0xa9, 0x51, 0x1f, 0xc8, 0x08, 0xb0, 0xb4, 0x4e, 0xb9, 0x00, 0x03, 0x71, + 0x42, 0xc2, 0xf1, 0x4a, 0x5a, 0x1e, 0xad, 0x24, 0x24, 0xc4, 0x0c, 0x62, 0xff, 0xb7, 0x12, 0x3c, + 0x9a, 0x1e, 0x43, 0xad, 0x02, 0xde, 0x97, 0x52, 0x01, 0xef, 0x36, 0x55, 0xc0, 0xbd, 0xdd, 0x89, + 0x77, 0xf6, 0x78, 0xec, 0xbb, 0x46, 0x43, 0xa0, 0xb9, 0xcc, 0x28, 0x4e, 0xa5, 0x47, 0xf1, 0xde, + 0xee, 0xc4, 0xe3, 0x3d, 0xde, 0x31, 0x33, 0xcc, 0x4f, 0xc1, 0x60, 0x44, 0x9c, 0x38, 0xf0, 0xc5, + 0x40, 0xab, 0xcf, 0x81, 0x59, 0x2b, 0x16, 0x50, 0xfb, 0xf7, 0x6b, 0xd9, 0xc1, 0x9e, 0xe3, 0x4e, + 0xb8, 0x20, 0x42, 0x2e, 0x0c, 0x30, 0xb3, 0x9e, 0x8b, 0x86, 0x6b, 0x47, 0x5b, 0x46, 0x54, 0x0d, + 0x28, 0xd2, 0xf5, 0x2a, 0xfd, 0x6a, 0xb4, 0x09, 0x33, 0x16, 0x68, 0x1b, 0xaa, 0x0d, 0x69, 0x6d, + 0x97, 0x8a, 0xf0, 0x4b, 0x09, 0x5b, 0x5b, 0x73, 0x1c, 0xa1, 0xf2, 0x5a, 0x99, 0xe8, 0x8a, 0x1b, + 0x22, 0x50, 0x6e, 0xb9, 0x89, 0xf8, 0xac, 0x47, 0xdc, 0x4f, 0xcd, 0xb9, 0xc6, 0x2b, 0x0e, 0x51, + 0x25, 0x32, 0xe7, 0x26, 0x98, 0xd2, 0x47, 0x3f, 0x63, 0xc1, 0x70, 0xdc, 0x68, 0x2f, 0x47, 0xc1, + 0x96, 0xdb, 0x24, 0x91, 0xb0, 0xa6, 0x8e, 0x28, 0x9a, 0x56, 0x66, 0x16, 0x25, 0x41, 0xcd, 0x97, + 0xef, 0x6f, 0x35, 0x04, 0x9b, 0x7c, 0xe9, 0x2e, 0xe3, 0x51, 0xf1, 0xee, 0xb3, 0xa4, 0xe1, 0x52, + 0xfd, 0x27, 0x37, 0x55, 0x6c, 0xa6, 0x1c, 0xd9, 0xba, 0x9c, 0xed, 0x34, 0x36, 0xe9, 0x7a, 0xd3, + 0x1d, 0x7a, 0xe7, 0xdd, 0xdd, 0x89, 0x47, 0x67, 0xf2, 0x79, 0xe2, 0x5e, 0x9d, 0x61, 0x03, 0x16, + 0x76, 0x3c, 0x0f, 0x93, 0xd7, 0x3b, 0x84, 0xb9, 0x4c, 0x0a, 0x18, 0xb0, 0x65, 0x4d, 0x30, 0x33, + 0x60, 0x06, 0x04, 0x9b, 0x7c, 0xd1, 0xeb, 0x30, 0xd8, 0x76, 0x92, 0xc8, 0xdd, 0x16, 0x7e, 0x92, + 0x23, 0xda, 0xfb, 0x8b, 0x8c, 0x96, 0x66, 0xce, 0x34, 0x35, 0x6f, 0xc4, 0x82, 0x11, 0x6a, 0x43, + 0xa5, 0x4d, 0xa2, 0x16, 0x19, 0xaf, 0x16, 0xe1, 0x13, 0x5e, 0xa4, 0xa4, 0x34, 0xc3, 0x1a, 0xb5, + 0x8e, 0x58, 0x1b, 0xe6, 0x5c, 0xd0, 0xab, 0x50, 0x8d, 0x89, 0x47, 0x1a, 0xd4, 0xbe, 0xa9, 0x31, + 0x8e, 0x3f, 0xd4, 0xa7, 0xad, 0x47, 0x0d, 0x8b, 0x15, 0xf1, 0x28, 0x5f, 0x60, 0xf2, 0x1f, 0x56, + 0x24, 0xe9, 0x00, 0x86, 0x5e, 0xa7, 0xe5, 0xfa, 0xe3, 0x50, 0xc4, 0x00, 0x2e, 0x33, 0x5a, 0x99, + 0x01, 0xe4, 0x8d, 0x58, 0x30, 0xb2, 0xff, 0xb3, 0x05, 0x28, 0x2d, 0xd4, 0xee, 0x83, 0x51, 0xfb, + 0x7a, 0xda, 0xa8, 0x5d, 0x28, 0xd2, 0xea, 0xe8, 0x61, 0xd7, 0xfe, 0x46, 0x0d, 0x32, 0xea, 0xe0, + 0x3a, 0x89, 0x13, 0xd2, 0x7c, 0x5b, 0x84, 0xbf, 0x2d, 0xc2, 0xdf, 0x16, 0xe1, 0x4a, 0x84, 0xaf, + 0x65, 0x44, 0xf8, 0x7b, 0x8d, 0x55, 0xaf, 0x0f, 0x55, 0x5f, 0x53, 0xa7, 0xae, 0x66, 0x0f, 0x0c, + 0x04, 0x2a, 0x09, 0xae, 0xae, 0x2c, 0x5d, 0xcf, 0x95, 0xd9, 0xaf, 0xa5, 0x65, 0xf6, 0x51, 0x59, + 0xfc, 0xff, 0x20, 0xa5, 0xff, 0x95, 0x05, 0xef, 0x4a, 0x4b, 0x2f, 0x39, 0x73, 0xe6, 0x5b, 0x7e, + 0x10, 0x91, 0x59, 0x77, 0x7d, 0x9d, 0x44, 0xc4, 0x6f, 0x90, 0x58, 0x79, 0x31, 0xac, 0x5e, 0x5e, + 0x0c, 0xf4, 0x3c, 0x8c, 0xdc, 0x8e, 0x03, 0x7f, 0x39, 0x70, 0x7d, 0x21, 0x82, 0xe8, 0x46, 0xf8, + 0xe4, 0xdd, 0xdd, 0x89, 0x11, 0x3a, 0xa2, 0xb2, 0x1d, 0xa7, 0xb0, 0xd0, 0x0c, 0x9c, 0xba, 0xfd, + 0xfa, 0xb2, 0x93, 0x18, 0xee, 0x00, 0xb9, 0x71, 0x67, 0x07, 0x16, 0x57, 0x5f, 0xce, 0x00, 0x71, + 0x37, 0xbe, 0xfd, 0x37, 0x4b, 0x70, 0x2e, 0xf3, 0x22, 0x81, 0xe7, 0x05, 0x9d, 0x84, 0x6e, 0x6a, + 0xd0, 0x57, 0x2c, 0x38, 0xd9, 0x4e, 0x7b, 0x1c, 0x62, 0xe1, 0xd8, 0x7d, 0x7f, 0x61, 0x3a, 0x22, + 0xe3, 0xd2, 0xa8, 0x8f, 0x8b, 0x11, 0x3a, 0x99, 0x01, 0xc4, 0xb8, 0xab, 0x2f, 0xe8, 0x55, 0xa8, + 0xb5, 0x9d, 0xed, 0x1b, 0x61, 0xd3, 0x49, 0xe4, 0x7e, 0xb2, 0xb7, 0x1b, 0xa0, 0x93, 0xb8, 0xde, + 0x24, 0x3f, 0xae, 0x9f, 0x9c, 0xf7, 0x93, 0xa5, 0x68, 0x25, 0x89, 0x5c, 0xbf, 0xc5, 0xdd, 0x79, + 0x8b, 0x92, 0x0c, 0xd6, 0x14, 0xed, 0x2f, 0x5b, 0x59, 0x25, 0xa5, 0x46, 0x27, 0x72, 0x12, 0xd2, + 0xda, 0x41, 0x1f, 0x81, 0x0a, 0xdd, 0xf8, 0xc9, 0x51, 0xb9, 0x55, 0xa4, 0xe6, 0x34, 0xbe, 0x84, + 0x56, 0xa2, 0xf4, 0x5f, 0x8c, 0x39, 0x53, 0xfb, 0x2b, 0xb5, 0xac, 0xb1, 0xc0, 0x0e, 0x6f, 0x2f, + 0x02, 0xb4, 0x82, 0x55, 0xd2, 0x0e, 0x3d, 0x3a, 0x2c, 0x16, 0x3b, 0x01, 0x50, 0xbe, 0x8e, 0x39, + 0x05, 0xc1, 0x06, 0x16, 0xfa, 0xcb, 0x16, 0x40, 0x4b, 0xce, 0x79, 0x69, 0x08, 0xdc, 0x28, 0xf2, + 0x75, 0xf4, 0x8a, 0xd2, 0x7d, 0x51, 0x0c, 0xb1, 0xc1, 0x1c, 0xfd, 0xb4, 0x05, 0xd5, 0x44, 0x76, + 0x9f, 0xab, 0xc6, 0xd5, 0x22, 0x7b, 0x22, 0x5f, 0x5a, 0xdb, 0x44, 0x6a, 0x48, 0x14, 0x5f, 0xf4, + 0xb3, 0x16, 0x40, 0xbc, 0xe3, 0x37, 0x96, 0x03, 0xcf, 0x6d, 0xec, 0x08, 0x8d, 0x79, 0xb3, 0x50, + 0x7f, 0x8c, 0xa2, 0x5e, 0x1f, 0xa3, 0xa3, 0xa1, 0xff, 0x63, 0x83, 0x33, 0xfa, 0x18, 0x54, 0x63, + 0x31, 0xdd, 0x84, 0x8e, 0x5c, 0x2d, 0xd6, 0x2b, 0xc4, 0x69, 0x0b, 0xf1, 0x2a, 0xfe, 0x61, 0xc5, + 0x13, 0xfd, 0xbc, 0x05, 0x27, 0xc2, 0xb4, 0x9f, 0x4f, 0xa8, 0xc3, 0xe2, 0x64, 0x40, 0xc6, 0x8f, + 0x58, 0x3f, 0x7d, 0x77, 0x77, 0xe2, 0x44, 0xa6, 0x11, 0x67, 0x7b, 0x41, 0x25, 0xa0, 0x9e, 0xc1, + 0x4b, 0x21, 0xf7, 0x39, 0x0e, 0x69, 0x09, 0x38, 0x97, 0x05, 0xe2, 0x6e, 0x7c, 0xb4, 0x0c, 0x67, + 0x68, 0xef, 0x76, 0xb8, 0xf9, 0x29, 0xd5, 0x4b, 0xcc, 0x94, 0x61, 0xb5, 0xfe, 0x98, 0x98, 0x21, + 0xcc, 0xab, 0x9f, 0xc5, 0xc1, 0xb9, 0x4f, 0xa2, 0xdf, 0xb5, 0xe0, 0x31, 0x97, 0xa9, 0x01, 0xd3, + 0x61, 0xae, 0x35, 0x82, 0x38, 0x89, 0x25, 0x85, 0xca, 0x8a, 0x5e, 0xea, 0xa7, 0xfe, 0x17, 0xc4, + 0x1b, 0x3c, 0x36, 0xbf, 0x47, 0x97, 0xf0, 0x9e, 0x1d, 0x46, 0x3f, 0x0c, 0xa3, 0x72, 0x5d, 0x2c, + 0x53, 0x11, 0xcc, 0x14, 0x6d, 0xad, 0x7e, 0xea, 0xee, 0xee, 0xc4, 0xe8, 0xaa, 0x09, 0xc0, 0x69, + 0x3c, 0xfb, 0x9b, 0xa5, 0xd4, 0x79, 0x88, 0x72, 0x42, 0x32, 0x71, 0xd3, 0x90, 0xfe, 0x1f, 0x29, + 0x3d, 0x0b, 0x15, 0x37, 0xca, 0xbb, 0xa4, 0xc5, 0x8d, 0x6a, 0x8a, 0xb1, 0xc1, 0x9c, 0x1a, 0xa5, + 0xa7, 0x9c, 0xac, 0xab, 0x53, 0x48, 0xc0, 0x57, 0x8b, 0xec, 0x52, 0xf7, 0xe9, 0xd5, 0x39, 0xd1, + 0xb5, 0x53, 0x5d, 0x20, 0xdc, 0xdd, 0x25, 0xfb, 0x9b, 0xe9, 0x33, 0x18, 0x63, 0xf1, 0xf6, 0x71, + 0xbe, 0xf4, 0x79, 0x0b, 0x86, 0xa3, 0xc0, 0xf3, 0x5c, 0xbf, 0x45, 0x05, 0x8d, 0xd0, 0x96, 0x1f, + 0x3c, 0x16, 0x85, 0x25, 0x24, 0x0a, 0x33, 0x6d, 0xb1, 0xe6, 0x89, 0xcd, 0x0e, 0xd8, 0x7f, 0x62, + 0xc1, 0x78, 0x2f, 0x81, 0x88, 0x08, 0xbc, 0x53, 0xae, 0x76, 0x15, 0x5d, 0xb1, 0xe4, 0xcf, 0x12, + 0x8f, 0x28, 0xc7, 0x73, 0xb5, 0xfe, 0xa4, 0x78, 0xcd, 0x77, 0x2e, 0xf7, 0x46, 0xc5, 0x7b, 0xd1, + 0x41, 0xaf, 0xc0, 0x49, 0xe3, 0xbd, 0x62, 0x35, 0x30, 0xb5, 0xfa, 0x24, 0xb5, 0x40, 0xa6, 0x33, + 0xb0, 0x7b, 0xbb, 0x13, 0x8f, 0x64, 0xdb, 0x84, 0xc4, 0xee, 0xa2, 0x63, 0xff, 0x72, 0x29, 0xfb, + 0xb5, 0x94, 0xb2, 0x7d, 0xcb, 0xea, 0xda, 0xce, 0xbf, 0xff, 0x38, 0x14, 0x1c, 0xdb, 0xf8, 0xab, + 0x00, 0x8e, 0xde, 0x38, 0x0f, 0xf0, 0x84, 0xd8, 0xfe, 0x37, 0x03, 0xb0, 0x47, 0xcf, 0xfa, 0xb0, + 0x9e, 0x0f, 0x7c, 0xac, 0xf8, 0x59, 0x4b, 0x1d, 0x39, 0x95, 0xd9, 0x22, 0x6f, 0x1e, 0xd7, 0xd8, + 0xf3, 0x0d, 0x4c, 0xcc, 0xa3, 0x14, 0x94, 0x1b, 0x3b, 0x7d, 0xb8, 0x85, 0xbe, 0x6a, 0xa5, 0x0f, + 0xcd, 0x78, 0xd8, 0x99, 0x7b, 0x6c, 0x7d, 0x32, 0x4e, 0xe2, 0x78, 0xc7, 0xf4, 0xf9, 0x4d, 0xaf, + 0x33, 0xba, 0x49, 0x80, 0x75, 0xd7, 0x77, 0x3c, 0xf7, 0x0d, 0xba, 0x3d, 0xa9, 0x30, 0x0d, 0xcb, + 0x4c, 0x96, 0xcb, 0xaa, 0x15, 0x1b, 0x18, 0xe7, 0xff, 0x12, 0x0c, 0x1b, 0x6f, 0x9e, 0x13, 0x5c, + 0x71, 0xc6, 0x0c, 0xae, 0xa8, 0x19, 0x31, 0x11, 0xe7, 0xdf, 0x0b, 0x27, 0xb3, 0x1d, 0x3c, 0xc8, + 0xf3, 0xf6, 0xff, 0x1a, 0xca, 0x9e, 0x62, 0xad, 0x92, 0xa8, 0x4d, 0xbb, 0xf6, 0xb6, 0x67, 0xe9, + 0x6d, 0xcf, 0xd2, 0xdb, 0x9e, 0x25, 0xf3, 0x70, 0x40, 0x78, 0x4d, 0x86, 0xee, 0x93, 0xd7, 0x24, + 0xe5, 0x07, 0xaa, 0x16, 0xee, 0x07, 0xb2, 0xef, 0x56, 0x20, 0x65, 0x47, 0xf1, 0xf1, 0xfe, 0x01, + 0x18, 0x8a, 0x48, 0x18, 0xdc, 0xc0, 0x0b, 0x42, 0x87, 0xe8, 0x00, 0x7a, 0xde, 0x8c, 0x25, 0x9c, + 0xea, 0x9a, 0xd0, 0x49, 0x36, 0x84, 0x12, 0x51, 0xba, 0x66, 0xd9, 0x49, 0x36, 0x30, 0x83, 0xa0, + 0xf7, 0xc2, 0x58, 0xe2, 0x44, 0x2d, 0x6a, 0x6f, 0x6f, 0xb1, 0xcf, 0x2a, 0xce, 0x3a, 0x1f, 0x11, + 0xb8, 0x63, 0xab, 0x29, 0x28, 0xce, 0x60, 0xa3, 0xd7, 0x61, 0x60, 0x83, 0x78, 0x6d, 0x31, 0xe4, + 0x2b, 0xc5, 0xc9, 0x78, 0xf6, 0xae, 0x57, 0x88, 0xd7, 0xe6, 0x12, 0x88, 0xfe, 0xc2, 0x8c, 0x15, + 0x9d, 0x6f, 0xb5, 0xcd, 0x4e, 0x9c, 0x04, 0x6d, 0xf7, 0x0d, 0xe9, 0xe2, 0x7b, 0x7f, 0xc1, 0x8c, + 0xaf, 0x49, 0xfa, 0xdc, 0x97, 0xa2, 0xfe, 0x62, 0xcd, 0x99, 0xf5, 0xa3, 0xe9, 0x46, 0xec, 0x53, + 0xed, 0x08, 0x4f, 0x5d, 0xd1, 0xfd, 0x98, 0x95, 0xf4, 0x79, 0x3f, 0xd4, 0x5f, 0xac, 0x39, 0xa3, + 0x1d, 0x35, 0xef, 0x87, 0x59, 0x1f, 0x6e, 0x14, 0xdc, 0x07, 0x3e, 0xe7, 0x73, 0xe7, 0xff, 0x93, + 0x50, 0x69, 0x6c, 0x38, 0x51, 0x32, 0x3e, 0xc2, 0x26, 0x8d, 0xf2, 0xe9, 0xcc, 0xd0, 0x46, 0xcc, + 0x61, 0xe8, 0x71, 0x28, 0x47, 0x64, 0x9d, 0xc5, 0x6d, 0x1a, 0x11, 0x3d, 0x98, 0xac, 0x63, 0xda, + 0x6e, 0xff, 0x62, 0x29, 0x6d, 0x2e, 0xa5, 0xdf, 0x9b, 0xcf, 0xf6, 0x46, 0x27, 0x8a, 0xa5, 0xdf, + 0xc7, 0x98, 0xed, 0xac, 0x19, 0x4b, 0x38, 0xfa, 0x84, 0x05, 0x43, 0xb7, 0xe3, 0xc0, 0xf7, 0x49, + 0x22, 0x54, 0xd3, 0xcd, 0x82, 0x87, 0xe2, 0x2a, 0xa7, 0xae, 0xfb, 0x20, 0x1a, 0xb0, 0xe4, 0x4b, + 0xbb, 0x4b, 0xb6, 0x1b, 0x5e, 0xa7, 0xd9, 0x15, 0xa4, 0x71, 0x89, 0x37, 0x63, 0x09, 0xa7, 0xa8, + 0xae, 0xcf, 0x51, 0x07, 0xd2, 0xa8, 0xf3, 0xbe, 0x40, 0x15, 0x70, 0xfb, 0xaf, 0x0f, 0xc2, 0xd9, + 0xdc, 0xc5, 0x41, 0x0d, 0x19, 0x66, 0x2a, 0x5c, 0x76, 0x3d, 0x22, 0xc3, 0x93, 0x98, 0x21, 0x73, + 0x53, 0xb5, 0x62, 0x03, 0x03, 0xfd, 0x14, 0x40, 0xe8, 0x44, 0x4e, 0x9b, 0x28, 0xbf, 0xec, 0x91, + 0xed, 0x05, 0xda, 0x8f, 0x65, 0x49, 0x53, 0xef, 0x4d, 0x55, 0x53, 0x8c, 0x0d, 0x96, 0xe8, 0x05, + 0x18, 0x8e, 0x88, 0x47, 0x9c, 0x98, 0x85, 0xfd, 0x66, 0x73, 0x18, 0xb0, 0x06, 0x61, 0x13, 0x0f, + 0x3d, 0xa5, 0x22, 0xb9, 0x32, 0x11, 0x2d, 0xe9, 0x68, 0x2e, 0xf4, 0xa6, 0x05, 0x63, 0xeb, 0xae, + 0x47, 0x34, 0x77, 0x91, 0x71, 0xb0, 0x74, 0xf4, 0x97, 0xbc, 0x6c, 0xd2, 0xd5, 0x12, 0x32, 0xd5, + 0x1c, 0xe3, 0x0c, 0x7b, 0xfa, 0x99, 0xb7, 0x48, 0xc4, 0x44, 0xeb, 0x60, 0xfa, 0x33, 0xdf, 0xe4, + 0xcd, 0x58, 0xc2, 0xd1, 0x34, 0x9c, 0x08, 0x9d, 0x38, 0x9e, 0x89, 0x48, 0x93, 0xf8, 0x89, 0xeb, + 0x78, 0x3c, 0x1f, 0xa0, 0xaa, 0xe3, 0x81, 0x97, 0xd3, 0x60, 0x9c, 0xc5, 0x47, 0x1f, 0x80, 0x47, + 0xb9, 0xe3, 0x63, 0xd1, 0x8d, 0x63, 0xd7, 0x6f, 0xe9, 0x69, 0x20, 0xfc, 0x3f, 0x13, 0x82, 0xd4, + 0xa3, 0xf3, 0xf9, 0x68, 0xb8, 0xd7, 0xf3, 0xe8, 0x19, 0xa8, 0xc6, 0x9b, 0x6e, 0x38, 0x13, 0x35, + 0x63, 0x76, 0xe8, 0x51, 0xd5, 0xde, 0xc6, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0x6a, 0xc0, 0x08, 0xff, + 0x24, 0x3c, 0x14, 0x4d, 0xc8, 0xc7, 0x67, 0x7b, 0xaa, 0x47, 0x91, 0xb2, 0x36, 0x89, 0x9d, 0x3b, + 0x97, 0xe4, 0x11, 0x0c, 0x3f, 0x31, 0xb8, 0x69, 0x90, 0xc1, 0x29, 0xa2, 0xf6, 0x2f, 0x94, 0xd2, + 0x3b, 0x6e, 0x73, 0x91, 0xa2, 0x98, 0x2e, 0xc5, 0xe4, 0xa6, 0x13, 0x49, 0x6f, 0xcc, 0x11, 0xd3, + 0x16, 0x04, 0xdd, 0x9b, 0x4e, 0x64, 0x2e, 0x6a, 0xc6, 0x00, 0x4b, 0x4e, 0xe8, 0x36, 0x0c, 0x24, + 0x9e, 0x53, 0x50, 0x9e, 0x93, 0xc1, 0x51, 0x3b, 0x40, 0x16, 0xa6, 0x63, 0xcc, 0x78, 0xa0, 0xc7, + 0xa8, 0xd5, 0xbf, 0x26, 0x8f, 0x48, 0x84, 0xa1, 0xbe, 0x16, 0x63, 0xd6, 0x6a, 0xff, 0x0a, 0xe4, + 0xc8, 0x55, 0xa5, 0xc8, 0xd0, 0x45, 0x00, 0xba, 0x81, 0x5c, 0x8e, 0xc8, 0xba, 0xbb, 0x2d, 0x0c, + 0x09, 0xb5, 0x76, 0xaf, 0x2b, 0x08, 0x36, 0xb0, 0xe4, 0x33, 0x2b, 0x9d, 0x75, 0xfa, 0x4c, 0xa9, + 0xfb, 0x19, 0x0e, 0xc1, 0x06, 0x16, 0x7a, 0x1e, 0x06, 0xdd, 0xb6, 0xd3, 0x52, 0x21, 0x98, 0x8f, + 0xd1, 0x45, 0x3b, 0xcf, 0x5a, 0xee, 0xed, 0x4e, 0x8c, 0xa9, 0x0e, 0xb1, 0x26, 0x2c, 0x70, 0xd1, + 0x2f, 0x5b, 0x30, 0xd2, 0x08, 0xda, 0xed, 0xc0, 0xe7, 0xdb, 0x2e, 0xb1, 0x87, 0xbc, 0x7d, 0x5c, + 0x6a, 0x7e, 0x72, 0xc6, 0x60, 0xc6, 0x37, 0x91, 0x2a, 0x21, 0xcb, 0x04, 0xe1, 0x54, 0xaf, 0xcc, + 0xb5, 0x5d, 0xd9, 0x67, 0x6d, 0xff, 0xba, 0x05, 0xa7, 0xf8, 0xb3, 0xc6, 0x6e, 0x50, 0xe4, 0x1e, + 0x05, 0xc7, 0xfc, 0x5a, 0x5d, 0x1b, 0x64, 0xe5, 0xa5, 0xeb, 0x82, 0xe3, 0xee, 0x4e, 0xa2, 0x39, + 0x38, 0xb5, 0x1e, 0x44, 0x0d, 0x62, 0x0e, 0x84, 0x10, 0x4c, 0x8a, 0xd0, 0xe5, 0x2c, 0x02, 0xee, + 0x7e, 0x06, 0xdd, 0x84, 0x47, 0x8c, 0x46, 0x73, 0x1c, 0xb8, 0x6c, 0x7a, 0x42, 0x50, 0x7b, 0xe4, + 0x72, 0x2e, 0x16, 0xee, 0xf1, 0x74, 0xda, 0x61, 0x52, 0xeb, 0xc3, 0x61, 0xf2, 0x1a, 0x9c, 0x6b, + 0x74, 0x8f, 0xcc, 0x56, 0xdc, 0x59, 0x8b, 0xb9, 0xa4, 0xaa, 0xd6, 0xbf, 0x4f, 0x10, 0x38, 0x37, + 0xd3, 0x0b, 0x11, 0xf7, 0xa6, 0x81, 0x3e, 0x02, 0xd5, 0x88, 0xb0, 0xaf, 0x12, 0x8b, 0x44, 0x9c, + 0x23, 0xee, 0x92, 0xb5, 0x05, 0xca, 0xc9, 0x6a, 0xd9, 0x2b, 0x1a, 0x62, 0xac, 0x38, 0xa2, 0x3b, + 0x30, 0x14, 0x3a, 0x49, 0x63, 0x43, 0xa4, 0xdf, 0x1c, 0x39, 0xfe, 0x45, 0x31, 0x67, 0x3e, 0x70, + 0x3d, 0xc9, 0x97, 0x39, 0x13, 0x2c, 0xb9, 0x51, 0x6b, 0xa4, 0x11, 0xb4, 0xc3, 0xc0, 0x27, 0x7e, + 0x12, 0x8f, 0x8f, 0x6a, 0x6b, 0x64, 0x46, 0xb5, 0x62, 0x03, 0xe3, 0xfc, 0xfb, 0xe0, 0x54, 0xd7, + 0xc2, 0x3b, 0x90, 0x73, 0x65, 0x16, 0x1e, 0xc9, 0x9f, 0xe2, 0x07, 0x72, 0xb1, 0xfc, 0xe3, 0x4c, + 0x90, 0xab, 0x61, 0xf6, 0xf6, 0xe1, 0xae, 0x73, 0xa0, 0x4c, 0xfc, 0x2d, 0x21, 0xf1, 0x2f, 0x1f, + 0x6d, 0xa4, 0x2f, 0xf9, 0x5b, 0x7c, 0x85, 0x32, 0x9f, 0xc4, 0x25, 0x7f, 0x0b, 0x53, 0xda, 0xe8, + 0x8b, 0x56, 0xca, 0x6c, 0xe3, 0x4e, 0xbe, 0x0f, 0x1d, 0x8b, 0x9d, 0xdf, 0xb7, 0x25, 0x67, 0xff, + 0xdb, 0x12, 0x5c, 0xd8, 0x8f, 0x48, 0x1f, 0xc3, 0xf7, 0x24, 0x0c, 0xc6, 0xec, 0xd8, 0x5a, 0x88, + 0xd0, 0x61, 0x3a, 0xb3, 0xf8, 0x41, 0xf6, 0x6b, 0x58, 0x80, 0x90, 0x07, 0xe5, 0xb6, 0x13, 0x0a, + 0xdf, 0xcf, 0xfc, 0x51, 0xd3, 0x5e, 0xe8, 0x7f, 0xc7, 0x5b, 0x74, 0x42, 0xee, 0x51, 0x30, 0x1a, + 0x30, 0x65, 0x83, 0x12, 0xa8, 0x38, 0x51, 0xe4, 0xc8, 0x33, 0xd2, 0x6b, 0xc5, 0xf0, 0x9b, 0xa6, + 0x24, 0xf9, 0x11, 0x53, 0xaa, 0x09, 0x73, 0x66, 0xf6, 0x67, 0x87, 0x52, 0xa9, 0x1f, 0xec, 0xe0, + 0x3b, 0x86, 0x41, 0xe1, 0xf2, 0xb1, 0x8a, 0xce, 0x36, 0xe2, 0xb9, 0x7b, 0x6c, 0x57, 0x27, 0x32, + 0xa0, 0x05, 0x2b, 0xf4, 0x19, 0x8b, 0xe5, 0x19, 0xcb, 0x74, 0x18, 0xb1, 0x97, 0x3a, 0x9e, 0xb4, + 0x67, 0x33, 0x7b, 0x59, 0x36, 0x62, 0x93, 0x3b, 0xd5, 0xb1, 0x21, 0xcf, 0x98, 0xcb, 0xee, 0xa8, + 0x64, 0x26, 0xb2, 0x84, 0xa3, 0xed, 0x9c, 0x03, 0xee, 0x02, 0x72, 0x55, 0xfb, 0x38, 0xd2, 0xfe, + 0xaa, 0x05, 0xa7, 0xdc, 0xec, 0x49, 0xa5, 0xd8, 0x79, 0x1c, 0x31, 0x84, 0xa2, 0xf7, 0x41, 0xa8, + 0x52, 0xbe, 0x5d, 0x20, 0xdc, 0xdd, 0x19, 0xd4, 0x84, 0x01, 0xd7, 0x5f, 0x0f, 0x84, 0xc9, 0x51, + 0x3f, 0x5a, 0xa7, 0xe6, 0xfd, 0xf5, 0x40, 0xaf, 0x66, 0xfa, 0x0f, 0x33, 0xea, 0x68, 0x01, 0xce, + 0x44, 0xc2, 0x37, 0x74, 0xc5, 0x8d, 0xe9, 0x0e, 0x7e, 0xc1, 0x6d, 0xbb, 0x09, 0x33, 0x17, 0xca, + 0xf5, 0xf1, 0xbb, 0xbb, 0x13, 0x67, 0x70, 0x0e, 0x1c, 0xe7, 0x3e, 0x85, 0xde, 0x80, 0x21, 0x99, + 0x18, 0x5d, 0x2d, 0x62, 0x17, 0xd7, 0x3d, 0xff, 0xd5, 0x64, 0x5a, 0x11, 0x39, 0xd0, 0x92, 0xa1, + 0xfd, 0xe6, 0x30, 0x74, 0x1f, 0x62, 0xa2, 0x8f, 0x42, 0x2d, 0x52, 0xc9, 0xda, 0x56, 0x11, 0xca, + 0x55, 0x7e, 0x5f, 0x71, 0x80, 0xaa, 0x0c, 0x17, 0x9d, 0x96, 0xad, 0x39, 0xd2, 0xed, 0x45, 0xac, + 0xcf, 0x3a, 0x0b, 0x98, 0xdb, 0x82, 0xab, 0x3e, 0xc7, 0xda, 0xf1, 0x1b, 0x98, 0xf1, 0x40, 0x11, + 0x0c, 0x6e, 0x10, 0xc7, 0x4b, 0x36, 0x8a, 0x71, 0xb9, 0x5f, 0x61, 0xb4, 0xb2, 0x29, 0x3b, 0xbc, + 0x15, 0x0b, 0x4e, 0x68, 0x1b, 0x86, 0x36, 0xf8, 0x04, 0x10, 0x16, 0xff, 0xe2, 0x51, 0x07, 0x37, + 0x35, 0xab, 0xf4, 0xe7, 0x16, 0x0d, 0x58, 0xb2, 0x63, 0xd1, 0x31, 0xc6, 0xf9, 0x3d, 0x5f, 0xba, + 0xc5, 0x65, 0x2b, 0xf5, 0x7f, 0x78, 0xff, 0x61, 0x18, 0x89, 0x48, 0x23, 0xf0, 0x1b, 0xae, 0x47, + 0x9a, 0xd3, 0xd2, 0x9d, 0x7e, 0x90, 0x1c, 0x17, 0xb6, 0x6b, 0xc6, 0x06, 0x0d, 0x9c, 0xa2, 0x88, + 0x3e, 0x6d, 0xc1, 0x98, 0xca, 0xf0, 0xa4, 0x1f, 0x84, 0x08, 0xf7, 0xed, 0x42, 0x41, 0xf9, 0xa4, + 0x8c, 0x66, 0x1d, 0xdd, 0xdd, 0x9d, 0x18, 0x4b, 0xb7, 0xe1, 0x0c, 0x5f, 0xf4, 0x0a, 0x40, 0xb0, + 0xc6, 0x43, 0x60, 0xa6, 0x13, 0xe1, 0xcb, 0x3d, 0xc8, 0xab, 0x8e, 0xf1, 0x64, 0x37, 0x49, 0x01, + 0x1b, 0xd4, 0xd0, 0x35, 0x00, 0xbe, 0x6c, 0x56, 0x77, 0x42, 0xb9, 0x2d, 0x90, 0x49, 0x4a, 0xb0, + 0xa2, 0x20, 0xf7, 0x76, 0x27, 0xba, 0x7d, 0x6b, 0x2c, 0xcc, 0xc0, 0x78, 0x1c, 0xfd, 0x24, 0x0c, + 0xc5, 0x9d, 0x76, 0xdb, 0x51, 0x9e, 0xde, 0x02, 0xd3, 0xe7, 0x38, 0x5d, 0x43, 0x14, 0xf1, 0x06, + 0x2c, 0x39, 0xa2, 0xdb, 0x54, 0xa8, 0xc6, 0xc2, 0xe9, 0xc7, 0x56, 0x11, 0xb7, 0x09, 0x86, 0xd9, + 0x3b, 0xbd, 0x47, 0x46, 0xf4, 0xe0, 0x1c, 0x9c, 0x7b, 0xbb, 0x13, 0x8f, 0xa4, 0xdb, 0x17, 0x02, + 0x91, 0xd0, 0x96, 0x4b, 0x13, 0x5d, 0x95, 0x75, 0x52, 0xe8, 0x6b, 0xcb, 0xf4, 0xfd, 0xa7, 0x75, + 0x9d, 0x14, 0xd6, 0xdc, 0x7b, 0xcc, 0xcc, 0x87, 0xd1, 0x22, 0x9c, 0x6e, 0x04, 0x7e, 0x12, 0x05, + 0x9e, 0xc7, 0x8b, 0xff, 0xf0, 0x1d, 0x1a, 0xf7, 0x04, 0xbf, 0x53, 0x74, 0xfb, 0xf4, 0x4c, 0x37, + 0x0a, 0xce, 0x7b, 0xce, 0xf6, 0xd3, 0xb1, 0x81, 0x62, 0x70, 0x9e, 0x87, 0x11, 0xb2, 0x9d, 0x90, + 0xc8, 0x77, 0xbc, 0x1b, 0x78, 0x41, 0xfa, 0x40, 0xd9, 0x1a, 0xb8, 0x64, 0xb4, 0xe3, 0x14, 0x16, + 0xb2, 0x95, 0x5b, 0xc2, 0x48, 0xd2, 0xe4, 0x6e, 0x09, 0xe9, 0x84, 0xb0, 0xff, 0x77, 0x29, 0x65, + 0x90, 0xad, 0x46, 0x84, 0xa0, 0x00, 0x2a, 0x7e, 0xd0, 0x54, 0xb2, 0xff, 0x6a, 0x31, 0xb2, 0xff, + 0x7a, 0xd0, 0x34, 0x8a, 0xa9, 0xd0, 0x7f, 0x31, 0xe6, 0x7c, 0x58, 0xb5, 0x09, 0x59, 0x96, 0x83, + 0x01, 0xc4, 0x46, 0xa3, 0x48, 0xce, 0xaa, 0xda, 0xc4, 0x92, 0xc9, 0x08, 0xa7, 0xf9, 0xa2, 0x4d, + 0xa8, 0x6c, 0x04, 0x71, 0x22, 0xb7, 0x1f, 0x47, 0xdc, 0xe9, 0x5c, 0x09, 0xe2, 0x84, 0x59, 0x11, + 0xea, 0xb5, 0x69, 0x4b, 0x8c, 0x39, 0x0f, 0xfb, 0xbf, 0x58, 0x29, 0x8f, 0xf7, 0x2d, 0x16, 0x27, + 0xbb, 0x45, 0x7c, 0xba, 0xac, 0xcd, 0xc0, 0xa0, 0x1f, 0xce, 0x64, 0x1d, 0xbe, 0xab, 0x57, 0x69, + 0xab, 0x3b, 0x94, 0xc2, 0x24, 0x23, 0x61, 0xc4, 0x10, 0x7d, 0xdc, 0x4a, 0xe7, 0x7f, 0x96, 0x8a, + 0xd8, 0x60, 0x98, 0x39, 0xd0, 0xfb, 0xa6, 0x92, 0xda, 0x5f, 0xb4, 0x60, 0xa8, 0xee, 0x34, 0x36, + 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0x54, 0x9b, 0x9d, 0xc8, 0x4c, 0x45, 0x55, 0xdb, 0xfc, 0x59, 0xd1, + 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x66, 0x42, 0x97, 0xf9, 0x1c, 0xbe, 0xcc, 0x5a, + 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xb8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, 0xf6, 0x45, 0x0d, 0xc2, + 0x26, 0x9e, 0xfd, 0x2f, 0x2d, 0x18, 0xaf, 0x3b, 0xb1, 0xdb, 0x98, 0xee, 0x24, 0x1b, 0x75, 0x37, + 0x59, 0xeb, 0x34, 0x36, 0x49, 0xc2, 0xd3, 0xdf, 0x69, 0x2f, 0x3b, 0x31, 0x5d, 0x4a, 0x6a, 0x5f, + 0xa7, 0x7a, 0x79, 0x43, 0xb4, 0x63, 0x85, 0x81, 0xde, 0x80, 0xe1, 0xd0, 0x89, 0xe3, 0x3b, 0x41, + 0xd4, 0xc4, 0x64, 0xbd, 0x98, 0xe2, 0x13, 0x2b, 0xa4, 0x11, 0x91, 0x04, 0x93, 0x75, 0x71, 0x24, + 0xac, 0xe9, 0x63, 0x93, 0x99, 0xfd, 0x79, 0x0b, 0xce, 0xd5, 0x89, 0x13, 0x91, 0x88, 0xd5, 0xaa, + 0x50, 0x2f, 0x32, 0xe3, 0x05, 0x9d, 0x26, 0x7a, 0x1d, 0xaa, 0x09, 0x6d, 0xa6, 0xdd, 0xb2, 0x8a, + 0xed, 0x16, 0x3b, 0xd1, 0x5d, 0x15, 0xc4, 0xb1, 0x62, 0x63, 0xff, 0x0d, 0x0b, 0x46, 0xd8, 0xe1, + 0xd8, 0x2c, 0x49, 0x1c, 0xd7, 0xeb, 0x2a, 0xe9, 0x64, 0xf5, 0x59, 0xd2, 0xe9, 0x02, 0x0c, 0x6c, + 0x04, 0x6d, 0x92, 0x3d, 0xd8, 0xbd, 0x12, 0xd0, 0x6d, 0x35, 0x85, 0xa0, 0xe7, 0xe8, 0x87, 0x77, + 0xfd, 0xc4, 0xa1, 0x4b, 0x40, 0x3a, 0x5f, 0x4f, 0xf0, 0x8f, 0xae, 0x9a, 0xb1, 0x89, 0x63, 0xff, + 0x56, 0x0d, 0x86, 0xc4, 0xe9, 0x7f, 0xdf, 0x25, 0x10, 0xe4, 0xfe, 0xbe, 0xd4, 0x73, 0x7f, 0x1f, + 0xc3, 0x60, 0x83, 0x15, 0x8c, 0x13, 0x66, 0xe4, 0xb5, 0x42, 0xc2, 0x45, 0x78, 0x0d, 0x3a, 0xdd, + 0x2d, 0xfe, 0x1f, 0x0b, 0x56, 0xe8, 0x0b, 0x16, 0x9c, 0x68, 0x04, 0xbe, 0x4f, 0x1a, 0xda, 0xc6, + 0x19, 0x28, 0x22, 0x2a, 0x60, 0x26, 0x4d, 0x54, 0x9f, 0xcc, 0x64, 0x00, 0x38, 0xcb, 0x1e, 0xbd, + 0x04, 0xa3, 0x7c, 0xcc, 0x6e, 0xa6, 0x3c, 0xc6, 0xba, 0xd2, 0x8f, 0x09, 0xc4, 0x69, 0x5c, 0x34, + 0xc9, 0x3d, 0xef, 0xa2, 0xa6, 0xce, 0xa0, 0x76, 0xac, 0x19, 0xd5, 0x74, 0x0c, 0x0c, 0x14, 0x01, + 0x8a, 0xc8, 0x7a, 0x44, 0xe2, 0x0d, 0x11, 0x1d, 0xc1, 0xec, 0xab, 0xa1, 0xc3, 0xa5, 0x4b, 0xe3, + 0x2e, 0x4a, 0x38, 0x87, 0x3a, 0xda, 0x14, 0x1b, 0xcc, 0x6a, 0x11, 0x32, 0x54, 0x7c, 0xe6, 0x9e, + 0xfb, 0xcc, 0x09, 0xa8, 0xc4, 0x1b, 0x4e, 0xd4, 0x64, 0x76, 0x5d, 0x99, 0xa7, 0xe8, 0xac, 0xd0, + 0x06, 0xcc, 0xdb, 0xd1, 0x2c, 0x9c, 0xcc, 0xd4, 0x29, 0x8a, 0x85, 0x67, 0x57, 0xa5, 0x63, 0x64, + 0x2a, 0x1c, 0xc5, 0xb8, 0xeb, 0x09, 0xd3, 0xf9, 0x30, 0xbc, 0x8f, 0xf3, 0x61, 0x47, 0xc5, 0xe0, + 0x71, 0x9f, 0xeb, 0xcb, 0x85, 0x0c, 0x40, 0x5f, 0x01, 0x77, 0x9f, 0xcb, 0x04, 0xdc, 0x8d, 0xb2, + 0x0e, 0xdc, 0x2c, 0xa6, 0x03, 0x07, 0x8f, 0xae, 0x7b, 0x90, 0xd1, 0x72, 0x7f, 0x6e, 0x81, 0xfc, + 0xae, 0x33, 0x4e, 0x63, 0x83, 0xd0, 0x29, 0x83, 0xde, 0x0b, 0x63, 0x6a, 0x0b, 0x3d, 0x13, 0x74, + 0x7c, 0x1e, 0x28, 0x57, 0xd6, 0x47, 0xb8, 0x38, 0x05, 0xc5, 0x19, 0x6c, 0x34, 0x05, 0x35, 0x3a, + 0x4e, 0xfc, 0x51, 0xae, 0x6b, 0xd5, 0x36, 0x7d, 0x7a, 0x79, 0x5e, 0x3c, 0xa5, 0x71, 0x50, 0x00, + 0xa7, 0x3c, 0x27, 0x4e, 0x58, 0x0f, 0xe8, 0x8e, 0xfa, 0x90, 0xc5, 0x0a, 0x58, 0xcc, 0xff, 0x42, + 0x96, 0x10, 0xee, 0xa6, 0x6d, 0x7f, 0x6b, 0x00, 0x46, 0x53, 0x92, 0xf1, 0x80, 0x4a, 0xfa, 0x19, + 0xa8, 0x4a, 0xbd, 0x99, 0x2d, 0xab, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, 0x6b, 0x4d, 0x6b, 0xd5, + 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, 0x8c, 0xe7, 0x12, 0x3f, + 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, 0xce, 0x00, 0x70, 0x96, + 0x3d, 0xfa, 0x94, 0x05, 0xa3, 0xce, 0x9d, 0x58, 0x57, 0x35, 0x15, 0xa1, 0x75, 0x47, 0x54, 0x52, + 0xa9, 0x42, 0xa9, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, 0x0b, 0x10, 0xd9, 0x26, + 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x58, 0xc4, 0x4e, 0xf3, 0x52, 0x17, 0x5d, 0x2e, 0xd5, 0xbb, + 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x56, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, 0x3a, 0x46, 0xdc, 0x9b, + 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0x03, 0x99, 0x4a, 0x99, 0x2a, 0x3d, 0xa0, 0x94, + 0xa9, 0x9f, 0xb6, 0x52, 0x05, 0x84, 0x86, 0x2f, 0xbe, 0x52, 0x6c, 0xac, 0xeb, 0x24, 0x8f, 0x6d, + 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, 0xe1, 0xbf, 0x2f, 0xc3, + 0xb0, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, 0x30, 0x8b, 0x7e, 0x0a, + 0x6a, 0x0d, 0x29, 0xe5, 0x8b, 0x29, 0xa1, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, 0xab, 0x26, 0xac, 0x79, + 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x03, 0x4c, 0x43, 0xe4, 0x65, 0xc2, 0x08, 0x4d, 0xd1, + 0xfd, 0x0c, 0xab, 0x33, 0x15, 0xba, 0xe2, 0xbd, 0x64, 0x44, 0x3a, 0xaf, 0x33, 0xb5, 0x3c, 0x2f, + 0x9b, 0xb1, 0x89, 0x63, 0x7f, 0xcb, 0x52, 0x1f, 0xf7, 0x3e, 0x54, 0x54, 0xb8, 0x9d, 0xae, 0xa8, + 0x70, 0xa9, 0x90, 0x61, 0xee, 0x51, 0x4a, 0xe1, 0x3a, 0x0c, 0xcd, 0x04, 0xed, 0xb6, 0xe3, 0x37, + 0xd1, 0xf7, 0xc3, 0x50, 0x83, 0xff, 0x14, 0x8e, 0x1d, 0x76, 0x3c, 0x28, 0xa0, 0x58, 0xc2, 0xd0, + 0x63, 0x30, 0xe0, 0x44, 0x2d, 0xe9, 0xcc, 0x61, 0xa1, 0x30, 0xd3, 0x51, 0x2b, 0xc6, 0xac, 0xd5, + 0xfe, 0x47, 0x03, 0xc0, 0x4e, 0xa0, 0x9d, 0x88, 0x34, 0x57, 0x03, 0x56, 0xc2, 0xef, 0x58, 0x0f, + 0xd5, 0xf4, 0x66, 0xe9, 0x61, 0x3e, 0x58, 0x33, 0x0e, 0x57, 0xca, 0xf7, 0xf9, 0x70, 0xa5, 0xc7, + 0x79, 0xd9, 0xc0, 0x43, 0x74, 0x5e, 0x66, 0x7f, 0xd6, 0x02, 0xa4, 0xc2, 0x16, 0xf4, 0x81, 0xf6, + 0x14, 0xd4, 0x54, 0x00, 0x83, 0x30, 0xac, 0xb4, 0x88, 0x90, 0x00, 0xac, 0x71, 0xfa, 0xd8, 0x21, + 0x3f, 0x29, 0xe5, 0x77, 0x39, 0x1d, 0x45, 0xcb, 0xa4, 0xbe, 0x10, 0xe7, 0xf6, 0x6f, 0x97, 0xe0, + 0x11, 0xae, 0x92, 0x17, 0x1d, 0xdf, 0x69, 0x91, 0x36, 0xed, 0x55, 0xbf, 0x21, 0x0a, 0x0d, 0xba, + 0x35, 0x73, 0x65, 0x54, 0xec, 0x51, 0xd7, 0x2e, 0x5f, 0x73, 0x7c, 0x95, 0xcd, 0xfb, 0x6e, 0x82, + 0x19, 0x71, 0x14, 0x43, 0x55, 0xd6, 0x8c, 0x17, 0xb2, 0xb8, 0x20, 0x46, 0x4a, 0x2c, 0x09, 0xbd, + 0x49, 0xb0, 0x62, 0x44, 0x0d, 0x57, 0x2f, 0x68, 0x6c, 0x62, 0x12, 0x06, 0x4c, 0xee, 0x1a, 0x41, + 0x89, 0x0b, 0xa2, 0x1d, 0x2b, 0x0c, 0xfb, 0xb7, 0x2d, 0xc8, 0x6a, 0x24, 0xa3, 0x56, 0x9a, 0xb5, + 0x67, 0xad, 0xb4, 0x03, 0x14, 0x2b, 0xfb, 0x09, 0x18, 0x76, 0x12, 0x6a, 0x44, 0xf0, 0x6d, 0x77, + 0xf9, 0x70, 0xc7, 0x1a, 0x8b, 0x41, 0xd3, 0x5d, 0x77, 0xd9, 0x76, 0xdb, 0x24, 0x67, 0xff, 0x8f, + 0x01, 0x38, 0xd5, 0x95, 0xbb, 0x81, 0x5e, 0x84, 0x91, 0x86, 0x98, 0x1e, 0xa1, 0x74, 0x68, 0xd5, + 0xcc, 0x20, 0x36, 0x0d, 0xc3, 0x29, 0xcc, 0x3e, 0x26, 0xe8, 0x3c, 0x9c, 0x8e, 0xe8, 0x46, 0xbf, + 0x43, 0xa6, 0xd7, 0x13, 0x12, 0xad, 0x90, 0x46, 0xe0, 0x37, 0x79, 0x45, 0xbf, 0x72, 0xfd, 0xd1, + 0xbb, 0xbb, 0x13, 0xa7, 0x71, 0x37, 0x18, 0xe7, 0x3d, 0x83, 0x42, 0x18, 0xf5, 0x4c, 0x1b, 0x50, + 0x6c, 0x00, 0x0e, 0x65, 0x3e, 0x2a, 0x1b, 0x21, 0xd5, 0x8c, 0xd3, 0x0c, 0xd2, 0x86, 0x64, 0xe5, + 0x01, 0x19, 0x92, 0x9f, 0xd4, 0x86, 0x24, 0x3f, 0x7f, 0xff, 0x60, 0xc1, 0xb9, 0x3b, 0xc7, 0x6d, + 0x49, 0xbe, 0x0c, 0x55, 0x19, 0x9b, 0xd4, 0x57, 0x4c, 0x8f, 0x49, 0xa7, 0x87, 0x44, 0xbb, 0x57, + 0x82, 0x9c, 0x4d, 0x08, 0x5d, 0x67, 0x5a, 0xe3, 0xa7, 0xd6, 0xd9, 0xc1, 0xb4, 0x3e, 0xda, 0xe6, + 0x71, 0x59, 0x5c, 0xb7, 0x7d, 0xa0, 0xe8, 0x4d, 0x94, 0x0e, 0xd5, 0x52, 0x29, 0x0d, 0x2a, 0x5c, + 0xeb, 0x22, 0x80, 0x36, 0xd4, 0x44, 0xc0, 0xba, 0x3a, 0xf6, 0xd5, 0xf6, 0x1c, 0x36, 0xb0, 0xe8, + 0x9e, 0xda, 0xf5, 0xe3, 0xc4, 0xf1, 0xbc, 0x2b, 0xae, 0x9f, 0x08, 0xe7, 0xa0, 0x52, 0xe2, 0xf3, + 0x1a, 0x84, 0x4d, 0xbc, 0xf3, 0xef, 0x31, 0xbe, 0xcb, 0x41, 0xbe, 0xe7, 0x06, 0x9c, 0x9b, 0x73, + 0x13, 0x95, 0x66, 0xa1, 0xe6, 0x11, 0xb5, 0xc3, 0x54, 0xda, 0x90, 0xd5, 0x33, 0x6d, 0xc8, 0x48, + 0x73, 0x28, 0xa5, 0xb3, 0x32, 0xb2, 0x69, 0x0e, 0xf6, 0x8b, 0x70, 0x66, 0xce, 0x4d, 0x2e, 0xbb, + 0x1e, 0x39, 0x20, 0x13, 0xfb, 0x37, 0x07, 0x61, 0xc4, 0x4c, 0xd4, 0x3b, 0x48, 0xe6, 0xd3, 0xe7, + 0xa9, 0xa9, 0x25, 0xde, 0xce, 0x55, 0x87, 0x66, 0xb7, 0x8e, 0x9c, 0x35, 0x98, 0x3f, 0x62, 0x86, + 0xb5, 0xa5, 0x79, 0x62, 0xb3, 0x03, 0xe8, 0x0e, 0x54, 0xd6, 0x59, 0x18, 0x7e, 0xb9, 0x88, 0xc8, + 0x82, 0xbc, 0x11, 0xd5, 0xcb, 0x8c, 0x07, 0xf2, 0x73, 0x7e, 0x54, 0x43, 0x46, 0xe9, 0xdc, 0x2e, + 0x23, 0x74, 0x54, 0x64, 0x75, 0x29, 0x8c, 0x5e, 0xa2, 0xbe, 0x72, 0x08, 0x51, 0x9f, 0x12, 0xbc, + 0x83, 0x0f, 0x48, 0xf0, 0xb2, 0x94, 0x8a, 0x64, 0x83, 0xd9, 0x6f, 0x22, 0xd6, 0x7d, 0x88, 0x0d, + 0x82, 0x91, 0x52, 0x91, 0x02, 0xe3, 0x2c, 0x3e, 0xfa, 0x98, 0x12, 0xdd, 0xd5, 0x22, 0xfc, 0xaa, + 0xe6, 0x8c, 0x3e, 0x6e, 0xa9, 0xfd, 0xd9, 0x12, 0x8c, 0xcd, 0xf9, 0x9d, 0xe5, 0xb9, 0xe5, 0xce, + 0x9a, 0xe7, 0x36, 0xae, 0x91, 0x1d, 0x2a, 0x9a, 0x37, 0xc9, 0xce, 0xfc, 0xac, 0x58, 0x41, 0x6a, + 0xce, 0x5c, 0xa3, 0x8d, 0x98, 0xc3, 0xa8, 0x30, 0x5a, 0x77, 0xfd, 0x16, 0x89, 0xc2, 0xc8, 0x15, + 0x2e, 0x4f, 0x43, 0x18, 0x5d, 0xd6, 0x20, 0x6c, 0xe2, 0x51, 0xda, 0xc1, 0x1d, 0x9f, 0x44, 0x59, + 0x43, 0x76, 0x89, 0x36, 0x62, 0x0e, 0xa3, 0x48, 0x49, 0xd4, 0x89, 0x13, 0x31, 0x19, 0x15, 0xd2, + 0x2a, 0x6d, 0xc4, 0x1c, 0x46, 0x57, 0x7a, 0xdc, 0x59, 0x63, 0x81, 0x1b, 0x99, 0xc0, 0xfa, 0x15, + 0xde, 0x8c, 0x25, 0x9c, 0xa2, 0x6e, 0x92, 0x9d, 0x59, 0xba, 0xeb, 0xcd, 0xe4, 0xd7, 0x5c, 0xe3, + 0xcd, 0x58, 0xc2, 0x59, 0x29, 0xc2, 0xf4, 0x70, 0x7c, 0xd7, 0x95, 0x22, 0x4c, 0x77, 0xbf, 0xc7, + 0xfe, 0xf9, 0x97, 0x2c, 0x18, 0x31, 0xc3, 0xad, 0x50, 0x2b, 0x63, 0xe3, 0x2e, 0x75, 0x55, 0xb2, + 0xfd, 0xb1, 0xbc, 0xab, 0xbd, 0x5a, 0x6e, 0x12, 0x84, 0xf1, 0xb3, 0xc4, 0x6f, 0xb9, 0x3e, 0x61, + 0xa7, 0xe8, 0x3c, 0x4c, 0x2b, 0x15, 0xcb, 0x35, 0x13, 0x34, 0xc9, 0x21, 0x8c, 0x64, 0xfb, 0x16, + 0x9c, 0xea, 0x4a, 0xaa, 0xea, 0xc3, 0xb4, 0xd8, 0x37, 0xa5, 0xd5, 0xc6, 0x30, 0x4c, 0x09, 0xcb, + 0x72, 0x38, 0x33, 0x70, 0x8a, 0x2f, 0x24, 0xca, 0x69, 0xa5, 0xb1, 0x41, 0xda, 0x2a, 0x51, 0x8e, + 0xf9, 0xd7, 0x6f, 0x66, 0x81, 0xb8, 0x1b, 0xdf, 0xfe, 0x9c, 0x05, 0xa3, 0xa9, 0x3c, 0xb7, 0x82, + 0x8c, 0x20, 0xb6, 0xd2, 0x02, 0x16, 0xfd, 0xc7, 0x42, 0xa0, 0xcb, 0x4c, 0x99, 0xea, 0x95, 0xa6, + 0x41, 0xd8, 0xc4, 0xb3, 0xbf, 0x58, 0x82, 0xaa, 0x8c, 0xa0, 0xe8, 0xa3, 0x2b, 0x9f, 0xb1, 0x60, + 0x54, 0x9d, 0x69, 0x30, 0x67, 0x59, 0xa9, 0x88, 0xa4, 0x04, 0xda, 0x03, 0xb5, 0xdd, 0xf6, 0xd7, + 0x03, 0x6d, 0x91, 0x63, 0x93, 0x19, 0x4e, 0xf3, 0x46, 0x37, 0x01, 0xe2, 0x9d, 0x38, 0x21, 0x6d, + 0xc3, 0x6d, 0x67, 0x1b, 0x2b, 0x6e, 0xb2, 0x11, 0x44, 0x84, 0xae, 0xaf, 0xeb, 0x41, 0x93, 0xac, + 0x28, 0x4c, 0x6d, 0x42, 0xe9, 0x36, 0x6c, 0x50, 0xb2, 0xff, 0x41, 0x09, 0x4e, 0x66, 0xbb, 0x84, + 0x3e, 0x08, 0x23, 0x92, 0xbb, 0x71, 0x4d, 0x99, 0x0c, 0x1b, 0x19, 0xc1, 0x06, 0xec, 0xde, 0xee, + 0xc4, 0x44, 0xf7, 0x35, 0x71, 0x93, 0x26, 0x0a, 0x4e, 0x11, 0xe3, 0x07, 0x4b, 0xe2, 0x04, 0xb4, + 0xbe, 0x33, 0x1d, 0x86, 0xe2, 0x74, 0xc8, 0x38, 0x58, 0x32, 0xa1, 0x38, 0x83, 0x8d, 0x96, 0xe1, + 0x8c, 0xd1, 0x72, 0x9d, 0xb8, 0xad, 0x8d, 0xb5, 0x20, 0x92, 0x3b, 0xab, 0xc7, 0x74, 0x60, 0x57, + 0x37, 0x0e, 0xce, 0x7d, 0x92, 0x6a, 0xfb, 0x86, 0x13, 0x3a, 0x0d, 0x37, 0xd9, 0x11, 0x7e, 0x48, + 0x25, 0x9b, 0x66, 0x44, 0x3b, 0x56, 0x18, 0xf6, 0x22, 0x0c, 0xf4, 0x39, 0x83, 0xfa, 0xb2, 0xe8, + 0x5f, 0x86, 0x2a, 0x25, 0x27, 0xcd, 0xbb, 0x22, 0x48, 0x06, 0x50, 0x95, 0x37, 0x8d, 0x20, 0x1b, + 0xca, 0xae, 0x23, 0xcf, 0xee, 0xd4, 0x6b, 0xcd, 0xc7, 0x71, 0x87, 0x6d, 0x92, 0x29, 0x10, 0x3d, + 0x09, 0x65, 0xb2, 0x1d, 0x66, 0x0f, 0xe9, 0x2e, 0x6d, 0x87, 0x6e, 0x44, 0x62, 0x8a, 0x44, 0xb6, + 0x43, 0x74, 0x1e, 0x4a, 0x6e, 0x53, 0x28, 0x29, 0x10, 0x38, 0xa5, 0xf9, 0x59, 0x5c, 0x72, 0x9b, + 0xf6, 0x36, 0xd4, 0xd4, 0xd5, 0x26, 0x68, 0x53, 0xca, 0x6e, 0xab, 0x88, 0x90, 0x27, 0x49, 0xb7, + 0x87, 0xd4, 0xee, 0x00, 0xe8, 0x84, 0xbf, 0xa2, 0xe4, 0xcb, 0x05, 0x18, 0x68, 0x04, 0x22, 0x19, + 0xb9, 0xaa, 0xc9, 0x30, 0xa1, 0xcd, 0x20, 0xf6, 0x2d, 0x18, 0xbb, 0xe6, 0x07, 0x77, 0x58, 0x5d, + 0x76, 0x56, 0x86, 0x8c, 0x12, 0x5e, 0xa7, 0x3f, 0xb2, 0x26, 0x02, 0x83, 0x62, 0x0e, 0x53, 0xf5, + 0x99, 0x4a, 0xbd, 0xea, 0x33, 0xd9, 0x1f, 0xb7, 0x60, 0x44, 0x65, 0x0e, 0xcd, 0x6d, 0x6d, 0x52, + 0xba, 0xad, 0x28, 0xe8, 0x84, 0x59, 0xba, 0xec, 0xf2, 0x21, 0xcc, 0x61, 0x66, 0x4a, 0x5d, 0x69, + 0x9f, 0x94, 0xba, 0x0b, 0x30, 0xb0, 0xe9, 0xfa, 0xcd, 0xec, 0x6d, 0x1a, 0xd7, 0x5c, 0xbf, 0x89, + 0x19, 0x84, 0x76, 0xe1, 0xa4, 0xea, 0x82, 0x54, 0x08, 0x2f, 0xc2, 0xc8, 0x5a, 0xc7, 0xf5, 0x9a, + 0xb2, 0xbe, 0x5a, 0xc6, 0x53, 0x52, 0x37, 0x60, 0x38, 0x85, 0x49, 0xf7, 0x75, 0x6b, 0xae, 0xef, + 0x44, 0x3b, 0xcb, 0x5a, 0x03, 0x29, 0xa1, 0x54, 0x57, 0x10, 0x6c, 0x60, 0xd9, 0x6f, 0x96, 0x61, + 0x2c, 0x9d, 0x3f, 0xd5, 0xc7, 0xf6, 0xea, 0x49, 0xa8, 0xb0, 0x94, 0xaa, 0xec, 0xa7, 0xe5, 0x25, + 0xc9, 0x38, 0x0c, 0xc5, 0x30, 0xc8, 0x8b, 0x31, 0x14, 0x73, 0x13, 0x8d, 0xea, 0xa4, 0xf2, 0xaf, + 0xb0, 0x78, 0x32, 0x51, 0xff, 0x41, 0xb0, 0x42, 0x9f, 0xb2, 0x60, 0x28, 0x08, 0xcd, 0xba, 0x3e, + 0x1f, 0x28, 0x32, 0xb7, 0x4c, 0x24, 0xcb, 0x08, 0x8b, 0x58, 0x7d, 0x7a, 0xf9, 0x39, 0x24, 0xeb, + 0xf3, 0x3f, 0x02, 0x23, 0x26, 0xe6, 0x7e, 0x46, 0x71, 0xd5, 0x34, 0x8a, 0x3f, 0x63, 0x4e, 0x0a, + 0x91, 0x3d, 0xd7, 0xc7, 0x72, 0xbb, 0x01, 0x95, 0x86, 0x0a, 0x00, 0x38, 0x54, 0x55, 0x4e, 0x55, + 0x1d, 0x81, 0x1d, 0x02, 0x71, 0x6a, 0xf6, 0xb7, 0x2c, 0x63, 0x7e, 0x60, 0x12, 0xcf, 0x37, 0x51, + 0x04, 0xe5, 0xd6, 0xd6, 0xa6, 0x30, 0x45, 0xaf, 0x16, 0x34, 0xbc, 0x73, 0x5b, 0x9b, 0x7a, 0x8e, + 0x9b, 0xad, 0x98, 0x32, 0xeb, 0xc3, 0x09, 0x98, 0x4a, 0xb2, 0x2c, 0xef, 0x9f, 0x64, 0x69, 0xbf, + 0x55, 0x82, 0x53, 0x5d, 0x93, 0x0a, 0xbd, 0x01, 0x95, 0x88, 0xbe, 0xa5, 0x78, 0xbd, 0x85, 0xc2, + 0xd2, 0x22, 0xe3, 0xf9, 0xa6, 0xd6, 0xbb, 0xe9, 0x76, 0xcc, 0x59, 0xa2, 0xab, 0x80, 0x74, 0x98, + 0x8a, 0xf2, 0x40, 0xf2, 0x57, 0x3e, 0x2f, 0x1e, 0x45, 0xd3, 0x5d, 0x18, 0x38, 0xe7, 0x29, 0xf4, + 0x52, 0xd6, 0x91, 0x59, 0x4e, 0x9f, 0x5b, 0xee, 0xe5, 0x93, 0xb4, 0xff, 0x79, 0x09, 0x46, 0x53, + 0x65, 0x96, 0x90, 0x07, 0x55, 0xe2, 0x31, 0xa7, 0xbe, 0x54, 0x36, 0x47, 0xad, 0x5a, 0xac, 0x14, + 0xe4, 0x25, 0x41, 0x17, 0x2b, 0x0e, 0x0f, 0xc7, 0xe1, 0xfa, 0x8b, 0x30, 0x22, 0x3b, 0xf4, 0x01, + 0xa7, 0xed, 0x89, 0x01, 0x54, 0x73, 0xf4, 0x92, 0x01, 0xc3, 0x29, 0x4c, 0xfb, 0x77, 0xca, 0x30, + 0xce, 0x4f, 0x41, 0x9a, 0x6a, 0xe6, 0x2d, 0xca, 0xfd, 0xd6, 0x5f, 0xd1, 0xc5, 0xd0, 0xf8, 0x40, + 0xae, 0x1d, 0xf5, 0x92, 0x80, 0x7c, 0x46, 0x7d, 0x45, 0x66, 0x7d, 0x25, 0x13, 0x99, 0xc5, 0xcd, + 0xee, 0xd6, 0x31, 0xf5, 0xe8, 0xbb, 0x2b, 0x54, 0xeb, 0x57, 0x4a, 0x70, 0x22, 0x73, 0x03, 0x03, + 0x7a, 0x33, 0x5d, 0xb4, 0xd7, 0x2a, 0xc2, 0x57, 0xbe, 0x67, 0x51, 0xfe, 0x83, 0x95, 0xee, 0x7d, + 0x40, 0x4b, 0xc5, 0xfe, 0x83, 0x12, 0x8c, 0xa5, 0xaf, 0x8e, 0x78, 0x08, 0x47, 0xea, 0xdd, 0x50, + 0x63, 0xd5, 0xd1, 0xd9, 0x95, 0x98, 0xdc, 0x25, 0xcf, 0x0b, 0x51, 0xcb, 0x46, 0xac, 0xe1, 0x0f, + 0x45, 0x45, 0x64, 0xfb, 0xef, 0x59, 0x70, 0x96, 0xbf, 0x65, 0x76, 0x1e, 0xfe, 0xd5, 0xbc, 0xd1, + 0x7d, 0xb5, 0xd8, 0x0e, 0x66, 0x8a, 0xf8, 0xed, 0x37, 0xbe, 0xec, 0x2a, 0x3e, 0xd1, 0xdb, 0xf4, + 0x54, 0x78, 0x08, 0x3b, 0x7b, 0xa0, 0xc9, 0x60, 0xff, 0x41, 0x19, 0xf4, 0xed, 0x83, 0xc8, 0x15, + 0x39, 0x8e, 0x85, 0x14, 0x33, 0x5c, 0xd9, 0xf1, 0x1b, 0xfa, 0x9e, 0xc3, 0x6a, 0x26, 0xc5, 0xf1, + 0xe7, 0x2c, 0x18, 0x76, 0x7d, 0x37, 0x71, 0x1d, 0xb6, 0x8d, 0x2e, 0xe6, 0x66, 0x34, 0xc5, 0x6e, + 0x9e, 0x53, 0x0e, 0x22, 0xf3, 0x1c, 0x47, 0x31, 0xc3, 0x26, 0x67, 0xf4, 0x61, 0x11, 0x3c, 0x5d, + 0x2e, 0x2c, 0x3b, 0xb7, 0x9a, 0x89, 0x98, 0x0e, 0xa9, 0xe1, 0x95, 0x44, 0x05, 0x25, 0xb5, 0x63, + 0x4a, 0x4a, 0xd5, 0xc5, 0xd5, 0xf7, 0x40, 0xd3, 0x66, 0xcc, 0x19, 0xd9, 0x31, 0xa0, 0xee, 0xb1, + 0x38, 0x60, 0x60, 0xea, 0x14, 0xd4, 0x9c, 0x4e, 0x12, 0xb4, 0xe9, 0x30, 0x89, 0xa3, 0x26, 0x1d, + 0x7a, 0x2b, 0x01, 0x58, 0xe3, 0xd8, 0x6f, 0x56, 0x20, 0x93, 0x74, 0x88, 0xb6, 0xcd, 0x9b, 0x33, + 0xad, 0x62, 0x6f, 0xce, 0x54, 0x9d, 0xc9, 0xbb, 0x3d, 0x13, 0xb5, 0xa0, 0x12, 0x6e, 0x38, 0xb1, + 0x34, 0xab, 0x5f, 0x56, 0xfb, 0x38, 0xda, 0x78, 0x6f, 0x77, 0xe2, 0xc7, 0xfb, 0xf3, 0xba, 0xd2, + 0xb9, 0x3a, 0xc5, 0x8b, 0x8d, 0x68, 0xd6, 0x8c, 0x06, 0xe6, 0xf4, 0x0f, 0x72, 0x37, 0xdc, 0x27, + 0x44, 0x19, 0x78, 0x4c, 0xe2, 0x8e, 0x97, 0x88, 0xd9, 0xf0, 0x72, 0x81, 0xab, 0x8c, 0x13, 0xd6, + 0xe9, 0xf2, 0xfc, 0x3f, 0x36, 0x98, 0xa2, 0x0f, 0x42, 0x2d, 0x4e, 0x9c, 0x28, 0x39, 0x64, 0x82, + 0xab, 0x1a, 0xf4, 0x15, 0x49, 0x04, 0x6b, 0x7a, 0xe8, 0x15, 0x56, 0xdb, 0xd5, 0x8d, 0x37, 0x0e, + 0x99, 0xf3, 0x20, 0xeb, 0xc0, 0x0a, 0x0a, 0xd8, 0xa0, 0x86, 0x2e, 0x02, 0xb0, 0xb9, 0xcd, 0x03, + 0xfd, 0xaa, 0xcc, 0xcb, 0xa4, 0x44, 0x21, 0x56, 0x10, 0x6c, 0x60, 0xd9, 0x3f, 0x08, 0xe9, 0x7a, + 0x0f, 0x68, 0x42, 0x96, 0x97, 0xe0, 0x5e, 0x68, 0x96, 0xbb, 0x90, 0xaa, 0x04, 0xf1, 0xeb, 0x16, + 0x98, 0x45, 0x29, 0xd0, 0xeb, 0xbc, 0xfa, 0x85, 0x55, 0xc4, 0xc9, 0xa1, 0x41, 0x77, 0x72, 0xd1, + 0x09, 0x33, 0x47, 0xd8, 0xb2, 0x04, 0xc6, 0xf9, 0xf7, 0x40, 0x55, 0x42, 0x0f, 0x64, 0xd4, 0x7d, + 0x0c, 0x4e, 0x67, 0xef, 0x15, 0x17, 0xa7, 0x4e, 0xfb, 0xbb, 0x7e, 0xa4, 0x3f, 0xa7, 0xd4, 0xcb, + 0x9f, 0xd3, 0xc7, 0xfd, 0xa9, 0xbf, 0x61, 0xc1, 0x85, 0xfd, 0xae, 0x3f, 0x47, 0x8f, 0xc1, 0xc0, + 0x1d, 0x27, 0x92, 0x45, 0xb7, 0x99, 0xa0, 0xbc, 0xe5, 0x44, 0x3e, 0x66, 0xad, 0x68, 0x07, 0x06, + 0x79, 0x34, 0x98, 0xb0, 0xd6, 0x5f, 0x2e, 0xf6, 0x32, 0xf6, 0x6b, 0xc4, 0xd8, 0x2e, 0xf0, 0x48, + 0x34, 0x2c, 0x18, 0xda, 0xdf, 0xb6, 0x00, 0x2d, 0x6d, 0x91, 0x28, 0x72, 0x9b, 0x46, 0xfc, 0x1a, + 0xbb, 0x4e, 0xc5, 0xb8, 0x36, 0xc5, 0x4c, 0x71, 0xcd, 0x5c, 0xa7, 0x62, 0xfc, 0xcb, 0xbf, 0x4e, + 0xa5, 0x74, 0xb0, 0xeb, 0x54, 0xd0, 0x12, 0x9c, 0x6d, 0xf3, 0xed, 0x06, 0xbf, 0xa2, 0x80, 0xef, + 0x3d, 0x54, 0x42, 0xd9, 0xb9, 0xbb, 0xbb, 0x13, 0x67, 0x17, 0xf3, 0x10, 0x70, 0xfe, 0x73, 0xf6, + 0x7b, 0x00, 0xf1, 0xb0, 0xb5, 0x99, 0xbc, 0x18, 0xa4, 0x9e, 0xee, 0x17, 0xfb, 0xcb, 0x15, 0x38, + 0x91, 0x29, 0xc9, 0x4a, 0xb7, 0x7a, 0xdd, 0x41, 0x4f, 0x47, 0xd6, 0xdf, 0xdd, 0xdd, 0xeb, 0x2b, + 0x8c, 0xca, 0x87, 0x8a, 0xeb, 0x87, 0x9d, 0xa4, 0x98, 0x1c, 0x52, 0xde, 0x89, 0x79, 0x4a, 0xd0, + 0x70, 0x17, 0xd3, 0xbf, 0x98, 0xb3, 0x29, 0x32, 0x28, 0x2b, 0x65, 0x8c, 0x0f, 0x3c, 0x20, 0x77, + 0xc0, 0x27, 0x74, 0x88, 0x54, 0xa5, 0x08, 0xc7, 0x62, 0x66, 0xb2, 0x1c, 0xf7, 0x51, 0xfb, 0xaf, + 0x95, 0x60, 0xd8, 0xf8, 0x68, 0xe8, 0x17, 0xd3, 0x25, 0x9b, 0xac, 0xe2, 0x5e, 0x89, 0xd1, 0x9f, + 0xd4, 0x45, 0x99, 0xf8, 0x2b, 0x3d, 0xd5, 0x5d, 0xad, 0xe9, 0xde, 0xee, 0xc4, 0xc9, 0x4c, 0x3d, + 0xa6, 0x54, 0x05, 0xa7, 0xf3, 0x1f, 0x85, 0x13, 0x19, 0x32, 0x39, 0xaf, 0xbc, 0x9a, 0xbe, 0x36, + 0xfe, 0x88, 0x6e, 0x29, 0x73, 0xc8, 0xbe, 0x4e, 0x87, 0x4c, 0xa4, 0xd1, 0x05, 0x1e, 0xe9, 0xc3, + 0x07, 0x9b, 0xc9, 0x96, 0x2d, 0xf5, 0x99, 0x2d, 0xfb, 0x34, 0x54, 0xc3, 0xc0, 0x73, 0x1b, 0xae, + 0xaa, 0x42, 0xc8, 0xf2, 0x73, 0x97, 0x45, 0x1b, 0x56, 0x50, 0x74, 0x07, 0x6a, 0xea, 0x86, 0x7d, + 0xe1, 0xdf, 0x2e, 0xea, 0xd0, 0x47, 0x19, 0x2d, 0xfa, 0xe6, 0x7c, 0xcd, 0x0b, 0xd9, 0x30, 0xc8, + 0x94, 0xa0, 0x0c, 0xfd, 0x67, 0xbe, 0x77, 0xa6, 0x1d, 0x63, 0x2c, 0x20, 0xf6, 0xd7, 0x6a, 0x70, + 0x26, 0xaf, 0x2e, 0x36, 0xfa, 0x08, 0x0c, 0xf2, 0x3e, 0x16, 0x73, 0xf5, 0x42, 0x1e, 0x8f, 0x39, + 0x46, 0x50, 0x74, 0x8b, 0xfd, 0xc6, 0x82, 0xa7, 0xe0, 0xee, 0x39, 0x6b, 0x62, 0x86, 0x1c, 0x0f, + 0xf7, 0x05, 0x47, 0x73, 0x5f, 0x70, 0x38, 0x77, 0xcf, 0x59, 0x43, 0xdb, 0x50, 0x69, 0xb9, 0x09, + 0x71, 0x84, 0x13, 0xe1, 0xd6, 0xb1, 0x30, 0x27, 0x0e, 0xb7, 0xd2, 0xd8, 0x4f, 0xcc, 0x19, 0xa2, + 0xaf, 0x5a, 0x70, 0x62, 0x2d, 0x9d, 0x1a, 0x2f, 0x84, 0xa7, 0x73, 0x0c, 0xb5, 0xcf, 0xd3, 0x8c, + 0xf8, 0x7d, 0x42, 0x99, 0x46, 0x9c, 0xed, 0x0e, 0xfa, 0xa4, 0x05, 0x43, 0xeb, 0xae, 0x67, 0x94, + 0xc1, 0x3d, 0x86, 0x8f, 0x73, 0x99, 0x31, 0xd0, 0x3b, 0x0e, 0xfe, 0x3f, 0xc6, 0x92, 0x73, 0x2f, + 0x4d, 0x35, 0x78, 0x54, 0x4d, 0x35, 0xf4, 0x80, 0x34, 0xd5, 0xa7, 0x2d, 0xa8, 0xa9, 0x91, 0x16, + 0xe9, 0xce, 0x1f, 0x3c, 0xc6, 0x4f, 0xce, 0x3d, 0x27, 0xea, 0x2f, 0xd6, 0xcc, 0xd1, 0x17, 0x2c, + 0x18, 0x76, 0xde, 0xe8, 0x44, 0xa4, 0x49, 0xb6, 0x82, 0x30, 0x16, 0x97, 0x11, 0xbe, 0x5a, 0x7c, + 0x67, 0xa6, 0x29, 0x93, 0x59, 0xb2, 0xb5, 0x14, 0xc6, 0x22, 0x2d, 0x49, 0x37, 0x60, 0xb3, 0x0b, + 0xf6, 0x6e, 0x09, 0x26, 0xf6, 0xa1, 0x80, 0x5e, 0x84, 0x91, 0x20, 0x6a, 0x39, 0xbe, 0xfb, 0x86, + 0x59, 0xeb, 0x42, 0x59, 0x59, 0x4b, 0x06, 0x0c, 0xa7, 0x30, 0xcd, 0x84, 0xec, 0xd2, 0x3e, 0x09, + 0xd9, 0x17, 0x60, 0x20, 0x22, 0x61, 0x90, 0xdd, 0x2c, 0xb0, 0x94, 0x00, 0x06, 0x41, 0x8f, 0x43, + 0xd9, 0x09, 0x5d, 0x11, 0x88, 0xa6, 0xf6, 0x40, 0xd3, 0xcb, 0xf3, 0x98, 0xb6, 0xa7, 0xea, 0x43, + 0x54, 0xee, 0x4b, 0x7d, 0x08, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0xa0, 0x56, 0x03, 0xe9, 0x33, 0x05, + 0xfb, 0xad, 0x32, 0x3c, 0xbe, 0xe7, 0x7c, 0xd1, 0x71, 0x78, 0xd6, 0x1e, 0x71, 0x78, 0x72, 0x78, + 0x4a, 0xfb, 0x0d, 0x4f, 0xb9, 0xc7, 0xf0, 0x7c, 0x92, 0x2e, 0x03, 0x59, 0x23, 0xa4, 0x98, 0xeb, + 0xe4, 0x7a, 0x95, 0x1c, 0x11, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, 0xa9, 0x64, 0xe4, + 0x4a, 0x11, 0x6a, 0xa0, 0x67, 0xcd, 0x10, 0x3e, 0xf7, 0x7b, 0x65, 0x38, 0xdb, 0x3f, 0x5f, 0x82, + 0x27, 0xfb, 0x90, 0xde, 0xe6, 0x2c, 0xb6, 0xfa, 0x9c, 0xc5, 0xdf, 0xdd, 0x9f, 0xc9, 0xfe, 0x6b, + 0x16, 0x9c, 0xef, 0xad, 0x3c, 0xd0, 0x73, 0x30, 0xbc, 0x16, 0x39, 0x7e, 0x63, 0x83, 0x5d, 0x91, + 0x29, 0x07, 0x85, 0x8d, 0xb5, 0x6e, 0xc6, 0x26, 0x0e, 0xdd, 0xde, 0xf2, 0x98, 0x04, 0x03, 0x43, + 0x26, 0x8f, 0xd2, 0xed, 0xed, 0x6a, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x3f, 0x2b, 0xe5, 0x77, 0x8b, + 0x1b, 0x19, 0x07, 0xf9, 0x4e, 0xe2, 0x2b, 0x94, 0xfa, 0x90, 0x25, 0xe5, 0xfb, 0x2d, 0x4b, 0x06, + 0x7a, 0xc9, 0x12, 0x34, 0x0b, 0x27, 0x8d, 0x2b, 0x54, 0x78, 0x42, 0x30, 0x0f, 0xb8, 0x55, 0x55, + 0x32, 0x96, 0x33, 0x70, 0xdc, 0xf5, 0x04, 0x7a, 0x06, 0xaa, 0xae, 0x1f, 0x93, 0x46, 0x27, 0xe2, + 0x81, 0xde, 0x46, 0x12, 0xd6, 0xbc, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0xa5, 0x12, 0x9c, 0xeb, 0x69, + 0x67, 0xdd, 0x27, 0xd9, 0x65, 0x7e, 0x8e, 0x81, 0xfb, 0xf3, 0x39, 0xcc, 0x41, 0xaa, 0xec, 0x3b, + 0x48, 0x7f, 0xd8, 0x7b, 0x62, 0x52, 0x9b, 0xfb, 0x7b, 0x76, 0x94, 0x5e, 0x82, 0x51, 0x27, 0x0c, + 0x39, 0x1e, 0x8b, 0xd7, 0xcc, 0x54, 0xc9, 0x99, 0x36, 0x81, 0x38, 0x8d, 0xdb, 0x97, 0xf6, 0xfc, + 0x63, 0x0b, 0x6a, 0x98, 0xac, 0x73, 0xe9, 0x80, 0x6e, 0x8b, 0x21, 0xb2, 0x8a, 0xa8, 0xa7, 0x49, + 0x07, 0x36, 0x76, 0x59, 0x9d, 0xc9, 0xbc, 0xc1, 0xee, 0xbe, 0x6a, 0xa7, 0x74, 0xa0, 0xab, 0x76, + 0xd4, 0x65, 0x2b, 0xe5, 0xde, 0x97, 0xad, 0xd8, 0x5f, 0x1f, 0xa2, 0xaf, 0x17, 0x06, 0x33, 0x11, + 0x69, 0xc6, 0xf4, 0xfb, 0x76, 0x22, 0x4f, 0x4c, 0x12, 0xf5, 0x7d, 0x6f, 0xe0, 0x05, 0x4c, 0xdb, + 0x53, 0x47, 0x31, 0xa5, 0x03, 0xd5, 0x08, 0x29, 0xef, 0x5b, 0x23, 0xe4, 0x25, 0x18, 0x8d, 0xe3, + 0x8d, 0xe5, 0xc8, 0xdd, 0x72, 0x12, 0x72, 0x8d, 0xec, 0x08, 0x2b, 0x4b, 0xe7, 0xf5, 0xaf, 0x5c, + 0xd1, 0x40, 0x9c, 0xc6, 0x45, 0x73, 0x70, 0x4a, 0x57, 0xea, 0x20, 0x51, 0xc2, 0xa2, 0xfb, 0xf9, + 0x4c, 0x50, 0x49, 0xbc, 0xba, 0xb6, 0x87, 0x40, 0xc0, 0xdd, 0xcf, 0x50, 0xf9, 0x96, 0x6a, 0xa4, + 0x1d, 0x19, 0x4c, 0xcb, 0xb7, 0x14, 0x1d, 0xda, 0x97, 0xae, 0x27, 0xd0, 0x22, 0x9c, 0xe6, 0x13, + 0x63, 0x3a, 0x0c, 0x8d, 0x37, 0x1a, 0x4a, 0xd7, 0x31, 0x9c, 0xeb, 0x46, 0xc1, 0x79, 0xcf, 0xa1, + 0x17, 0x60, 0x58, 0x35, 0xcf, 0xcf, 0x8a, 0x53, 0x04, 0xe5, 0xc5, 0x50, 0x64, 0xe6, 0x9b, 0xd8, + 0xc4, 0x43, 0x1f, 0x80, 0x47, 0xf5, 0x5f, 0x9e, 0x02, 0xc6, 0x8f, 0xd6, 0x66, 0x45, 0x11, 0x24, + 0x75, 0xb5, 0xc7, 0x5c, 0x2e, 0x5a, 0x13, 0xf7, 0x7a, 0x1e, 0xad, 0xc1, 0x79, 0x05, 0xba, 0xe4, + 0x27, 0x2c, 0x9f, 0x23, 0x26, 0x75, 0x27, 0x26, 0x37, 0x22, 0x4f, 0xdc, 0x8d, 0xaa, 0x6e, 0x5d, + 0x9c, 0x73, 0x93, 0x2b, 0x79, 0x98, 0x78, 0x01, 0xef, 0x41, 0x05, 0x4d, 0x41, 0x8d, 0xf8, 0xce, + 0x9a, 0x47, 0x96, 0x66, 0xe6, 0x59, 0x31, 0x25, 0xe3, 0x24, 0xef, 0x92, 0x04, 0x60, 0x8d, 0xa3, + 0x22, 0x4c, 0x47, 0x7a, 0xde, 0x00, 0xba, 0x0c, 0x67, 0x5a, 0x8d, 0x90, 0xda, 0x1e, 0x6e, 0x83, + 0x4c, 0x37, 0x58, 0x40, 0x1d, 0xfd, 0x30, 0xbc, 0xc0, 0xa4, 0x0a, 0x9f, 0x9e, 0x9b, 0x59, 0xee, + 0xc2, 0xc1, 0xb9, 0x4f, 0xb2, 0xc0, 0xcb, 0x28, 0xd8, 0xde, 0x19, 0x3f, 0x9d, 0x09, 0xbc, 0xa4, + 0x8d, 0x98, 0xc3, 0xd0, 0x55, 0x40, 0x2c, 0x16, 0xff, 0x4a, 0x92, 0x84, 0xca, 0xd8, 0x19, 0x3f, + 0xc3, 0x5e, 0x49, 0x85, 0x91, 0x5d, 0xee, 0xc2, 0xc0, 0x39, 0x4f, 0xd9, 0xff, 0xc1, 0x82, 0x51, + 0xb5, 0x5e, 0xef, 0x43, 0x36, 0x8a, 0x97, 0xce, 0x46, 0x99, 0x3b, 0xba, 0xc4, 0x63, 0x3d, 0xef, + 0x11, 0xd2, 0xfc, 0x33, 0xc3, 0x00, 0x5a, 0x2a, 0x2a, 0x85, 0x64, 0xf5, 0x54, 0x48, 0x0f, 0xad, + 0x44, 0xca, 0xab, 0x9c, 0x52, 0x79, 0xb0, 0x95, 0x53, 0x56, 0xe0, 0xac, 0x34, 0x17, 0xf8, 0x59, + 0xd1, 0x95, 0x20, 0x56, 0x02, 0xae, 0x5a, 0x7f, 0x5c, 0x10, 0x3a, 0x3b, 0x9f, 0x87, 0x84, 0xf3, + 0x9f, 0x4d, 0x59, 0x29, 0x43, 0xfb, 0x59, 0x29, 0x7a, 0x4d, 0x2f, 0xac, 0xcb, 0x3b, 0x3c, 0x32, + 0x6b, 0x7a, 0xe1, 0xf2, 0x0a, 0xd6, 0x38, 0xf9, 0x82, 0xbd, 0x56, 0x90, 0x60, 0x87, 0x03, 0x0b, + 0x76, 0x29, 0x62, 0x86, 0x7b, 0x8a, 0x18, 0xe9, 0x93, 0x1e, 0xe9, 0xe9, 0x93, 0x7e, 0x2f, 0x8c, + 0xb9, 0xfe, 0x06, 0x89, 0xdc, 0x84, 0x34, 0xd9, 0x5a, 0x60, 0xe2, 0xa7, 0xaa, 0xd5, 0xfa, 0x7c, + 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0xb9, 0x38, 0xd6, 0x87, 0x5c, 0xec, 0xa1, 0x8d, 0x4e, 0x14, 0xa3, + 0x8d, 0x4e, 0x1e, 0x5d, 0x1b, 0x9d, 0x3a, 0x56, 0x6d, 0x84, 0x0a, 0xd1, 0x46, 0x7d, 0x09, 0x7a, + 0x63, 0xfb, 0x77, 0x66, 0x9f, 0xed, 0x5f, 0x2f, 0x55, 0x74, 0xf6, 0xd0, 0xaa, 0x28, 0x5f, 0xcb, + 0x3c, 0x72, 0x28, 0x2d, 0xf3, 0xe9, 0x12, 0x9c, 0xd5, 0x72, 0x98, 0xce, 0x7e, 0x77, 0x9d, 0x4a, + 0x22, 0x76, 0x0d, 0x14, 0x3f, 0xb7, 0x31, 0x92, 0xa3, 0x74, 0x9e, 0x95, 0x82, 0x60, 0x03, 0x8b, + 0xe5, 0x18, 0x91, 0x88, 0x95, 0xd1, 0xcd, 0x0a, 0xe9, 0x19, 0xd1, 0x8e, 0x15, 0x06, 0x9d, 0x5f, + 0xf4, 0xb7, 0xc8, 0xdb, 0xcc, 0x16, 0x8b, 0x9b, 0xd1, 0x20, 0x6c, 0xe2, 0xa1, 0xa7, 0x39, 0x13, + 0x26, 0x20, 0xa8, 0xa0, 0x1e, 0x11, 0xf7, 0xc2, 0x4a, 0x99, 0xa0, 0xa0, 0xb2, 0x3b, 0x2c, 0x99, + 0xac, 0xd2, 0xdd, 0x1d, 0x16, 0x02, 0xa5, 0x30, 0xec, 0xff, 0x69, 0xc1, 0xb9, 0xdc, 0xa1, 0xb8, + 0x0f, 0xca, 0x77, 0x3b, 0xad, 0x7c, 0x57, 0x8a, 0xda, 0x6e, 0x18, 0x6f, 0xd1, 0x43, 0x11, 0xff, + 0x3b, 0x0b, 0xc6, 0x34, 0xfe, 0x7d, 0x78, 0x55, 0x37, 0xfd, 0xaa, 0xc5, 0xed, 0xac, 0x6a, 0x5d, + 0xef, 0xf6, 0x3b, 0x25, 0x50, 0x05, 0x1c, 0xa7, 0x1b, 0xb2, 0x3c, 0xee, 0x3e, 0x27, 0x89, 0x3b, + 0x30, 0xc8, 0x0e, 0x42, 0xe3, 0x62, 0x82, 0x3c, 0xd2, 0xfc, 0xd9, 0xa1, 0xaa, 0x3e, 0x64, 0x66, + 0x7f, 0x63, 0x2c, 0x18, 0xb2, 0x22, 0xcf, 0x6e, 0x4c, 0xa5, 0x79, 0x53, 0xa4, 0x65, 0xe9, 0x22, + 0xcf, 0xa2, 0x1d, 0x2b, 0x0c, 0xaa, 0x1e, 0xdc, 0x46, 0xe0, 0xcf, 0x78, 0x4e, 0x2c, 0xef, 0x3e, + 0x54, 0xea, 0x61, 0x5e, 0x02, 0xb0, 0xc6, 0x61, 0x67, 0xa4, 0x6e, 0x1c, 0x7a, 0xce, 0x8e, 0xb1, + 0x7f, 0x36, 0xea, 0x13, 0x28, 0x10, 0x36, 0xf1, 0xec, 0x36, 0x8c, 0xa7, 0x5f, 0x62, 0x96, 0xac, + 0xb3, 0x00, 0xc5, 0xbe, 0x86, 0x73, 0x0a, 0x6a, 0x0e, 0x7b, 0x6a, 0xa1, 0xe3, 0x64, 0xaf, 0x2c, + 0x9f, 0x96, 0x00, 0xac, 0x71, 0xec, 0x5f, 0xb5, 0xe0, 0x74, 0xce, 0xa0, 0x15, 0x98, 0xf6, 0x96, + 0x68, 0x69, 0x93, 0xa7, 0xd8, 0x7f, 0x00, 0x86, 0x9a, 0x64, 0xdd, 0x91, 0x21, 0x70, 0x86, 0x6c, + 0x9f, 0xe5, 0xcd, 0x58, 0xc2, 0xed, 0xff, 0x6e, 0xc1, 0x89, 0x74, 0x5f, 0x63, 0x96, 0x4a, 0xc2, + 0x87, 0xc9, 0x8d, 0x1b, 0xc1, 0x16, 0x89, 0x76, 0xe8, 0x9b, 0x5b, 0x99, 0x54, 0x92, 0x2e, 0x0c, + 0x9c, 0xf3, 0x14, 0x2b, 0xdf, 0xda, 0x54, 0xa3, 0x2d, 0x67, 0xe4, 0xcd, 0x22, 0x67, 0xa4, 0xfe, + 0x98, 0xe6, 0x71, 0xb9, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0xb7, 0x07, 0x40, 0xe5, 0xc5, 0xb2, 0xf8, + 0xa3, 0x82, 0xa2, 0xb7, 0x0e, 0x9a, 0x41, 0xa4, 0x26, 0xc3, 0xc0, 0x5e, 0x01, 0x01, 0xdc, 0x4b, + 0x62, 0xba, 0x2e, 0xd5, 0x1b, 0xae, 0x6a, 0x10, 0x36, 0xf1, 0x68, 0x4f, 0x3c, 0x77, 0x8b, 0xf0, + 0x87, 0x06, 0xd3, 0x3d, 0x59, 0x90, 0x00, 0xac, 0x71, 0x68, 0x4f, 0x9a, 0xee, 0xfa, 0xba, 0xd8, + 0xf2, 0xab, 0x9e, 0xd0, 0xd1, 0xc1, 0x0c, 0xc2, 0x2b, 0x72, 0x07, 0x9b, 0xc2, 0x0a, 0x36, 0x2a, + 0x72, 0x07, 0x9b, 0x98, 0x41, 0xa8, 0xdd, 0xe6, 0x07, 0x51, 0x9b, 0x5d, 0x29, 0xdf, 0x54, 0x5c, + 0x84, 0xf5, 0xab, 0xec, 0xb6, 0xeb, 0xdd, 0x28, 0x38, 0xef, 0x39, 0x3a, 0x03, 0xc3, 0x88, 0x34, + 0xdd, 0x46, 0x62, 0x52, 0x83, 0xf4, 0x0c, 0x5c, 0xee, 0xc2, 0xc0, 0x39, 0x4f, 0xa1, 0x69, 0x38, + 0x21, 0xf3, 0x9a, 0x65, 0xd5, 0x9a, 0xe1, 0x74, 0x95, 0x0c, 0x9c, 0x06, 0xe3, 0x2c, 0x3e, 0x95, + 0x6a, 0x6d, 0x51, 0xb0, 0x8a, 0x19, 0xcb, 0x86, 0x54, 0x93, 0x85, 0xac, 0xb0, 0xc2, 0xb0, 0x3f, + 0x51, 0xa6, 0x5a, 0xb8, 0x47, 0xa1, 0xb6, 0xfb, 0x16, 0x2d, 0x98, 0x9e, 0x91, 0x03, 0x7d, 0xcc, + 0xc8, 0xe7, 0x61, 0xe4, 0x76, 0x1c, 0xf8, 0x2a, 0x12, 0xaf, 0xd2, 0x33, 0x12, 0xcf, 0xc0, 0xca, + 0x8f, 0xc4, 0x1b, 0x2c, 0x2a, 0x12, 0x6f, 0xe8, 0x90, 0x91, 0x78, 0xdf, 0xac, 0x80, 0xba, 0x1a, + 0xe4, 0x3a, 0x49, 0xee, 0x04, 0xd1, 0xa6, 0xeb, 0xb7, 0x58, 0x3e, 0xf8, 0x57, 0x2d, 0x18, 0xe1, + 0xeb, 0x65, 0xc1, 0xcc, 0xa4, 0x5a, 0x2f, 0xe8, 0xce, 0x89, 0x14, 0xb3, 0xc9, 0x55, 0x83, 0x51, + 0xe6, 0xea, 0x4d, 0x13, 0x84, 0x53, 0x3d, 0x42, 0x1f, 0x05, 0x90, 0xfe, 0xd1, 0x75, 0x29, 0x32, + 0xe7, 0x8b, 0xe9, 0x1f, 0x26, 0xeb, 0xda, 0x06, 0x5e, 0x55, 0x4c, 0xb0, 0xc1, 0x10, 0x7d, 0x5a, + 0x67, 0x99, 0xf1, 0x90, 0xfd, 0x0f, 0x1f, 0xcb, 0xd8, 0xf4, 0x93, 0x63, 0x86, 0x61, 0xc8, 0xf5, + 0x5b, 0x74, 0x9e, 0x88, 0x88, 0xa5, 0x77, 0xe5, 0xd5, 0x52, 0x58, 0x08, 0x9c, 0x66, 0xdd, 0xf1, + 0x1c, 0xbf, 0x41, 0xa2, 0x79, 0x8e, 0x6e, 0x5e, 0x38, 0xcd, 0x1a, 0xb0, 0x24, 0xd4, 0x75, 0xa9, + 0x4a, 0xa5, 0x9f, 0x4b, 0x55, 0xce, 0xbf, 0x0f, 0x4e, 0x75, 0x7d, 0xcc, 0x03, 0xa5, 0x94, 0x1d, + 0x3e, 0x1b, 0xcd, 0xfe, 0x17, 0x83, 0x5a, 0x69, 0x5d, 0x0f, 0x9a, 0xfc, 0x6a, 0x8f, 0x48, 0x7f, + 0x51, 0x61, 0xe3, 0x16, 0x38, 0x45, 0x8c, 0x4b, 0xab, 0x55, 0x23, 0x36, 0x59, 0xd2, 0x39, 0x1a, + 0x3a, 0x11, 0xf1, 0x8f, 0x7b, 0x8e, 0x2e, 0x2b, 0x26, 0xd8, 0x60, 0x88, 0x36, 0x52, 0x39, 0x25, + 0x97, 0x8f, 0x9e, 0x53, 0xc2, 0xaa, 0x4c, 0xe5, 0x55, 0xe3, 0xff, 0x82, 0x05, 0x63, 0x7e, 0x6a, + 0xe6, 0x16, 0x13, 0x46, 0x9a, 0xbf, 0x2a, 0xf8, 0xcd, 0x52, 0xe9, 0x36, 0x9c, 0xe1, 0x9f, 0xa7, + 0xd2, 0x2a, 0x07, 0x54, 0x69, 0xfa, 0x8e, 0xa0, 0xc1, 0x5e, 0x77, 0x04, 0x21, 0x5f, 0x5d, 0x92, + 0x36, 0x54, 0xf8, 0x25, 0x69, 0x90, 0x73, 0x41, 0xda, 0x2d, 0xa8, 0x35, 0x22, 0xe2, 0x24, 0x87, + 0xbc, 0x2f, 0x8b, 0x1d, 0xd0, 0xcf, 0x48, 0x02, 0x58, 0xd3, 0xb2, 0xff, 0xcf, 0x00, 0x9c, 0x94, + 0x23, 0x22, 0x43, 0xd0, 0xa9, 0x7e, 0xe4, 0x7c, 0xb5, 0x71, 0xab, 0xf4, 0xe3, 0x15, 0x09, 0xc0, + 0x1a, 0x87, 0xda, 0x63, 0x9d, 0x98, 0x2c, 0x85, 0xc4, 0x5f, 0x70, 0xd7, 0x62, 0x71, 0xce, 0xa9, + 0x16, 0xca, 0x0d, 0x0d, 0xc2, 0x26, 0x1e, 0x35, 0xc6, 0xb9, 0x5d, 0x1c, 0x67, 0xd3, 0x57, 0x84, + 0xbd, 0x8d, 0x25, 0x1c, 0xfd, 0x42, 0x6e, 0xe5, 0xd8, 0x62, 0x12, 0xb7, 0xba, 0x22, 0xef, 0x0f, + 0x78, 0xc5, 0xe2, 0xdf, 0xb1, 0xe0, 0x2c, 0x6f, 0x95, 0x23, 0x79, 0x23, 0x6c, 0x3a, 0x09, 0x89, + 0x8b, 0xa9, 0xe4, 0x9e, 0xd3, 0x3f, 0xed, 0xe4, 0xcd, 0x63, 0x8b, 0xf3, 0x7b, 0x83, 0xde, 0xb4, + 0xe0, 0xc4, 0x66, 0xaa, 0xe6, 0x87, 0x54, 0x1d, 0x47, 0x4d, 0xc7, 0x4f, 0x11, 0xd5, 0x4b, 0x2d, + 0xdd, 0x1e, 0xe3, 0x2c, 0x77, 0xfb, 0xcf, 0x2c, 0x30, 0xc5, 0xe8, 0xfd, 0x2f, 0x15, 0x72, 0x70, + 0x53, 0x50, 0x5a, 0x97, 0x95, 0x9e, 0xd6, 0xe5, 0xe3, 0x50, 0xee, 0xb8, 0x4d, 0xb1, 0xbf, 0xd0, + 0xa7, 0xaf, 0xf3, 0xb3, 0x98, 0xb6, 0xdb, 0xff, 0xb4, 0xa2, 0xfd, 0x16, 0x22, 0x2f, 0xea, 0x7b, + 0xe2, 0xb5, 0xd7, 0x55, 0xb1, 0x31, 0xfe, 0xe6, 0xd7, 0xbb, 0x8a, 0x8d, 0xfd, 0xe8, 0xc1, 0xd3, + 0xde, 0xf8, 0x00, 0xf5, 0xaa, 0x35, 0x36, 0xb4, 0x4f, 0xce, 0xdb, 0x6d, 0xa8, 0xd2, 0x2d, 0x18, + 0x73, 0x40, 0x56, 0x53, 0x9d, 0xaa, 0x5e, 0x11, 0xed, 0xf7, 0x76, 0x27, 0x7e, 0xe4, 0xe0, 0xdd, + 0x92, 0x4f, 0x63, 0x45, 0x1f, 0xc5, 0x50, 0xa3, 0xbf, 0x59, 0x7a, 0x9e, 0xd8, 0xdc, 0xdd, 0x50, + 0x32, 0x53, 0x02, 0x0a, 0xc9, 0xfd, 0xd3, 0x7c, 0x90, 0x0f, 0x35, 0x76, 0x1b, 0x2d, 0x63, 0xca, + 0xf7, 0x80, 0xcb, 0x2a, 0x49, 0x4e, 0x02, 0xee, 0xed, 0x4e, 0xbc, 0x74, 0x70, 0xa6, 0xea, 0x71, + 0xac, 0x59, 0xd8, 0x5f, 0x1c, 0xd0, 0x73, 0x57, 0xd4, 0x98, 0xfb, 0x9e, 0x98, 0xbb, 0x2f, 0x66, + 0xe6, 0xee, 0x85, 0xae, 0xb9, 0x3b, 0xa6, 0x6f, 0x4d, 0x4d, 0xcd, 0xc6, 0xfb, 0x6d, 0x08, 0xec, + 0xef, 0x6f, 0x60, 0x16, 0xd0, 0xeb, 0x1d, 0x37, 0x22, 0xf1, 0x72, 0xd4, 0xf1, 0x5d, 0xbf, 0xc5, + 0xa6, 0x63, 0xd5, 0xb4, 0x80, 0x52, 0x60, 0x9c, 0xc5, 0xa7, 0x9b, 0x7a, 0xfa, 0xcd, 0x6f, 0x39, + 0x5b, 0x7c, 0x56, 0x19, 0x65, 0xb7, 0x56, 0x44, 0x3b, 0x56, 0x18, 0xf6, 0xd7, 0xd9, 0x59, 0xb6, + 0x91, 0x17, 0x4c, 0xe7, 0x84, 0xc7, 0xae, 0xff, 0xe5, 0x35, 0xbb, 0xd4, 0x9c, 0xe0, 0x77, 0xfe, + 0x72, 0x18, 0xba, 0x03, 0x43, 0x6b, 0xfc, 0xfe, 0xbb, 0x62, 0xea, 0x93, 0x8b, 0xcb, 0xf4, 0xd8, + 0x2d, 0x27, 0xf2, 0x66, 0xbd, 0x7b, 0xfa, 0x27, 0x96, 0xdc, 0xec, 0xdf, 0xaf, 0xc0, 0x89, 0xcc, + 0x05, 0xb1, 0xa9, 0x6a, 0xa9, 0xa5, 0x7d, 0xab, 0xa5, 0x7e, 0x08, 0xa0, 0x49, 0x42, 0x2f, 0xd8, + 0x61, 0xe6, 0xd8, 0xc0, 0x81, 0xcd, 0x31, 0x65, 0xc1, 0xcf, 0x2a, 0x2a, 0xd8, 0xa0, 0x28, 0x0a, + 0x95, 0xf1, 0xe2, 0xab, 0x99, 0x42, 0x65, 0xc6, 0x2d, 0x06, 0x83, 0xf7, 0xf7, 0x16, 0x03, 0x17, + 0x4e, 0xf0, 0x2e, 0xaa, 0xec, 0xdb, 0x43, 0x24, 0xd9, 0xb2, 0xfc, 0x85, 0xd9, 0x34, 0x19, 0x9c, + 0xa5, 0xfb, 0x20, 0xef, 0x7f, 0x46, 0xef, 0x86, 0x9a, 0xfc, 0xce, 0xf1, 0x78, 0x4d, 0x57, 0x30, + 0x90, 0xd3, 0x80, 0xdd, 0xcb, 0x2c, 0x7e, 0x76, 0x15, 0x12, 0x80, 0x07, 0x55, 0x48, 0xc0, 0xfe, + 0x7c, 0x89, 0xda, 0xf1, 0xbc, 0x5f, 0xaa, 0x26, 0xce, 0x53, 0x30, 0xe8, 0x74, 0x92, 0x8d, 0xa0, + 0xeb, 0x36, 0xbf, 0x69, 0xd6, 0x8a, 0x05, 0x14, 0x2d, 0xc0, 0x40, 0x53, 0xd7, 0x39, 0x39, 0xc8, + 0xf7, 0xd4, 0x2e, 0x51, 0x27, 0x21, 0x98, 0x51, 0x41, 0x8f, 0xc1, 0x40, 0xe2, 0xb4, 0x64, 0xca, + 0x15, 0x4b, 0xb3, 0x5d, 0x75, 0x5a, 0x31, 0x66, 0xad, 0xa6, 0xfa, 0x1e, 0xd8, 0x47, 0x7d, 0xbf, + 0x04, 0xa3, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x11, 0xe3, 0x98, 0x4f, 0x47, 0x6e, 0x98, 0x40, + 0x9c, 0xc6, 0xb5, 0x7f, 0x73, 0x04, 0xce, 0xac, 0xcc, 0x2c, 0xca, 0xea, 0xdd, 0xc7, 0x96, 0x35, + 0x95, 0xc7, 0xe3, 0xfe, 0x65, 0x4d, 0xf5, 0xe0, 0xee, 0x19, 0x59, 0x53, 0x9e, 0x91, 0x35, 0x95, + 0x4e, 0x61, 0x29, 0x17, 0x91, 0xc2, 0x92, 0xd7, 0x83, 0x7e, 0x52, 0x58, 0x8e, 0x2d, 0x8d, 0x6a, + 0xcf, 0x0e, 0x1d, 0x28, 0x8d, 0x4a, 0xe5, 0x98, 0x15, 0x92, 0x5c, 0xd0, 0xe3, 0x53, 0xe5, 0xe6, + 0x98, 0xa9, 0xfc, 0x1e, 0x9e, 0x38, 0x23, 0x44, 0xfd, 0xab, 0xc5, 0x77, 0xa0, 0x8f, 0xfc, 0x1e, + 0x91, 0xbb, 0x63, 0xe6, 0x94, 0x0d, 0x15, 0x91, 0x53, 0x96, 0xd7, 0x9d, 0x7d, 0x73, 0xca, 0x5e, + 0x82, 0xd1, 0x86, 0x17, 0xf8, 0x64, 0x39, 0x0a, 0x92, 0xa0, 0x11, 0x78, 0xc2, 0xac, 0x57, 0x22, + 0x61, 0xc6, 0x04, 0xe2, 0x34, 0x6e, 0xaf, 0x84, 0xb4, 0xda, 0x51, 0x13, 0xd2, 0xe0, 0x01, 0x25, + 0xa4, 0xfd, 0xac, 0x4e, 0x9d, 0x1e, 0x66, 0x5f, 0xe4, 0x43, 0xc5, 0x7f, 0x91, 0x7e, 0xf2, 0xa7, + 0xd1, 0x5b, 0xfc, 0x3a, 0x3d, 0x6a, 0x18, 0xcf, 0x04, 0x6d, 0x6a, 0xf8, 0x8d, 0xb0, 0x21, 0x79, + 0xed, 0x18, 0x26, 0xec, 0xad, 0x15, 0xcd, 0x46, 0x5d, 0xb1, 0xa7, 0x9b, 0x70, 0xba, 0x23, 0x47, + 0x49, 0xed, 0xfe, 0x72, 0x09, 0xbe, 0x6f, 0xdf, 0x2e, 0xa0, 0x3b, 0x00, 0x89, 0xd3, 0x12, 0x13, + 0x55, 0x1c, 0x98, 0x1c, 0x31, 0xbc, 0x72, 0x55, 0xd2, 0xe3, 0x35, 0x49, 0xd4, 0x5f, 0x76, 0x14, + 0x21, 0x7f, 0xb3, 0xa8, 0xca, 0xc0, 0xeb, 0x2a, 0xdd, 0x88, 0x03, 0x8f, 0x60, 0x06, 0xa1, 0xea, + 0x3f, 0x22, 0x2d, 0x7d, 0xff, 0xb3, 0xfa, 0x7c, 0x98, 0xb5, 0x62, 0x01, 0x45, 0x2f, 0xc0, 0xb0, + 0xe3, 0x79, 0x3c, 0x3f, 0x86, 0xc4, 0xe2, 0x3e, 0x1d, 0x5d, 0x43, 0x4e, 0x83, 0xb0, 0x89, 0x67, + 0xff, 0x69, 0x09, 0x26, 0xf6, 0x91, 0x29, 0x5d, 0x19, 0x7f, 0x95, 0xbe, 0x33, 0xfe, 0x44, 0x8e, + 0xc2, 0x60, 0x8f, 0x1c, 0x85, 0x17, 0x60, 0x38, 0x21, 0x4e, 0x5b, 0x04, 0x64, 0x09, 0x4f, 0x80, + 0x3e, 0x01, 0xd6, 0x20, 0x6c, 0xe2, 0x51, 0x29, 0x36, 0xe6, 0x34, 0x1a, 0x24, 0x8e, 0x65, 0x12, + 0x82, 0xf0, 0xa6, 0x16, 0x96, 0xe1, 0xc0, 0x9c, 0xd4, 0xd3, 0x29, 0x16, 0x38, 0xc3, 0x32, 0x3b, + 0xe0, 0xb5, 0x3e, 0x07, 0xfc, 0x6b, 0x25, 0x78, 0x7c, 0x4f, 0xed, 0xd6, 0x77, 0x7e, 0x48, 0x27, + 0x26, 0x51, 0x76, 0xe2, 0xdc, 0x88, 0x49, 0x84, 0x19, 0x84, 0x8f, 0x52, 0x18, 0x1a, 0xf7, 0x6b, + 0x17, 0x9d, 0xbc, 0xc4, 0x47, 0x29, 0xc5, 0x02, 0x67, 0x58, 0x1e, 0x76, 0x5a, 0xfe, 0xfd, 0x12, + 0x3c, 0xd9, 0x87, 0x0d, 0x50, 0x60, 0x92, 0x57, 0x3a, 0xd5, 0xae, 0xfc, 0x80, 0x32, 0x22, 0x0f, + 0x39, 0x5c, 0x5f, 0x2f, 0xc1, 0xf9, 0xde, 0xaa, 0x18, 0xfd, 0x18, 0x9c, 0x88, 0x54, 0x14, 0x96, + 0x99, 0xa5, 0x77, 0x9a, 0x7b, 0x12, 0x52, 0x20, 0x9c, 0xc5, 0x45, 0x93, 0x00, 0xa1, 0x93, 0x6c, + 0xc4, 0x97, 0xb6, 0xdd, 0x38, 0x11, 0x55, 0x68, 0xc6, 0xf8, 0xd9, 0x95, 0x6c, 0xc5, 0x06, 0x06, + 0x65, 0xc7, 0xfe, 0xcd, 0x06, 0xd7, 0x83, 0x84, 0x3f, 0xc4, 0xb7, 0x11, 0xa7, 0xe5, 0x9d, 0x1d, + 0x06, 0x08, 0x67, 0x71, 0x29, 0x3b, 0x76, 0x3a, 0xca, 0x3b, 0xca, 0xf7, 0x17, 0x8c, 0xdd, 0x82, + 0x6a, 0xc5, 0x06, 0x46, 0x36, 0xff, 0xb0, 0xb2, 0x7f, 0xfe, 0xa1, 0xfd, 0x4f, 0x4a, 0x70, 0xae, + 0xa7, 0x29, 0xd7, 0xdf, 0x02, 0x7c, 0xf8, 0x72, 0x06, 0x0f, 0x37, 0x77, 0x0e, 0x98, 0xdb, 0xf6, + 0xc7, 0x3d, 0x66, 0x9a, 0xc8, 0x6d, 0x3b, 0x7c, 0x72, 0xf8, 0xc3, 0x37, 0x9e, 0x5d, 0xe9, 0x6c, + 0x03, 0x07, 0x48, 0x67, 0xcb, 0x7c, 0x8c, 0x4a, 0x9f, 0x0b, 0xf9, 0xcf, 0xcb, 0x3d, 0x87, 0x97, + 0x6e, 0xfd, 0xfa, 0xf2, 0xd3, 0xce, 0xc2, 0x49, 0xd7, 0x67, 0xf7, 0x37, 0xad, 0x74, 0xd6, 0x44, + 0x61, 0x92, 0x52, 0xfa, 0xf6, 0xf4, 0xf9, 0x0c, 0x1c, 0x77, 0x3d, 0xf1, 0x10, 0xa6, 0x17, 0x1e, + 0x6e, 0x48, 0x0f, 0x96, 0xe0, 0x8a, 0x96, 0xe0, 0xac, 0x1c, 0x8a, 0x0d, 0x27, 0x22, 0x4d, 0xa1, + 0x46, 0x62, 0x91, 0x50, 0x71, 0x8e, 0x27, 0x65, 0xe4, 0x20, 0xe0, 0xfc, 0xe7, 0xd8, 0x95, 0x39, + 0x41, 0xe8, 0x36, 0xc4, 0x26, 0x47, 0x5f, 0x99, 0x43, 0x1b, 0x31, 0x87, 0xd9, 0x1f, 0x82, 0x9a, + 0x7a, 0x7f, 0x1e, 0xd6, 0xad, 0x26, 0x5d, 0x57, 0x58, 0xb7, 0x9a, 0x71, 0x06, 0x16, 0xfd, 0x5a, + 0xd4, 0x24, 0xce, 0xac, 0x9e, 0x6b, 0x64, 0x87, 0xd9, 0xc7, 0xf6, 0x0f, 0xc1, 0x88, 0xf2, 0xb3, + 0xf4, 0x7b, 0x91, 0x90, 0xfd, 0xc5, 0x41, 0x18, 0x4d, 0x15, 0x07, 0x4c, 0x39, 0x58, 0xad, 0x7d, + 0x1d, 0xac, 0x2c, 0x4c, 0xbf, 0xe3, 0xcb, 0x5b, 0xc6, 0x8c, 0x30, 0xfd, 0x8e, 0x4f, 0x30, 0x87, + 0x51, 0xf3, 0xb6, 0x19, 0xed, 0xe0, 0x8e, 0x2f, 0xc2, 0x69, 0x95, 0x79, 0x3b, 0xcb, 0x5a, 0xb1, + 0x80, 0xa2, 0x8f, 0x5b, 0x30, 0x12, 0x33, 0xef, 0x3d, 0x77, 0x4f, 0x8b, 0x49, 0x77, 0xf5, 0xe8, + 0xb5, 0x0f, 0x55, 0x21, 0x4c, 0x16, 0x21, 0x63, 0xb6, 0xe0, 0x14, 0x47, 0xf4, 0x29, 0x0b, 0x6a, + 0xea, 0x32, 0x14, 0x71, 0x15, 0xe0, 0x4a, 0xb1, 0xb5, 0x17, 0xb9, 0x5f, 0x53, 0x1d, 0x84, 0xa8, + 0x22, 0x78, 0x58, 0x33, 0x46, 0xb1, 0xf2, 0x1d, 0x0f, 0x1d, 0x8f, 0xef, 0x18, 0x72, 0xfc, 0xc6, + 0xef, 0x86, 0x5a, 0xdb, 0xf1, 0xdd, 0x75, 0x12, 0x27, 0xdc, 0x9d, 0x2b, 0x4b, 0xc2, 0xca, 0x46, + 0xac, 0xe1, 0x54, 0x21, 0xc7, 0xec, 0xc5, 0x12, 0xc3, 0xff, 0xca, 0x14, 0xf2, 0x8a, 0x6e, 0xc6, + 0x26, 0x8e, 0xe9, 0x2c, 0x86, 0x07, 0xea, 0x2c, 0x1e, 0xde, 0xdb, 0x59, 0x6c, 0xff, 0x43, 0x0b, + 0xce, 0xe6, 0x7e, 0xb5, 0x87, 0x37, 0xf0, 0xd1, 0xfe, 0x52, 0x05, 0x4e, 0xe7, 0x54, 0xf9, 0x44, + 0x3b, 0xe6, 0x7c, 0xb6, 0x8a, 0x88, 0x21, 0x48, 0x1f, 0x89, 0xcb, 0x61, 0xcc, 0x99, 0xc4, 0x07, + 0x3b, 0xaa, 0xd1, 0xc7, 0x25, 0xe5, 0xfb, 0x7b, 0x5c, 0x62, 0x4c, 0xcb, 0x81, 0x07, 0x3a, 0x2d, + 0x2b, 0xfb, 0x9c, 0x61, 0xfc, 0x9a, 0x05, 0xe3, 0xed, 0x1e, 0xa5, 0xe5, 0x85, 0xe3, 0xf1, 0xe6, + 0xf1, 0x14, 0xae, 0xaf, 0x3f, 0x76, 0x77, 0x77, 0xa2, 0x67, 0x45, 0x7f, 0xdc, 0xb3, 0x57, 0xf6, + 0xb7, 0xcb, 0xc0, 0x4a, 0xcc, 0xb2, 0x4a, 0x6e, 0x3b, 0xe8, 0x63, 0x66, 0xb1, 0x60, 0xab, 0xa8, + 0xc2, 0xb6, 0x9c, 0xb8, 0x2a, 0x36, 0xcc, 0x47, 0x30, 0xaf, 0xf6, 0x70, 0x56, 0x68, 0x95, 0xfa, + 0x10, 0x5a, 0x9e, 0xac, 0xca, 0x5c, 0x2e, 0xbe, 0x2a, 0x73, 0x2d, 0x5b, 0x91, 0x79, 0xef, 0x4f, + 0x3c, 0xf0, 0x50, 0x7e, 0xe2, 0xbf, 0x65, 0x71, 0xc1, 0x93, 0xf9, 0x0a, 0xda, 0x32, 0xb0, 0xf6, + 0xb0, 0x0c, 0x9e, 0x81, 0x6a, 0x4c, 0xbc, 0xf5, 0x2b, 0xc4, 0xf1, 0x84, 0x05, 0xa1, 0xcf, 0xaf, + 0x45, 0x3b, 0x56, 0x18, 0xec, 0xda, 0x56, 0xcf, 0x0b, 0xee, 0x5c, 0x6a, 0x87, 0xc9, 0x8e, 0xb0, + 0x25, 0xf4, 0xb5, 0xad, 0x0a, 0x82, 0x0d, 0x2c, 0xfb, 0x6f, 0x97, 0xf8, 0x0c, 0x14, 0x41, 0x10, + 0x2f, 0x66, 0x2e, 0xda, 0xeb, 0x3f, 0x7e, 0xe0, 0x23, 0x00, 0x0d, 0x75, 0x45, 0xbd, 0x38, 0x13, + 0xba, 0x72, 0xe4, 0xfb, 0xb3, 0x05, 0x3d, 0xfd, 0x1a, 0xba, 0x0d, 0x1b, 0xfc, 0x52, 0xb2, 0xb4, + 0xbc, 0xaf, 0x2c, 0x4d, 0x89, 0x95, 0x81, 0x7d, 0xb4, 0xdd, 0x9f, 0x5a, 0x90, 0xb2, 0x88, 0x50, + 0x08, 0x15, 0xda, 0xdd, 0x9d, 0x62, 0x6e, 0xdf, 0x37, 0x49, 0x53, 0xd1, 0x28, 0xa6, 0x3d, 0xfb, + 0x89, 0x39, 0x23, 0xe4, 0x89, 0x58, 0x09, 0x3e, 0xaa, 0xd7, 0x8b, 0x63, 0x78, 0x25, 0x08, 0x36, + 0xf9, 0xc1, 0xa6, 0x8e, 0xbb, 0xb0, 0x5f, 0x84, 0x53, 0x5d, 0x9d, 0x62, 0x77, 0x6a, 0x05, 0x54, + 0xfb, 0x64, 0xa6, 0x2b, 0x4b, 0xe0, 0xc4, 0x1c, 0x66, 0x7f, 0xdd, 0x82, 0x93, 0x59, 0xf2, 0xe8, + 0x2d, 0x0b, 0x4e, 0xc5, 0x59, 0x7a, 0xc7, 0x35, 0x76, 0x2a, 0xde, 0xb1, 0x0b, 0x84, 0xbb, 0x3b, + 0x61, 0xff, 0x5f, 0x31, 0xf9, 0x6f, 0xb9, 0x7e, 0x33, 0xb8, 0xa3, 0x0c, 0x13, 0xab, 0xa7, 0x61, + 0x42, 0xd7, 0x63, 0x63, 0x83, 0x34, 0x3b, 0x5e, 0x57, 0xe6, 0xe8, 0x8a, 0x68, 0xc7, 0x0a, 0x83, + 0x25, 0xca, 0x75, 0x44, 0xd9, 0xf6, 0xcc, 0xa4, 0x9c, 0x15, 0xed, 0x58, 0x61, 0xa0, 0xe7, 0x61, + 0xc4, 0x78, 0x49, 0x39, 0x2f, 0x99, 0x41, 0x6e, 0xa8, 0xcc, 0x18, 0xa7, 0xb0, 0xd0, 0x24, 0x80, + 0x32, 0x72, 0xa4, 0x8a, 0x64, 0x8e, 0x22, 0x25, 0x89, 0x62, 0x6c, 0x60, 0xb0, 0xb4, 0x54, 0xaf, + 0x13, 0x33, 0x1f, 0xff, 0xa0, 0x2e, 0x25, 0x3a, 0x23, 0xda, 0xb0, 0x82, 0x52, 0x69, 0xd2, 0x76, + 0xfc, 0x8e, 0xe3, 0xd1, 0x11, 0x12, 0x5b, 0x3f, 0xb5, 0x0c, 0x17, 0x15, 0x04, 0x1b, 0x58, 0xf4, + 0x8d, 0x13, 0xb7, 0x4d, 0x5e, 0x09, 0x7c, 0x19, 0xa7, 0xa6, 0x8f, 0x7d, 0x44, 0x3b, 0x56, 0x18, + 0xf6, 0x7f, 0xb5, 0xe0, 0x84, 0x4e, 0x72, 0xe7, 0xb7, 0x67, 0x9b, 0x3b, 0x55, 0x6b, 0xdf, 0x9d, + 0x6a, 0x3a, 0xfb, 0xb7, 0xd4, 0x57, 0xf6, 0xaf, 0x99, 0x98, 0x5b, 0xde, 0x33, 0x31, 0xf7, 0xfb, + 0xf5, 0xcd, 0xac, 0x3c, 0x83, 0x77, 0x38, 0xef, 0x56, 0x56, 0x64, 0xc3, 0x60, 0xc3, 0x51, 0x15, + 0x5e, 0x46, 0xf8, 0xde, 0x61, 0x66, 0x9a, 0x21, 0x09, 0x88, 0xbd, 0x04, 0x35, 0x75, 0xfa, 0x21, + 0x37, 0xaa, 0x56, 0xfe, 0x46, 0xb5, 0xaf, 0x04, 0xc1, 0xfa, 0xda, 0x37, 0xbe, 0xf3, 0xc4, 0x3b, + 0x7e, 0xef, 0x3b, 0x4f, 0xbc, 0xe3, 0x8f, 0xbe, 0xf3, 0xc4, 0x3b, 0x3e, 0x7e, 0xf7, 0x09, 0xeb, + 0x1b, 0x77, 0x9f, 0xb0, 0x7e, 0xef, 0xee, 0x13, 0xd6, 0x1f, 0xdd, 0x7d, 0xc2, 0xfa, 0xf6, 0xdd, + 0x27, 0xac, 0x2f, 0xfc, 0xa7, 0x27, 0xde, 0xf1, 0x4a, 0x6e, 0xa0, 0x22, 0xfd, 0xf1, 0x6c, 0xa3, + 0x39, 0xb5, 0x75, 0x91, 0xc5, 0xca, 0xd1, 0xe5, 0x35, 0x65, 0xcc, 0xa9, 0x29, 0xb9, 0xbc, 0xfe, + 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x8e, 0xba, 0x30, 0x2f, 0xe1, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -12794,6 +12794,16 @@ func (m *RevisionHistory) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + { + size, err := m.InitiatedBy.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x52 if len(m.Revisions) > 0 { for iNdEx := len(m.Revisions) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.Revisions[iNdEx]) @@ -17226,6 +17236,8 @@ func (m *RevisionHistory) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + l = m.InitiatedBy.Size() + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -19972,6 +19984,7 @@ func (this *RevisionHistory) String() string { `DeployStartedAt:` + strings.Replace(fmt.Sprintf("%v", this.DeployStartedAt), "Time", "v1.Time", 1) + `,`, `Sources:` + repeatedStringForSources + `,`, `Revisions:` + fmt.Sprintf("%v", this.Revisions) + `,`, + `InitiatedBy:` + strings.Replace(strings.Replace(this.InitiatedBy.String(), "OperationInitiator", "OperationInitiator", 1), `&`, ``, 1) + `,`, `}`, }, "") return s @@ -45766,6 +45779,39 @@ func (m *RevisionHistory) Unmarshal(dAtA []byte) error { } m.Revisions = append(m.Revisions, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitiatedBy", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if err := m.InitiatedBy.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index c080c04c3a088..a2b17373de259 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -1895,6 +1895,9 @@ message RevisionHistory { // Revisions holds the revision of each source in sources field the sync was performed against repeated string revisions = 9; + + // InitiatedBy contains information about who initiated the operations + optional OperationInitiator initiatedBy = 10; } // RevisionMetadata contains metadata for a specific revision in a Git repository diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 723ea884cb75b..2274e252a4148 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -6662,12 +6662,19 @@ func schema_pkg_apis_application_v1alpha1_RevisionHistory(ref common.ReferenceCa }, }, }, + "initiatedBy": { + SchemaProps: spec.SchemaProps{ + Description: "InitiatedBy contains information about who initiated the operations", + Default: map[string]interface{}{}, + Ref: ref("github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator"), + }, + }, }, Required: []string{"deployedAt", "id"}, }, }, Dependencies: []string{ - "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.ApplicationSource", "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1.OperationInitiator", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 49be82a443bc4..e271003ad6ad0 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -1401,6 +1401,8 @@ type RevisionHistory struct { Sources ApplicationSources `json:"sources,omitempty" protobuf:"bytes,8,opt,name=sources"` // Revisions holds the revision of each source in sources field the sync was performed against Revisions []string `json:"revisions,omitempty" protobuf:"bytes,9,opt,name=revisions"` + // InitiatedBy contains information about who initiated the operations + InitiatedBy OperationInitiator `json:"initiatedBy,omitempty" protobuf:"bytes,10,opt,name=initiatedBy"` } // ApplicationWatchEvent contains information about application change. diff --git a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go index c10b610cbd5a7..8c851067a6be3 100644 --- a/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/application/v1alpha1/zz_generated.deepcopy.go @@ -3689,6 +3689,7 @@ func (in *RevisionHistory) DeepCopyInto(out *RevisionHistory) { *out = make([]string, len(*in)) copy(*out, *in) } + out.InitiatedBy = in.InitiatedBy return } diff --git a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx index 55734b69ea0c4..37908fb1a35b8 100644 --- a/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx +++ b/ui/src/app/applications/components/application-deployment-history/application-deployment-history.tsx @@ -1,4 +1,5 @@ import {DataLoader, DropDownMenu, Duration} from 'argo-ui'; +import {InitiatedBy} from './initiated-by'; import * as moment from 'moment'; import * as React from 'react'; import {Revision, Timestamp} from '../../../shared/components'; @@ -42,6 +43,12 @@ export const ApplicationDeploymentHistory = ({
    {(info.deployStartedAt && ) || 'Unknown'}
    +
    +
    + Initiated by: +
    + +

    Active for: diff --git a/ui/src/app/applications/components/application-deployment-history/initiated-by.tsx b/ui/src/app/applications/components/application-deployment-history/initiated-by.tsx new file mode 100644 index 0000000000000..f691389b5daca --- /dev/null +++ b/ui/src/app/applications/components/application-deployment-history/initiated-by.tsx @@ -0,0 +1,6 @@ +import * as React from 'react'; + +export const InitiatedBy = (props: {username: string; automated: boolean}) => { + const initiator = props.automated ? 'automated sync policy' : props.username || 'Unknown'; + return {initiator}; +}; diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index 861513523c7a3..823c61c34dc9a 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -297,6 +297,7 @@ export interface RevisionHistory { sources: ApplicationSource[]; deployStartedAt: models.Time; deployedAt: models.Time; + initiatedBy: OperationInitiator; } export type SyncStatusCode = 'Unknown' | 'Synced' | 'OutOfSync'; From 7d1f6a1e94b43d85d93a4964e48ab576ac02c763 Mon Sep 17 00:00:00 2001 From: Sanchaai Mathiyarasan Date: Thu, 28 Dec 2023 05:15:36 -0500 Subject: [PATCH 171/269] Update contributors-quickstart.md to include minikube as local cluster alternative. (#16690) Signed-off-by: Sanchaai Mathiyarasan --- docs/developer-guide/contributors-quickstart.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/developer-guide/contributors-quickstart.md b/docs/developer-guide/contributors-quickstart.md index 0e98fab7ec940..cb3fe67e6e212 100644 --- a/docs/developer-guide/contributors-quickstart.md +++ b/docs/developer-guide/contributors-quickstart.md @@ -23,16 +23,29 @@ git clone https://github.com/argoproj/argo-cd.git -### Install or Upgrade `kind` (Optional - Should work with any local cluster) +### Install or Upgrade a Tool for Running Local Clusters (e.g. kind or minikube) + +#### Installation guide for kind: +#### Installation guide for minikube: + + + ### Start Your Local Cluster +For example, if you are using kind: ```shell kind create cluster ``` +Or, if you are using minikube: + +```shell +minikube start +``` + ### Install Argo CD ```shell From 20f718248998e698370fa43bb74f548072835c29 Mon Sep 17 00:00:00 2001 From: Mark Estiller Date: Thu, 28 Dec 2023 05:17:00 -0500 Subject: [PATCH 172/269] Update contributors-quickstart.md to include a link to Go's installation guide (#16691) Signed-off-by: Mark Estiller --- docs/developer-guide/contributors-quickstart.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/developer-guide/contributors-quickstart.md b/docs/developer-guide/contributors-quickstart.md index cb3fe67e6e212..a7646a6cf5f25 100644 --- a/docs/developer-guide/contributors-quickstart.md +++ b/docs/developer-guide/contributors-quickstart.md @@ -9,6 +9,8 @@ and the [toolchain guide](toolchain-guide.md). ### Install Go + + Install version 1.18 or newer (Verify version by running `go version`) ### Clone the Argo CD repo From f0f4a4e438eeff1ee985e4a0535b9597175aefa1 Mon Sep 17 00:00:00 2001 From: Nenad Strainovic Date: Thu, 28 Dec 2023 12:32:15 +0100 Subject: [PATCH 173/269] Multiple hook delete policies can be specified as a comma separated list (#16659) Based on https://github.com/argoproj/gitops-engine/blob/master/pkg/sync/hook/delete_policy.go#L13 multiple hook delete policies are also allowed. Signed-off-by: Nenad Strainovic --- docs/user-guide/resource_hooks.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/user-guide/resource_hooks.md b/docs/user-guide/resource_hooks.md index 74098b1810011..a6fdaf8bd2e05 100644 --- a/docs/user-guide/resource_hooks.md +++ b/docs/user-guide/resource_hooks.md @@ -62,6 +62,7 @@ metadata: argocd.argoproj.io/hook: PostSync argocd.argoproj.io/hook-delete-policy: HookSucceeded ``` +Multiple hook delete policies can be specified as a comma separated list. The following policies define when the hook will be deleted. From 80ca563909505ed18fea65e5e47ad6c9db87603e Mon Sep 17 00:00:00 2001 From: Noam Gal Date: Sun, 31 Dec 2023 18:46:58 +0200 Subject: [PATCH 174/269] fix broken link (#16722) Signed-off-by: Noam Gal --- docs/operator-manual/notifications/triggers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/notifications/triggers.md b/docs/operator-manual/notifications/triggers.md index c3e2dc601296b..02d0228c40997 100644 --- a/docs/operator-manual/notifications/triggers.md +++ b/docs/operator-manual/notifications/triggers.md @@ -1,7 +1,7 @@ The trigger defines the condition when the notification should be sent. The definition includes name, condition and notification templates reference. The condition is a predicate expression that returns true if the notification should be sent. The trigger condition evaluation is powered by [antonmedv/expr](https://github.com/antonmedv/expr). -The condition language syntax is described at [Language-Definition.md](https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md). +The condition language syntax is described at [language-definition.md](https://github.com/antonmedv/expr/blob/master/docs/language-definition.md). The trigger is configured in the `argocd-notifications-cm` ConfigMap. For example the following trigger sends a notification when application sync status changes to `Unknown` using the `app-sync-status` template: From a40330f5c80b413e22d1001ae27d75b3b70cbb72 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Wed, 3 Jan 2024 12:08:24 -0500 Subject: [PATCH 175/269] docs: configmap items are strings (#16737) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- docs/operator-manual/notifications/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/notifications/index.md b/docs/operator-manual/notifications/index.md index 3609089e23d08..eccca906ae91b 100644 --- a/docs/operator-manual/notifications/index.md +++ b/docs/operator-manual/notifications/index.md @@ -67,7 +67,7 @@ metadata: name: argocd-cmd-params-cm data: application.namespaces: app-team-one, app-team-two - notificationscontroller.selfservice.enabled: true + notificationscontroller.selfservice.enabled: "true" ``` To use this feature, you can deploy configmap named `argocd-notifications-cm` and possibly a secret `argocd-notifications-secret` in the namespace where the Argo CD application lives. From 1975074de5fb80cb56c94add93ba55979df67b98 Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Wed, 3 Jan 2024 12:58:26 -0500 Subject: [PATCH 176/269] docs: remove core install commands from getting started (#16735) * docs: remove core install commands from getting started I often accidentally run the core install commands when quickly copying and pasting commands from the getting started guide, which leads to confusion. I've also spent plenty of time helping newcomers to Argo CD who have done the same and are confused when they can't reach the UI. Given that this is a "getting started" guide, it's ideal to provide only the commands required. I've removed the commands and left the link out to the core install page for those who are interested in going down that path. Signed-off-by: Nicholas Morey * fix: use link to install commands in core docs Signed-off-by: Nicholas Morey * fix: use tip and improve wording Signed-off-by: Nicholas Morey --------- Signed-off-by: Nicholas Morey --- docs/getting_started.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/getting_started.md b/docs/getting_started.md index d81bd08897ad8..1000206eaf972 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -22,12 +22,8 @@ This will create a new namespace, `argocd`, where Argo CD services and applicati The installation manifests include `ClusterRoleBinding` resources that reference `argocd` namespace. If you are installing Argo CD into a different namespace then make sure to update the namespace reference. -If you are not interested in UI, SSO, multi-cluster features then you can install [core](operator-manual/installation.md#core) Argo CD components only: - -```bash -kubectl create namespace argocd -kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/core-install.yaml -``` +!!! tip + If you are not interested in UI, SSO, and multi-cluster features, then you can install only the [core](operator-manual/core/#installing) Argo CD components. This default installation will have a self-signed certificate and cannot be accessed without a bit of extra work. Do one of: From d5955508da5e1c1d26a2526d826bafe4f697b162 Mon Sep 17 00:00:00 2001 From: Greg Werner Date: Thu, 4 Jan 2024 00:35:33 -0500 Subject: [PATCH 177/269] Update USERS.md with IllumiDesk (#16742) Signed-off-by: Greg Werner --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index ea0c44ae1ff4b..9059df8450c33 100644 --- a/USERS.md +++ b/USERS.md @@ -128,6 +128,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [IBM](https://www.ibm.com/) 1. [Ibotta](https://home.ibotta.com) 1. [IITS-Consulting](https://iits-consulting.de) +1. [IllumiDesk](https://www.illumidesk.com) 1. [imaware](https://imaware.health) 1. [Indeed](https://indeed.com) 1. [Index Exchange](https://www.indexexchange.com/) From 1372529d5674405d214e8d96f91388a52db76b63 Mon Sep 17 00:00:00 2001 From: Yi Cai Date: Fri, 5 Jan 2024 11:53:08 -0500 Subject: [PATCH 178/269] fix(ui):Fixed log horizontal scroll for issue #16411 (#16727) * Fixed log horizontal scroll Signed-off-by: Yi Cai * Updated log line-height Signed-off-by: Yi Cai --------- Signed-off-by: Yi Cai --- .../components/pod-logs-viewer/pod-logs-viewer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx index 1ef2d83815821..309287fab2f37 100644 --- a/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx +++ b/ui/src/app/applications/components/pod-logs-viewer/pod-logs-viewer.tsx @@ -149,9 +149,9 @@ export const PodsLogsViewer = (props: PodLogsProps) => { const logsContent = (width: number, height: number, isWrapped: boolean) => (
    {logs.map((log, lineNum) => ( -
    +                
    {renderLog(log, lineNum)} -
    +
    ))}
    ); From 4afddf71cce23105b0989a497054c5faa85dfa92 Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Fri, 5 Jan 2024 08:53:52 -0800 Subject: [PATCH 179/269] feat: webhook should use 'rename' to copy app manifests of previous commit (#16754) Signed-off-by: Alexander Matyushentsev --- .../commands/argocd_application_controller.go | 12 +- .../commands/argocd_repo_server.go | 6 +- cmd/argocd-server/commands/argocd_server.go | 13 +- cmd/argocd/commands/headless/headless.go | 6 + .../server-commands/argocd-server.md | 147 ++++++++++-------- reposerver/cache/cache.go | 9 +- server/cache/cache.go | 3 +- server/server.go | 3 +- util/cache/appstate/cache.go | 3 +- util/cache/cache.go | 110 ++++++++++--- util/cache/client.go | 1 + util/cache/inmemory.go | 10 ++ util/cache/mocks/cacheclient.go | 11 +- util/cache/redis.go | 4 + util/cache/twolevelclient.go | 8 + util/webhook/webhook.go | 10 +- 16 files changed, 243 insertions(+), 113 deletions(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 796a645f03393..d5ef88a1702b6 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -6,11 +6,12 @@ import ( "math" "time" - "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" "github.com/argoproj/pkg/stats" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + kubeerrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" @@ -20,6 +21,7 @@ import ( "github.com/argoproj/argo-cd/v2/controller/sharding" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/v2/pkg/ratelimiter" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" appstatecache "github.com/argoproj/argo-cd/v2/util/cache/appstate" @@ -31,8 +33,6 @@ import ( "github.com/argoproj/argo-cd/v2/util/settings" "github.com/argoproj/argo-cd/v2/util/tls" "github.com/argoproj/argo-cd/v2/util/trace" - kubeerrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) const ( @@ -227,8 +227,10 @@ func NewCommand() *cobra.Command { command.Flags().Float64Var(&workqueueRateLimit.BackoffFactor, "wq-backoff-factor", env.ParseFloat64FromEnv("WORKQUEUE_BACKOFF_FACTOR", 1.5, 0, math.MaxFloat64), "Set Workqueue Per Item Rate Limiter Backoff Factor, default is 1.5") command.Flags().BoolVar(&enableDynamicClusterDistribution, "dynamic-cluster-distribution-enabled", env.ParseBoolFromEnv(common.EnvEnableDynamicClusterDistribution, false), "Enables dynamic cluster distribution.") command.Flags().BoolVar(&serverSideDiff, "server-side-diff-enabled", env.ParseBoolFromEnv(common.EnvServerSideDiff, false), "Feature flag to enable ServerSide diff. Default (\"false\")") - cacheSource = appstatecache.AddCacheFlagsToCmd(&command, func(client *redis.Client) { - redisClient = client + cacheSource = appstatecache.AddCacheFlagsToCmd(&command, cacheutil.Options{ + OnClientCreated: func(client *redis.Client) { + redisClient = client + }, }) return &command } diff --git a/cmd/argocd-repo-server/commands/argocd_repo_server.go b/cmd/argocd-repo-server/commands/argocd_repo_server.go index 2a16d192e01bd..84b50e7cd5ab9 100644 --- a/cmd/argocd-repo-server/commands/argocd_repo_server.go +++ b/cmd/argocd-repo-server/commands/argocd_repo_server.go @@ -210,8 +210,10 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&helmManifestMaxExtractedSize, "helm-manifest-max-extracted-size", env.StringFromEnv("ARGOCD_REPO_SERVER_HELM_MANIFEST_MAX_EXTRACTED_SIZE", "1G"), "Maximum size of helm manifest archives when extracted") command.Flags().BoolVar(&disableManifestMaxExtractedSize, "disable-helm-manifest-max-extracted-size", env.ParseBoolFromEnv("ARGOCD_REPO_SERVER_DISABLE_HELM_MANIFEST_MAX_EXTRACTED_SIZE", false), "Disable maximum size of helm manifest archives when extracted") tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(&command) - cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, func(client *redis.Client) { - redisClient = client + cacheSrc = reposervercache.AddCacheFlagsToCmd(&command, cacheutil.Options{ + OnClientCreated: func(client *redis.Client) { + redisClient = client + }, }) return &command } diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 6eeb5b299ce0f..72fe765c32c56 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -18,8 +18,10 @@ import ( "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/reposerver/apiclient" + reposervercache "github.com/argoproj/argo-cd/v2/reposerver/cache" "github.com/argoproj/argo-cd/v2/server" servercache "github.com/argoproj/argo-cd/v2/server/cache" + cacheutil "github.com/argoproj/argo-cd/v2/util/cache" "github.com/argoproj/argo-cd/v2/util/cli" "github.com/argoproj/argo-cd/v2/util/dex" "github.com/argoproj/argo-cd/v2/util/env" @@ -64,6 +66,7 @@ func NewCommand() *cobra.Command { enableGZip bool tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error) cacheSrc func() (*servercache.Cache, error) + repoServerCacheSrc func() (*reposervercache.Cache, error) frameOptions string contentSecurityPolicy string repoServerPlaintext bool @@ -105,6 +108,8 @@ func NewCommand() *cobra.Command { errors.CheckError(err) cache, err := cacheSrc() errors.CheckError(err) + repoServerCache, err := repoServerCacheSrc() + errors.CheckError(err) kubeclientset := kubernetes.NewForConfigOrDie(config) @@ -183,6 +188,7 @@ func NewCommand() *cobra.Command { EnableGZip: enableGZip, TLSConfigCustomizer: tlsConfigCustomizer, Cache: cache, + RepoServerCache: repoServerCache, XFrameOptions: frameOptions, ContentSecurityPolicy: contentSecurityPolicy, RedisClient: redisClient, @@ -254,8 +260,11 @@ func NewCommand() *cobra.Command { command.Flags().StringSliceVar(&applicationNamespaces, "application-namespaces", env.StringsFromEnv("ARGOCD_APPLICATION_NAMESPACES", []string{}, ","), "List of additional namespaces where application resources can be managed in") command.Flags().BoolVar(&enableProxyExtension, "enable-proxy-extension", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_PROXY_EXTENSION", false), "Enable Proxy Extension feature") tlsConfigCustomizerSrc = tls.AddTLSFlagsToCmd(command) - cacheSrc = servercache.AddCacheFlagsToCmd(command, func(client *redis.Client) { - redisClient = client + cacheSrc = servercache.AddCacheFlagsToCmd(command, cacheutil.Options{ + OnClientCreated: func(client *redis.Client) { + redisClient = client + }, }) + repoServerCacheSrc = reposervercache.AddCacheFlagsToCmd(command, cacheutil.Options{FlagPrefix: "repo-server-"}) return command } diff --git a/cmd/argocd/commands/headless/headless.go b/cmd/argocd/commands/headless/headless.go index 5c9828fc9f131..d48019a2216b9 100644 --- a/cmd/argocd/commands/headless/headless.go +++ b/cmd/argocd/commands/headless/headless.go @@ -78,6 +78,12 @@ func (c *forwardCacheClient) Set(item *cache.Item) error { }) } +func (c *forwardCacheClient) Rename(oldKey string, newKey string, expiration time.Duration) error { + return c.doLazy(func(client cache.CacheClient) error { + return client.Rename(oldKey, newKey, expiration) + }) +} + func (c *forwardCacheClient) Get(key string, obj interface{}) error { return c.doLazy(func(client cache.CacheClient) error { return client.Get(key, obj) diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index e3dcc937243df..1da27d735e1cd 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -25,73 +25,86 @@ argocd-server [flags] ### Options ``` - --address string Listen on given address (default "0.0.0.0") - --app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s) - --application-namespaces strings List of additional namespaces where application resources can be managed in - --as string Username to impersonate for the operation - --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. - --as-uid string UID to impersonate for the operation - --basehref string Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / (default "/") - --certificate-authority string Path to a cert file for the certificate authority - --client-certificate string Path to a client certificate file for TLS - --client-key string Path to a client key file for TLS - --cluster string The name of the kubeconfig cluster to use - --connection-status-cache-expiration duration Cache expiration for cluster/repo connection status (default 1h0m0s) - --content-security-policy value Set Content-Security-Policy header in HTTP responses to value. To disable, set to "". (default "frame-ancestors 'self';") - --context string The name of the kubeconfig context to use - --default-cache-expiration duration Cache expiration default (default 24h0m0s) - --dex-server string Dex server address (default "argocd-dex-server:5556") - --dex-server-plaintext Use a plaintext client (non-TLS) to connect to dex server - --dex-server-strict-tls Perform strict validation of TLS certificates when connecting to dex server - --disable-auth Disable client authentication - --disable-compression If true, opt-out of response compression for all requests to the server - --enable-gzip Enable GZIP compression (default true) - --enable-proxy-extension Enable Proxy Extension feature - --gloglevel int Set the glog logging level - -h, --help help for argocd-server - --insecure Run server without TLS - --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure - --kubeconfig string Path to a kube config. Only required if out-of-cluster - --logformat string Set the logging format. One of: text|json (default "text") - --login-attempts-expiration duration Cache expiration for failed login attempts (default 24h0m0s) - --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") - --metrics-address string Listen for metrics on given address (default "0.0.0.0") - --metrics-port int Start metrics on given port (default 8083) - -n, --namespace string If present, the namespace scope for this CLI request - --oidc-cache-expiration duration Cache expiration for OIDC state (default 3m0s) - --otlp-address string OpenTelemetry collector address to send traces to - --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) - --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) - --otlp-insecure OpenTelemetry collector insecure mode (default true) - --password string Password for basic authentication to the API server - --port int Listen on given port (default 8080) - --proxy-url string If provided, this URL will be used to connect via proxy - --redis string Redis server hostname and port (e.g. argocd-redis:6379). - --redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation. - --redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt). - --redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt). - --redis-compress string Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none) (default "gzip") - --redis-insecure-skip-tls-verify Skip Redis server certificate validation. - --redis-use-tls Use TLS when connecting to Redis. - --redisdb int Redis database. - --repo-server string Repo server address (default "argocd-repo-server:8081") - --repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server - --repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server - --repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60) - --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") - --rootpath string Used if Argo CD is running behind reverse proxy under subpath different from / - --sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). - --sentinelmaster string Redis sentinel master group name. (default "master") - --server string The address and port of the Kubernetes API server - --staticassets string Directory path that contains additional static assets (default "/shared/app") - --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. - --tlsciphers string The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384") - --tlsmaxversion string The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3") - --tlsminversion string The minimum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.2") - --token string Bearer token for authentication to the API server - --user string The name of the kubeconfig user to use - --username string Username for basic authentication to the API server - --x-frame-options value Set X-Frame-Options header in HTTP responses to value. To disable, set to "". (default "sameorigin") + --address string Listen on given address (default "0.0.0.0") + --app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s) + --application-namespaces strings List of additional namespaces where application resources can be managed in + --as string Username to impersonate for the operation + --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. + --as-uid string UID to impersonate for the operation + --basehref string Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / (default "/") + --certificate-authority string Path to a cert file for the certificate authority + --client-certificate string Path to a client certificate file for TLS + --client-key string Path to a client key file for TLS + --cluster string The name of the kubeconfig cluster to use + --connection-status-cache-expiration duration Cache expiration for cluster/repo connection status (default 1h0m0s) + --content-security-policy value Set Content-Security-Policy header in HTTP responses to value. To disable, set to "". (default "frame-ancestors 'self';") + --context string The name of the kubeconfig context to use + --default-cache-expiration duration Cache expiration default (default 24h0m0s) + --dex-server string Dex server address (default "argocd-dex-server:5556") + --dex-server-plaintext Use a plaintext client (non-TLS) to connect to dex server + --dex-server-strict-tls Perform strict validation of TLS certificates when connecting to dex server + --disable-auth Disable client authentication + --disable-compression If true, opt-out of response compression for all requests to the server + --enable-gzip Enable GZIP compression (default true) + --enable-proxy-extension Enable Proxy Extension feature + --gloglevel int Set the glog logging level + -h, --help help for argocd-server + --insecure Run server without TLS + --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure + --kubeconfig string Path to a kube config. Only required if out-of-cluster + --logformat string Set the logging format. One of: text|json (default "text") + --login-attempts-expiration duration Cache expiration for failed login attempts (default 24h0m0s) + --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") + --metrics-address string Listen for metrics on given address (default "0.0.0.0") + --metrics-port int Start metrics on given port (default 8083) + -n, --namespace string If present, the namespace scope for this CLI request + --oidc-cache-expiration duration Cache expiration for OIDC state (default 3m0s) + --otlp-address string OpenTelemetry collector address to send traces to + --otlp-attrs strings List of OpenTelemetry collector extra attrs when send traces, each attribute is separated by a colon(e.g. key:value) + --otlp-headers stringToString List of OpenTelemetry collector extra headers sent with traces, headers are comma-separated key-value pairs(e.g. key1=value1,key2=value2) (default []) + --otlp-insecure OpenTelemetry collector insecure mode (default true) + --password string Password for basic authentication to the API server + --port int Listen on given port (default 8080) + --proxy-url string If provided, this URL will be used to connect via proxy + --redis string Redis server hostname and port (e.g. argocd-redis:6379). + --redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation. + --redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt). + --redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt). + --redis-compress string Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none) (default "gzip") + --redis-insecure-skip-tls-verify Skip Redis server certificate validation. + --redis-use-tls Use TLS when connecting to Redis. + --redisdb int Redis database. + --repo-cache-expiration duration Cache expiration for repo state, incl. app lists, app details, manifest generation, revision meta-data (default 24h0m0s) + --repo-server string Repo server address (default "argocd-repo-server:8081") + --repo-server-default-cache-expiration duration Cache expiration default (default 24h0m0s) + --repo-server-plaintext Use a plaintext client (non-TLS) to connect to repository server + --repo-server-redis string Redis server hostname and port (e.g. argocd-redis:6379). + --repo-server-redis-ca-certificate string Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation. + --repo-server-redis-client-certificate string Path to Redis client certificate (e.g. /etc/certs/redis/client.crt). + --repo-server-redis-client-key string Path to Redis client key (e.g. /etc/certs/redis/client.crt). + --repo-server-redis-compress string Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none) (default "gzip") + --repo-server-redis-insecure-skip-tls-verify Skip Redis server certificate validation. + --repo-server-redis-use-tls Use TLS when connecting to Redis. + --repo-server-redisdb int Redis database. + --repo-server-sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). + --repo-server-sentinelmaster string Redis sentinel master group name. (default "master") + --repo-server-strict-tls Perform strict validation of TLS certificates when connecting to repo server + --repo-server-timeout-seconds int Repo server RPC call timeout seconds. (default 60) + --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") + --revision-cache-expiration duration Cache expiration for cached revision (default 3m0s) + --rootpath string Used if Argo CD is running behind reverse proxy under subpath different from / + --sentinel stringArray Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). + --sentinelmaster string Redis sentinel master group name. (default "master") + --server string The address and port of the Kubernetes API server + --staticassets string Directory path that contains additional static assets (default "/shared/app") + --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. + --tlsciphers string The list of acceptable ciphers to be used when establishing TLS connections. Use 'list' to list available ciphers. (default "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:TLS_RSA_WITH_AES_256_GCM_SHA384") + --tlsmaxversion string The maximum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.3") + --tlsminversion string The minimum SSL/TLS version that is acceptable (one of: 1.0|1.1|1.2|1.3) (default "1.2") + --token string Bearer token for authentication to the API server + --user string The name of the kubeconfig user to use + --username string Username for basic authentication to the API server + --x-frame-options value Set X-Frame-Options header in HTTP responses to value. To disable, set to "". (default "sameorigin") ``` ### SEE ALSO diff --git a/reposerver/cache/cache.go b/reposerver/cache/cache.go index 79d3a02b62750..4437bd3ac0dd7 100644 --- a/reposerver/cache/cache.go +++ b/reposerver/cache/cache.go @@ -12,7 +12,6 @@ import ( "github.com/argoproj/gitops-engine/pkg/utils/text" "github.com/go-git/go-git/v5/plumbing" - "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -44,7 +43,7 @@ func NewCache(cache *cacheutil.Cache, repoCacheExpiration time.Duration, revisio return &Cache{cache, repoCacheExpiration, revisionCacheExpiration} } -func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) func() (*Cache, error) { +func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...cacheutil.Options) func() (*Cache, error) { var repoCacheExpiration time.Duration var revisionCacheExpiration time.Duration @@ -225,6 +224,12 @@ func LogDebugManifestCacheKeyFields(message string, reason string, revision stri } } +func (c *Cache) SetNewRevisionManifests(newRevision string, revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, refSourceCommitSHAs ResolvedRevisions) error { + oldKey := manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs) + newKey := manifestCacheKey(newRevision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs) + return c.cache.RenameItem(oldKey, newKey, c.repoCacheExpiration) +} + func (c *Cache) GetManifests(revision string, appSrc *appv1.ApplicationSource, srcRefs appv1.RefTargetRevisionMapping, clusterInfo ClusterRuntimeInfo, namespace string, trackingMethod string, appLabelKey string, appName string, res *CachedManifestResponse, refSourceCommitSHAs ResolvedRevisions) error { err := c.cache.GetItem(manifestCacheKey(revision, appSrc, srcRefs, namespace, trackingMethod, appLabelKey, appName, clusterInfo, refSourceCommitSHAs), res) diff --git a/server/cache/cache.go b/server/cache/cache.go index ccbebd256be78..c2042c3f0e8d1 100644 --- a/server/cache/cache.go +++ b/server/cache/cache.go @@ -6,7 +6,6 @@ import ( "math" "time" - "github.com/redis/go-redis/v9" "github.com/spf13/cobra" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -33,7 +32,7 @@ func NewCache( return &Cache{cache, connectionStatusCacheExpiration, oidcCacheExpiration, loginAttemptsExpiration} } -func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) func() (*Cache, error) { +func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...cacheutil.Options) func() (*Cache, error) { var connectionStatusCacheExpiration time.Duration var oidcCacheExpiration time.Duration var loginAttemptsExpiration time.Duration diff --git a/server/server.go b/server/server.go index 0f9b0ddadd800..6ebbc9723167f 100644 --- a/server/server.go +++ b/server/server.go @@ -213,6 +213,7 @@ type ArgoCDServerOpts struct { AppClientset appclientset.Interface RepoClientset repoapiclient.Clientset Cache *servercache.Cache + RepoServerCache *repocache.Cache RedisClient *redis.Client TLSConfigCustomizer tlsutil.ConfigCustomizer XFrameOptions string @@ -1028,7 +1029,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl // Webhook handler for git events (Note: cache timeouts are hardcoded because API server does not write to cache and not really using them) argoDB := db.NewDB(a.Namespace, a.settingsMgr, a.KubeClientset) - acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.AppClientset, a.settings, a.settingsMgr, repocache.NewCache(a.Cache.GetCache(), 24*time.Hour, 3*time.Minute), a.Cache, argoDB) + acdWebhookHandler := webhook.NewHandler(a.Namespace, a.ArgoCDServerOpts.ApplicationNamespaces, a.AppClientset, a.settings, a.settingsMgr, a.RepoServerCache, a.Cache, argoDB) mux.HandleFunc("/api/webhook", acdWebhookHandler.Handler) diff --git a/util/cache/appstate/cache.go b/util/cache/appstate/cache.go index d59d31befb12e..bb161a429eff9 100644 --- a/util/cache/appstate/cache.go +++ b/util/cache/appstate/cache.go @@ -6,7 +6,6 @@ import ( "sort" "time" - "github.com/redis/go-redis/v9" "github.com/spf13/cobra" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" @@ -29,7 +28,7 @@ func NewCache(cache *cacheutil.Cache, appStateCacheExpiration time.Duration) *Ca return &Cache{cache, appStateCacheExpiration} } -func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) func() (*Cache, error) { +func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...cacheutil.Options) func() (*Cache, error) { var appStateCacheExpiration time.Duration cmd.Flags().DurationVar(&appStateCacheExpiration, "app-state-cache-expiration", env.ParseDurationFromEnv("ARGOCD_APP_STATE_CACHE_EXPIRATION", 1*time.Hour, 0, 10*time.Hour), "Cache expiration for app state") diff --git a/util/cache/cache.go b/util/cache/cache.go index c9cb8c3b8607a..9ac058756f4ca 100644 --- a/util/cache/cache.go +++ b/util/cache/cache.go @@ -5,17 +5,17 @@ import ( "fmt" "math" "os" + "strings" "time" "crypto/tls" "crypto/x509" - "github.com/redis/go-redis/v9" - "github.com/spf13/cobra" - "github.com/argoproj/argo-cd/v2/common" certutil "github.com/argoproj/argo-cd/v2/util/cert" "github.com/argoproj/argo-cd/v2/util/env" + "github.com/redis/go-redis/v9" + "github.com/spf13/cobra" ) const ( @@ -77,8 +77,52 @@ func buildFailoverRedisClient(sentinelMaster, password, username string, redisDB return client } +type Options struct { + FlagPrefix string + OnClientCreated func(client *redis.Client) +} + +func (o *Options) callOnClientCreated(client *redis.Client) { + if o.OnClientCreated != nil { + o.OnClientCreated(client) + } +} + +func (o *Options) getEnvPrefix() string { + return strings.Replace(strings.ToUpper(o.FlagPrefix), "-", "_", -1) +} + +func mergeOptions(opts ...Options) Options { + var result Options + for _, o := range opts { + if o.FlagPrefix != "" { + result.FlagPrefix = o.FlagPrefix + } + if o.OnClientCreated != nil { + result.OnClientCreated = o.OnClientCreated + } + } + return result +} + +func getFlagVal[T any](cmd *cobra.Command, o Options, name string, getVal func(name string) (T, error)) func() T { + return func() T { + var res T + var err error + if o.FlagPrefix != "" && cmd.Flags().Changed(o.FlagPrefix+name) { + res, err = getVal(o.FlagPrefix + name) + } else { + res, err = getVal(name) + } + if err != nil { + panic(err) + } + return res + } +} + // AddCacheFlagsToCmd adds flags which control caching to the specified command -func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) func() (*Cache, error) { +func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...Options) func() (*Cache, error) { redisAddress := "" sentinelAddresses := make([]string, 0) sentinelMaster := "" @@ -89,20 +133,44 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) redisUseTLS := false insecureRedis := false compressionStr := "" + opt := mergeOptions(opts...) var defaultCacheExpiration time.Duration - cmd.Flags().StringVar(&redisAddress, "redis", env.StringFromEnv("REDIS_SERVER", ""), "Redis server hostname and port (e.g. argocd-redis:6379). ") - cmd.Flags().IntVar(&redisDB, "redisdb", env.ParseNumFromEnv("REDISDB", 0, 0, math.MaxInt32), "Redis database.") - cmd.Flags().StringArrayVar(&sentinelAddresses, "sentinel", []string{}, "Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). ") - cmd.Flags().StringVar(&sentinelMaster, "sentinelmaster", "master", "Redis sentinel master group name.") - cmd.Flags().DurationVar(&defaultCacheExpiration, "default-cache-expiration", env.ParseDurationFromEnv("ARGOCD_DEFAULT_CACHE_EXPIRATION", 24*time.Hour, 0, math.MaxInt64), "Cache expiration default") - cmd.Flags().BoolVar(&redisUseTLS, "redis-use-tls", false, "Use TLS when connecting to Redis. ") - cmd.Flags().StringVar(&redisClientCertificate, "redis-client-certificate", "", "Path to Redis client certificate (e.g. /etc/certs/redis/client.crt).") - cmd.Flags().StringVar(&redisClientKey, "redis-client-key", "", "Path to Redis client key (e.g. /etc/certs/redis/client.crt).") - cmd.Flags().BoolVar(&insecureRedis, "redis-insecure-skip-tls-verify", false, "Skip Redis server certificate validation.") - cmd.Flags().StringVar(&redisCACertificate, "redis-ca-certificate", "", "Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.") - cmd.Flags().StringVar(&compressionStr, CLIFlagRedisCompress, env.StringFromEnv("REDIS_COMPRESSION", string(RedisCompressionGZip)), "Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none)") + cmd.Flags().StringVar(&redisAddress, opt.FlagPrefix+"redis", env.StringFromEnv(opt.getEnvPrefix()+"REDIS_SERVER", ""), "Redis server hostname and port (e.g. argocd-redis:6379). ") + redisAddressSrc := getFlagVal(cmd, opt, "redis", cmd.Flags().GetString) + cmd.Flags().IntVar(&redisDB, opt.FlagPrefix+"redisdb", env.ParseNumFromEnv(opt.getEnvPrefix()+"REDISDB", 0, 0, math.MaxInt32), "Redis database.") + redisDBSrc := getFlagVal(cmd, opt, "redisdb", cmd.Flags().GetInt) + cmd.Flags().StringArrayVar(&sentinelAddresses, opt.FlagPrefix+"sentinel", []string{}, "Redis sentinel hostname and port (e.g. argocd-redis-ha-announce-0:6379). ") + sentinelAddressesSrc := getFlagVal(cmd, opt, "sentinel", cmd.Flags().GetStringArray) + cmd.Flags().StringVar(&sentinelMaster, opt.FlagPrefix+"sentinelmaster", "master", "Redis sentinel master group name.") + sentinelMasterSrc := getFlagVal(cmd, opt, "sentinelmaster", cmd.Flags().GetString) + cmd.Flags().DurationVar(&defaultCacheExpiration, opt.FlagPrefix+"default-cache-expiration", env.ParseDurationFromEnv("ARGOCD_DEFAULT_CACHE_EXPIRATION", 24*time.Hour, 0, math.MaxInt64), "Cache expiration default") + defaultCacheExpirationSrc := getFlagVal(cmd, opt, "default-cache-expiration", cmd.Flags().GetDuration) + cmd.Flags().BoolVar(&redisUseTLS, opt.FlagPrefix+"redis-use-tls", false, "Use TLS when connecting to Redis. ") + redisUseTLSSrc := getFlagVal(cmd, opt, "redis-use-tls", cmd.Flags().GetBool) + cmd.Flags().StringVar(&redisClientCertificate, opt.FlagPrefix+"redis-client-certificate", "", "Path to Redis client certificate (e.g. /etc/certs/redis/client.crt).") + redisClientCertificateSrc := getFlagVal(cmd, opt, "redis-client-certificate", cmd.Flags().GetString) + cmd.Flags().StringVar(&redisClientKey, opt.FlagPrefix+"redis-client-key", "", "Path to Redis client key (e.g. /etc/certs/redis/client.crt).") + redisClientKeySrc := getFlagVal(cmd, opt, "redis-client-key", cmd.Flags().GetString) + cmd.Flags().BoolVar(&insecureRedis, opt.FlagPrefix+"redis-insecure-skip-tls-verify", false, "Skip Redis server certificate validation.") + insecureRedisSrc := getFlagVal(cmd, opt, "redis-insecure-skip-tls-verify", cmd.Flags().GetBool) + cmd.Flags().StringVar(&redisCACertificate, opt.FlagPrefix+"redis-ca-certificate", "", "Path to Redis server CA certificate (e.g. /etc/certs/redis/ca.crt). If not specified, system trusted CAs will be used for server certificate validation.") + redisCACertificateSrc := getFlagVal(cmd, opt, "redis-ca-certificate", cmd.Flags().GetString) + cmd.Flags().StringVar(&compressionStr, opt.FlagPrefix+CLIFlagRedisCompress, env.StringFromEnv(opt.getEnvPrefix()+"REDIS_COMPRESSION", string(RedisCompressionGZip)), "Enable compression for data sent to Redis with the required compression algorithm. (possible values: gzip, none)") + compressionStrSrc := getFlagVal(cmd, opt, CLIFlagRedisCompress, cmd.Flags().GetString) return func() (*Cache, error) { + redisAddress := redisAddressSrc() + redisDB := redisDBSrc() + sentinelAddresses := sentinelAddressesSrc() + sentinelMaster := sentinelMasterSrc() + defaultCacheExpiration := defaultCacheExpirationSrc() + redisUseTLS := redisUseTLSSrc() + redisClientCertificate := redisClientCertificateSrc() + redisClientKey := redisClientKeySrc() + insecureRedis := insecureRedisSrc() + redisCACertificate := redisCACertificateSrc() + compressionStr := compressionStrSrc() + var tlsConfig *tls.Config = nil if redisUseTLS { tlsConfig = &tls.Config{} @@ -138,9 +206,7 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) } if len(sentinelAddresses) > 0 { client := buildFailoverRedisClient(sentinelMaster, password, username, redisDB, maxRetries, tlsConfig, sentinelAddresses) - for i := range opts { - opts[i](client) - } + opt.callOnClientCreated(client) return NewCache(NewRedisCache(client, defaultCacheExpiration, compression)), nil } if redisAddress == "" { @@ -148,9 +214,7 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...func(client *redis.Client)) } client := buildRedisClient(redisAddress, password, username, redisDB, maxRetries, tlsConfig) - for i := range opts { - opts[i](client) - } + opt.callOnClientCreated(client) return NewCache(NewRedisCache(client, defaultCacheExpiration, compression)), nil } } @@ -168,6 +232,10 @@ func (c *Cache) SetClient(client CacheClient) { c.client = client } +func (c *Cache) RenameItem(oldKey string, newKey string, expiration time.Duration) error { + return c.client.Rename(fmt.Sprintf("%s|%s", oldKey, common.CacheVersion), fmt.Sprintf("%s|%s", newKey, common.CacheVersion), expiration) +} + func (c *Cache) SetItem(key string, item interface{}, expiration time.Duration, delete bool) error { key = fmt.Sprintf("%s|%s", key, common.CacheVersion) if delete { diff --git a/util/cache/client.go b/util/cache/client.go index 434c2a8da187a..c8c7b4a6baa80 100644 --- a/util/cache/client.go +++ b/util/cache/client.go @@ -17,6 +17,7 @@ type Item struct { type CacheClient interface { Set(item *Item) error + Rename(oldKey string, newKey string, expiration time.Duration) error Get(key string, obj interface{}) error Delete(key string) error OnUpdated(ctx context.Context, key string, callback func() error) error diff --git a/util/cache/inmemory.go b/util/cache/inmemory.go index f75688c275546..6d970c1d4f567 100644 --- a/util/cache/inmemory.go +++ b/util/cache/inmemory.go @@ -37,6 +37,16 @@ func (i *InMemoryCache) Set(item *Item) error { return nil } +func (i *InMemoryCache) Rename(oldKey string, newKey string, expiration time.Duration) error { + bufIf, found := i.memCache.Get(oldKey) + if !found { + return ErrCacheMiss + } + i.memCache.Set(newKey, bufIf, expiration) + i.memCache.Delete(oldKey) + return nil +} + // HasSame returns true if key with the same value already present in cache func (i *InMemoryCache) HasSame(key string, obj interface{}) (bool, error) { var buf bytes.Buffer diff --git a/util/cache/mocks/cacheclient.go b/util/cache/mocks/cacheclient.go index e653847ec49a8..2fdd9fc37f8be 100644 --- a/util/cache/mocks/cacheclient.go +++ b/util/cache/mocks/cacheclient.go @@ -4,8 +4,9 @@ import ( "context" "time" - cache "github.com/argoproj/argo-cd/v2/util/cache" "github.com/stretchr/testify/mock" + + "github.com/argoproj/argo-cd/v2/util/cache" ) type MockCacheClient struct { @@ -15,6 +16,14 @@ type MockCacheClient struct { WriteDelay time.Duration } +func (c *MockCacheClient) Rename(oldKey string, newKey string, expiration time.Duration) error { + args := c.Called(oldKey, newKey, expiration) + if len(args) > 0 && args.Get(0) != nil { + return args.Get(0).(error) + } + return c.BaseCache.Rename(oldKey, newKey, expiration) +} + func (c *MockCacheClient) Set(item *cache.Item) error { args := c.Called(item) if len(args) > 0 && args.Get(0) != nil { diff --git a/util/cache/redis.go b/util/cache/redis.go index c5365c4984e21..7d5303bb3a9fa 100644 --- a/util/cache/redis.go +++ b/util/cache/redis.go @@ -95,6 +95,10 @@ func (r *redisCache) unmarshal(data []byte, obj interface{}) error { return nil } +func (r *redisCache) Rename(oldKey string, newKey string, _ time.Duration) error { + return r.client.Rename(context.TODO(), r.getKey(oldKey), r.getKey(newKey)).Err() +} + func (r *redisCache) Set(item *Item) error { expiration := item.Expiration if expiration == 0 { diff --git a/util/cache/twolevelclient.go b/util/cache/twolevelclient.go index 14a4279e87c89..f221099844876 100644 --- a/util/cache/twolevelclient.go +++ b/util/cache/twolevelclient.go @@ -18,6 +18,14 @@ type twoLevelClient struct { externalCache CacheClient } +func (c *twoLevelClient) Rename(oldKey string, newKey string, expiration time.Duration) error { + err := c.inMemoryCache.Rename(oldKey, newKey, expiration) + if err != nil { + log.Warnf("Failed to move key '%s' in in-memory cache: %v", oldKey, err) + } + return c.externalCache.Rename(oldKey, newKey, expiration) +} + // Set stores the given value in both in-memory and external cache. // Skip storing the value in external cache if the same value already exists in memory to avoid requesting external cache. func (c *twoLevelClient) Set(item *Item) error { diff --git a/util/webhook/webhook.go b/util/webhook/webhook.go index 9955540ea04a9..25bd92e11802c 100644 --- a/util/webhook/webhook.go +++ b/util/webhook/webhook.go @@ -349,18 +349,12 @@ func (a *ArgoCDWebhookHandler) storePreviouslyCachedManifests(app *v1alpha1.Appl return fmt.Errorf("error getting ref sources: %w", err) } source := app.Spec.GetSource() - cache.LogDebugManifestCacheKeyFields("getting manifests cache", "webhook app revision changed", change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil) + cache.LogDebugManifestCacheKeyFields("moving manifests cache", "webhook app revision changed", change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil) - var cachedManifests cache.CachedManifestResponse - if err := a.repoCache.GetManifests(change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests, nil); err != nil { + if err := a.repoCache.SetNewRevisionManifests(change.shaAfter, change.shaBefore, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil); err != nil { return err } - cache.LogDebugManifestCacheKeyFields("setting manifests cache", "webhook app revision changed", change.shaAfter, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, nil) - - if err = a.repoCache.SetManifests(change.shaAfter, &source, refSources, &clusterInfo, app.Spec.Destination.Namespace, trackingMethod, appInstanceLabelKey, app.Name, &cachedManifests, nil); err != nil { - return err - } return nil } From c4ac5aaa972e8080c186f9b5145114ca7217b28d Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Fri, 5 Jan 2024 15:13:35 -0500 Subject: [PATCH 180/269] docs: add context to configmap example (#16763) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- docs/user-guide/diff-strategies.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/user-guide/diff-strategies.md b/docs/user-guide/diff-strategies.md index a7b3216fa7ec7..2890fe64cbb0e 100644 --- a/docs/user-guide/diff-strategies.md +++ b/docs/user-guide/diff-strategies.md @@ -56,7 +56,13 @@ Application. Add the following entry in the argocd-cmd-params-cm configmap: ``` -controller.diff.server.side: "true" +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmd-params-cm +data: + controller.diff.server.side: "true" +... ``` Note: It is necessary to restart the `argocd-application-controller` From ecbd24da1074f03b49d20994e01ddaf7c0c73b27 Mon Sep 17 00:00:00 2001 From: mfreeman451 Date: Fri, 5 Jan 2024 18:04:54 -0600 Subject: [PATCH 181/269] docs: Update signed-release-assets.md (#16755) Missing \ in example Signed-off-by: mfreeman451 --- docs/operator-manual/signed-release-assets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/signed-release-assets.md b/docs/operator-manual/signed-release-assets.md index 9aec6bb071047..b4e4f3fc97418 100644 --- a/docs/operator-manual/signed-release-assets.md +++ b/docs/operator-manual/signed-release-assets.md @@ -92,7 +92,7 @@ The attestation payload contains a non-forgeable provenance which is base64 enco ```bash slsa-verifier verify-image "$IMAGE" \ --source-uri github.com/argoproj/argo-cd \ - --source-tag v2.7.0 + --source-tag v2.7.0 \ --print-provenance | jq ``` From 40760eb8528766745328e67e124e2cf1f56d8d93 Mon Sep 17 00:00:00 2001 From: Lie Ryan Date: Mon, 8 Jan 2024 03:48:54 +1100 Subject: [PATCH 182/269] Document restarting argocd after modifying argocd-cm (#12405) Signed-off-by: Lie Ryan Co-authored-by: Blake Pettersson --- docs/user-guide/kustomize.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index 9c2bf1fc655a4..647e753649cce 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -131,6 +131,9 @@ data: kustomize.buildOptions: --load-restrictor LoadRestrictionsNone kustomize.buildOptions.v4.4.0: --output /tmp ``` + +After modifying `kustomize.buildOptions`, you may need to restart ArgoCD for the changes to take effect. + ## Custom Kustomize versions Argo CD supports using multiple Kustomize versions simultaneously and specifies required version per application. From c5b9c670737544f497c2f648d06e4540f568505f Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Mon, 8 Jan 2024 16:04:46 -0800 Subject: [PATCH 183/269] fix: support specifying username/password for redis holding manifests in argocd-server (#16786) Signed-off-by: Alexander Matyushentsev --- util/cache/cache.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/util/cache/cache.go b/util/cache/cache.go index 9ac058756f4ca..d34fba5d38f7b 100644 --- a/util/cache/cache.go +++ b/util/cache/cache.go @@ -199,6 +199,14 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...Options) func() (*Cache, err } password := os.Getenv(envRedisPassword) username := os.Getenv(envRedisUsername) + if opt.FlagPrefix != "" { + if val := os.Getenv(opt.getEnvPrefix() + envRedisUsername); val != "" { + username = val + } + if val := os.Getenv(opt.getEnvPrefix() + envRedisPassword); val != "" { + password = val + } + } maxRetries := env.ParseNumFromEnv(envRedisRetryCount, defaultRedisRetryCount, 0, math.MaxInt32) compression, err := CompressionTypeFromString(compressionStr) if err != nil { From 8ebe1cd3c441aab85c13cc03d297b846c9886b99 Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:58:34 -0500 Subject: [PATCH 184/269] fix: add list permission deployments (#16785) * add list permissions for deployments to application controller Signed-off-by: ishitasequeira * revert redis-ha chart changes Signed-off-by: ishitasequeira * revert redis-ha chart changes Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira --- .../argocd-application-controller-role.yaml | 8 ++++++++ manifests/core-install.yaml | 8 ++++++++ manifests/ha/install.yaml | 8 ++++++++ manifests/ha/namespace-install.yaml | 8 ++++++++ manifests/install.yaml | 8 ++++++++ manifests/namespace-install.yaml | 8 ++++++++ 6 files changed, 48 insertions(+) diff --git a/manifests/base/application-controller/argocd-application-controller-role.yaml b/manifests/base/application-controller/argocd-application-controller-role.yaml index 27e0bc7bfe9cb..a672268eb1dd9 100644 --- a/manifests/base/application-controller/argocd-application-controller-role.yaml +++ b/manifests/base/application-controller/argocd-application-controller-role.yaml @@ -36,3 +36,11 @@ rules: verbs: - create - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index c9028a44a1ae0..08d7d972e6362 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -20595,6 +20595,14 @@ rules: verbs: - create - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 81f365bb8a86d..a7086ae8a6c06 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -20631,6 +20631,14 @@ rules: verbs: - create - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index ad1a7baa8b017..01a8da2ffd7b9 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -109,6 +109,14 @@ rules: verbs: - create - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role diff --git a/manifests/install.yaml b/manifests/install.yaml index 3d1bbf942afb5..8d30e076d8bf7 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -20622,6 +20622,14 @@ rules: verbs: - create - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 6fa2cdb2b6de0..76301680f195a 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -100,6 +100,14 @@ rules: verbs: - create - list +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role From 20246596962814b732f20b8cc638156df80c4066 Mon Sep 17 00:00:00 2001 From: mugi <62197019+mugioka@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:57:27 +0900 Subject: [PATCH 185/269] chore(manifests): add ClsuterRole/ClusterRoleBinding for applicationset controller. (#16699) Closes https://github.com/argoproj/argo-cd/issues/16698. Signed-off-by: mugioka --- USERS.md | 1 + ...applicationset-controller-clusterrole.yaml | 88 +++++++++++++++++++ ...tionset-controller-clusterrolebinding.yaml | 16 ++++ .../kustomization.yaml | 6 ++ 4 files changed, 111 insertions(+) create mode 100644 manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml create mode 100644 manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrolebinding.yaml create mode 100644 manifests/cluster-rbac/applicationset-controller/kustomization.yaml diff --git a/USERS.md b/USERS.md index 9059df8450c33..60dd3b881c10b 100644 --- a/USERS.md +++ b/USERS.md @@ -40,6 +40,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Boozt](https://www.booztgroup.com/) 1. [Boticario](https://www.boticario.com.br/) 1. [Bulder Bank](https://bulderbank.no) +1. [CAM](https://cam-inc.co.jp) 1. [Camptocamp](https://camptocamp.com) 1. [Candis](https://www.candis.io) 1. [Capital One](https://www.capitalone.com) diff --git a/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml b/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml new file mode 100644 index 0000000000000..259a48e7aee9e --- /dev/null +++ b/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrole.yaml @@ -0,0 +1,88 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: applicationset-controller + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - update + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch diff --git a/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrolebinding.yaml b/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrolebinding.yaml new file mode 100644 index 0000000000000..820f16f472e4e --- /dev/null +++ b/manifests/cluster-rbac/applicationset-controller/argocd-applicationset-controller-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + app.kubernetes.io/component: applicationset-controller + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller + namespace: argocd diff --git a/manifests/cluster-rbac/applicationset-controller/kustomization.yaml b/manifests/cluster-rbac/applicationset-controller/kustomization.yaml new file mode 100644 index 0000000000000..b8f18c57a14f7 --- /dev/null +++ b/manifests/cluster-rbac/applicationset-controller/kustomization.yaml @@ -0,0 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- argocd-applicationset-controller-clusterrole.yaml +- argocd-applicationset-controller-clusterrolebinding.yaml From 9b27aeb1a4fb15d11a0f01cad65dea1fdfc60205 Mon Sep 17 00:00:00 2001 From: Anand Francis Joseph Date: Tue, 9 Jan 2024 20:11:12 +0530 Subject: [PATCH 186/269] Added socks5 proxy support for ssh based git URL, upgraded go-git to 5.10.1 (#15864) Signed-off-by: Anand Francis Joseph --- Dockerfile | 2 +- cmd/argocd/commands/repo.go | 6 ++ docs/user-guide/commands/argocd_repo_add.md | 6 ++ go.mod | 13 ++-- go.sum | 38 +++++----- .../application/v1alpha1/repository_types.go | 2 +- util/git/client.go | 1 - util/git/creds.go | 24 ++++++- util/git/creds_test.go | 72 ++++++++++++++++++- util/git/workaround.go | 20 ++++++ 10 files changed, 151 insertions(+), 33 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2c31b5077f67e..461a42305f3ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,7 +51,7 @@ RUN groupadd -g $ARGOCD_USER_ID argocd && \ apt-get update && \ apt-get dist-upgrade -y && \ apt-get install -y \ - git git-lfs tini gpg tzdata && \ + git git-lfs tini gpg tzdata connect-proxy && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* diff --git a/cmd/argocd/commands/repo.go b/cmd/argocd/commands/repo.go index 2bf9714a06f11..1a5b4388fbeba 100644 --- a/cmd/argocd/commands/repo.go +++ b/cmd/argocd/commands/repo.go @@ -64,6 +64,12 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { # Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here argocd repo add ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa + # Add a Git repository via SSH using socks5 proxy with no proxy credentials + argocd repo add ssh://git@github.com/argoproj/argocd-example-apps --ssh-private-key-path ~/id_rsa --proxy socks5://your.proxy.server.ip:1080 + + # Add a Git repository via SSH using socks5 proxy with proxy credentials + argocd repo add ssh://git@github.com/argoproj/argocd-example-apps --ssh-private-key-path ~/id_rsa --proxy socks5://username:password@your.proxy.server.ip:1080 + # Add a private Git repository via HTTPS using username/password and TLS client certificates: argocd repo add https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key diff --git a/docs/user-guide/commands/argocd_repo_add.md b/docs/user-guide/commands/argocd_repo_add.md index 263dda07af7dc..8399d48302509 100644 --- a/docs/user-guide/commands/argocd_repo_add.md +++ b/docs/user-guide/commands/argocd_repo_add.md @@ -17,6 +17,12 @@ argocd repo add REPOURL [flags] # Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here argocd repo add ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa + # Add a Git repository via SSH using socks5 proxy with no proxy credentials + argocd repo add ssh://git@github.com/argoproj/argocd-example-apps --ssh-private-key-path ~/id_rsa --proxy socks5://your.proxy.server.ip:1080 + + # Add a Git repository via SSH using socks5 proxy with proxy credentials + argocd repo add ssh://git@github.com/argoproj/argocd-example-apps --ssh-private-key-path ~/id_rsa --proxy socks5://username:password@your.proxy.server.ip:1080 + # Add a private Git repository via HTTPS using username/password and TLS client certificates: argocd repo add https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key diff --git a/go.mod b/go.mod index 377f5c2592d01..07dd99e4beff1 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/evanphx/json-patch v5.6.0+incompatible github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e - github.com/go-git/go-git/v5 v5.8.1 + github.com/go-git/go-git/v5 v5.10.1 github.com/go-logr/logr v1.3.0 github.com/go-openapi/loads v0.21.2 github.com/go-openapi/runtime v0.26.0 @@ -159,9 +159,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/PagerDuty/go-pagerduty v1.7.0 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60 // indirect - github.com/acomagu/bufpipe v1.0.4 // indirect github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -184,7 +183,7 @@ require ( github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect - github.com/go-git/go-billy/v5 v5.4.1 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect @@ -251,7 +250,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect - github.com/skeema/knownhosts v1.2.0 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/slack-go/slack v0.12.2 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/stretchr/objx v0.5.0 // indirect @@ -268,11 +267,11 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 + golang.org/x/net v0.18.0 golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 - golang.org/x/tools v0.12.0 // indirect + golang.org/x/tools v0.13.0 // indirect gomodules.xyz/envconfig v1.3.1-0.20190308184047-426f31af0d45 // indirect gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect gomodules.xyz/notify v0.1.1 // indirect diff --git a/go.sum b/go.sum index 495bafe5b4053..0c5e889f6bdf6 100644 --- a/go.sum +++ b/go.sum @@ -657,8 +657,8 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/PagerDuty/go-pagerduty v1.7.0 h1:S1NcMKECxT5hJwV4VT+QzeSsSiv4oWl1s2821dUqG/8= github.com/PagerDuty/go-pagerduty v1.7.0/go.mod h1:PuFyJKRz1liIAH4h5KVXVD18Obpp1ZXRdxHvmGXooro= github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/RocketChat/Rocket.Chat.Go.SDK v0.0.0-20210112200207-10ab4d695d60 h1:prBTRx78AQnXzivNT9Crhu564W/zPPr3ibSlpT9xKcE= @@ -668,8 +668,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d h1:WtAMR0fPCOfK7TPGZ8ZpLLY18HRvL7XJ3xcs0wnREgo= github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d/go.mod h1:WML6KOYjeU8N6YyusMjj2qRvaPNUEvrQvaxuFcMRFJY= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= -github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= @@ -850,8 +848,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1 github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0= -github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= @@ -925,12 +923,12 @@ github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2H github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8= -github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= -github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= +github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -1377,8 +1375,6 @@ github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8 h1:A6SLdFpRzUUF5v github.com/malexdev/utfutil v0.0.0-20180510171754-00c8d4a8e7a8/go.mod h1:UtpLyb/EupVKXF/N0b4NRe1DNg+QYJsnsHQ038romhM= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= @@ -1498,8 +1494,9 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.25.0 h1:Vw7br2PCDYijJHSfBOWhov+8cAnUf8MfMaIOV323l6Y= github.com/onsi/gomega v1.25.0/go.mod h1:r+zV744Re+DiYCIPRlYOTxn0YkOLcAnW8k1xXdMPGhM= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1625,8 +1622,8 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= -github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c h1:fyKiXKO1/I/B6Y2U8T7WdQGWzwehOuGIrljPtt7YTTI= github.com/skratchdot/open-golang v0.0.0-20160302144031-75fb7ed4208c/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/slack-go/slack v0.12.2 h1:x3OppyMyGIbbiyFhsBmpf9pwkUzMhthJMRNmNlA4LaQ= @@ -1962,8 +1959,9 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= 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= @@ -2263,8 +2261,8 @@ golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= -golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/apis/application/v1alpha1/repository_types.go b/pkg/apis/application/v1alpha1/repository_types.go index 31e8c47971414..3a557813d87c6 100644 --- a/pkg/apis/application/v1alpha1/repository_types.go +++ b/pkg/apis/application/v1alpha1/repository_types.go @@ -196,7 +196,7 @@ func (repo *Repository) GetGitCreds(store git.CredsStore) git.Creds { return git.NewHTTPSCreds(repo.Username, repo.Password, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, store, repo.ForceHttpBasicAuth) } if repo.SSHPrivateKey != "" { - return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure(), store) + return git.NewSSHCreds(repo.SSHPrivateKey, getCAPath(repo.Repo), repo.IsInsecure(), store, repo.Proxy) } if repo.GithubAppPrivateKey != "" && repo.GithubAppId != 0 && repo.GithubAppInstallationId != 0 { return git.NewGitHubAppCreds(repo.GithubAppId, repo.GithubAppInstallationId, repo.GithubAppPrivateKey, repo.GitHubAppEnterpriseBaseURL, repo.Repo, repo.TLSClientCertData, repo.TLSClientCertKey, repo.IsInsecure(), repo.Proxy, store) diff --git a/util/git/client.go b/util/git/client.go index 6a8828d13f432..73c85b54f3c1f 100644 --- a/util/git/client.go +++ b/util/git/client.go @@ -741,7 +741,6 @@ func (m *nativeGitClient) runCmdOutput(cmd *exec.Cmd, ropts runOpts) (string, er } } } - cmd.Env = proxy.UpsertEnv(cmd, m.proxy) opts := executil.ExecRunOpts{ TimeoutBehavior: argoexec.TimeoutBehavior{ diff --git a/util/git/creds.go b/util/git/creds.go index c3d09574eeb84..18698449082bf 100644 --- a/util/git/creds.go +++ b/util/git/creds.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "io" + "net/url" "os" "strconv" "strings" @@ -241,10 +242,11 @@ type SSHCreds struct { caPath string insecure bool store CredsStore + proxy string } -func NewSSHCreds(sshPrivateKey string, caPath string, insecureIgnoreHostKey bool, store CredsStore) SSHCreds { - return SSHCreds{sshPrivateKey, caPath, insecureIgnoreHostKey, store} +func NewSSHCreds(sshPrivateKey string, caPath string, insecureIgnoreHostKey bool, store CredsStore, proxy string) SSHCreds { + return SSHCreds{sshPrivateKey, caPath, insecureIgnoreHostKey, store, proxy} } type sshPrivateKeyFile string @@ -303,7 +305,25 @@ func (c SSHCreds) Environ() (io.Closer, []string, error) { knownHostsFile := certutil.GetSSHKnownHostsDataPath() args = append(args, "-o", "StrictHostKeyChecking=yes", "-o", fmt.Sprintf("UserKnownHostsFile=%s", knownHostsFile)) } + // Handle SSH socks5 proxy settings + proxyEnv := []string{} + if c.proxy != "" { + parsedProxyURL, err := url.Parse(c.proxy) + if err != nil { + return nil, nil, fmt.Errorf("failed to set environment variables related to socks5 proxy, could not parse proxy URL '%s': %w", c.proxy, err) + } + args = append(args, "-o", fmt.Sprintf("ProxyCommand='connect-proxy -S %s:%s -5 %%h %%p'", + parsedProxyURL.Hostname(), + parsedProxyURL.Port())) + if parsedProxyURL.User != nil { + proxyEnv = append(proxyEnv, fmt.Sprintf("SOCKS5_USER=%s", parsedProxyURL.User.Username())) + if socks5_passwd, isPasswdSet := parsedProxyURL.User.Password(); isPasswdSet { + proxyEnv = append(proxyEnv, fmt.Sprintf("SOCKS5_PASSWD=%s", socks5_passwd)) + } + } + } env = append(env, []string{fmt.Sprintf("GIT_SSH_COMMAND=%s", strings.Join(args, " "))}...) + env = append(env, proxyEnv...) return sshPrivateKeyFile(file.Name()), env, nil } diff --git a/util/git/creds_test.go b/util/git/creds_test.go index 40cc39c10f1bc..23a705ed33574 100644 --- a/util/git/creds_test.go +++ b/util/git/creds_test.go @@ -205,7 +205,7 @@ func Test_SSHCreds_Environ(t *testing.T) { caFile := path.Join(tempDir, "caFile") err := os.WriteFile(caFile, []byte(""), os.FileMode(0600)) require.NoError(t, err) - creds := NewSSHCreds("sshPrivateKey", caFile, insecureIgnoreHostKey, &NoopCredsStore{}) + creds := NewSSHCreds("sshPrivateKey", caFile, insecureIgnoreHostKey, &NoopCredsStore{}, "") closer, env, err := creds.Environ() require.NoError(t, err) require.Len(t, env, 2) @@ -232,6 +232,76 @@ func Test_SSHCreds_Environ(t *testing.T) { } } +func Test_SSHCreds_Environ_WithProxy(t *testing.T) { + for _, insecureIgnoreHostKey := range []bool{false, true} { + tempDir := t.TempDir() + caFile := path.Join(tempDir, "caFile") + err := os.WriteFile(caFile, []byte(""), os.FileMode(0600)) + require.NoError(t, err) + creds := NewSSHCreds("sshPrivateKey", caFile, insecureIgnoreHostKey, &NoopCredsStore{}, "socks5://127.0.0.1:1080") + closer, env, err := creds.Environ() + require.NoError(t, err) + require.Len(t, env, 2) + + assert.Equal(t, fmt.Sprintf("GIT_SSL_CAINFO=%s/caFile", tempDir), env[0], "CAINFO env var must be set") + + assert.True(t, strings.HasPrefix(env[1], "GIT_SSH_COMMAND=")) + + if insecureIgnoreHostKey { + assert.Contains(t, env[1], "-o StrictHostKeyChecking=no") + assert.Contains(t, env[1], "-o UserKnownHostsFile=/dev/null") + } else { + assert.Contains(t, env[1], "-o StrictHostKeyChecking=yes") + hostsPath := cert.GetSSHKnownHostsDataPath() + assert.Contains(t, env[1], fmt.Sprintf("-o UserKnownHostsFile=%s", hostsPath)) + } + assert.Contains(t, env[1], "-o ProxyCommand='connect-proxy -S 127.0.0.1:1080 -5 %h %p'") + + envRegex := regexp.MustCompile("-i ([^ ]+)") + assert.Regexp(t, envRegex, env[1]) + privateKeyFile := envRegex.FindStringSubmatch(env[1])[1] + assert.FileExists(t, privateKeyFile) + io.Close(closer) + assert.NoFileExists(t, privateKeyFile) + } +} + +func Test_SSHCreds_Environ_WithProxyUserNamePassword(t *testing.T) { + for _, insecureIgnoreHostKey := range []bool{false, true} { + tempDir := t.TempDir() + caFile := path.Join(tempDir, "caFile") + err := os.WriteFile(caFile, []byte(""), os.FileMode(0600)) + require.NoError(t, err) + creds := NewSSHCreds("sshPrivateKey", caFile, insecureIgnoreHostKey, &NoopCredsStore{}, "socks5://user:password@127.0.0.1:1080") + closer, env, err := creds.Environ() + require.NoError(t, err) + require.Len(t, env, 4) + + assert.Equal(t, fmt.Sprintf("GIT_SSL_CAINFO=%s/caFile", tempDir), env[0], "CAINFO env var must be set") + + assert.True(t, strings.HasPrefix(env[1], "GIT_SSH_COMMAND=")) + assert.Equal(t, "SOCKS5_USER=user", env[2], "SOCKS5 user env var must be set") + assert.Equal(t, "SOCKS5_PASSWD=password", env[3], "SOCKS5 password env var must be set") + + if insecureIgnoreHostKey { + assert.Contains(t, env[1], "-o StrictHostKeyChecking=no") + assert.Contains(t, env[1], "-o UserKnownHostsFile=/dev/null") + } else { + assert.Contains(t, env[1], "-o StrictHostKeyChecking=yes") + hostsPath := cert.GetSSHKnownHostsDataPath() + assert.Contains(t, env[1], fmt.Sprintf("-o UserKnownHostsFile=%s", hostsPath)) + } + assert.Contains(t, env[1], "-o ProxyCommand='connect-proxy -S 127.0.0.1:1080 -5 %h %p'") + + envRegex := regexp.MustCompile("-i ([^ ]+)") + assert.Regexp(t, envRegex, env[1]) + privateKeyFile := envRegex.FindStringSubmatch(env[1])[1] + assert.FileExists(t, privateKeyFile) + io.Close(closer) + assert.NoFileExists(t, privateKeyFile) + } +} + const gcpServiceAccountKeyJSON = `{ "type": "service_account", "project_id": "my-google-project", diff --git a/util/git/workaround.go b/util/git/workaround.go index c364c093c853e..47636125cf349 100644 --- a/util/git/workaround.go +++ b/util/git/workaround.go @@ -1,6 +1,9 @@ package git import ( + "fmt" + neturl "net/url" + "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport" @@ -30,6 +33,23 @@ func newClient(url string, insecure bool, creds Creds, proxy string) (transport. if !IsHTTPSURL(url) && !IsHTTPURL(url) { // use the default client for protocols other than HTTP/HTTPS + ep.InsecureSkipTLS = insecure + if proxy != "" { + parsedProxyURL, err := neturl.Parse(proxy) + if err != nil { + return nil, nil, fmt.Errorf("failed to create client for url '%s', error parsing proxy url '%s': %w", url, proxy, err) + } + var proxyUsername, proxyPasswd string + if parsedProxyURL.User != nil { + proxyUsername = parsedProxyURL.User.Username() + proxyPasswd, _ = parsedProxyURL.User.Password() + } + ep.Proxy = transport.ProxyOptions{ + URL: fmt.Sprintf("%s://%s:%s", parsedProxyURL.Scheme, parsedProxyURL.Hostname(), parsedProxyURL.Port()), + Username: proxyUsername, + Password: proxyPasswd, + } + } c, err := client.NewClient(ep) if err != nil { return nil, nil, err From d6da9f2a15fba708d70531c5b3f2797663fb3c08 Mon Sep 17 00:00:00 2001 From: Mahesh Kasbe <60398112+maheshkasabe@users.noreply.github.com> Date: Wed, 10 Jan 2024 07:35:07 +0530 Subject: [PATCH 187/269] Added Openkruise workload integration health check scripts (#16238) Signed-off-by: Mahesh Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- .../apps.kruise.io/AdvancedCronJob/health.lua | 36 ++++++++++++ .../AdvancedCronJob/health_test.yaml | 17 ++++++ .../AdvancedCronJob/testdata/activeJobs.yaml | 30 ++++++++++ .../testdata/lastScheduleTime.yaml | 23 ++++++++ .../testdata/notScheduled.yaml | 22 ++++++++ .../AdvancedCronJob/testdata/suspended.yaml | 23 ++++++++ .../apps.kruise.io/BroadcastJob/health.lua | 32 +++++++++++ .../BroadcastJob/health_test.yaml | 17 ++++++ .../BroadcastJob/testdata/failed.yaml | 31 ++++++++++ .../BroadcastJob/testdata/running.yaml | 22 ++++++++ .../BroadcastJob/testdata/succeeded.yaml | 31 ++++++++++ .../BroadcastJob/testdata/suspended.yaml | 31 ++++++++++ .../apps.kruise.io/CloneSet/health.lua | 33 +++++++++++ .../apps.kruise.io/CloneSet/health_test.yaml | 21 +++++++ .../CloneSet/testdata/degraded.yaml | 35 ++++++++++++ .../CloneSet/testdata/healthy.yaml | 36 ++++++++++++ .../testdata/partition_suspended.yaml | 31 ++++++++++ .../CloneSet/testdata/suspended.yaml | 35 ++++++++++++ .../CloneSet/testdata/unknown.yaml | 5 ++ .../apps.kruise.io/DaemonSet/health.lua | 35 ++++++++++++ .../apps.kruise.io/DaemonSet/health_test.yaml | 21 +++++++ .../DaemonSet/testdata/degraded.yaml | 34 +++++++++++ .../DaemonSet/testdata/healthy.yaml | 34 +++++++++++ .../testdata/partition_suspended.yaml | 33 +++++++++++ .../DaemonSet/testdata/suspended.yaml | 33 +++++++++++ .../DaemonSet/testdata/unknown.yaml | 5 ++ .../apps.kruise.io/StatefulSet/health.lua | 35 ++++++++++++ .../StatefulSet/health_test.yaml | 21 +++++++ .../StatefulSet/testdata/degraded.yaml | 42 ++++++++++++++ .../StatefulSet/testdata/healthy.yaml | 41 ++++++++++++++ .../testdata/partition_suspended.yaml | 36 ++++++++++++ .../StatefulSet/testdata/suspended.yaml | 36 ++++++++++++ .../StatefulSet/testdata/unknown.yaml | 5 ++ .../rollouts.kruise.io/Rollout/health.lua | 31 ++++++++++ .../Rollout/health_test.yaml | 17 ++++++ .../Rollout/testdata/degraded.yaml | 50 +++++++++++++++++ .../Rollout/testdata/healthy.yaml | 56 +++++++++++++++++++ .../Rollout/testdata/progressing.yaml | 48 ++++++++++++++++ .../Rollout/testdata/suspended.yaml | 50 +++++++++++++++++ 39 files changed, 1174 insertions(+) create mode 100644 resource_customizations/apps.kruise.io/AdvancedCronJob/health.lua create mode 100644 resource_customizations/apps.kruise.io/AdvancedCronJob/health_test.yaml create mode 100644 resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/activeJobs.yaml create mode 100644 resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/lastScheduleTime.yaml create mode 100644 resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/notScheduled.yaml create mode 100644 resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/BroadcastJob/health.lua create mode 100644 resource_customizations/apps.kruise.io/BroadcastJob/health_test.yaml create mode 100644 resource_customizations/apps.kruise.io/BroadcastJob/testdata/failed.yaml create mode 100644 resource_customizations/apps.kruise.io/BroadcastJob/testdata/running.yaml create mode 100644 resource_customizations/apps.kruise.io/BroadcastJob/testdata/succeeded.yaml create mode 100644 resource_customizations/apps.kruise.io/BroadcastJob/testdata/suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/CloneSet/health.lua create mode 100644 resource_customizations/apps.kruise.io/CloneSet/health_test.yaml create mode 100644 resource_customizations/apps.kruise.io/CloneSet/testdata/degraded.yaml create mode 100644 resource_customizations/apps.kruise.io/CloneSet/testdata/healthy.yaml create mode 100644 resource_customizations/apps.kruise.io/CloneSet/testdata/partition_suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/CloneSet/testdata/suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/CloneSet/testdata/unknown.yaml create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/health.lua create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/testdata/degraded.yaml create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/testdata/healthy.yaml create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/testdata/partition_suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/testdata/suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/DaemonSet/testdata/unknown.yaml create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/health.lua create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/health_test.yaml create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/testdata/degraded.yaml create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/testdata/healthy.yaml create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/testdata/partition_suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/testdata/suspended.yaml create mode 100644 resource_customizations/apps.kruise.io/StatefulSet/testdata/unknown.yaml create mode 100644 resource_customizations/rollouts.kruise.io/Rollout/health.lua create mode 100644 resource_customizations/rollouts.kruise.io/Rollout/health_test.yaml create mode 100644 resource_customizations/rollouts.kruise.io/Rollout/testdata/degraded.yaml create mode 100644 resource_customizations/rollouts.kruise.io/Rollout/testdata/healthy.yaml create mode 100644 resource_customizations/rollouts.kruise.io/Rollout/testdata/progressing.yaml create mode 100644 resource_customizations/rollouts.kruise.io/Rollout/testdata/suspended.yaml diff --git a/resource_customizations/apps.kruise.io/AdvancedCronJob/health.lua b/resource_customizations/apps.kruise.io/AdvancedCronJob/health.lua new file mode 100644 index 0000000000000..1e68d862722e1 --- /dev/null +++ b/resource_customizations/apps.kruise.io/AdvancedCronJob/health.lua @@ -0,0 +1,36 @@ +hs = { status = "Progressing", message = "AdvancedCronJobs has active jobs" } +-- Extract lastScheduleTime and convert to time objects +lastScheduleTime = nil + +if obj.status.lastScheduleTime ~= nil then + local year, month, day, hour, min, sec = string.match(obj.status.lastScheduleTime, "(%d+)-(%d+)-(%d+)T(%d+):(%d+):(%d+)Z") + lastScheduleTime = os.time({year=year, month=month, day=day, hour=hour, min=min, sec=sec}) +end + + +if lastScheduleTime == nil and obj.spec.paused == true then + hs.status = "Suspended" + hs.message = "AdvancedCronJob is Paused" + return hs +end + +-- AdvancedCronJobs are progressing if they have any object in the "active" state +if obj.status.active ~= nil and #obj.status.active > 0 then + hs.status = "Progressing" + hs.message = "AdvancedCronJobs has active jobs" + return hs +end +-- AdvancedCronJobs are Degraded if they don't have lastScheduleTime +if lastScheduleTime == nil then + hs.status = "Degraded" + hs.message = "AdvancedCronJobs has not run successfully" + return hs +end +-- AdvancedCronJobs are healthy if they have lastScheduleTime +if lastScheduleTime ~= nil then + hs.status = "Healthy" + hs.message = "AdvancedCronJobs has run successfully" + return hs +end + +return hs diff --git a/resource_customizations/apps.kruise.io/AdvancedCronJob/health_test.yaml b/resource_customizations/apps.kruise.io/AdvancedCronJob/health_test.yaml new file mode 100644 index 0000000000000..939c701955abb --- /dev/null +++ b/resource_customizations/apps.kruise.io/AdvancedCronJob/health_test.yaml @@ -0,0 +1,17 @@ +tests: + - healthStatus: + status: Healthy + message: AdvancedCronJobs has run successfully + inputPath: testdata/lastScheduleTime.yaml + - healthStatus: + status: Degraded + message: AdvancedCronJobs has not run successfully + inputPath: testdata/notScheduled.yaml + - healthStatus: + status: Progressing + message: AdvancedCronJobs has active jobs + inputPath: testdata/activeJobs.yaml + - healthStatus: + status: Suspended + message: AdvancedCronJob is Paused + inputPath: testdata/suspended.yaml diff --git a/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/activeJobs.yaml b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/activeJobs.yaml new file mode 100644 index 0000000000000..5748143874d5e --- /dev/null +++ b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/activeJobs.yaml @@ -0,0 +1,30 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: AdvancedCronJob +metadata: + name: acj-test +spec: + schedule: "*/1 * * * *" + template: + broadcastJobTemplate: + spec: + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 30 + +status: + active: + - apiVersion: apps.kruise.io/v1alpha1 + kind: BroadcastJob + name: acj-test-1694882400 + namespace: default + resourceVersion: '4012' + uid: 2b08a429-a43b-4382-8e5d-3db0c72b5b13 + lastScheduleTime: '2023-09-16T16:40:00Z' + type: BroadcastJob diff --git a/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/lastScheduleTime.yaml b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/lastScheduleTime.yaml new file mode 100644 index 0000000000000..bf48bdba777dc --- /dev/null +++ b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/lastScheduleTime.yaml @@ -0,0 +1,23 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: AdvancedCronJob +metadata: + name: acj-test +spec: + schedule: "*/1 * * * *" + template: + broadcastJobTemplate: + spec: + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 30 + +status: + lastScheduleTime: "2023-09-16T16:29:00Z" + type: BroadcastJob diff --git a/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/notScheduled.yaml b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/notScheduled.yaml new file mode 100644 index 0000000000000..cc8a9dd436d80 --- /dev/null +++ b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/notScheduled.yaml @@ -0,0 +1,22 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: AdvancedCronJob +metadata: + name: acj-test +spec: + schedule: "*/1 * * * *" + template: + broadcastJobTemplate: + spec: + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 30 + +status: + lastScheduleTime: null diff --git a/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/suspended.yaml b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/suspended.yaml new file mode 100644 index 0000000000000..dc79f1b41218b --- /dev/null +++ b/resource_customizations/apps.kruise.io/AdvancedCronJob/testdata/suspended.yaml @@ -0,0 +1,23 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: AdvancedCronJob +metadata: + name: acj-test +spec: + schedule: "*/1 * * * *" + template: + broadcastJobTemplate: + spec: + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 30 + paused: true + +status: + type: BroadcastJob diff --git a/resource_customizations/apps.kruise.io/BroadcastJob/health.lua b/resource_customizations/apps.kruise.io/BroadcastJob/health.lua new file mode 100644 index 0000000000000..3b20ca8849975 --- /dev/null +++ b/resource_customizations/apps.kruise.io/BroadcastJob/health.lua @@ -0,0 +1,32 @@ +hs={ status= "Progressing", message= "BroadcastJob is still running" } + +if obj.status ~= nil then + +-- BroadcastJob are healthy if desired number and succeeded number is equal + if obj.status.desired == obj.status.succeeded and obj.status.phase == "completed" then + hs.status = "Healthy" + hs.message = "BroadcastJob is completed successfully" + return hs + end +-- BroadcastJob are progressing if active is not equal to 0 + if obj.status.active ~= 0 and obj.status.phase == "running" then + hs.status = "Progressing" + hs.message = "BroadcastJob is still running" + return hs + end +-- BroadcastJob are progressing if failed is not equal to 0 + if obj.status.failed ~= 0 and obj.status.phase == "failed" then + hs.status = "Degraded" + hs.message = "BroadcastJob failed" + return hs + end + + if obj.status.phase == "paused" and obj.spec.paused == true then + hs.status = "Suspended" + hs.message = "BroadcastJob is Paused" + return hs + end + +end + +return hs diff --git a/resource_customizations/apps.kruise.io/BroadcastJob/health_test.yaml b/resource_customizations/apps.kruise.io/BroadcastJob/health_test.yaml new file mode 100644 index 0000000000000..e3e16e22bfeef --- /dev/null +++ b/resource_customizations/apps.kruise.io/BroadcastJob/health_test.yaml @@ -0,0 +1,17 @@ +tests: + - healthStatus: + status: Healthy + message: "BroadcastJob is completed successfully" + inputPath: testdata/succeeded.yaml + - healthStatus: + status: Degraded + message: "BroadcastJob failed" + inputPath: testdata/failed.yaml + - healthStatus: + status: Progressing + message: "BroadcastJob is still running" + inputPath: testdata/running.yaml + - healthStatus: + status: Suspended + message: "BroadcastJob is Paused" + inputPath: testdata/suspended.yaml diff --git a/resource_customizations/apps.kruise.io/BroadcastJob/testdata/failed.yaml b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/failed.yaml new file mode 100644 index 0000000000000..88b85cae28189 --- /dev/null +++ b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/failed.yaml @@ -0,0 +1,31 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: BroadcastJob +metadata: + name: failed-job +spec: + template: + spec: + containers: + - name: guestbook + image: openkruise/guestbook:v3 + command: ["exit", "1"] # a dummy command to fail + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 60 # the job will be deleted after 60 seconds + +status: + active: 0 + completionTime: '2023-09-17T14:31:38Z' + conditions: + - lastProbeTime: '2023-09-17T14:31:38Z' + lastTransitionTime: '2023-09-17T14:31:38Z' + message: failure policy is FailurePolicyTypeFailFast and failed pod is found + reason: Failed + status: 'True' + type: Failed + desired: 1 + failed: 1 + phase: failed + startTime: '2023-09-17T14:31:32Z' + succeeded: 0 diff --git a/resource_customizations/apps.kruise.io/BroadcastJob/testdata/running.yaml b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/running.yaml new file mode 100644 index 0000000000000..f679fa3ee0d50 --- /dev/null +++ b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/running.yaml @@ -0,0 +1,22 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: BroadcastJob +metadata: + name: download-image +spec: + template: + spec: + containers: + - name: guestbook + image: openkruise/guestbook:v3 + command: ["echo", "started"] # a dummy command to do nothing + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 60 # the job will be deleted after 60 seconds +status: + active: 1 + desired: 1 + failed: 0 + phase: running + startTime: '2023-09-17T14:43:30Z' + succeeded: 0 diff --git a/resource_customizations/apps.kruise.io/BroadcastJob/testdata/succeeded.yaml b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/succeeded.yaml new file mode 100644 index 0000000000000..61746b20cd907 --- /dev/null +++ b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/succeeded.yaml @@ -0,0 +1,31 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: BroadcastJob +metadata: + name: download-image +spec: + template: + spec: + containers: + - name: guestbook + image: openkruise/guestbook:v3 + command: ["echo", "started"] # a dummy command to do nothing + restartPolicy: Never + completionPolicy: + type: Always + ttlSecondsAfterFinished: 60 # the job will be deleted after 60 seconds +status: + active: 0 + completionTime: '2023-09-17T14:35:14Z' + conditions: + - lastProbeTime: '2023-09-17T14:35:14Z' + lastTransitionTime: '2023-09-17T14:35:14Z' + message: Job completed, 1 pods succeeded, 0 pods failed + reason: Complete + status: 'True' + type: Complete + desired: 1 + failed: 0 + phase: completed + startTime: '2023-09-17T14:35:07Z' + succeeded: 1 + diff --git a/resource_customizations/apps.kruise.io/BroadcastJob/testdata/suspended.yaml b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/suspended.yaml new file mode 100644 index 0000000000000..60a9b587b8ec0 --- /dev/null +++ b/resource_customizations/apps.kruise.io/BroadcastJob/testdata/suspended.yaml @@ -0,0 +1,31 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: BroadcastJob +metadata: + name: download-image +spec: + template: + spec: + containers: + - name: guestbook + image: openkruise/guestbook:v3 + command: ["echo", "started"] # a dummy command to do nothing + restartPolicy: Never + paused: true + completionPolicy: + type: Always + ttlSecondsAfterFinished: 60 # the job will be deleted after 60 seconds +status: + active: 0 + completionTime: '2023-09-17T14:35:14Z' + conditions: + - lastProbeTime: '2023-09-17T14:35:14Z' + lastTransitionTime: '2023-09-17T14:35:14Z' + message: Job completed, 1 pods succeeded, 0 pods failed + reason: Complete + status: 'True' + type: Complete + desired: 1 + failed: 0 + phase: paused + startTime: '2023-09-17T14:35:07Z' + succeeded: 0 diff --git a/resource_customizations/apps.kruise.io/CloneSet/health.lua b/resource_customizations/apps.kruise.io/CloneSet/health.lua new file mode 100644 index 0000000000000..197ab7573dfe8 --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/health.lua @@ -0,0 +1,33 @@ +hs={ status = "Progressing", message = "Waiting for initialization" } + +if obj.status ~= nil then + + if obj.metadata.generation == obj.status.observedGeneration then + + if obj.spec.updateStrategy.paused == true or not obj.status.updatedAvailableReplicas then + hs.status = "Suspended" + hs.message = "Cloneset is paused" + return hs + elseif obj.spec.updateStrategy.partition ~= 0 and obj.metadata.generation > 1 then + if obj.status.updatedReplicas >= obj.status.expectedUpdatedReplicas then + hs.status = "Suspended" + hs.message = "Cloneset needs manual intervention" + return hs + end + + elseif obj.status.updatedAvailableReplicas == obj.status.replicas then + hs.status = "Healthy" + hs.message = "All Cloneset workloads are ready and updated" + return hs + + else + if obj.status.updatedAvailableReplicas ~= obj.status.replicas then + hs.status = "Degraded" + hs.message = "Some replicas are not ready or available" + return hs + end + end + end +end + +return hs diff --git a/resource_customizations/apps.kruise.io/CloneSet/health_test.yaml b/resource_customizations/apps.kruise.io/CloneSet/health_test.yaml new file mode 100644 index 0000000000000..e740eca850778 --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/health_test.yaml @@ -0,0 +1,21 @@ +tests: + - healthStatus: + status: Healthy + message: "All Cloneset workloads are ready and updated" + inputPath: testdata/healthy.yaml + - healthStatus: + status: Degraded + message: "Some replicas are not ready or available" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Progressing + message: "Waiting for initialization" + inputPath: testdata/unknown.yaml + - healthStatus: + status: Suspended + message: "Cloneset is paused" + inputpath: testdata/suspended.yaml + - healthStatus: + status: Suspended + message: "Cloneset needs manual intervention" + inputpath: testdata/partition_suspended.yaml diff --git a/resource_customizations/apps.kruise.io/CloneSet/testdata/degraded.yaml b/resource_customizations/apps.kruise.io/CloneSet/testdata/degraded.yaml new file mode 100644 index 0000000000000..36e9a0d537c85 --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/testdata/degraded.yaml @@ -0,0 +1,35 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: CloneSet +metadata: + name: cloneset-test + namespace: kruise + generation: 1 + labels: + app: sample +spec: + replicas: 2 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + paused: false + +status: + observedGeneration: 1 + replicas: 2 + updatedReadyReplicas: 1 + updatedAvailableReplicas: 1 + conditions: + - lastTransitionTime: "2021-09-21T22:35:31Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: FailedScale diff --git a/resource_customizations/apps.kruise.io/CloneSet/testdata/healthy.yaml b/resource_customizations/apps.kruise.io/CloneSet/testdata/healthy.yaml new file mode 100644 index 0000000000000..8a1935381e04e --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/testdata/healthy.yaml @@ -0,0 +1,36 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: CloneSet +metadata: + name: cloneset-test + namespace: kruise + generation: 1 + labels: + app: sample +spec: + replicas: 1 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + paused: false + + +status: + observedGeneration: 1 + replicas: 2 + updatedReadyReplicas: 2 + updatedAvailableReplicas: 2 + conditions: + - lastTransitionTime: "2021-09-21T22:35:31Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: FailedScale diff --git a/resource_customizations/apps.kruise.io/CloneSet/testdata/partition_suspended.yaml b/resource_customizations/apps.kruise.io/CloneSet/testdata/partition_suspended.yaml new file mode 100644 index 0000000000000..674c5226b3072 --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/testdata/partition_suspended.yaml @@ -0,0 +1,31 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: CloneSet +metadata: + name: cloneset-test + namespace: kruise + generation: 2 + labels: + app: sample +spec: + replicas: 5 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + partition: 3 + +status: + observedGeneration: 2 + replicas: 5 + expectedUpdatedReplicas: 2 + updatedReadyReplicas: 1 + updatedAvailableReplicas: 1 + updatedReplicas: 3 diff --git a/resource_customizations/apps.kruise.io/CloneSet/testdata/suspended.yaml b/resource_customizations/apps.kruise.io/CloneSet/testdata/suspended.yaml new file mode 100644 index 0000000000000..9edfaca6a5149 --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/testdata/suspended.yaml @@ -0,0 +1,35 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: CloneSet +metadata: + name: cloneset-test + namespace: kruise + generation: 2 + labels: + app: sample +spec: + replicas: 1 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + paused: true + +status: + observedGeneration: 2 + replicas: 2 + updatedReadyReplicas: 2 + updatedAvailableReplicas: 2 + conditions: + - lastTransitionTime: "2021-09-21T22:35:31Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: FailedScale diff --git a/resource_customizations/apps.kruise.io/CloneSet/testdata/unknown.yaml b/resource_customizations/apps.kruise.io/CloneSet/testdata/unknown.yaml new file mode 100644 index 0000000000000..c1ccdb22fc76e --- /dev/null +++ b/resource_customizations/apps.kruise.io/CloneSet/testdata/unknown.yaml @@ -0,0 +1,5 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: CloneSet +metadata: + name: cloneset-test + namespace: kruise diff --git a/resource_customizations/apps.kruise.io/DaemonSet/health.lua b/resource_customizations/apps.kruise.io/DaemonSet/health.lua new file mode 100644 index 0000000000000..7705bcc3325e5 --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/health.lua @@ -0,0 +1,35 @@ +hs={ status = "Progressing", message = "Waiting for initialization" } + +if obj.status ~= nil then + + if obj.metadata.generation == obj.status.observedGeneration then + + if obj.spec.updateStrategy.rollingUpdate.paused == true or not obj.status.updatedNumberScheduled then + hs.status = "Suspended" + hs.message = "Daemonset is paused" + return hs + elseif obj.spec.updateStrategy.rollingUpdate.partition ~= 0 and obj.metadata.generation > 1 then + if obj.status.updatedNumberScheduled > (obj.status.desiredNumberScheduled - obj.spec.updateStrategy.rollingUpdate.partition) then + hs.status = "Suspended" + hs.message = "Daemonset needs manual intervention" + return hs + end + + elseif (obj.status.updatedNumberScheduled == obj.status.desiredNumberScheduled) and (obj.status.numberAvailable == obj.status.desiredNumberScheduled) then + hs.status = "Healthy" + hs.message = "All Daemonset workloads are ready and updated" + return hs + + else + if (obj.status.updatedNumberScheduled == obj.status.desiredNumberScheduled) and (obj.status.numberUnavailable == obj.status.desiredNumberScheduled) then + hs.status = "Degraded" + hs.message = "Some pods are not ready or available" + return hs + end + end + + end + +end + +return hs diff --git a/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml b/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml new file mode 100644 index 0000000000000..0a8c8292672f3 --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/health_test.yaml @@ -0,0 +1,21 @@ +tests: + - healthStatus: + status: Healthy + message: "All Daemonset workloads are ready and updated" + inputPath: testdata/healthy.yaml + - healthStatus: + status: Degraded + message: "Some pods are not ready or available" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Progressing + message: "Waiting for initialization" + inputPath: testdata/unknown.yaml + - healthStatus: + status: Suspended + message: "Daemonset is paused" + inputPath: testdata/suspended.yaml + - healthStatus: + status: Suspended + message: "Daemonset needs manual intervention" + inputPath: testdata/partition_suspended.yaml diff --git a/resource_customizations/apps.kruise.io/DaemonSet/testdata/degraded.yaml b/resource_customizations/apps.kruise.io/DaemonSet/testdata/degraded.yaml new file mode 100644 index 0000000000000..ed8cbc0b4699e --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/testdata/degraded.yaml @@ -0,0 +1,34 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: DaemonSet +metadata: + name: daemonset-test + namespace: kruise + generation: 1 + labels: + app: sample +spec: + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + partition: 0 + paused: false + +status: + currentNumberScheduled: 1 + daemonSetHash: 5dffcdfcd7 + desiredNumberScheduled: 1 + numberUnavailable: 1 + numberMisscheduled: 0 + numberReady: 0 + observedGeneration: 1 + updatedNumberScheduled: 1 diff --git a/resource_customizations/apps.kruise.io/DaemonSet/testdata/healthy.yaml b/resource_customizations/apps.kruise.io/DaemonSet/testdata/healthy.yaml new file mode 100644 index 0000000000000..6224ebf35e164 --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/testdata/healthy.yaml @@ -0,0 +1,34 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: DaemonSet +metadata: + name: daemonset-test + namespace: kruise + generation: 1 + labels: + app: sample +spec: + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + partition: 0 + paused: false + +status: + currentNumberScheduled: 1 + daemonSetHash: 5dffcdfcd7 + desiredNumberScheduled: 1 + numberAvailable: 1 + numberMisscheduled: 0 + numberReady: 1 + observedGeneration: 1 + updatedNumberScheduled: 1 diff --git a/resource_customizations/apps.kruise.io/DaemonSet/testdata/partition_suspended.yaml b/resource_customizations/apps.kruise.io/DaemonSet/testdata/partition_suspended.yaml new file mode 100644 index 0000000000000..4c0819cdc8703 --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/testdata/partition_suspended.yaml @@ -0,0 +1,33 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: DaemonSet +metadata: + name: daemonset-test + namespace: kruise + generation: 6 + labels: + app: sample +spec: + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + partition: 4 + +status: + currentNumberScheduled: 1 + daemonSetHash: 5f8cdcdc65 + desiredNumberScheduled: 10 + numberAvailable: 10 + numberMisscheduled: 0 + numberReady: 10 + observedGeneration: 6 + updatedNumberScheduled: 7 diff --git a/resource_customizations/apps.kruise.io/DaemonSet/testdata/suspended.yaml b/resource_customizations/apps.kruise.io/DaemonSet/testdata/suspended.yaml new file mode 100644 index 0000000000000..fb705f5578176 --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/testdata/suspended.yaml @@ -0,0 +1,33 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: DaemonSet +metadata: + name: daemonset-test + namespace: kruise + generation: 1 + labels: + app: sample +spec: + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + paused: true + +status: + currentNumberScheduled: 1 + daemonSetHash: 5dffcdfcd7 + desiredNumberScheduled: 1 + numberAvailable: 1 + numberMisscheduled: 0 + numberReady: 1 + observedGeneration: 1 + updatedNumberScheduled: 1 diff --git a/resource_customizations/apps.kruise.io/DaemonSet/testdata/unknown.yaml b/resource_customizations/apps.kruise.io/DaemonSet/testdata/unknown.yaml new file mode 100644 index 0000000000000..aa5791c52bc6c --- /dev/null +++ b/resource_customizations/apps.kruise.io/DaemonSet/testdata/unknown.yaml @@ -0,0 +1,5 @@ +apiVersion: apps.kruise.io/v1alpha1 +kind: DaemonSet +metadata: + name: daemonset-test + namespace: kruise diff --git a/resource_customizations/apps.kruise.io/StatefulSet/health.lua b/resource_customizations/apps.kruise.io/StatefulSet/health.lua new file mode 100644 index 0000000000000..47340452db2dc --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/health.lua @@ -0,0 +1,35 @@ +hs={ status = "Progressing", message = "Waiting for initialization" } + +if obj.status ~= nil then + + if obj.metadata.generation == obj.status.observedGeneration then + + if obj.spec.updateStrategy.rollingUpdate.paused == true or not obj.status.updatedAvailableReplicas then + hs.status = "Suspended" + hs.message = "Statefulset is paused" + return hs + elseif obj.spec.updateStrategy.rollingUpdate.partition ~= 0 and obj.metadata.generation > 1 then + if obj.status.updatedReplicas > (obj.status.replicas - obj.spec.updateStrategy.rollingUpdate.partition) then + hs.status = "Suspended" + hs.message = "Statefulset needs manual intervention" + return hs + end + + elseif obj.status.updatedAvailableReplicas == obj.status.replicas then + hs.status = "Healthy" + hs.message = "All Statefulset workloads are ready and updated" + return hs + + else + if obj.status.updatedAvailableReplicas ~= obj.status.replicas then + hs.status = "Degraded" + hs.message = "Some replicas are not ready or available" + return hs + end + end + + end + +end + +return hs diff --git a/resource_customizations/apps.kruise.io/StatefulSet/health_test.yaml b/resource_customizations/apps.kruise.io/StatefulSet/health_test.yaml new file mode 100644 index 0000000000000..6672b9f46d4f4 --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/health_test.yaml @@ -0,0 +1,21 @@ +tests: + - healthStatus: + status: Healthy + message: "All Statefulset workloads are ready and updated" + inputPath: testdata/healthy.yaml + - healthStatus: + status: Degraded + message: "Some replicas are not ready or available" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Progressing + message: "Waiting for initialization" + inputPath: testdata/unknown.yaml + - healthStatus: + status: Suspended + message: "Statefulset is paused" + inputPath: testdata/suspended.yaml + - healthStatus: + status: Suspended + message: "Statefulset needs manual intervention" + inputPath: testdata/partition_suspended.yaml diff --git a/resource_customizations/apps.kruise.io/StatefulSet/testdata/degraded.yaml b/resource_customizations/apps.kruise.io/StatefulSet/testdata/degraded.yaml new file mode 100644 index 0000000000000..88e58914940fc --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/testdata/degraded.yaml @@ -0,0 +1,42 @@ +apiVersion: apps.kruise.io/v1beta1 +kind: StatefulSet +metadata: + name: statefulset-test + namespace: kruise + generation: 5 + labels: + app: sample +spec: + replicas: 2 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 0 + paused: false + partition: 0 + podUpdatePolicy: ReCreate + type: RollingUpdate + +status: + observedGeneration: 5 + replicas: 2 + updatedAvailableReplicas: 1 + updatedReadyReplicas: 1 + conditions: + - lastTransitionTime: "2021-09-21T22:35:31Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'True' + type: FailedCreatePod + diff --git a/resource_customizations/apps.kruise.io/StatefulSet/testdata/healthy.yaml b/resource_customizations/apps.kruise.io/StatefulSet/testdata/healthy.yaml new file mode 100644 index 0000000000000..793de25d3da1c --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/testdata/healthy.yaml @@ -0,0 +1,41 @@ +apiVersion: apps.kruise.io/v1beta1 +kind: StatefulSet +metadata: + name: statefulset-test + namespace: kruise + generation: 2 + labels: + app: sample +spec: + replicas: 2 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 0 + paused: false + partition: 0 + podUpdatePolicy: ReCreate + type: RollingUpdate + +status: + observedGeneration: 2 + replicas: 2 + updatedAvailableReplicas: 2 + updatedReadyReplicas: 2 + conditions: + - lastTransitionTime: "2021-09-21T22:35:31Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'False' + type: FailedCreatePod diff --git a/resource_customizations/apps.kruise.io/StatefulSet/testdata/partition_suspended.yaml b/resource_customizations/apps.kruise.io/StatefulSet/testdata/partition_suspended.yaml new file mode 100644 index 0000000000000..b09a7726bf5d7 --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/testdata/partition_suspended.yaml @@ -0,0 +1,36 @@ +apiVersion: apps.kruise.io/v1beta1 +kind: StatefulSet +metadata: + name: statefulset-test + namespace: kruise + generation: 3 + labels: + app: sample +spec: + replicas: 10 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - image: nginx:mainline + updateStrategy: + rollingUpdate: + partition: 4 + +status: + availableReplicas: 10 + currentReplicas: 4 + currentRevision: statefulset-test-d4d4fb5bd + labelSelector: app=sample + observedGeneration: 3 + readyReplicas: 10 + replicas: 10 + updateRevision: statefulset-test-56dfb978d4 + updatedAvailableReplicas: 7 + updatedReadyReplicas: 7 + updatedReplicas: 7 diff --git a/resource_customizations/apps.kruise.io/StatefulSet/testdata/suspended.yaml b/resource_customizations/apps.kruise.io/StatefulSet/testdata/suspended.yaml new file mode 100644 index 0000000000000..42dae9cf5e322 --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/testdata/suspended.yaml @@ -0,0 +1,36 @@ +apiVersion: apps.kruise.io/v1beta1 +kind: StatefulSet +metadata: + name: statefulset-test + namespace: kruise + generation: 2 + labels: + app: sample +spec: + replicas: 2 + selector: + matchLabels: + app: sample + template: + metadata: + labels: + app: sample + spec: + containers: + - name: nginx + image: nginx:alpine + updateStrategy: + rollingUpdate: + paused: true + +status: + observedGeneration: 2 + replicas: 2 + updatedAvailableReplicas: 2 + updatedReadyReplicas: 2 + conditions: + - lastTransitionTime: "2021-09-21T22:35:31Z" + message: Deployment has minimum availability. + reason: MinimumReplicasAvailable + status: 'False' + type: FailedCreatePod diff --git a/resource_customizations/apps.kruise.io/StatefulSet/testdata/unknown.yaml b/resource_customizations/apps.kruise.io/StatefulSet/testdata/unknown.yaml new file mode 100644 index 0000000000000..67d28de6dae64 --- /dev/null +++ b/resource_customizations/apps.kruise.io/StatefulSet/testdata/unknown.yaml @@ -0,0 +1,5 @@ +apiVersion: apps.kruise.io/v1beta1 +kind: StatefulSet +metadata: + name: statefulset-test + namespace: kruise diff --git a/resource_customizations/rollouts.kruise.io/Rollout/health.lua b/resource_customizations/rollouts.kruise.io/Rollout/health.lua new file mode 100644 index 0000000000000..5fd4ddb2a5486 --- /dev/null +++ b/resource_customizations/rollouts.kruise.io/Rollout/health.lua @@ -0,0 +1,31 @@ +hs={ status = "Progressing", message = "Rollout is still progressing" } + +if obj.metadata.generation == obj.status.observedGeneration then + + if obj.status.canaryStatus.currentStepState == "StepUpgrade" and obj.status.phase == "Progressing" then + hs.status = "Progressing" + hs.message = "Rollout is still progressing" + return hs + end + + if obj.status.canaryStatus.currentStepState == "StepPaused" and obj.status.phase == "Progressing" then + hs.status = "Suspended" + hs.message = "Rollout is Paused need manual intervention" + return hs + end + + if obj.status.canaryStatus.currentStepState == "Completed" and obj.status.phase == "Healthy" then + hs.status = "Healthy" + hs.message = "Rollout is Completed" + return hs + end + + if obj.status.canaryStatus.currentStepState == "StepPaused" and (obj.status.phase == "Terminating" or obj.status.phase == "Disabled") then + hs.status = "Degraded" + hs.message = "Rollout is Disabled or Terminating" + return hs + end + +end + +return hs diff --git a/resource_customizations/rollouts.kruise.io/Rollout/health_test.yaml b/resource_customizations/rollouts.kruise.io/Rollout/health_test.yaml new file mode 100644 index 0000000000000..c89ea3409ec77 --- /dev/null +++ b/resource_customizations/rollouts.kruise.io/Rollout/health_test.yaml @@ -0,0 +1,17 @@ +tests: + - healthStatus: + status: Healthy + message: "Rollout is Completed" + inputPath: testdata/healthy.yaml + - healthStatus: + status: Degraded + message: "Rollout is Disabled or Terminating" + inputPath: testdata/degraded.yaml + - healthStatus: + status: Progressing + message: "Rollout is still progressing" + inputPath: testdata/progressing.yaml + - healthStatus: + status: Suspended + message: "Rollout is Paused need manual intervention" + inputPath: testdata/suspended.yaml diff --git a/resource_customizations/rollouts.kruise.io/Rollout/testdata/degraded.yaml b/resource_customizations/rollouts.kruise.io/Rollout/testdata/degraded.yaml new file mode 100644 index 0000000000000..97c40f10a0c96 --- /dev/null +++ b/resource_customizations/rollouts.kruise.io/Rollout/testdata/degraded.yaml @@ -0,0 +1,50 @@ +apiVersion: rollouts.kruise.io/v1alpha1 +kind: Rollout +metadata: + name: rollouts-demo + namespace: default + annotations: + rollouts.kruise.io/rolling-style: partition + generation: 5 +spec: + objectRef: + workloadRef: + apiVersion: apps/v1 + kind: Deployment + name: workload-demo + strategy: + canary: + steps: + - replicas: 1 + pause: + duration: 0 + - replicas: 50% + pause: + duration: 0 + - replicas: 100% + +status: + canaryStatus: + canaryReadyReplicas: 1 + canaryReplicas: 1 + canaryRevision: 76fd76f75b + currentStepIndex: 1 + currentStepState: StepPaused + lastUpdateTime: '2023-09-23T11:44:39Z' + message: BatchRelease is at state Ready, rollout-id , step 1 + observedWorkloadGeneration: 7 + podTemplateHash: 76fd76f75b + rolloutHash: 77cxd69w47b7bwddwv2w7vxvb4xxdbwcx9x289vw69w788w4w6z4x8dd4vbz2zbw + stableRevision: 6bfdfb5bfb + conditions: + - lastTransitionTime: '2023-09-23T11:44:09Z' + lastUpdateTime: '2023-09-23T11:44:09Z' + message: Rollout is in Progressing + reason: InRolling + status: 'True' + type: Progressing + message: >- + Rollout is in step(1/3), and you need manually confirm to enter the next + step + observedGeneration: 5 + phase: Disabled diff --git a/resource_customizations/rollouts.kruise.io/Rollout/testdata/healthy.yaml b/resource_customizations/rollouts.kruise.io/Rollout/testdata/healthy.yaml new file mode 100644 index 0000000000000..77743b50007ad --- /dev/null +++ b/resource_customizations/rollouts.kruise.io/Rollout/testdata/healthy.yaml @@ -0,0 +1,56 @@ +apiVersion: rollouts.kruise.io/v1alpha1 +kind: Rollout +metadata: + name: rollouts-demo + namespace: default + annotations: + rollouts.kruise.io/rolling-style: partition + generation: 7 +spec: + objectRef: + workloadRef: + apiVersion: apps/v1 + kind: Deployment + name: workload-demo + strategy: + canary: + steps: + - replicas: 1 + pause: + duration: 0 + - replicas: 50% + pause: + duration: 0 + - replicas: 100% + +status: + canaryStatus: + canaryReadyReplicas: 10 + canaryReplicas: 10 + canaryRevision: 76fd76f75b + currentStepIndex: 3 + currentStepState: Completed + lastUpdateTime: '2023-09-23T11:48:58Z' + message: BatchRelease is at state Ready, rollout-id , step 3 + observedWorkloadGeneration: 22 + podTemplateHash: 76fd76f75b + rolloutHash: 77cxd69w47b7bwddwv2w7vxvb4xxdbwcx9x289vw69w788w4w6z4x8dd4vbz2zbw + stableRevision: 6bfdfb5bfb + conditions: + - lastTransitionTime: '2023-09-23T11:44:09Z' + lastUpdateTime: '2023-09-23T11:44:09Z' + message: Rollout progressing has been completed + reason: Completed + status: 'False' + type: Progressing + - lastTransitionTime: '2023-09-23T11:49:01Z' + lastUpdateTime: '2023-09-23T11:49:01Z' + message: '' + reason: '' + status: 'True' + type: Succeeded + message: Rollout progressing has been completed + observedGeneration: 7 + phase: Healthy + + diff --git a/resource_customizations/rollouts.kruise.io/Rollout/testdata/progressing.yaml b/resource_customizations/rollouts.kruise.io/Rollout/testdata/progressing.yaml new file mode 100644 index 0000000000000..f84d395867530 --- /dev/null +++ b/resource_customizations/rollouts.kruise.io/Rollout/testdata/progressing.yaml @@ -0,0 +1,48 @@ +apiVersion: rollouts.kruise.io/v1alpha1 +kind: Rollout +metadata: + name: rollouts-demo + namespace: default + annotations: + rollouts.kruise.io/rolling-style: partition + generation: 5 +spec: + objectRef: + workloadRef: + apiVersion: apps/v1 + kind: Deployment + name: workload-demo + strategy: + canary: + steps: + - replicas: 1 + pause: + duration: 0 + - replicas: 50% + pause: + duration: 0 + - replicas: 100% + +status: + canaryStatus: + canaryReadyReplicas: 0 + canaryReplicas: 1 + canaryRevision: 76fd76f75b + currentStepIndex: 1 + currentStepState: StepUpgrade + lastUpdateTime: '2023-09-23T11:44:12Z' + message: BatchRelease is at state Verifying, rollout-id , step 1 + observedWorkloadGeneration: 6 + podTemplateHash: 76fd76f75b + rolloutHash: 77cxd69w47b7bwddwv2w7vxvb4xxdbwcx9x289vw69w788w4w6z4x8dd4vbz2zbw + stableRevision: 6bfdfb5bfb + conditions: + - lastTransitionTime: '2023-09-23T11:44:09Z' + lastUpdateTime: '2023-09-23T11:44:09Z' + message: Rollout is in Progressing + reason: InRolling + status: 'True' + type: Progressing + message: Rollout is in step(1/3), and upgrade workload to new version + observedGeneration: 5 + phase: Progressing diff --git a/resource_customizations/rollouts.kruise.io/Rollout/testdata/suspended.yaml b/resource_customizations/rollouts.kruise.io/Rollout/testdata/suspended.yaml new file mode 100644 index 0000000000000..77a67129a248e --- /dev/null +++ b/resource_customizations/rollouts.kruise.io/Rollout/testdata/suspended.yaml @@ -0,0 +1,50 @@ +apiVersion: rollouts.kruise.io/v1alpha1 +kind: Rollout +metadata: + name: rollouts-demo + namespace: default + annotations: + rollouts.kruise.io/rolling-style: partition + generation: 5 +spec: + objectRef: + workloadRef: + apiVersion: apps/v1 + kind: Deployment + name: workload-demo + strategy: + canary: + steps: + - replicas: 1 + pause: + duration: 0 + - replicas: 50% + pause: + duration: 0 + - replicas: 100% + +status: + canaryStatus: + canaryReadyReplicas: 1 + canaryReplicas: 1 + canaryRevision: 76fd76f75b + currentStepIndex: 1 + currentStepState: StepPaused + lastUpdateTime: '2023-09-23T11:44:39Z' + message: BatchRelease is at state Ready, rollout-id , step 1 + observedWorkloadGeneration: 7 + podTemplateHash: 76fd76f75b + rolloutHash: 77cxd69w47b7bwddwv2w7vxvb4xxdbwcx9x289vw69w788w4w6z4x8dd4vbz2zbw + stableRevision: 6bfdfb5bfb + conditions: + - lastTransitionTime: '2023-09-23T11:44:09Z' + lastUpdateTime: '2023-09-23T11:44:09Z' + message: Rollout is in Progressing + reason: InRolling + status: 'True' + type: Progressing + message: >- + Rollout is in step(1/3), and you need manually confirm to enter the next + step + observedGeneration: 5 + phase: Progressing From 54f1572d46d8d611018f4854cf2f24a24a3ac088 Mon Sep 17 00:00:00 2001 From: Alexandre Gaudreault Date: Tue, 9 Jan 2024 21:09:34 -0500 Subject: [PATCH 188/269] fix: allow to run codegen outside GOPATH (#16511) * fix: allow to run codegen outside GOPATH Signed-off-by: Alexandre Gaudreault * clientgen Signed-off-by: Alexandre Gaudreault * openapigen Signed-off-by: Alexandre Gaudreault * remove ensure-gopath Signed-off-by: Alexandre Gaudreault --------- Signed-off-by: Alexandre Gaudreault --- Makefile | 29 ++++++++++++----------------- hack/generate-proto.sh | 41 +++++++++++++++++++++++++++-------------- hack/update-codegen.sh | 18 ++++++++++++++---- hack/update-openapi.sh | 20 +++++++++++++++----- 4 files changed, 68 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index 880622e7279a9..8bd9a49b6bb02 100644 --- a/Makefile +++ b/Makefile @@ -175,29 +175,21 @@ endif .PHONY: all all: cli image -# We have some legacy requirements for being checked out within $GOPATH. -# The ensure-gopath target can be used as dependency to ensure we are running -# within these boundaries. -.PHONY: ensure-gopath -ensure-gopath: -ifneq ("$(PWD)","$(LEGACY_PATH)") - @echo "Due to legacy requirements for codegen, repository needs to be checked out within \$$GOPATH" - @echo "Location of this repo should be '$(LEGACY_PATH)' but is '$(PWD)'" - @exit 1 -endif - .PHONY: gogen -gogen: ensure-gopath +gogen: export GO111MODULE=off go generate ./util/argo/... .PHONY: protogen -protogen: ensure-gopath mod-vendor-local +protogen: mod-vendor-local protogen-fast + +.PHONY: protogen-fast +protogen-fast: export GO111MODULE=off ./hack/generate-proto.sh .PHONY: openapigen -openapigen: ensure-gopath +openapigen: export GO111MODULE=off ./hack/update-openapi.sh @@ -212,19 +204,22 @@ notification-docs: .PHONY: clientgen -clientgen: ensure-gopath +clientgen: export GO111MODULE=off ./hack/update-codegen.sh .PHONY: clidocsgen -clidocsgen: ensure-gopath +clidocsgen: go run tools/cmd-docs/main.go .PHONY: codegen-local -codegen-local: ensure-gopath mod-vendor-local gogen protogen clientgen openapigen clidocsgen manifests-local notification-docs notification-catalog +codegen-local: mod-vendor-local gogen protogen clientgen openapigen clidocsgen manifests-local notification-docs notification-catalog rm -rf vendor/ +.PHONY: codegen-local-fast +codegen-local-fast: gogen protogen-fast clientgen openapigen clidocsgen manifests-local notification-docs notification-catalog + .PHONY: codegen codegen: test-tools-image $(call run-in-test-client,make codegen-local) diff --git a/hack/generate-proto.sh b/hack/generate-proto.sh index 8466993ebc544..fa5d7322c7f81 100755 --- a/hack/generate-proto.sh +++ b/hack/generate-proto.sh @@ -10,9 +10,13 @@ set -o nounset set -o pipefail # shellcheck disable=SC2128 -PROJECT_ROOT=$(cd "$(dirname "${BASH_SOURCE}")"/..; pwd) +PROJECT_ROOT=$( + cd "$(dirname "${BASH_SOURCE}")"/.. + pwd +) PATH="${PROJECT_ROOT}/dist:${PATH}" GOPATH=$(go env GOPATH) +GOPATH_PROJECT_ROOT="${GOPATH}/src/github.com/argoproj/argo-cd" # output tool versions go version @@ -41,6 +45,7 @@ APIMACHINERY_PKGS=( export GO111MODULE=on [ -e ./v2 ] || ln -s . v2 +[ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") # protoc_include is the include directory containing the .proto files distributed with protoc binary if [ -d /dist/protoc-include ]; then @@ -53,10 +58,17 @@ fi go-to-protobuf \ --go-header-file="${PROJECT_ROOT}"/hack/custom-boilerplate.go.txt \ - --packages="$(IFS=, ; echo "${PACKAGES[*]}")" \ - --apimachinery-packages="$(IFS=, ; echo "${APIMACHINERY_PKGS[*]}")" \ - --proto-import=./vendor \ - --proto-import="${protoc_include}" + --packages="$( + IFS=, + echo "${PACKAGES[*]}" + )" \ + --apimachinery-packages="$( + IFS=, + echo "${APIMACHINERY_PKGS[*]}" + )" \ + --proto-import="${PROJECT_ROOT}"/vendor \ + --proto-import="${protoc_include}" \ + --output-base="${GOPATH}/src/" # Either protoc-gen-go, protoc-gen-gofast, or protoc-gen-gogofast can be used to build # server/*/.pb.go from .proto files. golang/protobuf and gogo/protobuf can be used @@ -86,9 +98,11 @@ for i in ${PROTO_FILES}; do --${GOPROTOBINARY}_out=plugins=grpc:"$GOPATH"/src \ --grpc-gateway_out=logtostderr=true:"$GOPATH"/src \ --swagger_out=logtostderr=true:. \ - $i + "$i" done -[ -e ./v2 ] && rm -rf v2 + +[ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" +[ -L ./v2 ] && rm -rf v2 # collect_swagger gathers swagger files into a subdirectory collect_swagger() { @@ -97,7 +111,7 @@ collect_swagger() { PRIMARY_SWAGGER=$(mktemp) COMBINED_SWAGGER=$(mktemp) - cat < "${PRIMARY_SWAGGER}" + cat <"${PRIMARY_SWAGGER}" { "swagger": "2.0", "info": { @@ -111,7 +125,7 @@ EOF rm -f "${SWAGGER_OUT}" - find "${SWAGGER_ROOT}" -name '*.swagger.json' -exec swagger mixin --ignore-conflicts "${PRIMARY_SWAGGER}" '{}' \+ > "${COMBINED_SWAGGER}" + find "${SWAGGER_ROOT}" -name '*.swagger.json' -exec swagger mixin --ignore-conflicts "${PRIMARY_SWAGGER}" '{}' \+ >"${COMBINED_SWAGGER}" jq -r 'del(.definitions[].properties[]? | select(."$ref"!=null and .description!=null).description) | del(.definitions[].properties[]? | select(."$ref"!=null and .title!=null).title) | # The "array" and "map" fields have custom unmarshaling. Modify the swagger to reflect this. .definitions.v1alpha1ApplicationSourcePluginParameter.properties.array = {"description":"Array is the value of an array type parameter.","type":"array","items":{"type":"string"}} | @@ -120,10 +134,10 @@ EOF del(.definitions.v1alpha1OptionalMap) | # Output for int64 is incorrect, because it is based on proto definitions, where int64 is a string. In our JSON API, we expect int64 to be an integer. https://github.com/grpc-ecosystem/grpc-gateway/issues/219 (.definitions[]?.properties[]? | select(.type == "string" and .format == "int64")) |= (.type = "integer") - ' "${COMBINED_SWAGGER}" | \ - jq '.definitions.v1Time.type = "string" | .definitions.v1Time.format = "date-time" | del(.definitions.v1Time.properties)' | \ - jq '.definitions.v1alpha1ResourceNode.allOf = [{"$ref": "#/definitions/v1alpha1ResourceRef"}] | del(.definitions.v1alpha1ResourceNode.properties.resourceRef) ' \ - > "${SWAGGER_OUT}" + ' "${COMBINED_SWAGGER}" | + jq '.definitions.v1Time.type = "string" | .definitions.v1Time.format = "date-time" | del(.definitions.v1Time.properties)' | + jq '.definitions.v1alpha1ResourceNode.allOf = [{"$ref": "#/definitions/v1alpha1ResourceRef"}] | del(.definitions.v1alpha1ResourceNode.properties.resourceRef) ' \ + >"${SWAGGER_OUT}" /bin/rm "${PRIMARY_SWAGGER}" "${COMBINED_SWAGGER}" } @@ -139,4 +153,3 @@ clean_swagger server clean_swagger reposerver clean_swagger controller clean_swagger cmpserver - diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index abee0493ead86..9f6d15524d04d 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -19,21 +19,31 @@ set -o errexit set -o nounset set -o pipefail -PROJECT_ROOT=$(cd $(dirname ${BASH_SOURCE})/..; pwd) +PROJECT_ROOT=$( + cd $(dirname ${BASH_SOURCE})/.. + pwd +) PATH="${PROJECT_ROOT}/dist:${PATH}" +GOPATH=$(go env GOPATH) +GOPATH_PROJECT_ROOT="${GOPATH}/src/github.com/argoproj/argo-cd" TARGET_SCRIPT=/tmp/generate-groups.sh # codegen utilities are installed outside of generate-groups.sh so remove the `go install` step in the script. -sed -e '/go install/d' ${PROJECT_ROOT}/vendor/k8s.io/code-generator/generate-groups.sh > ${TARGET_SCRIPT} +sed -e '/go install/d' ${PROJECT_ROOT}/vendor/k8s.io/code-generator/generate-groups.sh >${TARGET_SCRIPT} # generate-groups.sh assumes codegen utilities are installed to GOBIN, but we just ensure the CLIs # are in the path and invoke them without assumption of their location sed -i.bak -e 's#${gobin}/##g' ${TARGET_SCRIPT} [ -e ./v2 ] || ln -s . v2 +[ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") + bash -x ${TARGET_SCRIPT} "deepcopy,client,informer,lister" \ github.com/argoproj/argo-cd/v2/pkg/client github.com/argoproj/argo-cd/v2/pkg/apis \ "application:v1alpha1" \ - --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt -[ -e ./v2 ] && rm -rf v2 \ No newline at end of file + --go-header-file "${PROJECT_ROOT}/hack/custom-boilerplate.go.txt" \ + --output-base "${GOPATH}/src" + +[ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" +[ -L ./v2 ] && rm -rf v2 diff --git a/hack/update-openapi.sh b/hack/update-openapi.sh index 2db84ed5f6242..0250ed45b93ac 100755 --- a/hack/update-openapi.sh +++ b/hack/update-openapi.sh @@ -5,20 +5,30 @@ set -o errexit set -o nounset set -o pipefail -PROJECT_ROOT=$(cd $(dirname "$0")/.. ; pwd) +PROJECT_ROOT=$( + cd $(dirname "$0")/.. + pwd +) PATH="${PROJECT_ROOT}/dist:${PATH}" +GOPATH=$(go env GOPATH) +GOPATH_PROJECT_ROOT="${GOPATH}/src/github.com/argoproj/argo-cd" + VERSION="v1alpha1" - + [ -e ./v2 ] || ln -s . v2 +[ -e "${GOPATH_PROJECT_ROOT}" ] || (mkdir -p "$(dirname "${GOPATH_PROJECT_ROOT}")" && ln -s "${PROJECT_ROOT}" "${GOPATH_PROJECT_ROOT}") + openapi-gen \ --go-header-file ${PROJECT_ROOT}/hack/custom-boilerplate.go.txt \ --input-dirs github.com/argoproj/argo-cd/v2/pkg/apis/application/${VERSION} \ --output-package github.com/argoproj/argo-cd/v2/pkg/apis/application/${VERSION} \ --report-filename pkg/apis/api-rules/violation_exceptions.list \ + --output-base "${GOPATH}/src" \ $@ -[ -e ./v2 ] && rm -rf v2 + +[ -L "${GOPATH_PROJECT_ROOT}" ] && rm -rf "${GOPATH_PROJECT_ROOT}" +[ -L ./v2 ] && rm -rf v2 export GO111MODULE=on -go build -o ./dist/gen-crd-spec ${PROJECT_ROOT}/hack/gen-crd-spec +go build -o ./dist/gen-crd-spec "${PROJECT_ROOT}/hack/gen-crd-spec" ./dist/gen-crd-spec - From cd4fc97c9dee7b69721bbb577a4f50ba897399c5 Mon Sep 17 00:00:00 2001 From: Akram Ben Aissi Date: Thu, 11 Jan 2024 07:32:11 +0100 Subject: [PATCH 189/269] fix: Use the cache for sharding (#15237) * feat(sharding): use a cache Signed-off-by: Alexandre Gaudreault * cluster cmd Signed-off-by: Alexandre Gaudreault * - Assign shard 0 to in-cluster cluster and nil check updates - Caching clusters while sharding: Fixing unit tests - Update generated docs - Debug e2e tests - Default the shardNumber to the number of replicas if it is calculated to a higher value - defered Unlock only when a lock is set - Disabling temporarly other versions of k3s to check if e2e passes - Do not fail if hostname format is not abc-n - Fix unit test and skip some e2e - Skip TestGitSubmoduleHTTPSSupport test - Remove breaking defer c.lock.Unlock() - Reverting testing all k3s version - Default sharding fix Signed-off-by: Akram Ben Aissi Signed-off-by: Akram Ben Aissi * fixes related to code review: renaming structure param, moving db initialisation Signed-off-by: Akram Ben Aissi * Code review Signed-off-by: Akram Ben Aissi * Set default shard to 0 Signed-off-by: Akram Ben Aissi * Set different default value for Sts and Deployment mode Signed-off-by: Akram Ben Aissi * Expose ClusterShardingCache Signed-off-by: Akram Ben Aissi * Removing use of argoDB.db for DistributionFunction Signed-off-by: Akram Ben Aissi * Update generated documentation Signed-off-by: Akram Ben Aissi * Fix comment about NoShardingDistributionFunction and NoShardingAlgorithm Signed-off-by: Akram Ben Aissi --------- Signed-off-by: Alexandre Gaudreault Signed-off-by: Akram Ben Aissi Co-authored-by: Alexandre Gaudreault --- Makefile | 2 +- Procfile | 2 +- .../commands/argocd_application_controller.go | 42 ++- cmd/argocd/commands/admin/cluster.go | 30 +- common/common.go | 2 +- controller/appcontroller.go | 29 +- controller/appcontroller_test.go | 9 +- controller/cache/cache.go | 21 +- controller/cache/cache_test.go | 50 ++-- controller/sharding/cache.go | 163 +++++++++++ controller/sharding/sharding.go | 64 ++-- controller/sharding/sharding_test.go | 275 +++++++++--------- controller/sharding/shuffle_test.go | 12 +- .../commands/argocd_admin_cluster.md | 2 +- .../commands/argocd_admin_cluster_shards.md | 3 +- .../commands/argocd_admin_cluster_stats.md | 1 + test/e2e/cluster_test.go | 2 +- 17 files changed, 468 insertions(+), 241 deletions(-) create mode 100644 controller/sharding/cache.go diff --git a/Makefile b/Makefile index 8bd9a49b6bb02..a4d6bd5264624 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,7 @@ ARGOCD_E2E_DEX_PORT?=5556 ARGOCD_E2E_YARN_HOST?=localhost ARGOCD_E2E_DISABLE_AUTH?= -ARGOCD_E2E_TEST_TIMEOUT?=60m +ARGOCD_E2E_TEST_TIMEOUT?=90m ARGOCD_IN_CI?=false ARGOCD_TEST_E2E?=true diff --git a/Procfile b/Procfile index 3bc2de5eca5e0..4862b0230062f 100644 --- a/Procfile +++ b/Procfile @@ -1,4 +1,4 @@ -controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'}" +controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "HOSTNAME=testappcontroller-1 FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} --server-side-diff-enabled=${ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF:-'false'}" api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --otlp-address=${ARGOCD_OTLP_ADDRESS} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/cmd gendexcfg -o `pwd`/dist/dex.yaml && (test -f dist/dex.yaml || { echo 'Failed to generate dex configuration'; exit 1; }) && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:$(grep "image: ghcr.io/dexidp/dex" manifests/base/dex/argocd-dex-server-deployment.yaml | cut -d':' -f3) dex serve /dex.yaml" redis: bash -c "if [ \"$ARGOCD_REDIS_LOCAL\" = 'true' ]; then redis-server --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; else docker run --rm --name argocd-redis -i -p ${ARGOCD_E2E_REDIS_PORT:-6379}:${ARGOCD_E2E_REDIS_PORT:-6379} docker.io/library/redis:$(grep "image: redis" manifests/base/redis/argocd-redis-deployment.yaml | cut -d':' -f3) --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi" diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index d5ef88a1702b6..135bcab3a7298 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -146,7 +146,7 @@ func NewCommand() *cobra.Command { appController.InvalidateProjectsCache() })) kubectl := kubeutil.NewKubectl() - clusterFilter := getClusterFilter(kubeClient, settingsMgr, shardingAlgorithm, enableDynamicClusterDistribution) + clusterSharding := getClusterSharding(kubeClient, settingsMgr, shardingAlgorithm, enableDynamicClusterDistribution) appController, err = controller.NewApplicationController( namespace, settingsMgr, @@ -164,7 +164,7 @@ func NewCommand() *cobra.Command { metricsAplicationLabels, kubectlParallelismLimit, persistResourceHealth, - clusterFilter, + clusterSharding, applicationNamespaces, &workqueueRateLimit, serverSideDiff, @@ -235,11 +235,10 @@ func NewCommand() *cobra.Command { return &command } -func getClusterFilter(kubeClient *kubernetes.Clientset, settingsMgr *settings.SettingsManager, shardingAlgorithm string, enableDynamicClusterDistribution bool) sharding.ClusterFilterFunction { - - var replicas int - shard := env.ParseNumFromEnv(common.EnvControllerShard, -1, -math.MaxInt32, math.MaxInt32) - +func getClusterSharding(kubeClient *kubernetes.Clientset, settingsMgr *settings.SettingsManager, shardingAlgorithm string, enableDynamicClusterDistribution bool) sharding.ClusterShardingCache { + var replicasCount int + // StatefulSet mode and Deployment mode uses different default values for shard number. + defaultShardNumberValue := 0 applicationControllerName := env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName) appControllerDeployment, err := kubeClient.AppsV1().Deployments(settingsMgr.GetNamespace()).Get(context.Background(), applicationControllerName, metav1.GetOptions{}) @@ -249,22 +248,21 @@ func getClusterFilter(kubeClient *kubernetes.Clientset, settingsMgr *settings.Se } if enableDynamicClusterDistribution && appControllerDeployment != nil && appControllerDeployment.Spec.Replicas != nil { - replicas = int(*appControllerDeployment.Spec.Replicas) + replicasCount = int(*appControllerDeployment.Spec.Replicas) + defaultShardNumberValue = -1 } else { - replicas = env.ParseNumFromEnv(common.EnvControllerReplicas, 0, 0, math.MaxInt32) + replicasCount = env.ParseNumFromEnv(common.EnvControllerReplicas, 0, 0, math.MaxInt32) } - - var clusterFilter func(cluster *v1alpha1.Cluster) bool - if replicas > 1 { + shardNumber := env.ParseNumFromEnv(common.EnvControllerShard, defaultShardNumberValue, -math.MaxInt32, math.MaxInt32) + if replicasCount > 1 { // check for shard mapping using configmap if application-controller is a deployment // else use existing logic to infer shard from pod name if application-controller is a statefulset if enableDynamicClusterDistribution && appControllerDeployment != nil { - var err error // retry 3 times if we find a conflict while updating shard mapping configMap. // If we still see conflicts after the retries, wait for next iteration of heartbeat process. for i := 0; i <= common.AppControllerHeartbeatUpdateRetryCount; i++ { - shard, err = sharding.GetOrUpdateShardFromConfigMap(kubeClient, settingsMgr, replicas, shard) + shardNumber, err = sharding.GetOrUpdateShardFromConfigMap(kubeClient, settingsMgr, replicasCount, shardNumber) if !kubeerrors.IsConflict(err) { err = fmt.Errorf("unable to get shard due to error updating the sharding config map: %s", err) break @@ -273,19 +271,19 @@ func getClusterFilter(kubeClient *kubernetes.Clientset, settingsMgr *settings.Se } errors.CheckError(err) } else { - if shard < 0 { + if shardNumber < 0 { var err error - shard, err = sharding.InferShard() + shardNumber, err = sharding.InferShard() errors.CheckError(err) } + if shardNumber > replicasCount { + log.Warnf("Calculated shard number %d is greated than the number of replicas count. Defaulting to 0", shardNumber) + shardNumber = 0 + } } - log.Infof("Processing clusters from shard %d", shard) - db := db.NewDB(settingsMgr.GetNamespace(), settingsMgr, kubeClient) - log.Infof("Using filter function: %s", shardingAlgorithm) - distributionFunction := sharding.GetDistributionFunction(db, shardingAlgorithm) - clusterFilter = sharding.GetClusterFilter(db, distributionFunction, shard) } else { log.Info("Processing all cluster shards") } - return clusterFilter + db := db.NewDB(settingsMgr.GetNamespace(), settingsMgr, kubeClient) + return sharding.NewClusterSharding(db, shardNumber, replicasCount, shardingAlgorithm) } diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 5d14717a15e7d..6f626dd8d0534 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -25,6 +25,7 @@ import ( "github.com/argoproj/argo-cd/v2/common" "github.com/argoproj/argo-cd/v2/controller/sharding" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/util/argo" @@ -78,7 +79,7 @@ type ClusterWithInfo struct { Namespaces []string } -func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string, redisCompressionStr string) ([]ClusterWithInfo, error) { +func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClient *versioned.Clientset, replicas int, shardingAlgorithm string, namespace string, portForwardRedis bool, cacheSrc func() (*appstatecache.Cache, error), shard int, redisName string, redisHaProxyName string, redisCompressionStr string) ([]ClusterWithInfo, error) { settingsMgr := settings.NewSettingsManager(ctx, kubeClient, namespace) argoDB := db.NewDB(namespace, settingsMgr, kubeClient) @@ -86,6 +87,10 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie if err != nil { return nil, err } + clusterShardingCache := sharding.NewClusterSharding(argoDB, shard, replicas, shardingAlgorithm) + clusterShardingCache.Init(clustersList) + clusterShards := clusterShardingCache.GetDistribution() + var cache *appstatecache.Cache if portForwardRedis { overrides := clientcmd.ConfigOverrides{} @@ -122,8 +127,15 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie apps[i] = app } clusters := make([]ClusterWithInfo, len(clustersList.Items)) + batchSize := 10 batchesCount := int(math.Ceil(float64(len(clusters)) / float64(batchSize))) + clusterSharding := &sharding.ClusterSharding{ + Shard: shard, + Replicas: replicas, + Shards: make(map[string]int), + Clusters: make(map[string]*v1alpha1.Cluster), + } for batchNum := 0; batchNum < batchesCount; batchNum++ { batchStart := batchSize * batchNum batchEnd := batchSize * (batchNum + 1) @@ -135,12 +147,12 @@ func loadClusters(ctx context.Context, kubeClient *kubernetes.Clientset, appClie clusterShard := 0 cluster := batch[i] if replicas > 0 { - distributionFunction := sharding.GetDistributionFunction(argoDB, common.DefaultShardingAlgorithm) + distributionFunction := sharding.GetDistributionFunction(clusterSharding.GetClusterAccessor(), common.DefaultShardingAlgorithm, replicas) distributionFunction(&cluster) + clusterShard := clusterShards[cluster.Server] cluster.Shard = pointer.Int64(int64(clusterShard)) log.Infof("Cluster with uid: %s will be processed by shard %d", cluster.ID, clusterShard) } - if shard != -1 && clusterShard != shard { return nil } @@ -176,6 +188,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm var ( shard int replicas int + shardingAlgorithm string clientConfig clientcmd.ClientConfig cacheSrc func() (*appstatecache.Cache, error) portForwardRedis bool @@ -183,7 +196,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm ) var command = cobra.Command{ Use: "shards", - Short: "Print information about each controller shard and portion of Kubernetes resources it is responsible for.", + Short: "Print information about each controller shard and the estimated portion of Kubernetes resources it is responsible for.", Run: func(cmd *cobra.Command, args []string) { ctx := cmd.Context() @@ -203,8 +216,7 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm if replicas == 0 { return } - - clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) + clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, shardingAlgorithm, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) errors.CheckError(err) if len(clusters) == 0 { return @@ -216,7 +228,9 @@ func NewClusterShardsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comm clientConfig = cli.AddKubectlFlagsToCmd(&command) command.Flags().IntVar(&shard, "shard", -1, "Cluster shard filter") command.Flags().IntVar(&replicas, "replicas", 0, "Application controller replicas count. Inferred from number of running controller pods if not specified") + command.Flags().StringVar(&shardingAlgorithm, "sharding-method", common.DefaultShardingAlgorithm, "Sharding method. Defaults: legacy. Supported sharding methods are : [legacy, round-robin] ") command.Flags().BoolVar(&portForwardRedis, "port-forward-redis", true, "Automatically port-forward ha proxy redis from current namespace?") + cacheSrc = appstatecache.AddCacheFlagsToCmd(&command) // parse all added flags so far to get the redis-compression flag that was added by AddCacheFlagsToCmd() above @@ -461,6 +475,7 @@ func NewClusterStatsCommand(clientOpts *argocdclient.ClientOptions) *cobra.Comma var ( shard int replicas int + shardingAlgorithm string clientConfig clientcmd.ClientConfig cacheSrc func() (*appstatecache.Cache, error) portForwardRedis bool @@ -494,7 +509,7 @@ argocd admin cluster stats target-cluster`, replicas, err = getControllerReplicas(ctx, kubeClient, namespace, clientOpts.AppControllerName) errors.CheckError(err) } - clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) + clusters, err := loadClusters(ctx, kubeClient, appClient, replicas, shardingAlgorithm, namespace, portForwardRedis, cacheSrc, shard, clientOpts.RedisName, clientOpts.RedisHaProxyName, redisCompressionStr) errors.CheckError(err) w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) @@ -508,6 +523,7 @@ argocd admin cluster stats target-cluster`, clientConfig = cli.AddKubectlFlagsToCmd(&command) command.Flags().IntVar(&shard, "shard", -1, "Cluster shard filter") command.Flags().IntVar(&replicas, "replicas", 0, "Application controller replicas count. Inferred from number of running controller pods if not specified") + command.Flags().StringVar(&shardingAlgorithm, "sharding-method", common.DefaultShardingAlgorithm, "Sharding method. Defaults: legacy. Supported sharding methods are : [legacy, round-robin] ") command.Flags().BoolVar(&portForwardRedis, "port-forward-redis", true, "Automatically port-forward ha proxy redis from current namespace?") cacheSrc = appstatecache.AddCacheFlagsToCmd(&command) diff --git a/common/common.go b/common/common.go index c5b9362f7f943..2f053d7a28198 100644 --- a/common/common.go +++ b/common/common.go @@ -115,9 +115,9 @@ const ( LegacyShardingAlgorithm = "legacy" // RoundRobinShardingAlgorithm is a flag value that can be opted for Sharding Algorithm it uses an equal distribution accross all shards RoundRobinShardingAlgorithm = "round-robin" - DefaultShardingAlgorithm = LegacyShardingAlgorithm // AppControllerHeartbeatUpdateRetryCount is the retry count for updating the Shard Mapping to the Shard Mapping ConfigMap used by Application Controller AppControllerHeartbeatUpdateRetryCount = 3 + DefaultShardingAlgorithm = LegacyShardingAlgorithm ) // Dex related constants diff --git a/controller/appcontroller.go b/controller/appcontroller.go index 0ded95de65d15..c3498f831566c 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -126,7 +126,7 @@ type ApplicationController struct { refreshRequestedAppsMutex *sync.Mutex metricsServer *metrics.MetricsServer kubectlSemaphore *semaphore.Weighted - clusterFilter func(cluster *appv1.Cluster) bool + clusterSharding sharding.ClusterShardingCache projByNameCache sync.Map applicationNamespaces []string } @@ -149,7 +149,7 @@ func NewApplicationController( metricsApplicationLabels []string, kubectlParallelismLimit int64, persistResourceHealth bool, - clusterFilter func(cluster *appv1.Cluster) bool, + clusterSharding sharding.ClusterShardingCache, applicationNamespaces []string, rateLimiterConfig *ratelimiter.AppControllerRateLimiterConfig, serverSideDiff bool, @@ -179,7 +179,7 @@ func NewApplicationController( auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController), settingsMgr: settingsMgr, selfHealTimeout: selfHealTimeout, - clusterFilter: clusterFilter, + clusterSharding: clusterSharding, projByNameCache: sync.Map{}, applicationNamespaces: applicationNamespaces, } @@ -260,7 +260,7 @@ func NewApplicationController( return nil, err } } - stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterFilter, argo.NewResourceTracking()) + stateCache := statecache.NewLiveStateCache(db, appInformer, ctrl.settingsMgr, kubectl, ctrl.metricsServer, ctrl.handleObjectUpdated, clusterSharding, argo.NewResourceTracking()) appStateManager := NewAppStateManager(db, applicationClientset, repoClientset, namespace, kubectl, ctrl.settingsMgr, stateCache, projInformer, ctrl.metricsServer, argoCache, ctrl.statusRefreshTimeout, argo.NewResourceTracking(), persistResourceHealth, repoErrorGracePeriod, serverSideDiff) ctrl.appInformer = appInformer ctrl.appLister = appLister @@ -772,6 +772,13 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int go ctrl.projInformer.Run(ctx.Done()) go ctrl.deploymentInformer.Informer().Run(ctx.Done()) + clusters, err := ctrl.db.ListClusters(ctx) + if err != nil { + log.Warnf("Cannot init sharding. Error while querying clusters list from database: %v", err) + } else { + ctrl.clusterSharding.Init(clusters) + } + errors.CheckError(ctrl.stateCache.Init()) if !cache.WaitForCacheSync(ctx.Done(), ctrl.appInformer.HasSynced, ctrl.projInformer.HasSynced) { @@ -1976,15 +1983,11 @@ func (ctrl *ApplicationController) canProcessApp(obj interface{}) bool { } } - if ctrl.clusterFilter != nil { - cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server) - if err != nil { - return ctrl.clusterFilter(nil) - } - return ctrl.clusterFilter(cluster) + cluster, err := ctrl.db.GetCluster(context.Background(), app.Spec.Destination.Server) + if err != nil { + return ctrl.clusterSharding.IsManagedCluster(nil) } - - return true + return ctrl.clusterSharding.IsManagedCluster(cluster) } func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.SharedIndexInformer, applisters.ApplicationLister) { @@ -2136,7 +2139,7 @@ func (ctrl *ApplicationController) projectErrorToCondition(err error, app *appv1 } func (ctrl *ApplicationController) RegisterClusterSecretUpdater(ctx context.Context) { - updater := NewClusterInfoUpdater(ctrl.stateCache, ctrl.db, ctrl.appLister.Applications(""), ctrl.cache, ctrl.clusterFilter, ctrl.getAppProj, ctrl.namespace) + updater := NewClusterInfoUpdater(ctrl.stateCache, ctrl.db, ctrl.appLister.Applications(""), ctrl.cache, ctrl.clusterSharding.IsManagedCluster, ctrl.getAppProj, ctrl.namespace) go updater.Run(ctx) } diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index bf3d8bb3a2e4c..131c1deab99b0 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -17,7 +17,9 @@ import ( "github.com/argoproj/argo-cd/v2/common" statecache "github.com/argoproj/argo-cd/v2/controller/cache" + "github.com/argoproj/argo-cd/v2/controller/sharding" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" "github.com/argoproj/gitops-engine/pkg/cache/mocks" synccommon "github.com/argoproj/gitops-engine/pkg/sync/common" "github.com/argoproj/gitops-engine/pkg/utils/kube" @@ -154,6 +156,10 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { nil, false, ) + db := &dbmocks.ArgoDB{} + db.On("GetApplicationControllerReplicas").Return(1) + // Setting a default sharding algorithm for the tests where we cannot set it. + ctrl.clusterSharding = sharding.NewClusterSharding(db, 0, 1, common.DefaultShardingAlgorithm) if err != nil { panic(err) } @@ -686,7 +692,6 @@ func TestFinalizeAppDeletion(t *testing.T) { ctrl := newFakeController(&fakeData{apps: []runtime.Object{app, &defaultProj}, managedLiveObjs: map[kube.ResourceKey]*unstructured.Unstructured{ kube.GetResourceKey(appObj): appObj, }}, nil) - patched := false fakeAppCs := ctrl.applicationClientset.(*appclientset.Clientset) defaultReactor := fakeAppCs.ReactionChain[0] @@ -1809,13 +1814,11 @@ func Test_canProcessApp(t *testing.T) { }) t.Run("with cluster filter, good namespace", func(t *testing.T) { app.Namespace = "good" - ctrl.clusterFilter = func(_ *v1alpha1.Cluster) bool { return true } canProcess := ctrl.canProcessApp(app) assert.True(t, canProcess) }) t.Run("with cluster filter, bad namespace", func(t *testing.T) { app.Namespace = "bad" - ctrl.clusterFilter = func(_ *v1alpha1.Cluster) bool { return true } canProcess := ctrl.canProcessApp(app) assert.False(t, canProcess) }) diff --git a/controller/cache/cache.go b/controller/cache/cache.go index 9eac161714089..e3b1d7b77f19d 100644 --- a/controller/cache/cache.go +++ b/controller/cache/cache.go @@ -29,6 +29,7 @@ import ( "k8s.io/client-go/tools/cache" "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/controller/sharding" "github.com/argoproj/argo-cd/v2/pkg/apis/application" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/util/argo" @@ -168,7 +169,7 @@ func NewLiveStateCache( kubectl kube.Kubectl, metricsServer *metrics.MetricsServer, onObjectUpdated ObjectUpdatedHandler, - clusterFilter func(cluster *appv1.Cluster) bool, + clusterSharding sharding.ClusterShardingCache, resourceTracking argo.ResourceTracking) LiveStateCache { return &liveStateCache{ @@ -179,7 +180,7 @@ func NewLiveStateCache( kubectl: kubectl, settingsMgr: settingsMgr, metricsServer: metricsServer, - clusterFilter: clusterFilter, + clusterSharding: clusterSharding, resourceTracking: resourceTracking, } } @@ -202,7 +203,7 @@ type liveStateCache struct { kubectl kube.Kubectl settingsMgr *settings.SettingsManager metricsServer *metrics.MetricsServer - clusterFilter func(cluster *appv1.Cluster) bool + clusterSharding sharding.ClusterShardingCache resourceTracking argo.ResourceTracking clusters map[string]clustercache.ClusterCache @@ -722,22 +723,24 @@ func (c *liveStateCache) Run(ctx context.Context) error { } func (c *liveStateCache) canHandleCluster(cluster *appv1.Cluster) bool { - if c.clusterFilter == nil { - return true - } - return c.clusterFilter(cluster) + return c.clusterSharding.IsManagedCluster(cluster) } func (c *liveStateCache) handleAddEvent(cluster *appv1.Cluster) { + c.clusterSharding.Add(cluster) if !c.canHandleCluster(cluster) { log.Infof("Ignoring cluster %s", cluster.Server) return } - c.lock.Lock() _, ok := c.clusters[cluster.Server] c.lock.Unlock() if !ok { + log.Debugf("Checking if cache %v / cluster %v has appInformer %v", c, cluster, c.appInformer) + if c.appInformer == nil { + log.Warn("Cannot get a cluster appInformer. Cache may not be started this time") + return + } if c.isClusterHasApps(c.appInformer.GetStore().List(), cluster) { go func() { // warm up cache for cluster with apps @@ -748,6 +751,7 @@ func (c *liveStateCache) handleAddEvent(cluster *appv1.Cluster) { } func (c *liveStateCache) handleModEvent(oldCluster *appv1.Cluster, newCluster *appv1.Cluster) { + c.clusterSharding.Update(newCluster) c.lock.Lock() cluster, ok := c.clusters[newCluster.Server] c.lock.Unlock() @@ -790,6 +794,7 @@ func (c *liveStateCache) handleModEvent(oldCluster *appv1.Cluster, newCluster *a func (c *liveStateCache) handleDeleteEvent(clusterServer string) { c.lock.RLock() + c.clusterSharding.Delete(clusterServer) cluster, ok := c.clusters[clusterServer] c.lock.RUnlock() if ok { diff --git a/controller/cache/cache_test.go b/controller/cache/cache_test.go index c94038a89b881..53a03ca81995e 100644 --- a/controller/cache/cache_test.go +++ b/controller/cache/cache_test.go @@ -21,7 +21,11 @@ import ( "github.com/stretchr/testify/mock" "k8s.io/client-go/kubernetes/fake" + "github.com/argoproj/argo-cd/v2/common" + "github.com/argoproj/argo-cd/v2/controller/metrics" + "github.com/argoproj/argo-cd/v2/controller/sharding" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + dbmocks "github.com/argoproj/argo-cd/v2/util/db/mocks" argosettings "github.com/argoproj/argo-cd/v2/util/settings" ) @@ -35,11 +39,13 @@ func TestHandleModEvent_HasChanges(t *testing.T) { clusterCache := &mocks.ClusterCache{} clusterCache.On("Invalidate", mock.Anything, mock.Anything).Return(nil).Once() clusterCache.On("EnsureSynced").Return(nil).Once() - + db := &dbmocks.ArgoDB{} + db.On("GetApplicationControllerReplicas").Return(1) clustersCache := liveStateCache{ clusters: map[string]cache.ClusterCache{ "https://mycluster": clusterCache, }, + clusterSharding: sharding.NewClusterSharding(db, 0, 1, common.DefaultShardingAlgorithm), } clustersCache.handleModEvent(&appv1.Cluster{ @@ -56,14 +62,22 @@ func TestHandleModEvent_ClusterExcluded(t *testing.T) { clusterCache := &mocks.ClusterCache{} clusterCache.On("Invalidate", mock.Anything, mock.Anything).Return(nil).Once() clusterCache.On("EnsureSynced").Return(nil).Once() - + db := &dbmocks.ArgoDB{} + db.On("GetApplicationControllerReplicas").Return(1) clustersCache := liveStateCache{ - clusters: map[string]cache.ClusterCache{ - "https://mycluster": clusterCache, - }, - clusterFilter: func(cluster *appv1.Cluster) bool { - return false + db: nil, + appInformer: nil, + onObjectUpdated: func(managedByApp map[string]bool, ref v1.ObjectReference) { }, + kubectl: nil, + settingsMgr: &argosettings.SettingsManager{}, + metricsServer: &metrics.MetricsServer{}, + // returns a shard that never process any cluster + clusterSharding: sharding.NewClusterSharding(db, 0, 1, common.DefaultShardingAlgorithm), + resourceTracking: nil, + clusters: map[string]cache.ClusterCache{"https://mycluster": clusterCache}, + cacheSettings: cacheSettings{}, + lock: sync.RWMutex{}, } clustersCache.handleModEvent(&appv1.Cluster{ @@ -75,18 +89,20 @@ func TestHandleModEvent_ClusterExcluded(t *testing.T) { Namespaces: []string{"default"}, }) - assert.Len(t, clustersCache.clusters, 0) + assert.Len(t, clustersCache.clusters, 1) } func TestHandleModEvent_NoChanges(t *testing.T) { clusterCache := &mocks.ClusterCache{} clusterCache.On("Invalidate", mock.Anything).Panic("should not invalidate") clusterCache.On("EnsureSynced").Return(nil).Panic("should not re-sync") - + db := &dbmocks.ArgoDB{} + db.On("GetApplicationControllerReplicas").Return(1) clustersCache := liveStateCache{ clusters: map[string]cache.ClusterCache{ "https://mycluster": clusterCache, }, + clusterSharding: sharding.NewClusterSharding(db, 0, 1, common.DefaultShardingAlgorithm), } clustersCache.handleModEvent(&appv1.Cluster{ @@ -99,11 +115,11 @@ func TestHandleModEvent_NoChanges(t *testing.T) { } func TestHandleAddEvent_ClusterExcluded(t *testing.T) { + db := &dbmocks.ArgoDB{} + db.On("GetApplicationControllerReplicas").Return(1) clustersCache := liveStateCache{ - clusters: map[string]cache.ClusterCache{}, - clusterFilter: func(cluster *appv1.Cluster) bool { - return false - }, + clusters: map[string]cache.ClusterCache{}, + clusterSharding: sharding.NewClusterSharding(db, 0, 2, common.DefaultShardingAlgorithm), } clustersCache.handleAddEvent(&appv1.Cluster{ Server: "https://mycluster", @@ -118,6 +134,8 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { Server: "https://mycluster", Config: appv1.ClusterConfig{Username: "bar"}, } + db := &dbmocks.ArgoDB{} + db.On("GetApplicationControllerReplicas").Return(1) fakeClient := fake.NewSimpleClientset() settingsMgr := argosettings.NewSettingsManager(context.TODO(), fakeClient, "argocd") liveStateCacheLock := sync.RWMutex{} @@ -126,10 +144,8 @@ func TestHandleDeleteEvent_CacheDeadlock(t *testing.T) { clusters: map[string]cache.ClusterCache{ testCluster.Server: gitopsEngineClusterCache, }, - clusterFilter: func(cluster *appv1.Cluster) bool { - return true - }, - settingsMgr: settingsMgr, + clusterSharding: sharding.NewClusterSharding(db, 0, 1, common.DefaultShardingAlgorithm), + settingsMgr: settingsMgr, // Set the lock here so we can reference it later // nolint We need to overwrite here to have access to the lock lock: liveStateCacheLock, diff --git a/controller/sharding/cache.go b/controller/sharding/cache.go new file mode 100644 index 0000000000000..d16574accdf8a --- /dev/null +++ b/controller/sharding/cache.go @@ -0,0 +1,163 @@ +package sharding + +import ( + "sync" + + "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + "github.com/argoproj/argo-cd/v2/util/db" + log "github.com/sirupsen/logrus" +) + +type ClusterShardingCache interface { + Init(clusters *v1alpha1.ClusterList) + Add(c *v1alpha1.Cluster) + Delete(clusterServer string) + Update(c *v1alpha1.Cluster) + IsManagedCluster(c *v1alpha1.Cluster) bool + GetDistribution() map[string]int +} + +type ClusterSharding struct { + Shard int + Replicas int + Shards map[string]int + Clusters map[string]*v1alpha1.Cluster + lock sync.RWMutex + getClusterShard DistributionFunction +} + +func NewClusterSharding(db db.ArgoDB, shard, replicas int, shardingAlgorithm string) ClusterShardingCache { + log.Debugf("Processing clusters from shard %d: Using filter function: %s", shard, shardingAlgorithm) + clusterSharding := &ClusterSharding{ + Shard: shard, + Replicas: replicas, + Shards: make(map[string]int), + Clusters: make(map[string]*v1alpha1.Cluster), + } + distributionFunction := NoShardingDistributionFunction() + if replicas > 1 { + log.Debugf("Processing clusters from shard %d: Using filter function: %s", shard, shardingAlgorithm) + distributionFunction = GetDistributionFunction(clusterSharding.GetClusterAccessor(), shardingAlgorithm, replicas) + } else { + log.Info("Processing all cluster shards") + } + clusterSharding.getClusterShard = distributionFunction + return clusterSharding +} + +// IsManagedCluster returns wheter or not the cluster should be processed by a given shard. +func (s *ClusterSharding) IsManagedCluster(c *v1alpha1.Cluster) bool { + s.lock.RLock() + defer s.lock.RUnlock() + if c == nil { // nil cluster (in-cluster) is always managed by current clusterShard + return true + } + clusterShard := 0 + if shard, ok := s.Shards[c.Server]; ok { + clusterShard = shard + } else { + log.Warnf("The cluster %s has no assigned shard.", c.Server) + } + log.Debugf("Checking if cluster %s with clusterShard %d should be processed by shard %d", c.Server, clusterShard, s.Shard) + return clusterShard == s.Shard +} + +func (sharding *ClusterSharding) Init(clusters *v1alpha1.ClusterList) { + sharding.lock.Lock() + defer sharding.lock.Unlock() + newClusters := make(map[string]*v1alpha1.Cluster, len(clusters.Items)) + for _, c := range clusters.Items { + newClusters[c.Server] = &c + } + sharding.Clusters = newClusters + sharding.updateDistribution() +} + +func (sharding *ClusterSharding) Add(c *v1alpha1.Cluster) { + sharding.lock.Lock() + defer sharding.lock.Unlock() + + old, ok := sharding.Clusters[c.Server] + sharding.Clusters[c.Server] = c + if !ok || hasShardingUpdates(old, c) { + sharding.updateDistribution() + } else { + log.Debugf("Skipping sharding distribution update. Cluster already added") + } +} + +func (sharding *ClusterSharding) Delete(clusterServer string) { + sharding.lock.Lock() + defer sharding.lock.Unlock() + if _, ok := sharding.Clusters[clusterServer]; ok { + delete(sharding.Clusters, clusterServer) + delete(sharding.Shards, clusterServer) + sharding.updateDistribution() + } +} + +func (sharding *ClusterSharding) Update(c *v1alpha1.Cluster) { + sharding.lock.Lock() + defer sharding.lock.Unlock() + + old, ok := sharding.Clusters[c.Server] + sharding.Clusters[c.Server] = c + if !ok || hasShardingUpdates(old, c) { + sharding.updateDistribution() + } else { + log.Debugf("Skipping sharding distribution update. No relevant changes") + } +} + +func (sharding *ClusterSharding) GetDistribution() map[string]int { + sharding.lock.RLock() + shards := sharding.Shards + sharding.lock.RUnlock() + + distribution := make(map[string]int, len(shards)) + for k, v := range shards { + distribution[k] = v + } + return distribution +} + +func (sharding *ClusterSharding) updateDistribution() { + log.Info("Updating cluster shards") + + for _, c := range sharding.Clusters { + shard := 0 + if c.Shard != nil { + requestedShard := int(*c.Shard) + if requestedShard < sharding.Replicas { + shard = requestedShard + } else { + log.Warnf("Specified cluster shard (%d) for cluster: %s is greater than the number of available shard (%d). Using shard 0.", requestedShard, c.Server, sharding.Replicas) + } + } else { + shard = sharding.getClusterShard(c) + } + var shard64 int64 = int64(shard) + c.Shard = &shard64 + sharding.Shards[c.Server] = shard + } +} + +// hasShardingUpdates returns true if the sharding distribution has been updated. +// nil checking is done for the corner case of the in-cluster cluster which may +// have a nil shard assigned +func hasShardingUpdates(old, new *v1alpha1.Cluster) bool { + if old == nil || new == nil || (old.Shard == nil && new.Shard == nil) { + return false + } + return old.Shard != new.Shard +} + +func (d *ClusterSharding) GetClusterAccessor() clusterAccessor { + return func() []*v1alpha1.Cluster { + clusters := make([]*v1alpha1.Cluster, 0, len(d.Clusters)) + for _, c := range d.Clusters { + clusters = append(clusters, c) + } + return clusters + } +} diff --git a/controller/sharding/sharding.go b/controller/sharding/sharding.go index 526896531dbca..2b86ed3f82bc6 100644 --- a/controller/sharding/sharding.go +++ b/controller/sharding/sharding.go @@ -40,6 +40,7 @@ const ShardControllerMappingKey = "shardControllerMapping" type DistributionFunction func(c *v1alpha1.Cluster) int type ClusterFilterFunction func(c *v1alpha1.Cluster) bool +type clusterAccessor func() []*v1alpha1.Cluster // shardApplicationControllerMapping stores the mapping of Shard Number to Application Controller in ConfigMap. // It also stores the heartbeat of last synced time of the application controller. @@ -53,8 +54,7 @@ type shardApplicationControllerMapping struct { // and returns wheter or not the cluster should be processed by a given shard. It calls the distributionFunction // to determine which shard will process the cluster, and if the given shard is equal to the calculated shard // the function will return true. -func GetClusterFilter(db db.ArgoDB, distributionFunction DistributionFunction, shard int) ClusterFilterFunction { - replicas := db.GetApplicationControllerReplicas() +func GetClusterFilter(db db.ArgoDB, distributionFunction DistributionFunction, replicas, shard int) ClusterFilterFunction { return func(c *v1alpha1.Cluster) bool { clusterShard := 0 if c != nil && c.Shard != nil { @@ -73,14 +73,14 @@ func GetClusterFilter(db db.ArgoDB, distributionFunction DistributionFunction, s // GetDistributionFunction returns which DistributionFunction should be used based on the passed algorithm and // the current datas. -func GetDistributionFunction(db db.ArgoDB, shardingAlgorithm string) DistributionFunction { - log.Infof("Using filter function: %s", shardingAlgorithm) - distributionFunction := LegacyDistributionFunction(db) +func GetDistributionFunction(clusters clusterAccessor, shardingAlgorithm string, replicasCount int) DistributionFunction { + log.Debugf("Using filter function: %s", shardingAlgorithm) + distributionFunction := LegacyDistributionFunction(replicasCount) switch shardingAlgorithm { case common.RoundRobinShardingAlgorithm: - distributionFunction = RoundRobinDistributionFunction(db) + distributionFunction = RoundRobinDistributionFunction(clusters, replicasCount) case common.LegacyShardingAlgorithm: - distributionFunction = LegacyDistributionFunction(db) + distributionFunction = LegacyDistributionFunction(replicasCount) default: log.Warnf("distribution type %s is not supported, defaulting to %s", shardingAlgorithm, common.DefaultShardingAlgorithm) } @@ -92,15 +92,21 @@ func GetDistributionFunction(db db.ArgoDB, shardingAlgorithm string) Distributio // is lightweight and can be distributed easily, however, it does not ensure an homogenous distribution as // some shards may get assigned more clusters than others. It is the legacy function distribution that is // kept for compatibility reasons -func LegacyDistributionFunction(db db.ArgoDB) DistributionFunction { - replicas := db.GetApplicationControllerReplicas() +func LegacyDistributionFunction(replicas int) DistributionFunction { return func(c *v1alpha1.Cluster) int { if replicas == 0 { + log.Debugf("Replicas count is : %d, returning -1", replicas) return -1 } if c == nil { + log.Debug("In-cluster: returning 0") return 0 } + // if Shard is manually set and the assigned value is lower than the number of replicas, + // then its value is returned otherwise it is the default calculated value + if c.Shard != nil && int(*c.Shard) < replicas { + return int(*c.Shard) + } id := c.ID log.Debugf("Calculating cluster shard for cluster id: %s", id) if id == "" { @@ -121,14 +127,19 @@ func LegacyDistributionFunction(db db.ArgoDB) DistributionFunction { // This function ensures an homogenous distribution: each shards got assigned the same number of // clusters +/-1 , but with the drawback of a reshuffling of clusters accross shards in case of some changes // in the cluster list -func RoundRobinDistributionFunction(db db.ArgoDB) DistributionFunction { - replicas := db.GetApplicationControllerReplicas() + +func RoundRobinDistributionFunction(clusters clusterAccessor, replicas int) DistributionFunction { return func(c *v1alpha1.Cluster) int { if replicas > 0 { if c == nil { // in-cluster does not necessarly have a secret assigned. So we are receiving a nil cluster here. return 0 + } + // if Shard is manually set and the assigned value is lower than the number of replicas, + // then its value is returned otherwise it is the default calculated value + if c.Shard != nil && int(*c.Shard) < replicas { + return int(*c.Shard) } else { - clusterIndexdByClusterIdMap := createClusterIndexByClusterIdMap(db) + clusterIndexdByClusterIdMap := createClusterIndexByClusterIdMap(clusters) clusterIndex, ok := clusterIndexdByClusterIdMap[c.ID] if !ok { log.Warnf("Cluster with id=%s not found in cluster map.", c.ID) @@ -144,6 +155,12 @@ func RoundRobinDistributionFunction(db db.ArgoDB) DistributionFunction { } } +// NoShardingDistributionFunction returns a DistributionFunction that will process all cluster by shard 0 +// the function is created for API compatibility purposes and is not supposed to be activated. +func NoShardingDistributionFunction() DistributionFunction { + return func(c *v1alpha1.Cluster) int { return 0 } +} + // InferShard extracts the shard index based on its hostname. func InferShard() (int, error) { hostname, err := osHostnameFunction() @@ -152,33 +169,29 @@ func InferShard() (int, error) { } parts := strings.Split(hostname, "-") if len(parts) == 0 { - return 0, fmt.Errorf("hostname should ends with shard number separated by '-' but got: %s", hostname) + log.Warnf("hostname should end with shard number separated by '-' but got: %s", hostname) + return 0, nil } shard, err := strconv.Atoi(parts[len(parts)-1]) if err != nil { - return 0, fmt.Errorf("hostname should ends with shard number separated by '-' but got: %s", hostname) + log.Warnf("hostname should end with shard number separated by '-' but got: %s", hostname) + return 0, nil } return int(shard), nil } -func getSortedClustersList(db db.ArgoDB) []v1alpha1.Cluster { - ctx := context.Background() - clustersList, dbErr := db.ListClusters(ctx) - if dbErr != nil { - log.Warnf("Error while querying clusters list from database: %v", dbErr) - return []v1alpha1.Cluster{} - } - clusters := clustersList.Items +func getSortedClustersList(getCluster clusterAccessor) []*v1alpha1.Cluster { + clusters := getCluster() sort.Slice(clusters, func(i, j int) bool { return clusters[i].ID < clusters[j].ID }) return clusters } -func createClusterIndexByClusterIdMap(db db.ArgoDB) map[string]int { - clusters := getSortedClustersList(db) +func createClusterIndexByClusterIdMap(getCluster clusterAccessor) map[string]int { + clusters := getSortedClustersList(getCluster) log.Debugf("ClustersList has %d items", len(clusters)) - clusterById := make(map[string]v1alpha1.Cluster) + clusterById := make(map[string]*v1alpha1.Cluster) clusterIndexedByClusterId := make(map[string]int) for i, cluster := range clusters { log.Debugf("Adding cluster with id=%s and name=%s to cluster's map", cluster.ID, cluster.Name) @@ -194,7 +207,6 @@ func createClusterIndexByClusterIdMap(db db.ArgoDB) map[string]int { // If the shard value passed to this function is -1, that is, the shard was not set as an environment variable, // we default the shard number to 0 for computing the default config map. func GetOrUpdateShardFromConfigMap(kubeClient *kubernetes.Clientset, settingsMgr *settings.SettingsManager, replicas, shard int) (int, error) { - hostname, err := osHostnameFunction() if err != nil { return -1, err diff --git a/controller/sharding/sharding_test.go b/controller/sharding/sharding_test.go index a8a25e11c4978..0992f7a9dfd7f 100644 --- a/controller/sharding/sharding_test.go +++ b/controller/sharding/sharding_test.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "os" + "strconv" "testing" "time" @@ -19,18 +20,20 @@ import ( func TestGetShardByID_NotEmptyID(t *testing.T) { db := &dbmocks.ArgoDB{} - db.On("GetApplicationControllerReplicas").Return(1) - assert.Equal(t, 0, LegacyDistributionFunction(db)(&v1alpha1.Cluster{ID: "1"})) - assert.Equal(t, 0, LegacyDistributionFunction(db)(&v1alpha1.Cluster{ID: "2"})) - assert.Equal(t, 0, LegacyDistributionFunction(db)(&v1alpha1.Cluster{ID: "3"})) - assert.Equal(t, 0, LegacyDistributionFunction(db)(&v1alpha1.Cluster{ID: "4"})) + replicasCount := 1 + db.On("GetApplicationControllerReplicas").Return(replicasCount) + assert.Equal(t, 0, LegacyDistributionFunction(replicasCount)(&v1alpha1.Cluster{ID: "1"})) + assert.Equal(t, 0, LegacyDistributionFunction(replicasCount)(&v1alpha1.Cluster{ID: "2"})) + assert.Equal(t, 0, LegacyDistributionFunction(replicasCount)(&v1alpha1.Cluster{ID: "3"})) + assert.Equal(t, 0, LegacyDistributionFunction(replicasCount)(&v1alpha1.Cluster{ID: "4"})) } func TestGetShardByID_EmptyID(t *testing.T) { db := &dbmocks.ArgoDB{} - db.On("GetApplicationControllerReplicas").Return(1) + replicasCount := 1 + db.On("GetApplicationControllerReplicas").Return(replicasCount) distributionFunction := LegacyDistributionFunction - shard := distributionFunction(db)(&v1alpha1.Cluster{}) + shard := distributionFunction(replicasCount)(&v1alpha1.Cluster{}) assert.Equal(t, 0, shard) } @@ -38,7 +41,7 @@ func TestGetShardByID_NoReplicas(t *testing.T) { db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(0) distributionFunction := LegacyDistributionFunction - shard := distributionFunction(db)(&v1alpha1.Cluster{}) + shard := distributionFunction(0)(&v1alpha1.Cluster{}) assert.Equal(t, -1, shard) } @@ -46,16 +49,16 @@ func TestGetShardByID_NoReplicasUsingHashDistributionFunction(t *testing.T) { db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(0) distributionFunction := LegacyDistributionFunction - shard := distributionFunction(db)(&v1alpha1.Cluster{}) + shard := distributionFunction(0)(&v1alpha1.Cluster{}) assert.Equal(t, -1, shard) } func TestGetShardByID_NoReplicasUsingHashDistributionFunctionWithClusters(t *testing.T) { - db, cluster1, cluster2, cluster3, cluster4, cluster5 := createTestClusters() + clusters, db, cluster1, cluster2, cluster3, cluster4, cluster5 := createTestClusters() // Test with replicas set to 0 db.On("GetApplicationControllerReplicas").Return(0) t.Setenv(common.EnvControllerShardingAlgorithm, common.RoundRobinShardingAlgorithm) - distributionFunction := RoundRobinDistributionFunction(db) + distributionFunction := RoundRobinDistributionFunction(clusters, 0) assert.Equal(t, -1, distributionFunction(nil)) assert.Equal(t, -1, distributionFunction(&cluster1)) assert.Equal(t, -1, distributionFunction(&cluster2)) @@ -65,137 +68,112 @@ func TestGetShardByID_NoReplicasUsingHashDistributionFunctionWithClusters(t *tes } func TestGetClusterFilterDefault(t *testing.T) { - shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) + //shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) + clusterAccessor, _, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() os.Unsetenv(common.EnvControllerShardingAlgorithm) - db := &dbmocks.ArgoDB{} - db.On("GetApplicationControllerReplicas").Return(2) - filter := GetClusterFilter(db, GetDistributionFunction(db, common.DefaultShardingAlgorithm), shardIndex) - assert.False(t, filter(&v1alpha1.Cluster{ID: "1"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "2"})) - assert.False(t, filter(&v1alpha1.Cluster{ID: "3"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "4"})) + replicasCount := 2 + distributionFunction := RoundRobinDistributionFunction(clusterAccessor, replicasCount) + assert.Equal(t, 0, distributionFunction(nil)) + assert.Equal(t, 0, distributionFunction(&cluster1)) + assert.Equal(t, 1, distributionFunction(&cluster2)) + assert.Equal(t, 0, distributionFunction(&cluster3)) + assert.Equal(t, 1, distributionFunction(&cluster4)) } func TestGetClusterFilterLegacy(t *testing.T) { - shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) - db := &dbmocks.ArgoDB{} - db.On("GetApplicationControllerReplicas").Return(2) + //shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) + clusterAccessor, db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() + replicasCount := 2 + db.On("GetApplicationControllerReplicas").Return(replicasCount) t.Setenv(common.EnvControllerShardingAlgorithm, common.LegacyShardingAlgorithm) - filter := GetClusterFilter(db, GetDistributionFunction(db, common.LegacyShardingAlgorithm), shardIndex) - assert.False(t, filter(&v1alpha1.Cluster{ID: "1"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "2"})) - assert.False(t, filter(&v1alpha1.Cluster{ID: "3"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "4"})) + distributionFunction := RoundRobinDistributionFunction(clusterAccessor, replicasCount) + assert.Equal(t, 0, distributionFunction(nil)) + assert.Equal(t, 0, distributionFunction(&cluster1)) + assert.Equal(t, 1, distributionFunction(&cluster2)) + assert.Equal(t, 0, distributionFunction(&cluster3)) + assert.Equal(t, 1, distributionFunction(&cluster4)) } func TestGetClusterFilterUnknown(t *testing.T) { - shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) - db := &dbmocks.ArgoDB{} - db.On("GetApplicationControllerReplicas").Return(2) + clusterAccessor, db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() + // Test with replicas set to 0 + t.Setenv(common.EnvControllerReplicas, "2") + os.Unsetenv(common.EnvControllerShardingAlgorithm) t.Setenv(common.EnvControllerShardingAlgorithm, "unknown") - filter := GetClusterFilter(db, GetDistributionFunction(db, "unknown"), shardIndex) - assert.False(t, filter(&v1alpha1.Cluster{ID: "1"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "2"})) - assert.False(t, filter(&v1alpha1.Cluster{ID: "3"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "4"})) + replicasCount := 2 + db.On("GetApplicationControllerReplicas").Return(replicasCount) + distributionFunction := GetDistributionFunction(clusterAccessor, "unknown", replicasCount) + assert.Equal(t, 0, distributionFunction(nil)) + assert.Equal(t, 0, distributionFunction(&cluster1)) + assert.Equal(t, 1, distributionFunction(&cluster2)) + assert.Equal(t, 0, distributionFunction(&cluster3)) + assert.Equal(t, 1, distributionFunction(&cluster4)) } func TestLegacyGetClusterFilterWithFixedShard(t *testing.T) { - shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) - db := &dbmocks.ArgoDB{} - db.On("GetApplicationControllerReplicas").Return(2) - filter := GetClusterFilter(db, GetDistributionFunction(db, common.DefaultShardingAlgorithm), shardIndex) - assert.False(t, filter(nil)) - assert.False(t, filter(&v1alpha1.Cluster{ID: "1"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "2"})) - assert.False(t, filter(&v1alpha1.Cluster{ID: "3"})) - assert.True(t, filter(&v1alpha1.Cluster{ID: "4"})) + //shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) + t.Setenv(common.EnvControllerReplicas, "5") + clusterAccessor, db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() + replicasCount := 5 + db.On("GetApplicationControllerReplicas").Return(replicasCount) + filter := GetDistributionFunction(clusterAccessor, common.DefaultShardingAlgorithm, replicasCount) + assert.Equal(t, 0, filter(nil)) + assert.Equal(t, 4, filter(&cluster1)) + assert.Equal(t, 1, filter(&cluster2)) + assert.Equal(t, 2, filter(&cluster3)) + assert.Equal(t, 2, filter(&cluster4)) var fixedShard int64 = 4 - filter = GetClusterFilter(db, GetDistributionFunction(db, common.DefaultShardingAlgorithm), int(fixedShard)) - assert.False(t, filter(&v1alpha1.Cluster{ID: "4", Shard: &fixedShard})) + cluster5 := &v1alpha1.Cluster{ID: "5", Shard: &fixedShard} + clusterAccessor = getClusterAccessor([]v1alpha1.Cluster{cluster1, cluster2, cluster2, cluster4, *cluster5}) + filter = GetDistributionFunction(clusterAccessor, common.DefaultShardingAlgorithm, replicasCount) + assert.Equal(t, int(fixedShard), filter(cluster5)) fixedShard = 1 - filter = GetClusterFilter(db, GetDistributionFunction(db, common.DefaultShardingAlgorithm), int(fixedShard)) - assert.True(t, filter(&v1alpha1.Cluster{Name: "cluster4", ID: "4", Shard: &fixedShard})) + cluster5.Shard = &fixedShard + clusterAccessor = getClusterAccessor([]v1alpha1.Cluster{cluster1, cluster2, cluster2, cluster4, *cluster5}) + filter = GetDistributionFunction(clusterAccessor, common.DefaultShardingAlgorithm, replicasCount) + assert.Equal(t, int(fixedShard), filter(&v1alpha1.Cluster{ID: "4", Shard: &fixedShard})) } func TestRoundRobinGetClusterFilterWithFixedShard(t *testing.T) { - shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) - db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() - db.On("GetApplicationControllerReplicas").Return(2) - filter := GetClusterFilter(db, GetDistributionFunction(db, common.RoundRobinShardingAlgorithm), shardIndex) - assert.False(t, filter(nil)) - assert.False(t, filter(&cluster1)) - assert.True(t, filter(&cluster2)) - assert.False(t, filter(&cluster3)) - assert.True(t, filter(&cluster4)) + //shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) + t.Setenv(common.EnvControllerReplicas, "4") + clusterAccessor, db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() + replicasCount := 4 + db.On("GetApplicationControllerReplicas").Return(replicasCount) + + filter := GetDistributionFunction(clusterAccessor, common.RoundRobinShardingAlgorithm, replicasCount) + assert.Equal(t, filter(nil), 0) + assert.Equal(t, filter(&cluster1), 0) + assert.Equal(t, filter(&cluster2), 1) + assert.Equal(t, filter(&cluster3), 2) + assert.Equal(t, filter(&cluster4), 3) // a cluster with a fixed shard should be processed by the specified exact // same shard unless the specified shard index is greater than the number of replicas. - var fixedShard int64 = 4 - filter = GetClusterFilter(db, GetDistributionFunction(db, common.RoundRobinShardingAlgorithm), int(fixedShard)) - assert.False(t, filter(&v1alpha1.Cluster{Name: "cluster4", ID: "4", Shard: &fixedShard})) + var fixedShard int64 = 1 + cluster5 := v1alpha1.Cluster{Name: "cluster5", ID: "5", Shard: &fixedShard} + clusters := []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5} + clusterAccessor = getClusterAccessor(clusters) + filter = GetDistributionFunction(clusterAccessor, common.RoundRobinShardingAlgorithm, replicasCount) + assert.Equal(t, int(fixedShard), filter(&cluster5)) fixedShard = 1 - filter = GetClusterFilter(db, GetDistributionFunction(db, common.RoundRobinShardingAlgorithm), int(fixedShard)) - assert.True(t, filter(&v1alpha1.Cluster{Name: "cluster4", ID: "4", Shard: &fixedShard})) -} - -func TestGetClusterFilterLegacyHash(t *testing.T) { - shardIndex := 1 // ensuring that a shard with index 1 will process all the clusters with an "even" id (2,4,6,...) - t.Setenv(common.EnvControllerShardingAlgorithm, "hash") - db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() - db.On("GetApplicationControllerReplicas").Return(2) - filter := GetClusterFilter(db, GetDistributionFunction(db, common.LegacyShardingAlgorithm), shardIndex) - assert.False(t, filter(&cluster1)) - assert.True(t, filter(&cluster2)) - assert.False(t, filter(&cluster3)) - assert.True(t, filter(&cluster4)) - - // a cluster with a fixed shard should be processed by the specified exact - // same shard unless the specified shard index is greater than the number of replicas. - var fixedShard int64 = 4 - filter = GetClusterFilter(db, GetDistributionFunction(db, common.LegacyShardingAlgorithm), int(fixedShard)) - assert.False(t, filter(&v1alpha1.Cluster{Name: "cluster4", ID: "4", Shard: &fixedShard})) - - fixedShard = 1 - filter = GetClusterFilter(db, GetDistributionFunction(db, common.LegacyShardingAlgorithm), int(fixedShard)) - assert.True(t, filter(&v1alpha1.Cluster{Name: "cluster4", ID: "4", Shard: &fixedShard})) -} - -func TestGetClusterFilterWithEnvControllerShardingAlgorithms(t *testing.T) { - db, cluster1, cluster2, cluster3, cluster4, _ := createTestClusters() - shardIndex := 1 - db.On("GetApplicationControllerReplicas").Return(2) - - t.Run("legacy", func(t *testing.T) { - t.Setenv(common.EnvControllerShardingAlgorithm, common.LegacyShardingAlgorithm) - shardShouldProcessCluster := GetClusterFilter(db, GetDistributionFunction(db, common.LegacyShardingAlgorithm), shardIndex) - assert.False(t, shardShouldProcessCluster(&cluster1)) - assert.True(t, shardShouldProcessCluster(&cluster2)) - assert.False(t, shardShouldProcessCluster(&cluster3)) - assert.True(t, shardShouldProcessCluster(&cluster4)) - assert.False(t, shardShouldProcessCluster(nil)) - }) - - t.Run("roundrobin", func(t *testing.T) { - t.Setenv(common.EnvControllerShardingAlgorithm, common.RoundRobinShardingAlgorithm) - shardShouldProcessCluster := GetClusterFilter(db, GetDistributionFunction(db, common.LegacyShardingAlgorithm), shardIndex) - assert.False(t, shardShouldProcessCluster(&cluster1)) - assert.True(t, shardShouldProcessCluster(&cluster2)) - assert.False(t, shardShouldProcessCluster(&cluster3)) - assert.True(t, shardShouldProcessCluster(&cluster4)) - assert.False(t, shardShouldProcessCluster(nil)) - }) + cluster5 = v1alpha1.Cluster{Name: "cluster5", ID: "5", Shard: &fixedShard} + clusters = []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5} + clusterAccessor = getClusterAccessor(clusters) + filter = GetDistributionFunction(clusterAccessor, common.RoundRobinShardingAlgorithm, replicasCount) + assert.Equal(t, int(fixedShard), filter(&v1alpha1.Cluster{Name: "cluster4", ID: "4", Shard: &fixedShard})) } func TestGetShardByIndexModuloReplicasCountDistributionFunction2(t *testing.T) { - db, cluster1, cluster2, cluster3, cluster4, cluster5 := createTestClusters() + clusters, db, cluster1, cluster2, cluster3, cluster4, cluster5 := createTestClusters() t.Run("replicas set to 1", func(t *testing.T) { - db.On("GetApplicationControllerReplicas").Return(1).Once() - distributionFunction := RoundRobinDistributionFunction(db) + replicasCount := 1 + db.On("GetApplicationControllerReplicas").Return(replicasCount).Once() + distributionFunction := RoundRobinDistributionFunction(clusters, replicasCount) assert.Equal(t, 0, distributionFunction(nil)) assert.Equal(t, 0, distributionFunction(&cluster1)) assert.Equal(t, 0, distributionFunction(&cluster2)) @@ -205,8 +183,9 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunction2(t *testing.T) { }) t.Run("replicas set to 2", func(t *testing.T) { - db.On("GetApplicationControllerReplicas").Return(2).Once() - distributionFunction := RoundRobinDistributionFunction(db) + replicasCount := 2 + db.On("GetApplicationControllerReplicas").Return(replicasCount).Once() + distributionFunction := RoundRobinDistributionFunction(clusters, replicasCount) assert.Equal(t, 0, distributionFunction(nil)) assert.Equal(t, 0, distributionFunction(&cluster1)) assert.Equal(t, 1, distributionFunction(&cluster2)) @@ -216,8 +195,9 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunction2(t *testing.T) { }) t.Run("replicas set to 3", func(t *testing.T) { - db.On("GetApplicationControllerReplicas").Return(3).Once() - distributionFunction := RoundRobinDistributionFunction(db) + replicasCount := 3 + db.On("GetApplicationControllerReplicas").Return(replicasCount).Once() + distributionFunction := RoundRobinDistributionFunction(clusters, replicasCount) assert.Equal(t, 0, distributionFunction(nil)) assert.Equal(t, 0, distributionFunction(&cluster1)) assert.Equal(t, 1, distributionFunction(&cluster2)) @@ -233,17 +213,19 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunctionWhenClusterNumber // Initial tests where showing that under 1024 clusters, execution time was around 400ms // and for 4096 clusters, execution time was under 9s // The other implementation was giving almost linear time of 400ms up to 10'000 clusters - db := dbmocks.ArgoDB{} - clusterList := &v1alpha1.ClusterList{Items: []v1alpha1.Cluster{}} + clusterPointers := []*v1alpha1.Cluster{} for i := 0; i < 2048; i++ { cluster := createCluster(fmt.Sprintf("cluster-%d", i), fmt.Sprintf("%d", i)) - clusterList.Items = append(clusterList.Items, cluster) + clusterPointers = append(clusterPointers, &cluster) } - db.On("ListClusters", mock.Anything).Return(clusterList, nil) - db.On("GetApplicationControllerReplicas").Return(2) - distributionFunction := RoundRobinDistributionFunction(&db) - for i, c := range clusterList.Items { - assert.Equal(t, i%2, distributionFunction(&c)) + replicasCount := 2 + t.Setenv(common.EnvControllerReplicas, strconv.Itoa(replicasCount)) + _, db, _, _, _, _, _ := createTestClusters() + clusterAccessor := func() []*v1alpha1.Cluster { return clusterPointers } + db.On("GetApplicationControllerReplicas").Return(replicasCount) + distributionFunction := RoundRobinDistributionFunction(clusterAccessor, replicasCount) + for i, c := range clusterPointers { + assert.Equal(t, i%2, distributionFunction(c)) } } @@ -256,12 +238,15 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunctionWhenClusterIsAdde cluster5 := createCluster("cluster5", "5") cluster6 := createCluster("cluster6", "6") + clusters := []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5} + clusterAccessor := getClusterAccessor(clusters) + clusterList := &v1alpha1.ClusterList{Items: []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5}} db.On("ListClusters", mock.Anything).Return(clusterList, nil) - // Test with replicas set to 2 - db.On("GetApplicationControllerReplicas").Return(2) - distributionFunction := RoundRobinDistributionFunction(&db) + replicasCount := 2 + db.On("GetApplicationControllerReplicas").Return(replicasCount) + distributionFunction := RoundRobinDistributionFunction(clusterAccessor, replicasCount) assert.Equal(t, 0, distributionFunction(nil)) assert.Equal(t, 0, distributionFunction(&cluster1)) assert.Equal(t, 1, distributionFunction(&cluster2)) @@ -272,17 +257,20 @@ func TestGetShardByIndexModuloReplicasCountDistributionFunctionWhenClusterIsAdde // Now, the database knows cluster6. Shard should be assigned a proper shard clusterList.Items = append(clusterList.Items, cluster6) + distributionFunction = RoundRobinDistributionFunction(getClusterAccessor(clusterList.Items), replicasCount) assert.Equal(t, 1, distributionFunction(&cluster6)) // Now, we remove the last added cluster, it should be unassigned as well clusterList.Items = clusterList.Items[:len(clusterList.Items)-1] + distributionFunction = RoundRobinDistributionFunction(getClusterAccessor(clusterList.Items), replicasCount) assert.Equal(t, -1, distributionFunction(&cluster6)) } func TestGetShardByIndexModuloReplicasCountDistributionFunction(t *testing.T) { - db, cluster1, cluster2, _, _, _ := createTestClusters() - db.On("GetApplicationControllerReplicas").Return(2) - distributionFunction := RoundRobinDistributionFunction(db) + clusters, db, cluster1, cluster2, _, _, _ := createTestClusters() + replicasCount := 2 + db.On("GetApplicationControllerReplicas").Return(replicasCount) + distributionFunction := RoundRobinDistributionFunction(clusters, replicasCount) // Test that the function returns the correct shard for cluster1 and cluster2 expectedShardForCluster1 := 0 @@ -315,14 +303,14 @@ func TestInferShard(t *testing.T) { osHostnameFunction = func() (string, error) { return "exampleshard", nil } _, err = InferShard() - assert.NotNil(t, err) + assert.Nil(t, err) osHostnameFunction = func() (string, error) { return "example-shard", nil } _, err = InferShard() - assert.NotNil(t, err) + assert.Nil(t, err) } -func createTestClusters() (*dbmocks.ArgoDB, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster) { +func createTestClusters() (clusterAccessor, *dbmocks.ArgoDB, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster, v1alpha1.Cluster) { db := dbmocks.ArgoDB{} cluster1 := createCluster("cluster1", "1") cluster2 := createCluster("cluster2", "2") @@ -330,10 +318,27 @@ func createTestClusters() (*dbmocks.ArgoDB, v1alpha1.Cluster, v1alpha1.Cluster, cluster4 := createCluster("cluster4", "4") cluster5 := createCluster("cluster5", "5") + clusters := []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5} + db.On("ListClusters", mock.Anything).Return(&v1alpha1.ClusterList{Items: []v1alpha1.Cluster{ cluster1, cluster2, cluster3, cluster4, cluster5, }}, nil) - return &db, cluster1, cluster2, cluster3, cluster4, cluster5 + return getClusterAccessor(clusters), &db, cluster1, cluster2, cluster3, cluster4, cluster5 +} + +func getClusterAccessor(clusters []v1alpha1.Cluster) clusterAccessor { + // Convert the array to a slice of pointers + clusterPointers := getClusterPointers(clusters) + clusterAccessor := func() []*v1alpha1.Cluster { return clusterPointers } + return clusterAccessor +} + +func getClusterPointers(clusters []v1alpha1.Cluster) []*v1alpha1.Cluster { + var clusterPointers []*v1alpha1.Cluster + for i := range clusters { + clusterPointers = append(clusterPointers, &clusters[i]) + } + return clusterPointers } func createCluster(name string, id string) v1alpha1.Cluster { diff --git a/controller/sharding/shuffle_test.go b/controller/sharding/shuffle_test.go index 9e089e31bad0f..1cca783a2afe9 100644 --- a/controller/sharding/shuffle_test.go +++ b/controller/sharding/shuffle_test.go @@ -3,6 +3,7 @@ package sharding import ( "fmt" "math" + "strconv" "testing" "github.com/argoproj/argo-cd/v2/common" @@ -22,9 +23,11 @@ func TestLargeShuffle(t *testing.T) { clusterList.Items = append(clusterList.Items, cluster) } db.On("ListClusters", mock.Anything).Return(clusterList, nil) + clusterAccessor := getClusterAccessor(clusterList.Items) // Test with replicas set to 256 - t.Setenv(common.EnvControllerReplicas, "256") - distributionFunction := RoundRobinDistributionFunction(&db) + replicasCount := 256 + t.Setenv(common.EnvControllerReplicas, strconv.Itoa(replicasCount)) + distributionFunction := RoundRobinDistributionFunction(clusterAccessor, replicasCount) for i, c := range clusterList.Items { assert.Equal(t, i%2567, distributionFunction(&c)) } @@ -44,10 +47,11 @@ func TestShuffle(t *testing.T) { clusterList := &v1alpha1.ClusterList{Items: []v1alpha1.Cluster{cluster1, cluster2, cluster3, cluster4, cluster5, cluster6}} db.On("ListClusters", mock.Anything).Return(clusterList, nil) - + clusterAccessor := getClusterAccessor(clusterList.Items) // Test with replicas set to 3 t.Setenv(common.EnvControllerReplicas, "3") - distributionFunction := RoundRobinDistributionFunction(&db) + replicasCount := 3 + distributionFunction := RoundRobinDistributionFunction(clusterAccessor, replicasCount) assert.Equal(t, 0, distributionFunction(nil)) assert.Equal(t, 0, distributionFunction(&cluster1)) assert.Equal(t, 1, distributionFunction(&cluster2)) diff --git a/docs/user-guide/commands/argocd_admin_cluster.md b/docs/user-guide/commands/argocd_admin_cluster.md index bad60a0dd32bf..544c0de08959c 100644 --- a/docs/user-guide/commands/argocd_admin_cluster.md +++ b/docs/user-guide/commands/argocd_admin_cluster.md @@ -62,6 +62,6 @@ argocd admin cluster namespaces my-cluster * [argocd admin cluster generate-spec](argocd_admin_cluster_generate-spec.md) - Generate declarative config for a cluster * [argocd admin cluster kubeconfig](argocd_admin_cluster_kubeconfig.md) - Generates kubeconfig for the specified cluster * [argocd admin cluster namespaces](argocd_admin_cluster_namespaces.md) - Print information namespaces which Argo CD manages in each cluster. -* [argocd admin cluster shards](argocd_admin_cluster_shards.md) - Print information about each controller shard and portion of Kubernetes resources it is responsible for. +* [argocd admin cluster shards](argocd_admin_cluster_shards.md) - Print information about each controller shard and the estimated portion of Kubernetes resources it is responsible for. * [argocd admin cluster stats](argocd_admin_cluster_stats.md) - Prints information cluster statistics and inferred shard number diff --git a/docs/user-guide/commands/argocd_admin_cluster_shards.md b/docs/user-guide/commands/argocd_admin_cluster_shards.md index 6648b91b2199e..48f6138d47b4a 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_shards.md +++ b/docs/user-guide/commands/argocd_admin_cluster_shards.md @@ -2,7 +2,7 @@ ## argocd admin cluster shards -Print information about each controller shard and portion of Kubernetes resources it is responsible for. +Print information about each controller shard and the estimated portion of Kubernetes resources it is responsible for. ``` argocd admin cluster shards [flags] @@ -43,6 +43,7 @@ argocd admin cluster shards [flags] --sentinelmaster string Redis sentinel master group name. (default "master") --server string The address and port of the Kubernetes API server --shard int Cluster shard filter (default -1) + --sharding-method string Sharding method. Defaults: legacy. Supported sharding methods are : [legacy, round-robin] (default "legacy") --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use diff --git a/docs/user-guide/commands/argocd_admin_cluster_stats.md b/docs/user-guide/commands/argocd_admin_cluster_stats.md index 960fd12caaef1..c5297ce7e35ed 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_stats.md +++ b/docs/user-guide/commands/argocd_admin_cluster_stats.md @@ -57,6 +57,7 @@ argocd admin cluster stats target-cluster --sentinelmaster string Redis sentinel master group name. (default "master") --server string The address and port of the Kubernetes API server --shard int Cluster shard filter (default -1) + --sharding-method string Sharding method. Defaults: legacy. Supported sharding methods are : [legacy, round-robin] (default "legacy") --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use diff --git a/test/e2e/cluster_test.go b/test/e2e/cluster_test.go index e57b2132b7472..2074a6aa1b7b1 100644 --- a/test/e2e/cluster_test.go +++ b/test/e2e/cluster_test.go @@ -38,7 +38,7 @@ https://kubernetes.default.svc in-cluster %v Successful `, GetVe When(). CreateApp() - tries := 2 + tries := 5 for i := 0; i <= tries; i += 1 { clusterFixture.GivenWithSameState(t). When(). From 54de532940d7d4a0581579c16dcec9b5ec066e91 Mon Sep 17 00:00:00 2001 From: mugi <62197019+mugioka@users.noreply.github.com> Date: Thu, 11 Jan 2024 21:52:18 +0900 Subject: [PATCH 190/269] fix(manifests): applicationset-controller dir is not added to cluster-rbac/kustomization.yaml. (#16810) * fix(manifests): applicationset-controller dir is not added to cluster-rbac/kustomization.yaml. Related PR: https://github.com/argoproj/argo-cd/pull/16699. I missed adding a new folder(applicationset-controller) to kustomization.yaml. So, i addressed it. Signed-off-by: mugioka * chore: exec `make manifests`. Signed-off-by: mugioka * chore: exec `make manifests`. Signed-off-by: mugioka --------- Signed-off-by: mugioka --- manifests/cluster-rbac/kustomization.yaml | 1 + manifests/ha/install.yaml | 106 ++++++++++++++++++++++ manifests/install.yaml | 106 ++++++++++++++++++++++ 3 files changed, 213 insertions(+) diff --git a/manifests/cluster-rbac/kustomization.yaml b/manifests/cluster-rbac/kustomization.yaml index 7f791905b661b..55e6e2d72df9e 100644 --- a/manifests/cluster-rbac/kustomization.yaml +++ b/manifests/cluster-rbac/kustomization.yaml @@ -3,4 +3,5 @@ kind: Kustomization resources: - ./application-controller +- ./applicationset-controller - ./server diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index a7086ae8a6c06..2029be1e07e12 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -20868,6 +20868,95 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - update + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/component: server @@ -21049,6 +21138,23 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: labels: app.kubernetes.io/component: server diff --git a/manifests/install.yaml b/manifests/install.yaml index 8d30e076d8bf7..83ac4f903fb7b 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -20827,6 +20827,95 @@ rules: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update +- apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get +- apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - update + - delete + - get + - list + - patch + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole metadata: labels: app.kubernetes.io/component: server @@ -20976,6 +21065,23 @@ subjects: --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: applicationset-controller + app.kubernetes.io/name: argocd-applicationset-controller + app.kubernetes.io/part-of: argocd + name: argocd-applicationset-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: argocd-applicationset-controller +subjects: +- kind: ServiceAccount + name: argocd-applicationset-controller + namespace: argocd +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: labels: app.kubernetes.io/component: server From b12630c4be3dc73bc89eb5295ef3a582c7ae628b Mon Sep 17 00:00:00 2001 From: eddimull Date: Thu, 11 Jan 2024 11:08:42 -0600 Subject: [PATCH 191/269] typo in comment (#16834) Signed-off-by: eddimull --- docs/operator-manual/application.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operator-manual/application.yaml b/docs/operator-manual/application.yaml index aa2dea5c65b7c..864a293ce6890 100644 --- a/docs/operator-manual/application.yaml +++ b/docs/operator-manual/application.yaml @@ -119,7 +119,7 @@ spec: extVars: - name: foo value: bar - # You can use "code to determine if the value is either string (false, the default) or Jsonnet code (if code is true). + # You can use "code" to determine if the value is either string (false, the default) or Jsonnet code (if code is true). - code: true name: baz value: "true" From d9df2525c57d4870215a6ce149dbedd08ae05fdb Mon Sep 17 00:00:00 2001 From: Isaac Gaskin Date: Fri, 12 Jan 2024 15:39:41 -0800 Subject: [PATCH 192/269] feat: adding option to specify an aws profile to use by the argocd-server when adding a EKS cluster (#16767) useful for argocd-servers which are not running in AWS and want to add multiple EKS clusters using separate keys instead of assuming roles #16766 Signed-off-by: Isaac Gaskin Co-authored-by: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> --- assets/swagger.json | 4 + cmd/argocd-k8s-auth/commands/aws.go | 16 +- cmd/argocd-k8s-auth/commands/aws_test.go | 8 +- cmd/argocd/commands/admin/cluster.go | 1 + cmd/argocd/commands/cluster.go | 1 + cmd/util/cluster.go | 2 + docs/operator-manual/declarative-setup.md | 1 + .../argocd_admin_cluster_generate-spec.md | 1 + .../user-guide/commands/argocd_cluster_add.md | 1 + pkg/apis/application/v1alpha1/generated.pb.go | 1417 +++++++++-------- pkg/apis/application/v1alpha1/generated.proto | 3 + .../application/v1alpha1/openapi_generated.go | 7 + pkg/apis/application/v1alpha1/types.go | 6 + 13 files changed, 770 insertions(+), 698 deletions(-) diff --git a/assets/swagger.json b/assets/swagger.json index a9f45fcbb1956..91e815203eee0 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -5664,6 +5664,10 @@ "type": "string", "title": "ClusterName contains AWS cluster name" }, + "profile": { + "description": "Profile contains optional role ARN. If set then AWS IAM Authenticator uses the profile to perform cluster operations instead of the default AWS credential provider chain.", + "type": "string" + }, "roleARN": { "description": "RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain.", "type": "string" diff --git a/cmd/argocd-k8s-auth/commands/aws.go b/cmd/argocd-k8s-auth/commands/aws.go index 79a118d2653a3..9b750ac5f92f8 100644 --- a/cmd/argocd-k8s-auth/commands/aws.go +++ b/cmd/argocd-k8s-auth/commands/aws.go @@ -37,13 +37,14 @@ func newAWSCommand() *cobra.Command { var ( clusterName string roleARN string + profile string ) var command = &cobra.Command{ Use: "aws", Run: func(c *cobra.Command, args []string) { ctx := c.Context() - presignedURLString, err := getSignedRequestWithRetry(ctx, time.Minute, 5*time.Second, clusterName, roleARN, getSignedRequest) + presignedURLString, err := getSignedRequestWithRetry(ctx, time.Minute, 5*time.Second, clusterName, roleARN, profile, getSignedRequest) errors.CheckError(err) token := v1Prefix + base64.RawURLEncoding.EncodeToString([]byte(presignedURLString)) // Set token expiration to 1 minute before the presigned URL expires for some cushion @@ -53,16 +54,17 @@ func newAWSCommand() *cobra.Command { } command.Flags().StringVar(&clusterName, "cluster-name", "", "AWS Cluster name") command.Flags().StringVar(&roleARN, "role-arn", "", "AWS Role ARN") + command.Flags().StringVar(&profile, "profile", "", "AWS Profile") return command } -type getSignedRequestFunc func(clusterName, roleARN string) (string, error) +type getSignedRequestFunc func(clusterName, roleARN string, profile string) (string, error) -func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Duration, clusterName, roleARN string, fn getSignedRequestFunc) (string, error) { +func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Duration, clusterName, roleARN string, profile string, fn getSignedRequestFunc) (string, error) { ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() for { - signed, err := fn(clusterName, roleARN) + signed, err := fn(clusterName, roleARN, profile) if err == nil { return signed, nil } @@ -74,8 +76,10 @@ func getSignedRequestWithRetry(ctx context.Context, timeout, interval time.Durat } } -func getSignedRequest(clusterName, roleARN string) (string, error) { - sess, err := session.NewSession() +func getSignedRequest(clusterName, roleARN string, profile string) (string, error) { + sess, err := session.NewSessionWithOptions(session.Options{ + Profile: profile, + }) if err != nil { return "", fmt.Errorf("error creating new AWS session: %s", err) } diff --git a/cmd/argocd-k8s-auth/commands/aws_test.go b/cmd/argocd-k8s-auth/commands/aws_test.go index c22449eba42be..578aae71a2c29 100644 --- a/cmd/argocd-k8s-auth/commands/aws_test.go +++ b/cmd/argocd-k8s-auth/commands/aws_test.go @@ -22,7 +22,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) { } // when - signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock) + signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", "", mock.getSignedRequestMock) // then assert.NoError(t, err) @@ -41,7 +41,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) { } // when - signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock) + signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", "", mock.getSignedRequestMock) // then assert.NoError(t, err) @@ -57,7 +57,7 @@ func TestGetSignedRequestWithRetry(t *testing.T) { } // when - signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", mock.getSignedRequestMock) + signed, err := getSignedRequestWithRetry(ctx, time.Second, time.Millisecond, "cluster-name", "", "", mock.getSignedRequestMock) // then assert.Error(t, err) @@ -70,7 +70,7 @@ type signedRequestMock struct { returnFunc func(m *signedRequestMock) (string, error) } -func (m *signedRequestMock) getSignedRequestMock(clusterName, roleARN string) (string, error) { +func (m *signedRequestMock) getSignedRequestMock(clusterName, roleARN string, profile string) (string, error) { m.getSignedRequestCalls++ return m.returnFunc(m) } diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 6f626dd8d0534..24d45828c86c1 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -632,6 +632,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command awsAuthConf = &argoappv1.AWSAuthConfig{ ClusterName: clusterOpts.AwsClusterName, RoleARN: clusterOpts.AwsRoleArn, + Profile: clusterOpts.AwsProfile, } } else if clusterOpts.ExecProviderCommand != "" { execProviderConf = &argoappv1.ExecProviderConfig{ diff --git a/cmd/argocd/commands/cluster.go b/cmd/argocd/commands/cluster.go index 3df4be6632d85..f203b82ae9ac0 100644 --- a/cmd/argocd/commands/cluster.go +++ b/cmd/argocd/commands/cluster.go @@ -111,6 +111,7 @@ func NewClusterAddCommand(clientOpts *argocdclient.ClientOptions, pathOpts *clie awsAuthConf = &argoappv1.AWSAuthConfig{ ClusterName: clusterOpts.AwsClusterName, RoleARN: clusterOpts.AwsRoleArn, + Profile: clusterOpts.AwsProfile, } } else if clusterOpts.ExecProviderCommand != "" { execProviderConf = &argoappv1.ExecProviderConfig{ diff --git a/cmd/util/cluster.go b/cmd/util/cluster.go index 95c071c882b12..dffb52e775a97 100644 --- a/cmd/util/cluster.go +++ b/cmd/util/cluster.go @@ -144,6 +144,7 @@ type ClusterOptions struct { Upsert bool ServiceAccount string AwsRoleArn string + AwsProfile string AwsClusterName string SystemNamespace string Namespaces []string @@ -169,6 +170,7 @@ func AddClusterFlags(command *cobra.Command, opts *ClusterOptions) { command.Flags().BoolVar(&opts.InCluster, "in-cluster", false, "Indicates Argo CD resides inside this cluster and should connect using the internal k8s hostname (kubernetes.default.svc)") command.Flags().StringVar(&opts.AwsClusterName, "aws-cluster-name", "", "AWS Cluster name if set then aws cli eks token command will be used to access cluster") command.Flags().StringVar(&opts.AwsRoleArn, "aws-role-arn", "", "Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain.") + command.Flags().StringVar(&opts.AwsProfile, "aws-profile", "", "Optional AWS profile. If set then AWS IAM Authenticator uses this profile to perform cluster operations instead of the default AWS credential provider chain.") command.Flags().StringArrayVar(&opts.Namespaces, "namespace", nil, "List of namespaces which are allowed to manage") command.Flags().BoolVar(&opts.ClusterResources, "cluster-resources", false, "Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty.") command.Flags().StringVar(&opts.Name, "name", "", "Overwrite the cluster name") diff --git a/docs/operator-manual/declarative-setup.md b/docs/operator-manual/declarative-setup.md index c1f5ba2b2d3bd..4d87ae9f80286 100644 --- a/docs/operator-manual/declarative-setup.md +++ b/docs/operator-manual/declarative-setup.md @@ -549,6 +549,7 @@ bearerToken: string awsAuthConfig: clusterName: string roleARN: string + profile: string # Configure external command to supply client credentials # See https://godoc.org/k8s.io/client-go/tools/clientcmd/api#ExecConfig execProviderConfig: diff --git a/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md b/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md index cc24418b023f8..79f88233fab32 100644 --- a/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_cluster_generate-spec.md @@ -13,6 +13,7 @@ argocd admin cluster generate-spec CONTEXT [flags] ``` --annotation stringArray Set metadata annotations (e.g. --annotation key=value) --aws-cluster-name string AWS Cluster name if set then aws cli eks token command will be used to access cluster + --aws-profile string Optional AWS profile. If set then AWS IAM Authenticator uses this profile to perform cluster operations instead of the default AWS credential provider chain. --aws-role-arn string Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain. --bearer-token string Authentication token that should be used to access K8S API server --cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'. diff --git a/docs/user-guide/commands/argocd_cluster_add.md b/docs/user-guide/commands/argocd_cluster_add.md index 6d3a094b4bf83..8a80a12f5a4d5 100644 --- a/docs/user-guide/commands/argocd_cluster_add.md +++ b/docs/user-guide/commands/argocd_cluster_add.md @@ -13,6 +13,7 @@ argocd cluster add CONTEXT [flags] ``` --annotation stringArray Set metadata annotations (e.g. --annotation key=value) --aws-cluster-name string AWS Cluster name if set then aws cli eks token command will be used to access cluster + --aws-profile string Optional AWS profile. If set then AWS IAM Authenticator uses this profile to perform cluster operations instead of the default AWS credential provider chain. --aws-role-arn string Optional AWS role arn. If set then AWS IAM Authenticator assumes a role to perform cluster operations instead of the default AWS credential provider chain. --cluster-endpoint string Cluster endpoint to use. Can be one of the following: 'kubeconfig', 'kube-public', or 'internal'. --cluster-resources Indicates if cluster level resources should be managed. The setting is used only if list of managed namespaces is not empty. diff --git a/pkg/apis/application/v1alpha1/generated.pb.go b/pkg/apis/application/v1alpha1/generated.pb.go index cccbc3f7f15a4..cade795dcebd7 100644 --- a/pkg/apis/application/v1alpha1/generated.pb.go +++ b/pkg/apis/application/v1alpha1/generated.pb.go @@ -4448,694 +4448,695 @@ func init() { } var fileDescriptor_030104ce3b95bcac = []byte{ - // 10990 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x1c, 0xc9, - 0x75, 0x98, 0x66, 0x17, 0x0b, 0xec, 0x3e, 0x7c, 0x90, 0x6c, 0x92, 0x77, 0x20, 0x75, 0x77, 0xa0, - 0xe7, 0xe2, 0xd3, 0x39, 0xba, 0x03, 0x7c, 0xf4, 0x9d, 0x7c, 0xf1, 0xd9, 0x92, 0xb1, 0x00, 0x09, - 0x82, 0x04, 0x08, 0x5c, 0x03, 0x24, 0xa5, 0x93, 0x4f, 0xa7, 0xc1, 0x6e, 0x63, 0x31, 0xc4, 0xec, - 0xcc, 0xdc, 0xcc, 0x2c, 0x08, 0x9c, 0x25, 0x59, 0xb2, 0x64, 0x5b, 0x89, 0x3e, 0x4e, 0x91, 0x92, - 0xf2, 0x39, 0x89, 0x14, 0xd9, 0x72, 0x52, 0x76, 0x25, 0xaa, 0x38, 0xc9, 0x8f, 0x38, 0x71, 0x52, - 0x2e, 0xdb, 0xa9, 0x94, 0x52, 0x4a, 0xca, 0x2e, 0x97, 0xcb, 0x72, 0x12, 0x1b, 0x91, 0x98, 0x4a, - 0x25, 0x95, 0xaa, 0xb8, 0xca, 0x89, 0x7f, 0x24, 0x4c, 0x7e, 0xa4, 0xfa, 0xbb, 0x67, 0x76, 0x16, - 0x58, 0x00, 0x03, 0x92, 0x52, 0xee, 0xdf, 0x6e, 0xbf, 0x37, 0xef, 0xf5, 0xf4, 0x74, 0xbf, 0xf7, - 0xfa, 0xf5, 0x7b, 0xaf, 0x61, 0xa1, 0xe5, 0x26, 0x1b, 0x9d, 0xb5, 0xc9, 0x46, 0xd0, 0x9e, 0x72, - 0xa2, 0x56, 0x10, 0x46, 0xc1, 0x6d, 0xf6, 0xe3, 0xd9, 0x46, 0x73, 0x6a, 0xeb, 0xe2, 0x54, 0xb8, - 0xd9, 0x9a, 0x72, 0x42, 0x37, 0x9e, 0x72, 0xc2, 0xd0, 0x73, 0x1b, 0x4e, 0xe2, 0x06, 0xfe, 0xd4, - 0xd6, 0x73, 0x8e, 0x17, 0x6e, 0x38, 0xcf, 0x4d, 0xb5, 0x88, 0x4f, 0x22, 0x27, 0x21, 0xcd, 0xc9, - 0x30, 0x0a, 0x92, 0x00, 0xfd, 0xa8, 0xa6, 0x36, 0x29, 0xa9, 0xb1, 0x1f, 0xaf, 0x35, 0x9a, 0x93, - 0x5b, 0x17, 0x27, 0xc3, 0xcd, 0xd6, 0x24, 0xa5, 0x36, 0x69, 0x50, 0x9b, 0x94, 0xd4, 0xce, 0x3f, - 0x6b, 0xf4, 0xa5, 0x15, 0xb4, 0x82, 0x29, 0x46, 0x74, 0xad, 0xb3, 0xce, 0xfe, 0xb1, 0x3f, 0xec, - 0x17, 0x67, 0x76, 0xde, 0xde, 0x7c, 0x31, 0x9e, 0x74, 0x03, 0xda, 0xbd, 0xa9, 0x46, 0x10, 0x91, - 0xa9, 0xad, 0xae, 0x0e, 0x9d, 0xbf, 0xa2, 0x71, 0xc8, 0x76, 0x42, 0xfc, 0xd8, 0x0d, 0xfc, 0xf8, - 0x59, 0xda, 0x05, 0x12, 0x6d, 0x91, 0xc8, 0x7c, 0x3d, 0x03, 0x21, 0x8f, 0xd2, 0xf3, 0x9a, 0x52, - 0xdb, 0x69, 0x6c, 0xb8, 0x3e, 0x89, 0x76, 0xf4, 0xe3, 0x6d, 0x92, 0x38, 0x79, 0x4f, 0x4d, 0xf5, - 0x7a, 0x2a, 0xea, 0xf8, 0x89, 0xdb, 0x26, 0x5d, 0x0f, 0xbc, 0x67, 0xbf, 0x07, 0xe2, 0xc6, 0x06, - 0x69, 0x3b, 0x5d, 0xcf, 0xfd, 0x50, 0xaf, 0xe7, 0x3a, 0x89, 0xeb, 0x4d, 0xb9, 0x7e, 0x12, 0x27, - 0x51, 0xf6, 0x21, 0xfb, 0x75, 0x18, 0x9d, 0xbe, 0xb5, 0x32, 0xdd, 0x49, 0x36, 0x66, 0x02, 0x7f, - 0xdd, 0x6d, 0xa1, 0x17, 0x60, 0xb8, 0xe1, 0x75, 0xe2, 0x84, 0x44, 0xd7, 0x9d, 0x36, 0x19, 0xb7, - 0x2e, 0x58, 0x4f, 0xd7, 0xea, 0xa7, 0xbf, 0xb1, 0x3b, 0xf1, 0x8e, 0xbb, 0xbb, 0x13, 0xc3, 0x33, - 0x1a, 0x84, 0x4d, 0x3c, 0xf4, 0x03, 0x30, 0x14, 0x05, 0x1e, 0x99, 0xc6, 0xd7, 0xc7, 0x4b, 0xec, - 0x91, 0x13, 0xe2, 0x91, 0x21, 0xcc, 0x9b, 0xb1, 0x84, 0xdb, 0x7f, 0x58, 0x02, 0x98, 0x0e, 0xc3, - 0xe5, 0x28, 0xb8, 0x4d, 0x1a, 0x09, 0xfa, 0x30, 0x54, 0xe9, 0xd0, 0x35, 0x9d, 0xc4, 0x61, 0xdc, - 0x86, 0x2f, 0xfe, 0xe0, 0x24, 0x7f, 0x93, 0x49, 0xf3, 0x4d, 0xf4, 0xc4, 0xa1, 0xd8, 0x93, 0x5b, - 0xcf, 0x4d, 0x2e, 0xad, 0xd1, 0xe7, 0x17, 0x49, 0xe2, 0xd4, 0x91, 0x60, 0x06, 0xba, 0x0d, 0x2b, - 0xaa, 0xc8, 0x87, 0x81, 0x38, 0x24, 0x0d, 0xd6, 0xb1, 0xe1, 0x8b, 0x0b, 0x93, 0x47, 0x99, 0xa1, - 0x93, 0xba, 0xe7, 0x2b, 0x21, 0x69, 0xd4, 0x47, 0x04, 0xe7, 0x01, 0xfa, 0x0f, 0x33, 0x3e, 0x68, - 0x0b, 0x06, 0xe3, 0xc4, 0x49, 0x3a, 0xf1, 0x78, 0x99, 0x71, 0xbc, 0x5e, 0x18, 0x47, 0x46, 0xb5, - 0x3e, 0x26, 0x78, 0x0e, 0xf2, 0xff, 0x58, 0x70, 0xb3, 0xff, 0xc4, 0x82, 0x31, 0x8d, 0xbc, 0xe0, - 0xc6, 0x09, 0xfa, 0x89, 0xae, 0xc1, 0x9d, 0xec, 0x6f, 0x70, 0xe9, 0xd3, 0x6c, 0x68, 0x4f, 0x0a, - 0x66, 0x55, 0xd9, 0x62, 0x0c, 0x6c, 0x1b, 0x2a, 0x6e, 0x42, 0xda, 0xf1, 0x78, 0xe9, 0x42, 0xf9, - 0xe9, 0xe1, 0x8b, 0x57, 0x8a, 0x7a, 0xcf, 0xfa, 0xa8, 0x60, 0x5a, 0x99, 0xa7, 0xe4, 0x31, 0xe7, - 0x62, 0xff, 0xea, 0x88, 0xf9, 0x7e, 0x74, 0xc0, 0xd1, 0x73, 0x30, 0x1c, 0x07, 0x9d, 0xa8, 0x41, - 0x30, 0x09, 0x83, 0x78, 0xdc, 0xba, 0x50, 0xa6, 0x53, 0x8f, 0xce, 0xd4, 0x15, 0xdd, 0x8c, 0x4d, - 0x1c, 0xf4, 0x79, 0x0b, 0x46, 0x9a, 0x24, 0x4e, 0x5c, 0x9f, 0xf1, 0x97, 0x9d, 0x5f, 0x3d, 0x72, - 0xe7, 0x65, 0xe3, 0xac, 0x26, 0x5e, 0x3f, 0x23, 0x5e, 0x64, 0xc4, 0x68, 0x8c, 0x71, 0x8a, 0x3f, - 0x5d, 0x71, 0x4d, 0x12, 0x37, 0x22, 0x37, 0xa4, 0xff, 0xd9, 0x9c, 0x31, 0x56, 0xdc, 0xac, 0x06, - 0x61, 0x13, 0x0f, 0xf9, 0x50, 0xa1, 0x2b, 0x2a, 0x1e, 0x1f, 0x60, 0xfd, 0x9f, 0x3f, 0x5a, 0xff, - 0xc5, 0xa0, 0xd2, 0xc5, 0xaa, 0x47, 0x9f, 0xfe, 0x8b, 0x31, 0x67, 0x83, 0x3e, 0x67, 0xc1, 0xb8, - 0x58, 0xf1, 0x98, 0xf0, 0x01, 0xbd, 0xb5, 0xe1, 0x26, 0xc4, 0x73, 0xe3, 0x64, 0xbc, 0xc2, 0xfa, - 0x30, 0xd5, 0xdf, 0xdc, 0x9a, 0x8b, 0x82, 0x4e, 0x78, 0xcd, 0xf5, 0x9b, 0xf5, 0x0b, 0x82, 0xd3, - 0xf8, 0x4c, 0x0f, 0xc2, 0xb8, 0x27, 0x4b, 0xf4, 0x25, 0x0b, 0xce, 0xfb, 0x4e, 0x9b, 0xc4, 0xa1, - 0x43, 0x3f, 0x2d, 0x07, 0xd7, 0x3d, 0xa7, 0xb1, 0xc9, 0x7a, 0x34, 0x78, 0xb8, 0x1e, 0xd9, 0xa2, - 0x47, 0xe7, 0xaf, 0xf7, 0x24, 0x8d, 0xf7, 0x60, 0x8b, 0xbe, 0x66, 0xc1, 0xa9, 0x20, 0x0a, 0x37, - 0x1c, 0x9f, 0x34, 0x25, 0x34, 0x1e, 0x1f, 0x62, 0x4b, 0xef, 0x43, 0x47, 0xfb, 0x44, 0x4b, 0x59, - 0xb2, 0x8b, 0x81, 0xef, 0x26, 0x41, 0xb4, 0x42, 0x92, 0xc4, 0xf5, 0x5b, 0x71, 0xfd, 0xec, 0xdd, - 0xdd, 0x89, 0x53, 0x5d, 0x58, 0xb8, 0xbb, 0x3f, 0xe8, 0x27, 0x61, 0x38, 0xde, 0xf1, 0x1b, 0xb7, - 0x5c, 0xbf, 0x19, 0xdc, 0x89, 0xc7, 0xab, 0x45, 0x2c, 0xdf, 0x15, 0x45, 0x50, 0x2c, 0x40, 0xcd, - 0x00, 0x9b, 0xdc, 0xf2, 0x3f, 0x9c, 0x9e, 0x4a, 0xb5, 0xa2, 0x3f, 0x9c, 0x9e, 0x4c, 0x7b, 0xb0, - 0x45, 0x3f, 0x67, 0xc1, 0x68, 0xec, 0xb6, 0x7c, 0x27, 0xe9, 0x44, 0xe4, 0x1a, 0xd9, 0x89, 0xc7, - 0x81, 0x75, 0xe4, 0xea, 0x11, 0x47, 0xc5, 0x20, 0x59, 0x3f, 0x2b, 0xfa, 0x38, 0x6a, 0xb6, 0xc6, - 0x38, 0xcd, 0x37, 0x6f, 0xa1, 0xe9, 0x69, 0x3d, 0x5c, 0xec, 0x42, 0xd3, 0x93, 0xba, 0x27, 0x4b, - 0xf4, 0xe3, 0x70, 0x92, 0x37, 0xa9, 0x91, 0x8d, 0xc7, 0x47, 0x98, 0xa0, 0x3d, 0x73, 0x77, 0x77, - 0xe2, 0xe4, 0x4a, 0x06, 0x86, 0xbb, 0xb0, 0xd1, 0xeb, 0x30, 0x11, 0x92, 0xa8, 0xed, 0x26, 0x4b, - 0xbe, 0xb7, 0x23, 0xc5, 0x77, 0x23, 0x08, 0x49, 0x53, 0x74, 0x27, 0x1e, 0x1f, 0xbd, 0x60, 0x3d, - 0x5d, 0xad, 0xbf, 0x4b, 0x74, 0x73, 0x62, 0x79, 0x6f, 0x74, 0xbc, 0x1f, 0x3d, 0xfb, 0x5f, 0x97, - 0xe0, 0x64, 0x56, 0x71, 0xa2, 0xbf, 0x6b, 0xc1, 0x89, 0xdb, 0x77, 0x92, 0xd5, 0x60, 0x93, 0xf8, - 0x71, 0x7d, 0x87, 0x8a, 0x37, 0xa6, 0x32, 0x86, 0x2f, 0x36, 0x8a, 0x55, 0xd1, 0x93, 0x57, 0xd3, - 0x5c, 0x2e, 0xf9, 0x49, 0xb4, 0x53, 0x7f, 0x54, 0xbc, 0xdd, 0x89, 0xab, 0xb7, 0x56, 0x4d, 0x28, - 0xce, 0x76, 0xea, 0xfc, 0x67, 0x2c, 0x38, 0x93, 0x47, 0x02, 0x9d, 0x84, 0xf2, 0x26, 0xd9, 0xe1, - 0x56, 0x19, 0xa6, 0x3f, 0xd1, 0xab, 0x50, 0xd9, 0x72, 0xbc, 0x0e, 0x11, 0xd6, 0xcd, 0xdc, 0xd1, - 0x5e, 0x44, 0xf5, 0x0c, 0x73, 0xaa, 0x3f, 0x52, 0x7a, 0xd1, 0xb2, 0x7f, 0xb7, 0x0c, 0xc3, 0x86, - 0x7e, 0xbb, 0x0f, 0x16, 0x5b, 0x90, 0xb2, 0xd8, 0x16, 0x0b, 0x53, 0xcd, 0x3d, 0x4d, 0xb6, 0x3b, - 0x19, 0x93, 0x6d, 0xa9, 0x38, 0x96, 0x7b, 0xda, 0x6c, 0x28, 0x81, 0x5a, 0x10, 0x52, 0x8b, 0x9c, - 0xaa, 0xfe, 0x81, 0x22, 0x3e, 0xe1, 0x92, 0x24, 0x57, 0x1f, 0xbd, 0xbb, 0x3b, 0x51, 0x53, 0x7f, - 0xb1, 0x66, 0x64, 0x7f, 0xcb, 0x82, 0x33, 0x46, 0x1f, 0x67, 0x02, 0xbf, 0xe9, 0xb2, 0x4f, 0x7b, - 0x01, 0x06, 0x92, 0x9d, 0x50, 0x9a, 0xfd, 0x6a, 0xa4, 0x56, 0x77, 0x42, 0x82, 0x19, 0x84, 0x1a, - 0xfa, 0x6d, 0x12, 0xc7, 0x4e, 0x8b, 0x64, 0x0d, 0xfd, 0x45, 0xde, 0x8c, 0x25, 0x1c, 0x45, 0x80, - 0x3c, 0x27, 0x4e, 0x56, 0x23, 0xc7, 0x8f, 0x19, 0xf9, 0x55, 0xb7, 0x4d, 0xc4, 0x00, 0xff, 0xc5, - 0xfe, 0x66, 0x0c, 0x7d, 0xa2, 0xfe, 0xc8, 0xdd, 0xdd, 0x09, 0xb4, 0xd0, 0x45, 0x09, 0xe7, 0x50, - 0xb7, 0xbf, 0x64, 0xc1, 0x23, 0xf9, 0xb6, 0x18, 0x7a, 0x0a, 0x06, 0xf9, 0x96, 0x4f, 0xbc, 0x9d, - 0xfe, 0x24, 0xac, 0x15, 0x0b, 0x28, 0x9a, 0x82, 0x9a, 0xd2, 0x13, 0xe2, 0x1d, 0x4f, 0x09, 0xd4, - 0x9a, 0x56, 0x2e, 0x1a, 0x87, 0x0e, 0x1a, 0xfd, 0x23, 0x2c, 0x37, 0x35, 0x68, 0x6c, 0x93, 0xc4, - 0x20, 0xf6, 0x7f, 0xb4, 0xe0, 0x84, 0xd1, 0xab, 0xfb, 0x60, 0x9a, 0xfb, 0x69, 0xd3, 0x7c, 0xbe, - 0xb0, 0xf9, 0xdc, 0xc3, 0x36, 0xff, 0x9c, 0x05, 0xe7, 0x0d, 0xac, 0x45, 0x27, 0x69, 0x6c, 0x5c, - 0xda, 0x0e, 0x23, 0x12, 0xd3, 0xed, 0x34, 0x7a, 0xdc, 0x90, 0x5b, 0xf5, 0x61, 0x41, 0xa1, 0x7c, - 0x8d, 0xec, 0x70, 0x21, 0xf6, 0x0c, 0x54, 0xf9, 0xe4, 0x0c, 0x22, 0x31, 0xe2, 0xea, 0xdd, 0x96, - 0x44, 0x3b, 0x56, 0x18, 0xc8, 0x86, 0x41, 0x26, 0x9c, 0xe8, 0x62, 0xa5, 0x6a, 0x08, 0xe8, 0x47, - 0xbc, 0xc9, 0x5a, 0xb0, 0x80, 0xd8, 0x71, 0xaa, 0x3b, 0xcb, 0x11, 0x61, 0x1f, 0xb7, 0x79, 0xd9, - 0x25, 0x5e, 0x33, 0xa6, 0xdb, 0x06, 0xc7, 0xf7, 0x83, 0x44, 0xec, 0x00, 0x8c, 0x6d, 0xc3, 0xb4, - 0x6e, 0xc6, 0x26, 0x0e, 0x65, 0xea, 0x39, 0x6b, 0xc4, 0xe3, 0x23, 0x2a, 0x98, 0x2e, 0xb0, 0x16, - 0x2c, 0x20, 0xf6, 0xdd, 0x12, 0xdb, 0xa0, 0xa8, 0xa5, 0x4f, 0xee, 0xc7, 0xee, 0x36, 0x4a, 0xc9, - 0xca, 0xe5, 0xe2, 0x04, 0x17, 0xe9, 0xbd, 0xc3, 0x7d, 0x23, 0x23, 0x2e, 0x71, 0xa1, 0x5c, 0xf7, - 0xde, 0xe5, 0xfe, 0x56, 0x09, 0x26, 0xd2, 0x0f, 0x74, 0x49, 0x5b, 0xba, 0xa5, 0x32, 0x18, 0x65, - 0x9d, 0x18, 0x06, 0x3e, 0x36, 0xf1, 0x7a, 0x08, 0xac, 0xd2, 0x71, 0x0a, 0x2c, 0x53, 0x9e, 0x96, - 0xf7, 0x91, 0xa7, 0x4f, 0xa9, 0x51, 0x1f, 0xc8, 0x08, 0xb0, 0xb4, 0x4e, 0xb9, 0x00, 0x03, 0x71, - 0x42, 0xc2, 0xf1, 0x4a, 0x5a, 0x1e, 0xad, 0x24, 0x24, 0xc4, 0x0c, 0x62, 0xff, 0xb7, 0x12, 0x3c, - 0x9a, 0x1e, 0x43, 0xad, 0x02, 0xde, 0x97, 0x52, 0x01, 0xef, 0x36, 0x55, 0xc0, 0xbd, 0xdd, 0x89, - 0x77, 0xf6, 0x78, 0xec, 0xbb, 0x46, 0x43, 0xa0, 0xb9, 0xcc, 0x28, 0x4e, 0xa5, 0x47, 0xf1, 0xde, - 0xee, 0xc4, 0xe3, 0x3d, 0xde, 0x31, 0x33, 0xcc, 0x4f, 0xc1, 0x60, 0x44, 0x9c, 0x38, 0xf0, 0xc5, - 0x40, 0xab, 0xcf, 0x81, 0x59, 0x2b, 0x16, 0x50, 0xfb, 0xf7, 0x6b, 0xd9, 0xc1, 0x9e, 0xe3, 0x4e, - 0xb8, 0x20, 0x42, 0x2e, 0x0c, 0x30, 0xb3, 0x9e, 0x8b, 0x86, 0x6b, 0x47, 0x5b, 0x46, 0x54, 0x0d, - 0x28, 0xd2, 0xf5, 0x2a, 0xfd, 0x6a, 0xb4, 0x09, 0x33, 0x16, 0x68, 0x1b, 0xaa, 0x0d, 0x69, 0x6d, - 0x97, 0x8a, 0xf0, 0x4b, 0x09, 0x5b, 0x5b, 0x73, 0x1c, 0xa1, 0xf2, 0x5a, 0x99, 0xe8, 0x8a, 0x1b, - 0x22, 0x50, 0x6e, 0xb9, 0x89, 0xf8, 0xac, 0x47, 0xdc, 0x4f, 0xcd, 0xb9, 0xc6, 0x2b, 0x0e, 0x51, - 0x25, 0x32, 0xe7, 0x26, 0x98, 0xd2, 0x47, 0x3f, 0x63, 0xc1, 0x70, 0xdc, 0x68, 0x2f, 0x47, 0xc1, - 0x96, 0xdb, 0x24, 0x91, 0xb0, 0xa6, 0x8e, 0x28, 0x9a, 0x56, 0x66, 0x16, 0x25, 0x41, 0xcd, 0x97, - 0xef, 0x6f, 0x35, 0x04, 0x9b, 0x7c, 0xe9, 0x2e, 0xe3, 0x51, 0xf1, 0xee, 0xb3, 0xa4, 0xe1, 0x52, - 0xfd, 0x27, 0x37, 0x55, 0x6c, 0xa6, 0x1c, 0xd9, 0xba, 0x9c, 0xed, 0x34, 0x36, 0xe9, 0x7a, 0xd3, - 0x1d, 0x7a, 0xe7, 0xdd, 0xdd, 0x89, 0x47, 0x67, 0xf2, 0x79, 0xe2, 0x5e, 0x9d, 0x61, 0x03, 0x16, - 0x76, 0x3c, 0x0f, 0x93, 0xd7, 0x3b, 0x84, 0xb9, 0x4c, 0x0a, 0x18, 0xb0, 0x65, 0x4d, 0x30, 0x33, - 0x60, 0x06, 0x04, 0x9b, 0x7c, 0xd1, 0xeb, 0x30, 0xd8, 0x76, 0x92, 0xc8, 0xdd, 0x16, 0x7e, 0x92, - 0x23, 0xda, 0xfb, 0x8b, 0x8c, 0x96, 0x66, 0xce, 0x34, 0x35, 0x6f, 0xc4, 0x82, 0x11, 0x6a, 0x43, - 0xa5, 0x4d, 0xa2, 0x16, 0x19, 0xaf, 0x16, 0xe1, 0x13, 0x5e, 0xa4, 0xa4, 0x34, 0xc3, 0x1a, 0xb5, - 0x8e, 0x58, 0x1b, 0xe6, 0x5c, 0xd0, 0xab, 0x50, 0x8d, 0x89, 0x47, 0x1a, 0xd4, 0xbe, 0xa9, 0x31, - 0x8e, 0x3f, 0xd4, 0xa7, 0xad, 0x47, 0x0d, 0x8b, 0x15, 0xf1, 0x28, 0x5f, 0x60, 0xf2, 0x1f, 0x56, - 0x24, 0xe9, 0x00, 0x86, 0x5e, 0xa7, 0xe5, 0xfa, 0xe3, 0x50, 0xc4, 0x00, 0x2e, 0x33, 0x5a, 0x99, - 0x01, 0xe4, 0x8d, 0x58, 0x30, 0xb2, 0xff, 0xb3, 0x05, 0x28, 0x2d, 0xd4, 0xee, 0x83, 0x51, 0xfb, - 0x7a, 0xda, 0xa8, 0x5d, 0x28, 0xd2, 0xea, 0xe8, 0x61, 0xd7, 0xfe, 0x46, 0x0d, 0x32, 0xea, 0xe0, - 0x3a, 0x89, 0x13, 0xd2, 0x7c, 0x5b, 0x84, 0xbf, 0x2d, 0xc2, 0xdf, 0x16, 0xe1, 0x4a, 0x84, 0xaf, - 0x65, 0x44, 0xf8, 0x7b, 0x8d, 0x55, 0xaf, 0x0f, 0x55, 0x5f, 0x53, 0xa7, 0xae, 0x66, 0x0f, 0x0c, - 0x04, 0x2a, 0x09, 0xae, 0xae, 0x2c, 0x5d, 0xcf, 0x95, 0xd9, 0xaf, 0xa5, 0x65, 0xf6, 0x51, 0x59, - 0xfc, 0xff, 0x20, 0xa5, 0xff, 0x95, 0x05, 0xef, 0x4a, 0x4b, 0x2f, 0x39, 0x73, 0xe6, 0x5b, 0x7e, - 0x10, 0x91, 0x59, 0x77, 0x7d, 0x9d, 0x44, 0xc4, 0x6f, 0x90, 0x58, 0x79, 0x31, 0xac, 0x5e, 0x5e, - 0x0c, 0xf4, 0x3c, 0x8c, 0xdc, 0x8e, 0x03, 0x7f, 0x39, 0x70, 0x7d, 0x21, 0x82, 0xe8, 0x46, 0xf8, - 0xe4, 0xdd, 0xdd, 0x89, 0x11, 0x3a, 0xa2, 0xb2, 0x1d, 0xa7, 0xb0, 0xd0, 0x0c, 0x9c, 0xba, 0xfd, - 0xfa, 0xb2, 0x93, 0x18, 0xee, 0x00, 0xb9, 0x71, 0x67, 0x07, 0x16, 0x57, 0x5f, 0xce, 0x00, 0x71, - 0x37, 0xbe, 0xfd, 0x37, 0x4b, 0x70, 0x2e, 0xf3, 0x22, 0x81, 0xe7, 0x05, 0x9d, 0x84, 0x6e, 0x6a, - 0xd0, 0x57, 0x2c, 0x38, 0xd9, 0x4e, 0x7b, 0x1c, 0x62, 0xe1, 0xd8, 0x7d, 0x7f, 0x61, 0x3a, 0x22, - 0xe3, 0xd2, 0xa8, 0x8f, 0x8b, 0x11, 0x3a, 0x99, 0x01, 0xc4, 0xb8, 0xab, 0x2f, 0xe8, 0x55, 0xa8, - 0xb5, 0x9d, 0xed, 0x1b, 0x61, 0xd3, 0x49, 0xe4, 0x7e, 0xb2, 0xb7, 0x1b, 0xa0, 0x93, 0xb8, 0xde, - 0x24, 0x3f, 0xae, 0x9f, 0x9c, 0xf7, 0x93, 0xa5, 0x68, 0x25, 0x89, 0x5c, 0xbf, 0xc5, 0xdd, 0x79, - 0x8b, 0x92, 0x0c, 0xd6, 0x14, 0xed, 0x2f, 0x5b, 0x59, 0x25, 0xa5, 0x46, 0x27, 0x72, 0x12, 0xd2, - 0xda, 0x41, 0x1f, 0x81, 0x0a, 0xdd, 0xf8, 0xc9, 0x51, 0xb9, 0x55, 0xa4, 0xe6, 0x34, 0xbe, 0x84, - 0x56, 0xa2, 0xf4, 0x5f, 0x8c, 0x39, 0x53, 0xfb, 0x2b, 0xb5, 0xac, 0xb1, 0xc0, 0x0e, 0x6f, 0x2f, - 0x02, 0xb4, 0x82, 0x55, 0xd2, 0x0e, 0x3d, 0x3a, 0x2c, 0x16, 0x3b, 0x01, 0x50, 0xbe, 0x8e, 0x39, - 0x05, 0xc1, 0x06, 0x16, 0xfa, 0xcb, 0x16, 0x40, 0x4b, 0xce, 0x79, 0x69, 0x08, 0xdc, 0x28, 0xf2, - 0x75, 0xf4, 0x8a, 0xd2, 0x7d, 0x51, 0x0c, 0xb1, 0xc1, 0x1c, 0xfd, 0xb4, 0x05, 0xd5, 0x44, 0x76, - 0x9f, 0xab, 0xc6, 0xd5, 0x22, 0x7b, 0x22, 0x5f, 0x5a, 0xdb, 0x44, 0x6a, 0x48, 0x14, 0x5f, 0xf4, - 0xb3, 0x16, 0x40, 0xbc, 0xe3, 0x37, 0x96, 0x03, 0xcf, 0x6d, 0xec, 0x08, 0x8d, 0x79, 0xb3, 0x50, - 0x7f, 0x8c, 0xa2, 0x5e, 0x1f, 0xa3, 0xa3, 0xa1, 0xff, 0x63, 0x83, 0x33, 0xfa, 0x18, 0x54, 0x63, - 0x31, 0xdd, 0x84, 0x8e, 0x5c, 0x2d, 0xd6, 0x2b, 0xc4, 0x69, 0x0b, 0xf1, 0x2a, 0xfe, 0x61, 0xc5, - 0x13, 0xfd, 0xbc, 0x05, 0x27, 0xc2, 0xb4, 0x9f, 0x4f, 0xa8, 0xc3, 0xe2, 0x64, 0x40, 0xc6, 0x8f, - 0x58, 0x3f, 0x7d, 0x77, 0x77, 0xe2, 0x44, 0xa6, 0x11, 0x67, 0x7b, 0x41, 0x25, 0xa0, 0x9e, 0xc1, - 0x4b, 0x21, 0xf7, 0x39, 0x0e, 0x69, 0x09, 0x38, 0x97, 0x05, 0xe2, 0x6e, 0x7c, 0xb4, 0x0c, 0x67, - 0x68, 0xef, 0x76, 0xb8, 0xf9, 0x29, 0xd5, 0x4b, 0xcc, 0x94, 0x61, 0xb5, 0xfe, 0x98, 0x98, 0x21, - 0xcc, 0xab, 0x9f, 0xc5, 0xc1, 0xb9, 0x4f, 0xa2, 0xdf, 0xb5, 0xe0, 0x31, 0x97, 0xa9, 0x01, 0xd3, - 0x61, 0xae, 0x35, 0x82, 0x38, 0x89, 0x25, 0x85, 0xca, 0x8a, 0x5e, 0xea, 0xa7, 0xfe, 0x17, 0xc4, - 0x1b, 0x3c, 0x36, 0xbf, 0x47, 0x97, 0xf0, 0x9e, 0x1d, 0x46, 0x3f, 0x0c, 0xa3, 0x72, 0x5d, 0x2c, - 0x53, 0x11, 0xcc, 0x14, 0x6d, 0xad, 0x7e, 0xea, 0xee, 0xee, 0xc4, 0xe8, 0xaa, 0x09, 0xc0, 0x69, - 0x3c, 0xfb, 0x9b, 0xa5, 0xd4, 0x79, 0x88, 0x72, 0x42, 0x32, 0x71, 0xd3, 0x90, 0xfe, 0x1f, 0x29, - 0x3d, 0x0b, 0x15, 0x37, 0xca, 0xbb, 0xa4, 0xc5, 0x8d, 0x6a, 0x8a, 0xb1, 0xc1, 0x9c, 0x1a, 0xa5, - 0xa7, 0x9c, 0xac, 0xab, 0x53, 0x48, 0xc0, 0x57, 0x8b, 0xec, 0x52, 0xf7, 0xe9, 0xd5, 0x39, 0xd1, - 0xb5, 0x53, 0x5d, 0x20, 0xdc, 0xdd, 0x25, 0xfb, 0x9b, 0xe9, 0x33, 0x18, 0x63, 0xf1, 0xf6, 0x71, - 0xbe, 0xf4, 0x79, 0x0b, 0x86, 0xa3, 0xc0, 0xf3, 0x5c, 0xbf, 0x45, 0x05, 0x8d, 0xd0, 0x96, 0x1f, - 0x3c, 0x16, 0x85, 0x25, 0x24, 0x0a, 0x33, 0x6d, 0xb1, 0xe6, 0x89, 0xcd, 0x0e, 0xd8, 0x7f, 0x62, - 0xc1, 0x78, 0x2f, 0x81, 0x88, 0x08, 0xbc, 0x53, 0xae, 0x76, 0x15, 0x5d, 0xb1, 0xe4, 0xcf, 0x12, - 0x8f, 0x28, 0xc7, 0x73, 0xb5, 0xfe, 0xa4, 0x78, 0xcd, 0x77, 0x2e, 0xf7, 0x46, 0xc5, 0x7b, 0xd1, - 0x41, 0xaf, 0xc0, 0x49, 0xe3, 0xbd, 0x62, 0x35, 0x30, 0xb5, 0xfa, 0x24, 0xb5, 0x40, 0xa6, 0x33, - 0xb0, 0x7b, 0xbb, 0x13, 0x8f, 0x64, 0xdb, 0x84, 0xc4, 0xee, 0xa2, 0x63, 0xff, 0x72, 0x29, 0xfb, - 0xb5, 0x94, 0xb2, 0x7d, 0xcb, 0xea, 0xda, 0xce, 0xbf, 0xff, 0x38, 0x14, 0x1c, 0xdb, 0xf8, 0xab, - 0x00, 0x8e, 0xde, 0x38, 0x0f, 0xf0, 0x84, 0xd8, 0xfe, 0x37, 0x03, 0xb0, 0x47, 0xcf, 0xfa, 0xb0, - 0x9e, 0x0f, 0x7c, 0xac, 0xf8, 0x59, 0x4b, 0x1d, 0x39, 0x95, 0xd9, 0x22, 0x6f, 0x1e, 0xd7, 0xd8, - 0xf3, 0x0d, 0x4c, 0xcc, 0xa3, 0x14, 0x94, 0x1b, 0x3b, 0x7d, 0xb8, 0x85, 0xbe, 0x6a, 0xa5, 0x0f, - 0xcd, 0x78, 0xd8, 0x99, 0x7b, 0x6c, 0x7d, 0x32, 0x4e, 0xe2, 0x78, 0xc7, 0xf4, 0xf9, 0x4d, 0xaf, - 0x33, 0xba, 0x49, 0x80, 0x75, 0xd7, 0x77, 0x3c, 0xf7, 0x0d, 0xba, 0x3d, 0xa9, 0x30, 0x0d, 0xcb, - 0x4c, 0x96, 0xcb, 0xaa, 0x15, 0x1b, 0x18, 0xe7, 0xff, 0x12, 0x0c, 0x1b, 0x6f, 0x9e, 0x13, 0x5c, - 0x71, 0xc6, 0x0c, 0xae, 0xa8, 0x19, 0x31, 0x11, 0xe7, 0xdf, 0x0b, 0x27, 0xb3, 0x1d, 0x3c, 0xc8, - 0xf3, 0xf6, 0xff, 0x1a, 0xca, 0x9e, 0x62, 0xad, 0x92, 0xa8, 0x4d, 0xbb, 0xf6, 0xb6, 0x67, 0xe9, - 0x6d, 0xcf, 0xd2, 0xdb, 0x9e, 0x25, 0xf3, 0x70, 0x40, 0x78, 0x4d, 0x86, 0xee, 0x93, 0xd7, 0x24, - 0xe5, 0x07, 0xaa, 0x16, 0xee, 0x07, 0xb2, 0xef, 0x56, 0x20, 0x65, 0x47, 0xf1, 0xf1, 0xfe, 0x01, - 0x18, 0x8a, 0x48, 0x18, 0xdc, 0xc0, 0x0b, 0x42, 0x87, 0xe8, 0x00, 0x7a, 0xde, 0x8c, 0x25, 0x9c, - 0xea, 0x9a, 0xd0, 0x49, 0x36, 0x84, 0x12, 0x51, 0xba, 0x66, 0xd9, 0x49, 0x36, 0x30, 0x83, 0xa0, - 0xf7, 0xc2, 0x58, 0xe2, 0x44, 0x2d, 0x6a, 0x6f, 0x6f, 0xb1, 0xcf, 0x2a, 0xce, 0x3a, 0x1f, 0x11, - 0xb8, 0x63, 0xab, 0x29, 0x28, 0xce, 0x60, 0xa3, 0xd7, 0x61, 0x60, 0x83, 0x78, 0x6d, 0x31, 0xe4, - 0x2b, 0xc5, 0xc9, 0x78, 0xf6, 0xae, 0x57, 0x88, 0xd7, 0xe6, 0x12, 0x88, 0xfe, 0xc2, 0x8c, 0x15, - 0x9d, 0x6f, 0xb5, 0xcd, 0x4e, 0x9c, 0x04, 0x6d, 0xf7, 0x0d, 0xe9, 0xe2, 0x7b, 0x7f, 0xc1, 0x8c, - 0xaf, 0x49, 0xfa, 0xdc, 0x97, 0xa2, 0xfe, 0x62, 0xcd, 0x99, 0xf5, 0xa3, 0xe9, 0x46, 0xec, 0x53, - 0xed, 0x08, 0x4f, 0x5d, 0xd1, 0xfd, 0x98, 0x95, 0xf4, 0x79, 0x3f, 0xd4, 0x5f, 0xac, 0x39, 0xa3, - 0x1d, 0x35, 0xef, 0x87, 0x59, 0x1f, 0x6e, 0x14, 0xdc, 0x07, 0x3e, 0xe7, 0x73, 0xe7, 0xff, 0x93, - 0x50, 0x69, 0x6c, 0x38, 0x51, 0x32, 0x3e, 0xc2, 0x26, 0x8d, 0xf2, 0xe9, 0xcc, 0xd0, 0x46, 0xcc, - 0x61, 0xe8, 0x71, 0x28, 0x47, 0x64, 0x9d, 0xc5, 0x6d, 0x1a, 0x11, 0x3d, 0x98, 0xac, 0x63, 0xda, - 0x6e, 0xff, 0x62, 0x29, 0x6d, 0x2e, 0xa5, 0xdf, 0x9b, 0xcf, 0xf6, 0x46, 0x27, 0x8a, 0xa5, 0xdf, - 0xc7, 0x98, 0xed, 0xac, 0x19, 0x4b, 0x38, 0xfa, 0x84, 0x05, 0x43, 0xb7, 0xe3, 0xc0, 0xf7, 0x49, - 0x22, 0x54, 0xd3, 0xcd, 0x82, 0x87, 0xe2, 0x2a, 0xa7, 0xae, 0xfb, 0x20, 0x1a, 0xb0, 0xe4, 0x4b, - 0xbb, 0x4b, 0xb6, 0x1b, 0x5e, 0xa7, 0xd9, 0x15, 0xa4, 0x71, 0x89, 0x37, 0x63, 0x09, 0xa7, 0xa8, - 0xae, 0xcf, 0x51, 0x07, 0xd2, 0xa8, 0xf3, 0xbe, 0x40, 0x15, 0x70, 0xfb, 0xaf, 0x0f, 0xc2, 0xd9, - 0xdc, 0xc5, 0x41, 0x0d, 0x19, 0x66, 0x2a, 0x5c, 0x76, 0x3d, 0x22, 0xc3, 0x93, 0x98, 0x21, 0x73, - 0x53, 0xb5, 0x62, 0x03, 0x03, 0xfd, 0x14, 0x40, 0xe8, 0x44, 0x4e, 0x9b, 0x28, 0xbf, 0xec, 0x91, - 0xed, 0x05, 0xda, 0x8f, 0x65, 0x49, 0x53, 0xef, 0x4d, 0x55, 0x53, 0x8c, 0x0d, 0x96, 0xe8, 0x05, - 0x18, 0x8e, 0x88, 0x47, 0x9c, 0x98, 0x85, 0xfd, 0x66, 0x73, 0x18, 0xb0, 0x06, 0x61, 0x13, 0x0f, - 0x3d, 0xa5, 0x22, 0xb9, 0x32, 0x11, 0x2d, 0xe9, 0x68, 0x2e, 0xf4, 0xa6, 0x05, 0x63, 0xeb, 0xae, - 0x47, 0x34, 0x77, 0x91, 0x71, 0xb0, 0x74, 0xf4, 0x97, 0xbc, 0x6c, 0xd2, 0xd5, 0x12, 0x32, 0xd5, - 0x1c, 0xe3, 0x0c, 0x7b, 0xfa, 0x99, 0xb7, 0x48, 0xc4, 0x44, 0xeb, 0x60, 0xfa, 0x33, 0xdf, 0xe4, - 0xcd, 0x58, 0xc2, 0xd1, 0x34, 0x9c, 0x08, 0x9d, 0x38, 0x9e, 0x89, 0x48, 0x93, 0xf8, 0x89, 0xeb, - 0x78, 0x3c, 0x1f, 0xa0, 0xaa, 0xe3, 0x81, 0x97, 0xd3, 0x60, 0x9c, 0xc5, 0x47, 0x1f, 0x80, 0x47, - 0xb9, 0xe3, 0x63, 0xd1, 0x8d, 0x63, 0xd7, 0x6f, 0xe9, 0x69, 0x20, 0xfc, 0x3f, 0x13, 0x82, 0xd4, - 0xa3, 0xf3, 0xf9, 0x68, 0xb8, 0xd7, 0xf3, 0xe8, 0x19, 0xa8, 0xc6, 0x9b, 0x6e, 0x38, 0x13, 0x35, - 0x63, 0x76, 0xe8, 0x51, 0xd5, 0xde, 0xc6, 0x15, 0xd1, 0x8e, 0x15, 0x06, 0x6a, 0xc0, 0x08, 0xff, - 0x24, 0x3c, 0x14, 0x4d, 0xc8, 0xc7, 0x67, 0x7b, 0xaa, 0x47, 0x91, 0xb2, 0x36, 0x89, 0x9d, 0x3b, - 0x97, 0xe4, 0x11, 0x0c, 0x3f, 0x31, 0xb8, 0x69, 0x90, 0xc1, 0x29, 0xa2, 0xf6, 0x2f, 0x94, 0xd2, - 0x3b, 0x6e, 0x73, 0x91, 0xa2, 0x98, 0x2e, 0xc5, 0xe4, 0xa6, 0x13, 0x49, 0x6f, 0xcc, 0x11, 0xd3, - 0x16, 0x04, 0xdd, 0x9b, 0x4e, 0x64, 0x2e, 0x6a, 0xc6, 0x00, 0x4b, 0x4e, 0xe8, 0x36, 0x0c, 0x24, - 0x9e, 0x53, 0x50, 0x9e, 0x93, 0xc1, 0x51, 0x3b, 0x40, 0x16, 0xa6, 0x63, 0xcc, 0x78, 0xa0, 0xc7, - 0xa8, 0xd5, 0xbf, 0x26, 0x8f, 0x48, 0x84, 0xa1, 0xbe, 0x16, 0x63, 0xd6, 0x6a, 0xff, 0x0a, 0xe4, - 0xc8, 0x55, 0xa5, 0xc8, 0xd0, 0x45, 0x00, 0xba, 0x81, 0x5c, 0x8e, 0xc8, 0xba, 0xbb, 0x2d, 0x0c, - 0x09, 0xb5, 0x76, 0xaf, 0x2b, 0x08, 0x36, 0xb0, 0xe4, 0x33, 0x2b, 0x9d, 0x75, 0xfa, 0x4c, 0xa9, - 0xfb, 0x19, 0x0e, 0xc1, 0x06, 0x16, 0x7a, 0x1e, 0x06, 0xdd, 0xb6, 0xd3, 0x52, 0x21, 0x98, 0x8f, - 0xd1, 0x45, 0x3b, 0xcf, 0x5a, 0xee, 0xed, 0x4e, 0x8c, 0xa9, 0x0e, 0xb1, 0x26, 0x2c, 0x70, 0xd1, - 0x2f, 0x5b, 0x30, 0xd2, 0x08, 0xda, 0xed, 0xc0, 0xe7, 0xdb, 0x2e, 0xb1, 0x87, 0xbc, 0x7d, 0x5c, - 0x6a, 0x7e, 0x72, 0xc6, 0x60, 0xc6, 0x37, 0x91, 0x2a, 0x21, 0xcb, 0x04, 0xe1, 0x54, 0xaf, 0xcc, - 0xb5, 0x5d, 0xd9, 0x67, 0x6d, 0xff, 0xba, 0x05, 0xa7, 0xf8, 0xb3, 0xc6, 0x6e, 0x50, 0xe4, 0x1e, - 0x05, 0xc7, 0xfc, 0x5a, 0x5d, 0x1b, 0x64, 0xe5, 0xa5, 0xeb, 0x82, 0xe3, 0xee, 0x4e, 0xa2, 0x39, - 0x38, 0xb5, 0x1e, 0x44, 0x0d, 0x62, 0x0e, 0x84, 0x10, 0x4c, 0x8a, 0xd0, 0xe5, 0x2c, 0x02, 0xee, - 0x7e, 0x06, 0xdd, 0x84, 0x47, 0x8c, 0x46, 0x73, 0x1c, 0xb8, 0x6c, 0x7a, 0x42, 0x50, 0x7b, 0xe4, - 0x72, 0x2e, 0x16, 0xee, 0xf1, 0x74, 0xda, 0x61, 0x52, 0xeb, 0xc3, 0x61, 0xf2, 0x1a, 0x9c, 0x6b, - 0x74, 0x8f, 0xcc, 0x56, 0xdc, 0x59, 0x8b, 0xb9, 0xa4, 0xaa, 0xd6, 0xbf, 0x4f, 0x10, 0x38, 0x37, - 0xd3, 0x0b, 0x11, 0xf7, 0xa6, 0x81, 0x3e, 0x02, 0xd5, 0x88, 0xb0, 0xaf, 0x12, 0x8b, 0x44, 0x9c, - 0x23, 0xee, 0x92, 0xb5, 0x05, 0xca, 0xc9, 0x6a, 0xd9, 0x2b, 0x1a, 0x62, 0xac, 0x38, 0xa2, 0x3b, - 0x30, 0x14, 0x3a, 0x49, 0x63, 0x43, 0xa4, 0xdf, 0x1c, 0x39, 0xfe, 0x45, 0x31, 0x67, 0x3e, 0x70, - 0x3d, 0xc9, 0x97, 0x39, 0x13, 0x2c, 0xb9, 0x51, 0x6b, 0xa4, 0x11, 0xb4, 0xc3, 0xc0, 0x27, 0x7e, - 0x12, 0x8f, 0x8f, 0x6a, 0x6b, 0x64, 0x46, 0xb5, 0x62, 0x03, 0xe3, 0xfc, 0xfb, 0xe0, 0x54, 0xd7, - 0xc2, 0x3b, 0x90, 0x73, 0x65, 0x16, 0x1e, 0xc9, 0x9f, 0xe2, 0x07, 0x72, 0xb1, 0xfc, 0xe3, 0x4c, - 0x90, 0xab, 0x61, 0xf6, 0xf6, 0xe1, 0xae, 0x73, 0xa0, 0x4c, 0xfc, 0x2d, 0x21, 0xf1, 0x2f, 0x1f, - 0x6d, 0xa4, 0x2f, 0xf9, 0x5b, 0x7c, 0x85, 0x32, 0x9f, 0xc4, 0x25, 0x7f, 0x0b, 0x53, 0xda, 0xe8, - 0x8b, 0x56, 0xca, 0x6c, 0xe3, 0x4e, 0xbe, 0x0f, 0x1d, 0x8b, 0x9d, 0xdf, 0xb7, 0x25, 0x67, 0xff, - 0xdb, 0x12, 0x5c, 0xd8, 0x8f, 0x48, 0x1f, 0xc3, 0xf7, 0x24, 0x0c, 0xc6, 0xec, 0xd8, 0x5a, 0x88, - 0xd0, 0x61, 0x3a, 0xb3, 0xf8, 0x41, 0xf6, 0x6b, 0x58, 0x80, 0x90, 0x07, 0xe5, 0xb6, 0x13, 0x0a, - 0xdf, 0xcf, 0xfc, 0x51, 0xd3, 0x5e, 0xe8, 0x7f, 0xc7, 0x5b, 0x74, 0x42, 0xee, 0x51, 0x30, 0x1a, - 0x30, 0x65, 0x83, 0x12, 0xa8, 0x38, 0x51, 0xe4, 0xc8, 0x33, 0xd2, 0x6b, 0xc5, 0xf0, 0x9b, 0xa6, - 0x24, 0xf9, 0x11, 0x53, 0xaa, 0x09, 0x73, 0x66, 0xf6, 0x67, 0x87, 0x52, 0xa9, 0x1f, 0xec, 0xe0, - 0x3b, 0x86, 0x41, 0xe1, 0xf2, 0xb1, 0x8a, 0xce, 0x36, 0xe2, 0xb9, 0x7b, 0x6c, 0x57, 0x27, 0x32, - 0xa0, 0x05, 0x2b, 0xf4, 0x19, 0x8b, 0xe5, 0x19, 0xcb, 0x74, 0x18, 0xb1, 0x97, 0x3a, 0x9e, 0xb4, - 0x67, 0x33, 0x7b, 0x59, 0x36, 0x62, 0x93, 0x3b, 0xd5, 0xb1, 0x21, 0xcf, 0x98, 0xcb, 0xee, 0xa8, - 0x64, 0x26, 0xb2, 0x84, 0xa3, 0xed, 0x9c, 0x03, 0xee, 0x02, 0x72, 0x55, 0xfb, 0x38, 0xd2, 0xfe, - 0xaa, 0x05, 0xa7, 0xdc, 0xec, 0x49, 0xa5, 0xd8, 0x79, 0x1c, 0x31, 0x84, 0xa2, 0xf7, 0x41, 0xa8, - 0x52, 0xbe, 0x5d, 0x20, 0xdc, 0xdd, 0x19, 0xd4, 0x84, 0x01, 0xd7, 0x5f, 0x0f, 0x84, 0xc9, 0x51, - 0x3f, 0x5a, 0xa7, 0xe6, 0xfd, 0xf5, 0x40, 0xaf, 0x66, 0xfa, 0x0f, 0x33, 0xea, 0x68, 0x01, 0xce, - 0x44, 0xc2, 0x37, 0x74, 0xc5, 0x8d, 0xe9, 0x0e, 0x7e, 0xc1, 0x6d, 0xbb, 0x09, 0x33, 0x17, 0xca, - 0xf5, 0xf1, 0xbb, 0xbb, 0x13, 0x67, 0x70, 0x0e, 0x1c, 0xe7, 0x3e, 0x85, 0xde, 0x80, 0x21, 0x99, - 0x18, 0x5d, 0x2d, 0x62, 0x17, 0xd7, 0x3d, 0xff, 0xd5, 0x64, 0x5a, 0x11, 0x39, 0xd0, 0x92, 0xa1, - 0xfd, 0xe6, 0x30, 0x74, 0x1f, 0x62, 0xa2, 0x8f, 0x42, 0x2d, 0x52, 0xc9, 0xda, 0x56, 0x11, 0xca, - 0x55, 0x7e, 0x5f, 0x71, 0x80, 0xaa, 0x0c, 0x17, 0x9d, 0x96, 0xad, 0x39, 0xd2, 0xed, 0x45, 0xac, - 0xcf, 0x3a, 0x0b, 0x98, 0xdb, 0x82, 0xab, 0x3e, 0xc7, 0xda, 0xf1, 0x1b, 0x98, 0xf1, 0x40, 0x11, - 0x0c, 0x6e, 0x10, 0xc7, 0x4b, 0x36, 0x8a, 0x71, 0xb9, 0x5f, 0x61, 0xb4, 0xb2, 0x29, 0x3b, 0xbc, - 0x15, 0x0b, 0x4e, 0x68, 0x1b, 0x86, 0x36, 0xf8, 0x04, 0x10, 0x16, 0xff, 0xe2, 0x51, 0x07, 0x37, - 0x35, 0xab, 0xf4, 0xe7, 0x16, 0x0d, 0x58, 0xb2, 0x63, 0xd1, 0x31, 0xc6, 0xf9, 0x3d, 0x5f, 0xba, - 0xc5, 0x65, 0x2b, 0xf5, 0x7f, 0x78, 0xff, 0x61, 0x18, 0x89, 0x48, 0x23, 0xf0, 0x1b, 0xae, 0x47, - 0x9a, 0xd3, 0xd2, 0x9d, 0x7e, 0x90, 0x1c, 0x17, 0xb6, 0x6b, 0xc6, 0x06, 0x0d, 0x9c, 0xa2, 0x88, - 0x3e, 0x6d, 0xc1, 0x98, 0xca, 0xf0, 0xa4, 0x1f, 0x84, 0x08, 0xf7, 0xed, 0x42, 0x41, 0xf9, 0xa4, - 0x8c, 0x66, 0x1d, 0xdd, 0xdd, 0x9d, 0x18, 0x4b, 0xb7, 0xe1, 0x0c, 0x5f, 0xf4, 0x0a, 0x40, 0xb0, - 0xc6, 0x43, 0x60, 0xa6, 0x13, 0xe1, 0xcb, 0x3d, 0xc8, 0xab, 0x8e, 0xf1, 0x64, 0x37, 0x49, 0x01, - 0x1b, 0xd4, 0xd0, 0x35, 0x00, 0xbe, 0x6c, 0x56, 0x77, 0x42, 0xb9, 0x2d, 0x90, 0x49, 0x4a, 0xb0, - 0xa2, 0x20, 0xf7, 0x76, 0x27, 0xba, 0x7d, 0x6b, 0x2c, 0xcc, 0xc0, 0x78, 0x1c, 0xfd, 0x24, 0x0c, - 0xc5, 0x9d, 0x76, 0xdb, 0x51, 0x9e, 0xde, 0x02, 0xd3, 0xe7, 0x38, 0x5d, 0x43, 0x14, 0xf1, 0x06, - 0x2c, 0x39, 0xa2, 0xdb, 0x54, 0xa8, 0xc6, 0xc2, 0xe9, 0xc7, 0x56, 0x11, 0xb7, 0x09, 0x86, 0xd9, - 0x3b, 0xbd, 0x47, 0x46, 0xf4, 0xe0, 0x1c, 0x9c, 0x7b, 0xbb, 0x13, 0x8f, 0xa4, 0xdb, 0x17, 0x02, - 0x91, 0xd0, 0x96, 0x4b, 0x13, 0x5d, 0x95, 0x75, 0x52, 0xe8, 0x6b, 0xcb, 0xf4, 0xfd, 0xa7, 0x75, - 0x9d, 0x14, 0xd6, 0xdc, 0x7b, 0xcc, 0xcc, 0x87, 0xd1, 0x22, 0x9c, 0x6e, 0x04, 0x7e, 0x12, 0x05, - 0x9e, 0xc7, 0x8b, 0xff, 0xf0, 0x1d, 0x1a, 0xf7, 0x04, 0xbf, 0x53, 0x74, 0xfb, 0xf4, 0x4c, 0x37, - 0x0a, 0xce, 0x7b, 0xce, 0xf6, 0xd3, 0xb1, 0x81, 0x62, 0x70, 0x9e, 0x87, 0x11, 0xb2, 0x9d, 0x90, - 0xc8, 0x77, 0xbc, 0x1b, 0x78, 0x41, 0xfa, 0x40, 0xd9, 0x1a, 0xb8, 0x64, 0xb4, 0xe3, 0x14, 0x16, - 0xb2, 0x95, 0x5b, 0xc2, 0x48, 0xd2, 0xe4, 0x6e, 0x09, 0xe9, 0x84, 0xb0, 0xff, 0x77, 0x29, 0x65, - 0x90, 0xad, 0x46, 0x84, 0xa0, 0x00, 0x2a, 0x7e, 0xd0, 0x54, 0xb2, 0xff, 0x6a, 0x31, 0xb2, 0xff, - 0x7a, 0xd0, 0x34, 0x8a, 0xa9, 0xd0, 0x7f, 0x31, 0xe6, 0x7c, 0x58, 0xb5, 0x09, 0x59, 0x96, 0x83, - 0x01, 0xc4, 0x46, 0xa3, 0x48, 0xce, 0xaa, 0xda, 0xc4, 0x92, 0xc9, 0x08, 0xa7, 0xf9, 0xa2, 0x4d, - 0xa8, 0x6c, 0x04, 0x71, 0x22, 0xb7, 0x1f, 0x47, 0xdc, 0xe9, 0x5c, 0x09, 0xe2, 0x84, 0x59, 0x11, - 0xea, 0xb5, 0x69, 0x4b, 0x8c, 0x39, 0x0f, 0xfb, 0xbf, 0x58, 0x29, 0x8f, 0xf7, 0x2d, 0x16, 0x27, - 0xbb, 0x45, 0x7c, 0xba, 0xac, 0xcd, 0xc0, 0xa0, 0x1f, 0xce, 0x64, 0x1d, 0xbe, 0xab, 0x57, 0x69, - 0xab, 0x3b, 0x94, 0xc2, 0x24, 0x23, 0x61, 0xc4, 0x10, 0x7d, 0xdc, 0x4a, 0xe7, 0x7f, 0x96, 0x8a, - 0xd8, 0x60, 0x98, 0x39, 0xd0, 0xfb, 0xa6, 0x92, 0xda, 0x5f, 0xb4, 0x60, 0xa8, 0xee, 0x34, 0x36, - 0x83, 0xf5, 0x75, 0xf4, 0x0c, 0x54, 0x9b, 0x9d, 0xc8, 0x4c, 0x45, 0x55, 0xdb, 0xfc, 0x59, 0xd1, - 0x8e, 0x15, 0x06, 0x9d, 0xc3, 0xeb, 0x4e, 0x43, 0x66, 0x42, 0x97, 0xf9, 0x1c, 0xbe, 0xcc, 0x5a, - 0xb0, 0x80, 0xa0, 0x17, 0x60, 0xb8, 0xed, 0x6c, 0xcb, 0x87, 0xb3, 0xee, 0xf6, 0x45, 0x0d, 0xc2, - 0x26, 0x9e, 0xfd, 0x2f, 0x2d, 0x18, 0xaf, 0x3b, 0xb1, 0xdb, 0x98, 0xee, 0x24, 0x1b, 0x75, 0x37, - 0x59, 0xeb, 0x34, 0x36, 0x49, 0xc2, 0xd3, 0xdf, 0x69, 0x2f, 0x3b, 0x31, 0x5d, 0x4a, 0x6a, 0x5f, - 0xa7, 0x7a, 0x79, 0x43, 0xb4, 0x63, 0x85, 0x81, 0xde, 0x80, 0xe1, 0xd0, 0x89, 0xe3, 0x3b, 0x41, - 0xd4, 0xc4, 0x64, 0xbd, 0x98, 0xe2, 0x13, 0x2b, 0xa4, 0x11, 0x91, 0x04, 0x93, 0x75, 0x71, 0x24, - 0xac, 0xe9, 0x63, 0x93, 0x99, 0xfd, 0x79, 0x0b, 0xce, 0xd5, 0x89, 0x13, 0x91, 0x88, 0xd5, 0xaa, - 0x50, 0x2f, 0x32, 0xe3, 0x05, 0x9d, 0x26, 0x7a, 0x1d, 0xaa, 0x09, 0x6d, 0xa6, 0xdd, 0xb2, 0x8a, - 0xed, 0x16, 0x3b, 0xd1, 0x5d, 0x15, 0xc4, 0xb1, 0x62, 0x63, 0xff, 0x0d, 0x0b, 0x46, 0xd8, 0xe1, - 0xd8, 0x2c, 0x49, 0x1c, 0xd7, 0xeb, 0x2a, 0xe9, 0x64, 0xf5, 0x59, 0xd2, 0xe9, 0x02, 0x0c, 0x6c, - 0x04, 0x6d, 0x92, 0x3d, 0xd8, 0xbd, 0x12, 0xd0, 0x6d, 0x35, 0x85, 0xa0, 0xe7, 0xe8, 0x87, 0x77, - 0xfd, 0xc4, 0xa1, 0x4b, 0x40, 0x3a, 0x5f, 0x4f, 0xf0, 0x8f, 0xae, 0x9a, 0xb1, 0x89, 0x63, 0xff, - 0x56, 0x0d, 0x86, 0xc4, 0xe9, 0x7f, 0xdf, 0x25, 0x10, 0xe4, 0xfe, 0xbe, 0xd4, 0x73, 0x7f, 0x1f, - 0xc3, 0x60, 0x83, 0x15, 0x8c, 0x13, 0x66, 0xe4, 0xb5, 0x42, 0xc2, 0x45, 0x78, 0x0d, 0x3a, 0xdd, - 0x2d, 0xfe, 0x1f, 0x0b, 0x56, 0xe8, 0x0b, 0x16, 0x9c, 0x68, 0x04, 0xbe, 0x4f, 0x1a, 0xda, 0xc6, - 0x19, 0x28, 0x22, 0x2a, 0x60, 0x26, 0x4d, 0x54, 0x9f, 0xcc, 0x64, 0x00, 0x38, 0xcb, 0x1e, 0xbd, - 0x04, 0xa3, 0x7c, 0xcc, 0x6e, 0xa6, 0x3c, 0xc6, 0xba, 0xd2, 0x8f, 0x09, 0xc4, 0x69, 0x5c, 0x34, - 0xc9, 0x3d, 0xef, 0xa2, 0xa6, 0xce, 0xa0, 0x76, 0xac, 0x19, 0xd5, 0x74, 0x0c, 0x0c, 0x14, 0x01, - 0x8a, 0xc8, 0x7a, 0x44, 0xe2, 0x0d, 0x11, 0x1d, 0xc1, 0xec, 0xab, 0xa1, 0xc3, 0xa5, 0x4b, 0xe3, - 0x2e, 0x4a, 0x38, 0x87, 0x3a, 0xda, 0x14, 0x1b, 0xcc, 0x6a, 0x11, 0x32, 0x54, 0x7c, 0xe6, 0x9e, - 0xfb, 0xcc, 0x09, 0xa8, 0xc4, 0x1b, 0x4e, 0xd4, 0x64, 0x76, 0x5d, 0x99, 0xa7, 0xe8, 0xac, 0xd0, - 0x06, 0xcc, 0xdb, 0xd1, 0x2c, 0x9c, 0xcc, 0xd4, 0x29, 0x8a, 0x85, 0x67, 0x57, 0xa5, 0x63, 0x64, - 0x2a, 0x1c, 0xc5, 0xb8, 0xeb, 0x09, 0xd3, 0xf9, 0x30, 0xbc, 0x8f, 0xf3, 0x61, 0x47, 0xc5, 0xe0, - 0x71, 0x9f, 0xeb, 0xcb, 0x85, 0x0c, 0x40, 0x5f, 0x01, 0x77, 0x9f, 0xcb, 0x04, 0xdc, 0x8d, 0xb2, - 0x0e, 0xdc, 0x2c, 0xa6, 0x03, 0x07, 0x8f, 0xae, 0x7b, 0x90, 0xd1, 0x72, 0x7f, 0x6e, 0x81, 0xfc, - 0xae, 0x33, 0x4e, 0x63, 0x83, 0xd0, 0x29, 0x83, 0xde, 0x0b, 0x63, 0x6a, 0x0b, 0x3d, 0x13, 0x74, - 0x7c, 0x1e, 0x28, 0x57, 0xd6, 0x47, 0xb8, 0x38, 0x05, 0xc5, 0x19, 0x6c, 0x34, 0x05, 0x35, 0x3a, - 0x4e, 0xfc, 0x51, 0xae, 0x6b, 0xd5, 0x36, 0x7d, 0x7a, 0x79, 0x5e, 0x3c, 0xa5, 0x71, 0x50, 0x00, - 0xa7, 0x3c, 0x27, 0x4e, 0x58, 0x0f, 0xe8, 0x8e, 0xfa, 0x90, 0xc5, 0x0a, 0x58, 0xcc, 0xff, 0x42, - 0x96, 0x10, 0xee, 0xa6, 0x6d, 0x7f, 0x6b, 0x00, 0x46, 0x53, 0x92, 0xf1, 0x80, 0x4a, 0xfa, 0x19, - 0xa8, 0x4a, 0xbd, 0x99, 0x2d, 0xab, 0xa2, 0x94, 0xab, 0xc2, 0xa0, 0x4a, 0x6b, 0x4d, 0x6b, 0xd5, - 0xac, 0x51, 0x61, 0x28, 0x5c, 0x6c, 0xe2, 0x31, 0xa1, 0x9c, 0x78, 0xf1, 0x8c, 0xe7, 0x12, 0x3f, - 0xe1, 0xdd, 0x2c, 0x46, 0x28, 0xaf, 0x2e, 0xac, 0x98, 0x44, 0xb5, 0x50, 0xce, 0x00, 0x70, 0x96, - 0x3d, 0xfa, 0x94, 0x05, 0xa3, 0xce, 0x9d, 0x58, 0x57, 0x35, 0x15, 0xa1, 0x75, 0x47, 0x54, 0x52, - 0xa9, 0x42, 0xa9, 0xdc, 0xe5, 0x9b, 0x6a, 0xc2, 0x69, 0xa6, 0xe8, 0x2d, 0x0b, 0x10, 0xd9, 0x26, - 0x0d, 0x19, 0xfc, 0x27, 0xfa, 0x32, 0x58, 0xc4, 0x4e, 0xf3, 0x52, 0x17, 0x5d, 0x2e, 0xd5, 0xbb, - 0xdb, 0x71, 0x4e, 0x1f, 0xec, 0x7f, 0x56, 0x56, 0x0b, 0x4a, 0xc7, 0x9b, 0x3a, 0x46, 0xdc, 0x9b, - 0x75, 0xf8, 0xb8, 0x37, 0x1d, 0x3f, 0xd0, 0x9d, 0x03, 0x99, 0x4a, 0x99, 0x2a, 0x3d, 0xa0, 0x94, - 0xa9, 0x9f, 0xb6, 0x52, 0x05, 0x84, 0x86, 0x2f, 0xbe, 0x52, 0x6c, 0xac, 0xeb, 0x24, 0x8f, 0x6d, - 0xc8, 0x48, 0xf7, 0x74, 0x48, 0x0b, 0x95, 0xa6, 0x06, 0xda, 0x81, 0xa4, 0xe1, 0xbf, 0x2f, 0xc3, - 0xb0, 0xa1, 0x49, 0x73, 0xcd, 0x22, 0xeb, 0x21, 0x33, 0x8b, 0x4a, 0x07, 0x30, 0x8b, 0x7e, 0x0a, - 0x6a, 0x0d, 0x29, 0xe5, 0x8b, 0x29, 0xa1, 0x9b, 0xd5, 0x1d, 0x5a, 0xd0, 0xab, 0x26, 0xac, 0x79, - 0xa2, 0xb9, 0x54, 0xa2, 0x8d, 0xd0, 0x10, 0x03, 0x4c, 0x43, 0xe4, 0x65, 0xc2, 0x08, 0x4d, 0xd1, - 0xfd, 0x0c, 0xab, 0x33, 0x15, 0xba, 0xe2, 0xbd, 0x64, 0x44, 0x3a, 0xaf, 0x33, 0xb5, 0x3c, 0x2f, - 0x9b, 0xb1, 0x89, 0x63, 0x7f, 0xcb, 0x52, 0x1f, 0xf7, 0x3e, 0x54, 0x54, 0xb8, 0x9d, 0xae, 0xa8, - 0x70, 0xa9, 0x90, 0x61, 0xee, 0x51, 0x4a, 0xe1, 0x3a, 0x0c, 0xcd, 0x04, 0xed, 0xb6, 0xe3, 0x37, - 0xd1, 0xf7, 0xc3, 0x50, 0x83, 0xff, 0x14, 0x8e, 0x1d, 0x76, 0x3c, 0x28, 0xa0, 0x58, 0xc2, 0xd0, - 0x63, 0x30, 0xe0, 0x44, 0x2d, 0xe9, 0xcc, 0x61, 0xa1, 0x30, 0xd3, 0x51, 0x2b, 0xc6, 0xac, 0xd5, - 0xfe, 0x47, 0x03, 0xc0, 0x4e, 0xa0, 0x9d, 0x88, 0x34, 0x57, 0x03, 0x56, 0xc2, 0xef, 0x58, 0x0f, - 0xd5, 0xf4, 0x66, 0xe9, 0x61, 0x3e, 0x58, 0x33, 0x0e, 0x57, 0xca, 0xf7, 0xf9, 0x70, 0xa5, 0xc7, - 0x79, 0xd9, 0xc0, 0x43, 0x74, 0x5e, 0x66, 0x7f, 0xd6, 0x02, 0xa4, 0xc2, 0x16, 0xf4, 0x81, 0xf6, - 0x14, 0xd4, 0x54, 0x00, 0x83, 0x30, 0xac, 0xb4, 0x88, 0x90, 0x00, 0xac, 0x71, 0xfa, 0xd8, 0x21, - 0x3f, 0x29, 0xe5, 0x77, 0x39, 0x1d, 0x45, 0xcb, 0xa4, 0xbe, 0x10, 0xe7, 0xf6, 0x6f, 0x97, 0xe0, - 0x11, 0xae, 0x92, 0x17, 0x1d, 0xdf, 0x69, 0x91, 0x36, 0xed, 0x55, 0xbf, 0x21, 0x0a, 0x0d, 0xba, - 0x35, 0x73, 0x65, 0x54, 0xec, 0x51, 0xd7, 0x2e, 0x5f, 0x73, 0x7c, 0x95, 0xcd, 0xfb, 0x6e, 0x82, - 0x19, 0x71, 0x14, 0x43, 0x55, 0xd6, 0x8c, 0x17, 0xb2, 0xb8, 0x20, 0x46, 0x4a, 0x2c, 0x09, 0xbd, - 0x49, 0xb0, 0x62, 0x44, 0x0d, 0x57, 0x2f, 0x68, 0x6c, 0x62, 0x12, 0x06, 0x4c, 0xee, 0x1a, 0x41, - 0x89, 0x0b, 0xa2, 0x1d, 0x2b, 0x0c, 0xfb, 0xb7, 0x2d, 0xc8, 0x6a, 0x24, 0xa3, 0x56, 0x9a, 0xb5, - 0x67, 0xad, 0xb4, 0x03, 0x14, 0x2b, 0xfb, 0x09, 0x18, 0x76, 0x12, 0x6a, 0x44, 0xf0, 0x6d, 0x77, - 0xf9, 0x70, 0xc7, 0x1a, 0x8b, 0x41, 0xd3, 0x5d, 0x77, 0xd9, 0x76, 0xdb, 0x24, 0x67, 0xff, 0x8f, - 0x01, 0x38, 0xd5, 0x95, 0xbb, 0x81, 0x5e, 0x84, 0x91, 0x86, 0x98, 0x1e, 0xa1, 0x74, 0x68, 0xd5, - 0xcc, 0x20, 0x36, 0x0d, 0xc3, 0x29, 0xcc, 0x3e, 0x26, 0xe8, 0x3c, 0x9c, 0x8e, 0xe8, 0x46, 0xbf, - 0x43, 0xa6, 0xd7, 0x13, 0x12, 0xad, 0x90, 0x46, 0xe0, 0x37, 0x79, 0x45, 0xbf, 0x72, 0xfd, 0xd1, - 0xbb, 0xbb, 0x13, 0xa7, 0x71, 0x37, 0x18, 0xe7, 0x3d, 0x83, 0x42, 0x18, 0xf5, 0x4c, 0x1b, 0x50, - 0x6c, 0x00, 0x0e, 0x65, 0x3e, 0x2a, 0x1b, 0x21, 0xd5, 0x8c, 0xd3, 0x0c, 0xd2, 0x86, 0x64, 0xe5, - 0x01, 0x19, 0x92, 0x9f, 0xd4, 0x86, 0x24, 0x3f, 0x7f, 0xff, 0x60, 0xc1, 0xb9, 0x3b, 0xc7, 0x6d, - 0x49, 0xbe, 0x0c, 0x55, 0x19, 0x9b, 0xd4, 0x57, 0x4c, 0x8f, 0x49, 0xa7, 0x87, 0x44, 0xbb, 0x57, - 0x82, 0x9c, 0x4d, 0x08, 0x5d, 0x67, 0x5a, 0xe3, 0xa7, 0xd6, 0xd9, 0xc1, 0xb4, 0x3e, 0xda, 0xe6, - 0x71, 0x59, 0x5c, 0xb7, 0x7d, 0xa0, 0xe8, 0x4d, 0x94, 0x0e, 0xd5, 0x52, 0x29, 0x0d, 0x2a, 0x5c, - 0xeb, 0x22, 0x80, 0x36, 0xd4, 0x44, 0xc0, 0xba, 0x3a, 0xf6, 0xd5, 0xf6, 0x1c, 0x36, 0xb0, 0xe8, - 0x9e, 0xda, 0xf5, 0xe3, 0xc4, 0xf1, 0xbc, 0x2b, 0xae, 0x9f, 0x08, 0xe7, 0xa0, 0x52, 0xe2, 0xf3, - 0x1a, 0x84, 0x4d, 0xbc, 0xf3, 0xef, 0x31, 0xbe, 0xcb, 0x41, 0xbe, 0xe7, 0x06, 0x9c, 0x9b, 0x73, - 0x13, 0x95, 0x66, 0xa1, 0xe6, 0x11, 0xb5, 0xc3, 0x54, 0xda, 0x90, 0xd5, 0x33, 0x6d, 0xc8, 0x48, - 0x73, 0x28, 0xa5, 0xb3, 0x32, 0xb2, 0x69, 0x0e, 0xf6, 0x8b, 0x70, 0x66, 0xce, 0x4d, 0x2e, 0xbb, - 0x1e, 0x39, 0x20, 0x13, 0xfb, 0x37, 0x07, 0x61, 0xc4, 0x4c, 0xd4, 0x3b, 0x48, 0xe6, 0xd3, 0xe7, - 0xa9, 0xa9, 0x25, 0xde, 0xce, 0x55, 0x87, 0x66, 0xb7, 0x8e, 0x9c, 0x35, 0x98, 0x3f, 0x62, 0x86, - 0xb5, 0xa5, 0x79, 0x62, 0xb3, 0x03, 0xe8, 0x0e, 0x54, 0xd6, 0x59, 0x18, 0x7e, 0xb9, 0x88, 0xc8, - 0x82, 0xbc, 0x11, 0xd5, 0xcb, 0x8c, 0x07, 0xf2, 0x73, 0x7e, 0x54, 0x43, 0x46, 0xe9, 0xdc, 0x2e, - 0x23, 0x74, 0x54, 0x64, 0x75, 0x29, 0x8c, 0x5e, 0xa2, 0xbe, 0x72, 0x08, 0x51, 0x9f, 0x12, 0xbc, - 0x83, 0x0f, 0x48, 0xf0, 0xb2, 0x94, 0x8a, 0x64, 0x83, 0xd9, 0x6f, 0x22, 0xd6, 0x7d, 0x88, 0x0d, - 0x82, 0x91, 0x52, 0x91, 0x02, 0xe3, 0x2c, 0x3e, 0xfa, 0x98, 0x12, 0xdd, 0xd5, 0x22, 0xfc, 0xaa, - 0xe6, 0x8c, 0x3e, 0x6e, 0xa9, 0xfd, 0xd9, 0x12, 0x8c, 0xcd, 0xf9, 0x9d, 0xe5, 0xb9, 0xe5, 0xce, - 0x9a, 0xe7, 0x36, 0xae, 0x91, 0x1d, 0x2a, 0x9a, 0x37, 0xc9, 0xce, 0xfc, 0xac, 0x58, 0x41, 0x6a, - 0xce, 0x5c, 0xa3, 0x8d, 0x98, 0xc3, 0xa8, 0x30, 0x5a, 0x77, 0xfd, 0x16, 0x89, 0xc2, 0xc8, 0x15, - 0x2e, 0x4f, 0x43, 0x18, 0x5d, 0xd6, 0x20, 0x6c, 0xe2, 0x51, 0xda, 0xc1, 0x1d, 0x9f, 0x44, 0x59, - 0x43, 0x76, 0x89, 0x36, 0x62, 0x0e, 0xa3, 0x48, 0x49, 0xd4, 0x89, 0x13, 0x31, 0x19, 0x15, 0xd2, - 0x2a, 0x6d, 0xc4, 0x1c, 0x46, 0x57, 0x7a, 0xdc, 0x59, 0x63, 0x81, 0x1b, 0x99, 0xc0, 0xfa, 0x15, - 0xde, 0x8c, 0x25, 0x9c, 0xa2, 0x6e, 0x92, 0x9d, 0x59, 0xba, 0xeb, 0xcd, 0xe4, 0xd7, 0x5c, 0xe3, - 0xcd, 0x58, 0xc2, 0x59, 0x29, 0xc2, 0xf4, 0x70, 0x7c, 0xd7, 0x95, 0x22, 0x4c, 0x77, 0xbf, 0xc7, - 0xfe, 0xf9, 0x97, 0x2c, 0x18, 0x31, 0xc3, 0xad, 0x50, 0x2b, 0x63, 0xe3, 0x2e, 0x75, 0x55, 0xb2, - 0xfd, 0xb1, 0xbc, 0xab, 0xbd, 0x5a, 0x6e, 0x12, 0x84, 0xf1, 0xb3, 0xc4, 0x6f, 0xb9, 0x3e, 0x61, - 0xa7, 0xe8, 0x3c, 0x4c, 0x2b, 0x15, 0xcb, 0x35, 0x13, 0x34, 0xc9, 0x21, 0x8c, 0x64, 0xfb, 0x16, - 0x9c, 0xea, 0x4a, 0xaa, 0xea, 0xc3, 0xb4, 0xd8, 0x37, 0xa5, 0xd5, 0xc6, 0x30, 0x4c, 0x09, 0xcb, - 0x72, 0x38, 0x33, 0x70, 0x8a, 0x2f, 0x24, 0xca, 0x69, 0xa5, 0xb1, 0x41, 0xda, 0x2a, 0x51, 0x8e, - 0xf9, 0xd7, 0x6f, 0x66, 0x81, 0xb8, 0x1b, 0xdf, 0xfe, 0x9c, 0x05, 0xa3, 0xa9, 0x3c, 0xb7, 0x82, - 0x8c, 0x20, 0xb6, 0xd2, 0x02, 0x16, 0xfd, 0xc7, 0x42, 0xa0, 0xcb, 0x4c, 0x99, 0xea, 0x95, 0xa6, - 0x41, 0xd8, 0xc4, 0xb3, 0xbf, 0x58, 0x82, 0xaa, 0x8c, 0xa0, 0xe8, 0xa3, 0x2b, 0x9f, 0xb1, 0x60, - 0x54, 0x9d, 0x69, 0x30, 0x67, 0x59, 0xa9, 0x88, 0xa4, 0x04, 0xda, 0x03, 0xb5, 0xdd, 0xf6, 0xd7, - 0x03, 0x6d, 0x91, 0x63, 0x93, 0x19, 0x4e, 0xf3, 0x46, 0x37, 0x01, 0xe2, 0x9d, 0x38, 0x21, 0x6d, - 0xc3, 0x6d, 0x67, 0x1b, 0x2b, 0x6e, 0xb2, 0x11, 0x44, 0x84, 0xae, 0xaf, 0xeb, 0x41, 0x93, 0xac, - 0x28, 0x4c, 0x6d, 0x42, 0xe9, 0x36, 0x6c, 0x50, 0xb2, 0xff, 0x41, 0x09, 0x4e, 0x66, 0xbb, 0x84, - 0x3e, 0x08, 0x23, 0x92, 0xbb, 0x71, 0x4d, 0x99, 0x0c, 0x1b, 0x19, 0xc1, 0x06, 0xec, 0xde, 0xee, - 0xc4, 0x44, 0xf7, 0x35, 0x71, 0x93, 0x26, 0x0a, 0x4e, 0x11, 0xe3, 0x07, 0x4b, 0xe2, 0x04, 0xb4, - 0xbe, 0x33, 0x1d, 0x86, 0xe2, 0x74, 0xc8, 0x38, 0x58, 0x32, 0xa1, 0x38, 0x83, 0x8d, 0x96, 0xe1, - 0x8c, 0xd1, 0x72, 0x9d, 0xb8, 0xad, 0x8d, 0xb5, 0x20, 0x92, 0x3b, 0xab, 0xc7, 0x74, 0x60, 0x57, - 0x37, 0x0e, 0xce, 0x7d, 0x92, 0x6a, 0xfb, 0x86, 0x13, 0x3a, 0x0d, 0x37, 0xd9, 0x11, 0x7e, 0x48, - 0x25, 0x9b, 0x66, 0x44, 0x3b, 0x56, 0x18, 0xf6, 0x22, 0x0c, 0xf4, 0x39, 0x83, 0xfa, 0xb2, 0xe8, - 0x5f, 0x86, 0x2a, 0x25, 0x27, 0xcd, 0xbb, 0x22, 0x48, 0x06, 0x50, 0x95, 0x37, 0x8d, 0x20, 0x1b, - 0xca, 0xae, 0x23, 0xcf, 0xee, 0xd4, 0x6b, 0xcd, 0xc7, 0x71, 0x87, 0x6d, 0x92, 0x29, 0x10, 0x3d, - 0x09, 0x65, 0xb2, 0x1d, 0x66, 0x0f, 0xe9, 0x2e, 0x6d, 0x87, 0x6e, 0x44, 0x62, 0x8a, 0x44, 0xb6, - 0x43, 0x74, 0x1e, 0x4a, 0x6e, 0x53, 0x28, 0x29, 0x10, 0x38, 0xa5, 0xf9, 0x59, 0x5c, 0x72, 0x9b, - 0xf6, 0x36, 0xd4, 0xd4, 0xd5, 0x26, 0x68, 0x53, 0xca, 0x6e, 0xab, 0x88, 0x90, 0x27, 0x49, 0xb7, - 0x87, 0xd4, 0xee, 0x00, 0xe8, 0x84, 0xbf, 0xa2, 0xe4, 0xcb, 0x05, 0x18, 0x68, 0x04, 0x22, 0x19, - 0xb9, 0xaa, 0xc9, 0x30, 0xa1, 0xcd, 0x20, 0xf6, 0x2d, 0x18, 0xbb, 0xe6, 0x07, 0x77, 0x58, 0x5d, - 0x76, 0x56, 0x86, 0x8c, 0x12, 0x5e, 0xa7, 0x3f, 0xb2, 0x26, 0x02, 0x83, 0x62, 0x0e, 0x53, 0xf5, - 0x99, 0x4a, 0xbd, 0xea, 0x33, 0xd9, 0x1f, 0xb7, 0x60, 0x44, 0x65, 0x0e, 0xcd, 0x6d, 0x6d, 0x52, - 0xba, 0xad, 0x28, 0xe8, 0x84, 0x59, 0xba, 0xec, 0xf2, 0x21, 0xcc, 0x61, 0x66, 0x4a, 0x5d, 0x69, - 0x9f, 0x94, 0xba, 0x0b, 0x30, 0xb0, 0xe9, 0xfa, 0xcd, 0xec, 0x6d, 0x1a, 0xd7, 0x5c, 0xbf, 0x89, - 0x19, 0x84, 0x76, 0xe1, 0xa4, 0xea, 0x82, 0x54, 0x08, 0x2f, 0xc2, 0xc8, 0x5a, 0xc7, 0xf5, 0x9a, - 0xb2, 0xbe, 0x5a, 0xc6, 0x53, 0x52, 0x37, 0x60, 0x38, 0x85, 0x49, 0xf7, 0x75, 0x6b, 0xae, 0xef, - 0x44, 0x3b, 0xcb, 0x5a, 0x03, 0x29, 0xa1, 0x54, 0x57, 0x10, 0x6c, 0x60, 0xd9, 0x6f, 0x96, 0x61, - 0x2c, 0x9d, 0x3f, 0xd5, 0xc7, 0xf6, 0xea, 0x49, 0xa8, 0xb0, 0x94, 0xaa, 0xec, 0xa7, 0xe5, 0x25, - 0xc9, 0x38, 0x0c, 0xc5, 0x30, 0xc8, 0x8b, 0x31, 0x14, 0x73, 0x13, 0x8d, 0xea, 0xa4, 0xf2, 0xaf, - 0xb0, 0x78, 0x32, 0x51, 0xff, 0x41, 0xb0, 0x42, 0x9f, 0xb2, 0x60, 0x28, 0x08, 0xcd, 0xba, 0x3e, - 0x1f, 0x28, 0x32, 0xb7, 0x4c, 0x24, 0xcb, 0x08, 0x8b, 0x58, 0x7d, 0x7a, 0xf9, 0x39, 0x24, 0xeb, - 0xf3, 0x3f, 0x02, 0x23, 0x26, 0xe6, 0x7e, 0x46, 0x71, 0xd5, 0x34, 0x8a, 0x3f, 0x63, 0x4e, 0x0a, - 0x91, 0x3d, 0xd7, 0xc7, 0x72, 0xbb, 0x01, 0x95, 0x86, 0x0a, 0x00, 0x38, 0x54, 0x55, 0x4e, 0x55, - 0x1d, 0x81, 0x1d, 0x02, 0x71, 0x6a, 0xf6, 0xb7, 0x2c, 0x63, 0x7e, 0x60, 0x12, 0xcf, 0x37, 0x51, - 0x04, 0xe5, 0xd6, 0xd6, 0xa6, 0x30, 0x45, 0xaf, 0x16, 0x34, 0xbc, 0x73, 0x5b, 0x9b, 0x7a, 0x8e, - 0x9b, 0xad, 0x98, 0x32, 0xeb, 0xc3, 0x09, 0x98, 0x4a, 0xb2, 0x2c, 0xef, 0x9f, 0x64, 0x69, 0xbf, - 0x55, 0x82, 0x53, 0x5d, 0x93, 0x0a, 0xbd, 0x01, 0x95, 0x88, 0xbe, 0xa5, 0x78, 0xbd, 0x85, 0xc2, - 0xd2, 0x22, 0xe3, 0xf9, 0xa6, 0xd6, 0xbb, 0xe9, 0x76, 0xcc, 0x59, 0xa2, 0xab, 0x80, 0x74, 0x98, - 0x8a, 0xf2, 0x40, 0xf2, 0x57, 0x3e, 0x2f, 0x1e, 0x45, 0xd3, 0x5d, 0x18, 0x38, 0xe7, 0x29, 0xf4, - 0x52, 0xd6, 0x91, 0x59, 0x4e, 0x9f, 0x5b, 0xee, 0xe5, 0x93, 0xb4, 0xff, 0x79, 0x09, 0x46, 0x53, - 0x65, 0x96, 0x90, 0x07, 0x55, 0xe2, 0x31, 0xa7, 0xbe, 0x54, 0x36, 0x47, 0xad, 0x5a, 0xac, 0x14, - 0xe4, 0x25, 0x41, 0x17, 0x2b, 0x0e, 0x0f, 0xc7, 0xe1, 0xfa, 0x8b, 0x30, 0x22, 0x3b, 0xf4, 0x01, - 0xa7, 0xed, 0x89, 0x01, 0x54, 0x73, 0xf4, 0x92, 0x01, 0xc3, 0x29, 0x4c, 0xfb, 0x77, 0xca, 0x30, - 0xce, 0x4f, 0x41, 0x9a, 0x6a, 0xe6, 0x2d, 0xca, 0xfd, 0xd6, 0x5f, 0xd1, 0xc5, 0xd0, 0xf8, 0x40, - 0xae, 0x1d, 0xf5, 0x92, 0x80, 0x7c, 0x46, 0x7d, 0x45, 0x66, 0x7d, 0x25, 0x13, 0x99, 0xc5, 0xcd, - 0xee, 0xd6, 0x31, 0xf5, 0xe8, 0xbb, 0x2b, 0x54, 0xeb, 0x57, 0x4a, 0x70, 0x22, 0x73, 0x03, 0x03, - 0x7a, 0x33, 0x5d, 0xb4, 0xd7, 0x2a, 0xc2, 0x57, 0xbe, 0x67, 0x51, 0xfe, 0x83, 0x95, 0xee, 0x7d, - 0x40, 0x4b, 0xc5, 0xfe, 0x83, 0x12, 0x8c, 0xa5, 0xaf, 0x8e, 0x78, 0x08, 0x47, 0xea, 0xdd, 0x50, - 0x63, 0xd5, 0xd1, 0xd9, 0x95, 0x98, 0xdc, 0x25, 0xcf, 0x0b, 0x51, 0xcb, 0x46, 0xac, 0xe1, 0x0f, - 0x45, 0x45, 0x64, 0xfb, 0xef, 0x59, 0x70, 0x96, 0xbf, 0x65, 0x76, 0x1e, 0xfe, 0xd5, 0xbc, 0xd1, - 0x7d, 0xb5, 0xd8, 0x0e, 0x66, 0x8a, 0xf8, 0xed, 0x37, 0xbe, 0xec, 0x2a, 0x3e, 0xd1, 0xdb, 0xf4, - 0x54, 0x78, 0x08, 0x3b, 0x7b, 0xa0, 0xc9, 0x60, 0xff, 0x41, 0x19, 0xf4, 0xed, 0x83, 0xc8, 0x15, - 0x39, 0x8e, 0x85, 0x14, 0x33, 0x5c, 0xd9, 0xf1, 0x1b, 0xfa, 0x9e, 0xc3, 0x6a, 0x26, 0xc5, 0xf1, - 0xe7, 0x2c, 0x18, 0x76, 0x7d, 0x37, 0x71, 0x1d, 0xb6, 0x8d, 0x2e, 0xe6, 0x66, 0x34, 0xc5, 0x6e, - 0x9e, 0x53, 0x0e, 0x22, 0xf3, 0x1c, 0x47, 0x31, 0xc3, 0x26, 0x67, 0xf4, 0x61, 0x11, 0x3c, 0x5d, - 0x2e, 0x2c, 0x3b, 0xb7, 0x9a, 0x89, 0x98, 0x0e, 0xa9, 0xe1, 0x95, 0x44, 0x05, 0x25, 0xb5, 0x63, - 0x4a, 0x4a, 0xd5, 0xc5, 0xd5, 0xf7, 0x40, 0xd3, 0x66, 0xcc, 0x19, 0xd9, 0x31, 0xa0, 0xee, 0xb1, - 0x38, 0x60, 0x60, 0xea, 0x14, 0xd4, 0x9c, 0x4e, 0x12, 0xb4, 0xe9, 0x30, 0x89, 0xa3, 0x26, 0x1d, - 0x7a, 0x2b, 0x01, 0x58, 0xe3, 0xd8, 0x6f, 0x56, 0x20, 0x93, 0x74, 0x88, 0xb6, 0xcd, 0x9b, 0x33, - 0xad, 0x62, 0x6f, 0xce, 0x54, 0x9d, 0xc9, 0xbb, 0x3d, 0x13, 0xb5, 0xa0, 0x12, 0x6e, 0x38, 0xb1, - 0x34, 0xab, 0x5f, 0x56, 0xfb, 0x38, 0xda, 0x78, 0x6f, 0x77, 0xe2, 0xc7, 0xfb, 0xf3, 0xba, 0xd2, - 0xb9, 0x3a, 0xc5, 0x8b, 0x8d, 0x68, 0xd6, 0x8c, 0x06, 0xe6, 0xf4, 0x0f, 0x72, 0x37, 0xdc, 0x27, - 0x44, 0x19, 0x78, 0x4c, 0xe2, 0x8e, 0x97, 0x88, 0xd9, 0xf0, 0x72, 0x81, 0xab, 0x8c, 0x13, 0xd6, - 0xe9, 0xf2, 0xfc, 0x3f, 0x36, 0x98, 0xa2, 0x0f, 0x42, 0x2d, 0x4e, 0x9c, 0x28, 0x39, 0x64, 0x82, - 0xab, 0x1a, 0xf4, 0x15, 0x49, 0x04, 0x6b, 0x7a, 0xe8, 0x15, 0x56, 0xdb, 0xd5, 0x8d, 0x37, 0x0e, - 0x99, 0xf3, 0x20, 0xeb, 0xc0, 0x0a, 0x0a, 0xd8, 0xa0, 0x86, 0x2e, 0x02, 0xb0, 0xb9, 0xcd, 0x03, - 0xfd, 0xaa, 0xcc, 0xcb, 0xa4, 0x44, 0x21, 0x56, 0x10, 0x6c, 0x60, 0xd9, 0x3f, 0x08, 0xe9, 0x7a, - 0x0f, 0x68, 0x42, 0x96, 0x97, 0xe0, 0x5e, 0x68, 0x96, 0xbb, 0x90, 0xaa, 0x04, 0xf1, 0xeb, 0x16, - 0x98, 0x45, 0x29, 0xd0, 0xeb, 0xbc, 0xfa, 0x85, 0x55, 0xc4, 0xc9, 0xa1, 0x41, 0x77, 0x72, 0xd1, - 0x09, 0x33, 0x47, 0xd8, 0xb2, 0x04, 0xc6, 0xf9, 0xf7, 0x40, 0x55, 0x42, 0x0f, 0x64, 0xd4, 0x7d, - 0x0c, 0x4e, 0x67, 0xef, 0x15, 0x17, 0xa7, 0x4e, 0xfb, 0xbb, 0x7e, 0xa4, 0x3f, 0xa7, 0xd4, 0xcb, - 0x9f, 0xd3, 0xc7, 0xfd, 0xa9, 0xbf, 0x61, 0xc1, 0x85, 0xfd, 0xae, 0x3f, 0x47, 0x8f, 0xc1, 0xc0, - 0x1d, 0x27, 0x92, 0x45, 0xb7, 0x99, 0xa0, 0xbc, 0xe5, 0x44, 0x3e, 0x66, 0xad, 0x68, 0x07, 0x06, - 0x79, 0x34, 0x98, 0xb0, 0xd6, 0x5f, 0x2e, 0xf6, 0x32, 0xf6, 0x6b, 0xc4, 0xd8, 0x2e, 0xf0, 0x48, - 0x34, 0x2c, 0x18, 0xda, 0xdf, 0xb6, 0x00, 0x2d, 0x6d, 0x91, 0x28, 0x72, 0x9b, 0x46, 0xfc, 0x1a, - 0xbb, 0x4e, 0xc5, 0xb8, 0x36, 0xc5, 0x4c, 0x71, 0xcd, 0x5c, 0xa7, 0x62, 0xfc, 0xcb, 0xbf, 0x4e, - 0xa5, 0x74, 0xb0, 0xeb, 0x54, 0xd0, 0x12, 0x9c, 0x6d, 0xf3, 0xed, 0x06, 0xbf, 0xa2, 0x80, 0xef, - 0x3d, 0x54, 0x42, 0xd9, 0xb9, 0xbb, 0xbb, 0x13, 0x67, 0x17, 0xf3, 0x10, 0x70, 0xfe, 0x73, 0xf6, - 0x7b, 0x00, 0xf1, 0xb0, 0xb5, 0x99, 0xbc, 0x18, 0xa4, 0x9e, 0xee, 0x17, 0xfb, 0xcb, 0x15, 0x38, - 0x91, 0x29, 0xc9, 0x4a, 0xb7, 0x7a, 0xdd, 0x41, 0x4f, 0x47, 0xd6, 0xdf, 0xdd, 0xdd, 0xeb, 0x2b, - 0x8c, 0xca, 0x87, 0x8a, 0xeb, 0x87, 0x9d, 0xa4, 0x98, 0x1c, 0x52, 0xde, 0x89, 0x79, 0x4a, 0xd0, - 0x70, 0x17, 0xd3, 0xbf, 0x98, 0xb3, 0x29, 0x32, 0x28, 0x2b, 0x65, 0x8c, 0x0f, 0x3c, 0x20, 0x77, - 0xc0, 0x27, 0x74, 0x88, 0x54, 0xa5, 0x08, 0xc7, 0x62, 0x66, 0xb2, 0x1c, 0xf7, 0x51, 0xfb, 0xaf, - 0x95, 0x60, 0xd8, 0xf8, 0x68, 0xe8, 0x17, 0xd3, 0x25, 0x9b, 0xac, 0xe2, 0x5e, 0x89, 0xd1, 0x9f, - 0xd4, 0x45, 0x99, 0xf8, 0x2b, 0x3d, 0xd5, 0x5d, 0xad, 0xe9, 0xde, 0xee, 0xc4, 0xc9, 0x4c, 0x3d, - 0xa6, 0x54, 0x05, 0xa7, 0xf3, 0x1f, 0x85, 0x13, 0x19, 0x32, 0x39, 0xaf, 0xbc, 0x9a, 0xbe, 0x36, - 0xfe, 0x88, 0x6e, 0x29, 0x73, 0xc8, 0xbe, 0x4e, 0x87, 0x4c, 0xa4, 0xd1, 0x05, 0x1e, 0xe9, 0xc3, - 0x07, 0x9b, 0xc9, 0x96, 0x2d, 0xf5, 0x99, 0x2d, 0xfb, 0x34, 0x54, 0xc3, 0xc0, 0x73, 0x1b, 0xae, - 0xaa, 0x42, 0xc8, 0xf2, 0x73, 0x97, 0x45, 0x1b, 0x56, 0x50, 0x74, 0x07, 0x6a, 0xea, 0x86, 0x7d, - 0xe1, 0xdf, 0x2e, 0xea, 0xd0, 0x47, 0x19, 0x2d, 0xfa, 0xe6, 0x7c, 0xcd, 0x0b, 0xd9, 0x30, 0xc8, - 0x94, 0xa0, 0x0c, 0xfd, 0x67, 0xbe, 0x77, 0xa6, 0x1d, 0x63, 0x2c, 0x20, 0xf6, 0xd7, 0x6a, 0x70, - 0x26, 0xaf, 0x2e, 0x36, 0xfa, 0x08, 0x0c, 0xf2, 0x3e, 0x16, 0x73, 0xf5, 0x42, 0x1e, 0x8f, 0x39, - 0x46, 0x50, 0x74, 0x8b, 0xfd, 0xc6, 0x82, 0xa7, 0xe0, 0xee, 0x39, 0x6b, 0x62, 0x86, 0x1c, 0x0f, - 0xf7, 0x05, 0x47, 0x73, 0x5f, 0x70, 0x38, 0x77, 0xcf, 0x59, 0x43, 0xdb, 0x50, 0x69, 0xb9, 0x09, - 0x71, 0x84, 0x13, 0xe1, 0xd6, 0xb1, 0x30, 0x27, 0x0e, 0xb7, 0xd2, 0xd8, 0x4f, 0xcc, 0x19, 0xa2, - 0xaf, 0x5a, 0x70, 0x62, 0x2d, 0x9d, 0x1a, 0x2f, 0x84, 0xa7, 0x73, 0x0c, 0xb5, 0xcf, 0xd3, 0x8c, - 0xf8, 0x7d, 0x42, 0x99, 0x46, 0x9c, 0xed, 0x0e, 0xfa, 0xa4, 0x05, 0x43, 0xeb, 0xae, 0x67, 0x94, - 0xc1, 0x3d, 0x86, 0x8f, 0x73, 0x99, 0x31, 0xd0, 0x3b, 0x0e, 0xfe, 0x3f, 0xc6, 0x92, 0x73, 0x2f, - 0x4d, 0x35, 0x78, 0x54, 0x4d, 0x35, 0xf4, 0x80, 0x34, 0xd5, 0xa7, 0x2d, 0xa8, 0xa9, 0x91, 0x16, - 0xe9, 0xce, 0x1f, 0x3c, 0xc6, 0x4f, 0xce, 0x3d, 0x27, 0xea, 0x2f, 0xd6, 0xcc, 0xd1, 0x17, 0x2c, - 0x18, 0x76, 0xde, 0xe8, 0x44, 0xa4, 0x49, 0xb6, 0x82, 0x30, 0x16, 0x97, 0x11, 0xbe, 0x5a, 0x7c, - 0x67, 0xa6, 0x29, 0x93, 0x59, 0xb2, 0xb5, 0x14, 0xc6, 0x22, 0x2d, 0x49, 0x37, 0x60, 0xb3, 0x0b, - 0xf6, 0x6e, 0x09, 0x26, 0xf6, 0xa1, 0x80, 0x5e, 0x84, 0x91, 0x20, 0x6a, 0x39, 0xbe, 0xfb, 0x86, - 0x59, 0xeb, 0x42, 0x59, 0x59, 0x4b, 0x06, 0x0c, 0xa7, 0x30, 0xcd, 0x84, 0xec, 0xd2, 0x3e, 0x09, - 0xd9, 0x17, 0x60, 0x20, 0x22, 0x61, 0x90, 0xdd, 0x2c, 0xb0, 0x94, 0x00, 0x06, 0x41, 0x8f, 0x43, - 0xd9, 0x09, 0x5d, 0x11, 0x88, 0xa6, 0xf6, 0x40, 0xd3, 0xcb, 0xf3, 0x98, 0xb6, 0xa7, 0xea, 0x43, - 0x54, 0xee, 0x4b, 0x7d, 0x08, 0xaa, 0x06, 0xc4, 0xd9, 0xc5, 0xa0, 0x56, 0x03, 0xe9, 0x33, 0x05, - 0xfb, 0xad, 0x32, 0x3c, 0xbe, 0xe7, 0x7c, 0xd1, 0x71, 0x78, 0xd6, 0x1e, 0x71, 0x78, 0x72, 0x78, - 0x4a, 0xfb, 0x0d, 0x4f, 0xb9, 0xc7, 0xf0, 0x7c, 0x92, 0x2e, 0x03, 0x59, 0x23, 0xa4, 0x98, 0xeb, - 0xe4, 0x7a, 0x95, 0x1c, 0x11, 0x2b, 0x40, 0x42, 0xb1, 0xe6, 0x4b, 0xf7, 0x00, 0xa9, 0x64, 0xe4, - 0x4a, 0x11, 0x6a, 0xa0, 0x67, 0xcd, 0x10, 0x3e, 0xf7, 0x7b, 0x65, 0x38, 0xdb, 0x3f, 0x5f, 0x82, - 0x27, 0xfb, 0x90, 0xde, 0xe6, 0x2c, 0xb6, 0xfa, 0x9c, 0xc5, 0xdf, 0xdd, 0x9f, 0xc9, 0xfe, 0x6b, - 0x16, 0x9c, 0xef, 0xad, 0x3c, 0xd0, 0x73, 0x30, 0xbc, 0x16, 0x39, 0x7e, 0x63, 0x83, 0x5d, 0x91, - 0x29, 0x07, 0x85, 0x8d, 0xb5, 0x6e, 0xc6, 0x26, 0x0e, 0xdd, 0xde, 0xf2, 0x98, 0x04, 0x03, 0x43, - 0x26, 0x8f, 0xd2, 0xed, 0xed, 0x6a, 0x16, 0x88, 0xbb, 0xf1, 0xed, 0x3f, 0x2b, 0xe5, 0x77, 0x8b, - 0x1b, 0x19, 0x07, 0xf9, 0x4e, 0xe2, 0x2b, 0x94, 0xfa, 0x90, 0x25, 0xe5, 0xfb, 0x2d, 0x4b, 0x06, - 0x7a, 0xc9, 0x12, 0x34, 0x0b, 0x27, 0x8d, 0x2b, 0x54, 0x78, 0x42, 0x30, 0x0f, 0xb8, 0x55, 0x55, - 0x32, 0x96, 0x33, 0x70, 0xdc, 0xf5, 0x04, 0x7a, 0x06, 0xaa, 0xae, 0x1f, 0x93, 0x46, 0x27, 0xe2, - 0x81, 0xde, 0x46, 0x12, 0xd6, 0xbc, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0xa5, 0x12, 0x9c, 0xeb, 0x69, - 0x67, 0xdd, 0x27, 0xd9, 0x65, 0x7e, 0x8e, 0x81, 0xfb, 0xf3, 0x39, 0xcc, 0x41, 0xaa, 0xec, 0x3b, - 0x48, 0x7f, 0xd8, 0x7b, 0x62, 0x52, 0x9b, 0xfb, 0x7b, 0x76, 0x94, 0x5e, 0x82, 0x51, 0x27, 0x0c, - 0x39, 0x1e, 0x8b, 0xd7, 0xcc, 0x54, 0xc9, 0x99, 0x36, 0x81, 0x38, 0x8d, 0xdb, 0x97, 0xf6, 0xfc, - 0x63, 0x0b, 0x6a, 0x98, 0xac, 0x73, 0xe9, 0x80, 0x6e, 0x8b, 0x21, 0xb2, 0x8a, 0xa8, 0xa7, 0x49, - 0x07, 0x36, 0x76, 0x59, 0x9d, 0xc9, 0xbc, 0xc1, 0xee, 0xbe, 0x6a, 0xa7, 0x74, 0xa0, 0xab, 0x76, - 0xd4, 0x65, 0x2b, 0xe5, 0xde, 0x97, 0xad, 0xd8, 0x5f, 0x1f, 0xa2, 0xaf, 0x17, 0x06, 0x33, 0x11, - 0x69, 0xc6, 0xf4, 0xfb, 0x76, 0x22, 0x4f, 0x4c, 0x12, 0xf5, 0x7d, 0x6f, 0xe0, 0x05, 0x4c, 0xdb, - 0x53, 0x47, 0x31, 0xa5, 0x03, 0xd5, 0x08, 0x29, 0xef, 0x5b, 0x23, 0xe4, 0x25, 0x18, 0x8d, 0xe3, - 0x8d, 0xe5, 0xc8, 0xdd, 0x72, 0x12, 0x72, 0x8d, 0xec, 0x08, 0x2b, 0x4b, 0xe7, 0xf5, 0xaf, 0x5c, - 0xd1, 0x40, 0x9c, 0xc6, 0x45, 0x73, 0x70, 0x4a, 0x57, 0xea, 0x20, 0x51, 0xc2, 0xa2, 0xfb, 0xf9, - 0x4c, 0x50, 0x49, 0xbc, 0xba, 0xb6, 0x87, 0x40, 0xc0, 0xdd, 0xcf, 0x50, 0xf9, 0x96, 0x6a, 0xa4, - 0x1d, 0x19, 0x4c, 0xcb, 0xb7, 0x14, 0x1d, 0xda, 0x97, 0xae, 0x27, 0xd0, 0x22, 0x9c, 0xe6, 0x13, - 0x63, 0x3a, 0x0c, 0x8d, 0x37, 0x1a, 0x4a, 0xd7, 0x31, 0x9c, 0xeb, 0x46, 0xc1, 0x79, 0xcf, 0xa1, - 0x17, 0x60, 0x58, 0x35, 0xcf, 0xcf, 0x8a, 0x53, 0x04, 0xe5, 0xc5, 0x50, 0x64, 0xe6, 0x9b, 0xd8, - 0xc4, 0x43, 0x1f, 0x80, 0x47, 0xf5, 0x5f, 0x9e, 0x02, 0xc6, 0x8f, 0xd6, 0x66, 0x45, 0x11, 0x24, - 0x75, 0xb5, 0xc7, 0x5c, 0x2e, 0x5a, 0x13, 0xf7, 0x7a, 0x1e, 0xad, 0xc1, 0x79, 0x05, 0xba, 0xe4, - 0x27, 0x2c, 0x9f, 0x23, 0x26, 0x75, 0x27, 0x26, 0x37, 0x22, 0x4f, 0xdc, 0x8d, 0xaa, 0x6e, 0x5d, - 0x9c, 0x73, 0x93, 0x2b, 0x79, 0x98, 0x78, 0x01, 0xef, 0x41, 0x05, 0x4d, 0x41, 0x8d, 0xf8, 0xce, - 0x9a, 0x47, 0x96, 0x66, 0xe6, 0x59, 0x31, 0x25, 0xe3, 0x24, 0xef, 0x92, 0x04, 0x60, 0x8d, 0xa3, - 0x22, 0x4c, 0x47, 0x7a, 0xde, 0x00, 0xba, 0x0c, 0x67, 0x5a, 0x8d, 0x90, 0xda, 0x1e, 0x6e, 0x83, - 0x4c, 0x37, 0x58, 0x40, 0x1d, 0xfd, 0x30, 0xbc, 0xc0, 0xa4, 0x0a, 0x9f, 0x9e, 0x9b, 0x59, 0xee, - 0xc2, 0xc1, 0xb9, 0x4f, 0xb2, 0xc0, 0xcb, 0x28, 0xd8, 0xde, 0x19, 0x3f, 0x9d, 0x09, 0xbc, 0xa4, - 0x8d, 0x98, 0xc3, 0xd0, 0x55, 0x40, 0x2c, 0x16, 0xff, 0x4a, 0x92, 0x84, 0xca, 0xd8, 0x19, 0x3f, - 0xc3, 0x5e, 0x49, 0x85, 0x91, 0x5d, 0xee, 0xc2, 0xc0, 0x39, 0x4f, 0xd9, 0xff, 0xc1, 0x82, 0x51, - 0xb5, 0x5e, 0xef, 0x43, 0x36, 0x8a, 0x97, 0xce, 0x46, 0x99, 0x3b, 0xba, 0xc4, 0x63, 0x3d, 0xef, - 0x11, 0xd2, 0xfc, 0x33, 0xc3, 0x00, 0x5a, 0x2a, 0x2a, 0x85, 0x64, 0xf5, 0x54, 0x48, 0x0f, 0xad, - 0x44, 0xca, 0xab, 0x9c, 0x52, 0x79, 0xb0, 0x95, 0x53, 0x56, 0xe0, 0xac, 0x34, 0x17, 0xf8, 0x59, - 0xd1, 0x95, 0x20, 0x56, 0x02, 0xae, 0x5a, 0x7f, 0x5c, 0x10, 0x3a, 0x3b, 0x9f, 0x87, 0x84, 0xf3, - 0x9f, 0x4d, 0x59, 0x29, 0x43, 0xfb, 0x59, 0x29, 0x7a, 0x4d, 0x2f, 0xac, 0xcb, 0x3b, 0x3c, 0x32, - 0x6b, 0x7a, 0xe1, 0xf2, 0x0a, 0xd6, 0x38, 0xf9, 0x82, 0xbd, 0x56, 0x90, 0x60, 0x87, 0x03, 0x0b, - 0x76, 0x29, 0x62, 0x86, 0x7b, 0x8a, 0x18, 0xe9, 0x93, 0x1e, 0xe9, 0xe9, 0x93, 0x7e, 0x2f, 0x8c, - 0xb9, 0xfe, 0x06, 0x89, 0xdc, 0x84, 0x34, 0xd9, 0x5a, 0x60, 0xe2, 0xa7, 0xaa, 0xd5, 0xfa, 0x7c, - 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0xb9, 0x38, 0xd6, 0x87, 0x5c, 0xec, 0xa1, 0x8d, 0x4e, 0x14, 0xa3, - 0x8d, 0x4e, 0x1e, 0x5d, 0x1b, 0x9d, 0x3a, 0x56, 0x6d, 0x84, 0x0a, 0xd1, 0x46, 0x7d, 0x09, 0x7a, - 0x63, 0xfb, 0x77, 0x66, 0x9f, 0xed, 0x5f, 0x2f, 0x55, 0x74, 0xf6, 0xd0, 0xaa, 0x28, 0x5f, 0xcb, - 0x3c, 0x72, 0x28, 0x2d, 0xf3, 0xe9, 0x12, 0x9c, 0xd5, 0x72, 0x98, 0xce, 0x7e, 0x77, 0x9d, 0x4a, - 0x22, 0x76, 0x0d, 0x14, 0x3f, 0xb7, 0x31, 0x92, 0xa3, 0x74, 0x9e, 0x95, 0x82, 0x60, 0x03, 0x8b, - 0xe5, 0x18, 0x91, 0x88, 0x95, 0xd1, 0xcd, 0x0a, 0xe9, 0x19, 0xd1, 0x8e, 0x15, 0x06, 0x9d, 0x5f, - 0xf4, 0xb7, 0xc8, 0xdb, 0xcc, 0x16, 0x8b, 0x9b, 0xd1, 0x20, 0x6c, 0xe2, 0xa1, 0xa7, 0x39, 0x13, - 0x26, 0x20, 0xa8, 0xa0, 0x1e, 0x11, 0xf7, 0xc2, 0x4a, 0x99, 0xa0, 0xa0, 0xb2, 0x3b, 0x2c, 0x99, - 0xac, 0xd2, 0xdd, 0x1d, 0x16, 0x02, 0xa5, 0x30, 0xec, 0xff, 0x69, 0xc1, 0xb9, 0xdc, 0xa1, 0xb8, - 0x0f, 0xca, 0x77, 0x3b, 0xad, 0x7c, 0x57, 0x8a, 0xda, 0x6e, 0x18, 0x6f, 0xd1, 0x43, 0x11, 0xff, - 0x3b, 0x0b, 0xc6, 0x34, 0xfe, 0x7d, 0x78, 0x55, 0x37, 0xfd, 0xaa, 0xc5, 0xed, 0xac, 0x6a, 0x5d, - 0xef, 0xf6, 0x3b, 0x25, 0x50, 0x05, 0x1c, 0xa7, 0x1b, 0xb2, 0x3c, 0xee, 0x3e, 0x27, 0x89, 0x3b, - 0x30, 0xc8, 0x0e, 0x42, 0xe3, 0x62, 0x82, 0x3c, 0xd2, 0xfc, 0xd9, 0xa1, 0xaa, 0x3e, 0x64, 0x66, - 0x7f, 0x63, 0x2c, 0x18, 0xb2, 0x22, 0xcf, 0x6e, 0x4c, 0xa5, 0x79, 0x53, 0xa4, 0x65, 0xe9, 0x22, - 0xcf, 0xa2, 0x1d, 0x2b, 0x0c, 0xaa, 0x1e, 0xdc, 0x46, 0xe0, 0xcf, 0x78, 0x4e, 0x2c, 0xef, 0x3e, - 0x54, 0xea, 0x61, 0x5e, 0x02, 0xb0, 0xc6, 0x61, 0x67, 0xa4, 0x6e, 0x1c, 0x7a, 0xce, 0x8e, 0xb1, - 0x7f, 0x36, 0xea, 0x13, 0x28, 0x10, 0x36, 0xf1, 0xec, 0x36, 0x8c, 0xa7, 0x5f, 0x62, 0x96, 0xac, - 0xb3, 0x00, 0xc5, 0xbe, 0x86, 0x73, 0x0a, 0x6a, 0x0e, 0x7b, 0x6a, 0xa1, 0xe3, 0x64, 0xaf, 0x2c, - 0x9f, 0x96, 0x00, 0xac, 0x71, 0xec, 0x5f, 0xb5, 0xe0, 0x74, 0xce, 0xa0, 0x15, 0x98, 0xf6, 0x96, - 0x68, 0x69, 0x93, 0xa7, 0xd8, 0x7f, 0x00, 0x86, 0x9a, 0x64, 0xdd, 0x91, 0x21, 0x70, 0x86, 0x6c, - 0x9f, 0xe5, 0xcd, 0x58, 0xc2, 0xed, 0xff, 0x6e, 0xc1, 0x89, 0x74, 0x5f, 0x63, 0x96, 0x4a, 0xc2, - 0x87, 0xc9, 0x8d, 0x1b, 0xc1, 0x16, 0x89, 0x76, 0xe8, 0x9b, 0x5b, 0x99, 0x54, 0x92, 0x2e, 0x0c, - 0x9c, 0xf3, 0x14, 0x2b, 0xdf, 0xda, 0x54, 0xa3, 0x2d, 0x67, 0xe4, 0xcd, 0x22, 0x67, 0xa4, 0xfe, - 0x98, 0xe6, 0x71, 0xb9, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0xb7, 0x07, 0x40, 0xe5, 0xc5, 0xb2, 0xf8, - 0xa3, 0x82, 0xa2, 0xb7, 0x0e, 0x9a, 0x41, 0xa4, 0x26, 0xc3, 0xc0, 0x5e, 0x01, 0x01, 0xdc, 0x4b, - 0x62, 0xba, 0x2e, 0xd5, 0x1b, 0xae, 0x6a, 0x10, 0x36, 0xf1, 0x68, 0x4f, 0x3c, 0x77, 0x8b, 0xf0, - 0x87, 0x06, 0xd3, 0x3d, 0x59, 0x90, 0x00, 0xac, 0x71, 0x68, 0x4f, 0x9a, 0xee, 0xfa, 0xba, 0xd8, - 0xf2, 0xab, 0x9e, 0xd0, 0xd1, 0xc1, 0x0c, 0xc2, 0x2b, 0x72, 0x07, 0x9b, 0xc2, 0x0a, 0x36, 0x2a, - 0x72, 0x07, 0x9b, 0x98, 0x41, 0xa8, 0xdd, 0xe6, 0x07, 0x51, 0x9b, 0x5d, 0x29, 0xdf, 0x54, 0x5c, - 0x84, 0xf5, 0xab, 0xec, 0xb6, 0xeb, 0xdd, 0x28, 0x38, 0xef, 0x39, 0x3a, 0x03, 0xc3, 0x88, 0x34, - 0xdd, 0x46, 0x62, 0x52, 0x83, 0xf4, 0x0c, 0x5c, 0xee, 0xc2, 0xc0, 0x39, 0x4f, 0xa1, 0x69, 0x38, - 0x21, 0xf3, 0x9a, 0x65, 0xd5, 0x9a, 0xe1, 0x74, 0x95, 0x0c, 0x9c, 0x06, 0xe3, 0x2c, 0x3e, 0x95, - 0x6a, 0x6d, 0x51, 0xb0, 0x8a, 0x19, 0xcb, 0x86, 0x54, 0x93, 0x85, 0xac, 0xb0, 0xc2, 0xb0, 0x3f, - 0x51, 0xa6, 0x5a, 0xb8, 0x47, 0xa1, 0xb6, 0xfb, 0x16, 0x2d, 0x98, 0x9e, 0x91, 0x03, 0x7d, 0xcc, - 0xc8, 0xe7, 0x61, 0xe4, 0x76, 0x1c, 0xf8, 0x2a, 0x12, 0xaf, 0xd2, 0x33, 0x12, 0xcf, 0xc0, 0xca, - 0x8f, 0xc4, 0x1b, 0x2c, 0x2a, 0x12, 0x6f, 0xe8, 0x90, 0x91, 0x78, 0xdf, 0xac, 0x80, 0xba, 0x1a, - 0xe4, 0x3a, 0x49, 0xee, 0x04, 0xd1, 0xa6, 0xeb, 0xb7, 0x58, 0x3e, 0xf8, 0x57, 0x2d, 0x18, 0xe1, - 0xeb, 0x65, 0xc1, 0xcc, 0xa4, 0x5a, 0x2f, 0xe8, 0xce, 0x89, 0x14, 0xb3, 0xc9, 0x55, 0x83, 0x51, - 0xe6, 0xea, 0x4d, 0x13, 0x84, 0x53, 0x3d, 0x42, 0x1f, 0x05, 0x90, 0xfe, 0xd1, 0x75, 0x29, 0x32, - 0xe7, 0x8b, 0xe9, 0x1f, 0x26, 0xeb, 0xda, 0x06, 0x5e, 0x55, 0x4c, 0xb0, 0xc1, 0x10, 0x7d, 0x5a, - 0x67, 0x99, 0xf1, 0x90, 0xfd, 0x0f, 0x1f, 0xcb, 0xd8, 0xf4, 0x93, 0x63, 0x86, 0x61, 0xc8, 0xf5, - 0x5b, 0x74, 0x9e, 0x88, 0x88, 0xa5, 0x77, 0xe5, 0xd5, 0x52, 0x58, 0x08, 0x9c, 0x66, 0xdd, 0xf1, - 0x1c, 0xbf, 0x41, 0xa2, 0x79, 0x8e, 0x6e, 0x5e, 0x38, 0xcd, 0x1a, 0xb0, 0x24, 0xd4, 0x75, 0xa9, - 0x4a, 0xa5, 0x9f, 0x4b, 0x55, 0xce, 0xbf, 0x0f, 0x4e, 0x75, 0x7d, 0xcc, 0x03, 0xa5, 0x94, 0x1d, - 0x3e, 0x1b, 0xcd, 0xfe, 0x17, 0x83, 0x5a, 0x69, 0x5d, 0x0f, 0x9a, 0xfc, 0x6a, 0x8f, 0x48, 0x7f, - 0x51, 0x61, 0xe3, 0x16, 0x38, 0x45, 0x8c, 0x4b, 0xab, 0x55, 0x23, 0x36, 0x59, 0xd2, 0x39, 0x1a, - 0x3a, 0x11, 0xf1, 0x8f, 0x7b, 0x8e, 0x2e, 0x2b, 0x26, 0xd8, 0x60, 0x88, 0x36, 0x52, 0x39, 0x25, - 0x97, 0x8f, 0x9e, 0x53, 0xc2, 0xaa, 0x4c, 0xe5, 0x55, 0xe3, 0xff, 0x82, 0x05, 0x63, 0x7e, 0x6a, - 0xe6, 0x16, 0x13, 0x46, 0x9a, 0xbf, 0x2a, 0xf8, 0xcd, 0x52, 0xe9, 0x36, 0x9c, 0xe1, 0x9f, 0xa7, - 0xd2, 0x2a, 0x07, 0x54, 0x69, 0xfa, 0x8e, 0xa0, 0xc1, 0x5e, 0x77, 0x04, 0x21, 0x5f, 0x5d, 0x92, - 0x36, 0x54, 0xf8, 0x25, 0x69, 0x90, 0x73, 0x41, 0xda, 0x2d, 0xa8, 0x35, 0x22, 0xe2, 0x24, 0x87, - 0xbc, 0x2f, 0x8b, 0x1d, 0xd0, 0xcf, 0x48, 0x02, 0x58, 0xd3, 0xb2, 0xff, 0xcf, 0x00, 0x9c, 0x94, - 0x23, 0x22, 0x43, 0xd0, 0xa9, 0x7e, 0xe4, 0x7c, 0xb5, 0x71, 0xab, 0xf4, 0xe3, 0x15, 0x09, 0xc0, - 0x1a, 0x87, 0xda, 0x63, 0x9d, 0x98, 0x2c, 0x85, 0xc4, 0x5f, 0x70, 0xd7, 0x62, 0x71, 0xce, 0xa9, - 0x16, 0xca, 0x0d, 0x0d, 0xc2, 0x26, 0x1e, 0x35, 0xc6, 0xb9, 0x5d, 0x1c, 0x67, 0xd3, 0x57, 0x84, - 0xbd, 0x8d, 0x25, 0x1c, 0xfd, 0x42, 0x6e, 0xe5, 0xd8, 0x62, 0x12, 0xb7, 0xba, 0x22, 0xef, 0x0f, - 0x78, 0xc5, 0xe2, 0xdf, 0xb1, 0xe0, 0x2c, 0x6f, 0x95, 0x23, 0x79, 0x23, 0x6c, 0x3a, 0x09, 0x89, - 0x8b, 0xa9, 0xe4, 0x9e, 0xd3, 0x3f, 0xed, 0xe4, 0xcd, 0x63, 0x8b, 0xf3, 0x7b, 0x83, 0xde, 0xb4, - 0xe0, 0xc4, 0x66, 0xaa, 0xe6, 0x87, 0x54, 0x1d, 0x47, 0x4d, 0xc7, 0x4f, 0x11, 0xd5, 0x4b, 0x2d, - 0xdd, 0x1e, 0xe3, 0x2c, 0x77, 0xfb, 0xcf, 0x2c, 0x30, 0xc5, 0xe8, 0xfd, 0x2f, 0x15, 0x72, 0x70, - 0x53, 0x50, 0x5a, 0x97, 0x95, 0x9e, 0xd6, 0xe5, 0xe3, 0x50, 0xee, 0xb8, 0x4d, 0xb1, 0xbf, 0xd0, - 0xa7, 0xaf, 0xf3, 0xb3, 0x98, 0xb6, 0xdb, 0xff, 0xb4, 0xa2, 0xfd, 0x16, 0x22, 0x2f, 0xea, 0x7b, - 0xe2, 0xb5, 0xd7, 0x55, 0xb1, 0x31, 0xfe, 0xe6, 0xd7, 0xbb, 0x8a, 0x8d, 0xfd, 0xe8, 0xc1, 0xd3, - 0xde, 0xf8, 0x00, 0xf5, 0xaa, 0x35, 0x36, 0xb4, 0x4f, 0xce, 0xdb, 0x6d, 0xa8, 0xd2, 0x2d, 0x18, - 0x73, 0x40, 0x56, 0x53, 0x9d, 0xaa, 0x5e, 0x11, 0xed, 0xf7, 0x76, 0x27, 0x7e, 0xe4, 0xe0, 0xdd, - 0x92, 0x4f, 0x63, 0x45, 0x1f, 0xc5, 0x50, 0xa3, 0xbf, 0x59, 0x7a, 0x9e, 0xd8, 0xdc, 0xdd, 0x50, - 0x32, 0x53, 0x02, 0x0a, 0xc9, 0xfd, 0xd3, 0x7c, 0x90, 0x0f, 0x35, 0x76, 0x1b, 0x2d, 0x63, 0xca, - 0xf7, 0x80, 0xcb, 0x2a, 0x49, 0x4e, 0x02, 0xee, 0xed, 0x4e, 0xbc, 0x74, 0x70, 0xa6, 0xea, 0x71, - 0xac, 0x59, 0xd8, 0x5f, 0x1c, 0xd0, 0x73, 0x57, 0xd4, 0x98, 0xfb, 0x9e, 0x98, 0xbb, 0x2f, 0x66, - 0xe6, 0xee, 0x85, 0xae, 0xb9, 0x3b, 0xa6, 0x6f, 0x4d, 0x4d, 0xcd, 0xc6, 0xfb, 0x6d, 0x08, 0xec, - 0xef, 0x6f, 0x60, 0x16, 0xd0, 0xeb, 0x1d, 0x37, 0x22, 0xf1, 0x72, 0xd4, 0xf1, 0x5d, 0xbf, 0xc5, - 0xa6, 0x63, 0xd5, 0xb4, 0x80, 0x52, 0x60, 0x9c, 0xc5, 0xa7, 0x9b, 0x7a, 0xfa, 0xcd, 0x6f, 0x39, - 0x5b, 0x7c, 0x56, 0x19, 0x65, 0xb7, 0x56, 0x44, 0x3b, 0x56, 0x18, 0xf6, 0xd7, 0xd9, 0x59, 0xb6, - 0x91, 0x17, 0x4c, 0xe7, 0x84, 0xc7, 0xae, 0xff, 0xe5, 0x35, 0xbb, 0xd4, 0x9c, 0xe0, 0x77, 0xfe, - 0x72, 0x18, 0xba, 0x03, 0x43, 0x6b, 0xfc, 0xfe, 0xbb, 0x62, 0xea, 0x93, 0x8b, 0xcb, 0xf4, 0xd8, - 0x2d, 0x27, 0xf2, 0x66, 0xbd, 0x7b, 0xfa, 0x27, 0x96, 0xdc, 0xec, 0xdf, 0xaf, 0xc0, 0x89, 0xcc, - 0x05, 0xb1, 0xa9, 0x6a, 0xa9, 0xa5, 0x7d, 0xab, 0xa5, 0x7e, 0x08, 0xa0, 0x49, 0x42, 0x2f, 0xd8, - 0x61, 0xe6, 0xd8, 0xc0, 0x81, 0xcd, 0x31, 0x65, 0xc1, 0xcf, 0x2a, 0x2a, 0xd8, 0xa0, 0x28, 0x0a, - 0x95, 0xf1, 0xe2, 0xab, 0x99, 0x42, 0x65, 0xc6, 0x2d, 0x06, 0x83, 0xf7, 0xf7, 0x16, 0x03, 0x17, - 0x4e, 0xf0, 0x2e, 0xaa, 0xec, 0xdb, 0x43, 0x24, 0xd9, 0xb2, 0xfc, 0x85, 0xd9, 0x34, 0x19, 0x9c, - 0xa5, 0xfb, 0x20, 0xef, 0x7f, 0x46, 0xef, 0x86, 0x9a, 0xfc, 0xce, 0xf1, 0x78, 0x4d, 0x57, 0x30, - 0x90, 0xd3, 0x80, 0xdd, 0xcb, 0x2c, 0x7e, 0x76, 0x15, 0x12, 0x80, 0x07, 0x55, 0x48, 0xc0, 0xfe, - 0x7c, 0x89, 0xda, 0xf1, 0xbc, 0x5f, 0xaa, 0x26, 0xce, 0x53, 0x30, 0xe8, 0x74, 0x92, 0x8d, 0xa0, - 0xeb, 0x36, 0xbf, 0x69, 0xd6, 0x8a, 0x05, 0x14, 0x2d, 0xc0, 0x40, 0x53, 0xd7, 0x39, 0x39, 0xc8, - 0xf7, 0xd4, 0x2e, 0x51, 0x27, 0x21, 0x98, 0x51, 0x41, 0x8f, 0xc1, 0x40, 0xe2, 0xb4, 0x64, 0xca, - 0x15, 0x4b, 0xb3, 0x5d, 0x75, 0x5a, 0x31, 0x66, 0xad, 0xa6, 0xfa, 0x1e, 0xd8, 0x47, 0x7d, 0xbf, - 0x04, 0xa3, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x11, 0xe3, 0x98, 0x4f, 0x47, 0x6e, 0x98, 0x40, - 0x9c, 0xc6, 0xb5, 0x7f, 0x73, 0x04, 0xce, 0xac, 0xcc, 0x2c, 0xca, 0xea, 0xdd, 0xc7, 0x96, 0x35, - 0x95, 0xc7, 0xe3, 0xfe, 0x65, 0x4d, 0xf5, 0xe0, 0xee, 0x19, 0x59, 0x53, 0x9e, 0x91, 0x35, 0x95, - 0x4e, 0x61, 0x29, 0x17, 0x91, 0xc2, 0x92, 0xd7, 0x83, 0x7e, 0x52, 0x58, 0x8e, 0x2d, 0x8d, 0x6a, - 0xcf, 0x0e, 0x1d, 0x28, 0x8d, 0x4a, 0xe5, 0x98, 0x15, 0x92, 0x5c, 0xd0, 0xe3, 0x53, 0xe5, 0xe6, - 0x98, 0xa9, 0xfc, 0x1e, 0x9e, 0x38, 0x23, 0x44, 0xfd, 0xab, 0xc5, 0x77, 0xa0, 0x8f, 0xfc, 0x1e, - 0x91, 0xbb, 0x63, 0xe6, 0x94, 0x0d, 0x15, 0x91, 0x53, 0x96, 0xd7, 0x9d, 0x7d, 0x73, 0xca, 0x5e, - 0x82, 0xd1, 0x86, 0x17, 0xf8, 0x64, 0x39, 0x0a, 0x92, 0xa0, 0x11, 0x78, 0xc2, 0xac, 0x57, 0x22, - 0x61, 0xc6, 0x04, 0xe2, 0x34, 0x6e, 0xaf, 0x84, 0xb4, 0xda, 0x51, 0x13, 0xd2, 0xe0, 0x01, 0x25, - 0xa4, 0xfd, 0xac, 0x4e, 0x9d, 0x1e, 0x66, 0x5f, 0xe4, 0x43, 0xc5, 0x7f, 0x91, 0x7e, 0xf2, 0xa7, - 0xd1, 0x5b, 0xfc, 0x3a, 0x3d, 0x6a, 0x18, 0xcf, 0x04, 0x6d, 0x6a, 0xf8, 0x8d, 0xb0, 0x21, 0x79, - 0xed, 0x18, 0x26, 0xec, 0xad, 0x15, 0xcd, 0x46, 0x5d, 0xb1, 0xa7, 0x9b, 0x70, 0xba, 0x23, 0x47, - 0x49, 0xed, 0xfe, 0x72, 0x09, 0xbe, 0x6f, 0xdf, 0x2e, 0xa0, 0x3b, 0x00, 0x89, 0xd3, 0x12, 0x13, - 0x55, 0x1c, 0x98, 0x1c, 0x31, 0xbc, 0x72, 0x55, 0xd2, 0xe3, 0x35, 0x49, 0xd4, 0x5f, 0x76, 0x14, - 0x21, 0x7f, 0xb3, 0xa8, 0xca, 0xc0, 0xeb, 0x2a, 0xdd, 0x88, 0x03, 0x8f, 0x60, 0x06, 0xa1, 0xea, - 0x3f, 0x22, 0x2d, 0x7d, 0xff, 0xb3, 0xfa, 0x7c, 0x98, 0xb5, 0x62, 0x01, 0x45, 0x2f, 0xc0, 0xb0, - 0xe3, 0x79, 0x3c, 0x3f, 0x86, 0xc4, 0xe2, 0x3e, 0x1d, 0x5d, 0x43, 0x4e, 0x83, 0xb0, 0x89, 0x67, - 0xff, 0x69, 0x09, 0x26, 0xf6, 0x91, 0x29, 0x5d, 0x19, 0x7f, 0x95, 0xbe, 0x33, 0xfe, 0x44, 0x8e, - 0xc2, 0x60, 0x8f, 0x1c, 0x85, 0x17, 0x60, 0x38, 0x21, 0x4e, 0x5b, 0x04, 0x64, 0x09, 0x4f, 0x80, - 0x3e, 0x01, 0xd6, 0x20, 0x6c, 0xe2, 0x51, 0x29, 0x36, 0xe6, 0x34, 0x1a, 0x24, 0x8e, 0x65, 0x12, - 0x82, 0xf0, 0xa6, 0x16, 0x96, 0xe1, 0xc0, 0x9c, 0xd4, 0xd3, 0x29, 0x16, 0x38, 0xc3, 0x32, 0x3b, - 0xe0, 0xb5, 0x3e, 0x07, 0xfc, 0x6b, 0x25, 0x78, 0x7c, 0x4f, 0xed, 0xd6, 0x77, 0x7e, 0x48, 0x27, - 0x26, 0x51, 0x76, 0xe2, 0xdc, 0x88, 0x49, 0x84, 0x19, 0x84, 0x8f, 0x52, 0x18, 0x1a, 0xf7, 0x6b, - 0x17, 0x9d, 0xbc, 0xc4, 0x47, 0x29, 0xc5, 0x02, 0x67, 0x58, 0x1e, 0x76, 0x5a, 0xfe, 0xfd, 0x12, - 0x3c, 0xd9, 0x87, 0x0d, 0x50, 0x60, 0x92, 0x57, 0x3a, 0xd5, 0xae, 0xfc, 0x80, 0x32, 0x22, 0x0f, - 0x39, 0x5c, 0x5f, 0x2f, 0xc1, 0xf9, 0xde, 0xaa, 0x18, 0xfd, 0x18, 0x9c, 0x88, 0x54, 0x14, 0x96, - 0x99, 0xa5, 0x77, 0x9a, 0x7b, 0x12, 0x52, 0x20, 0x9c, 0xc5, 0x45, 0x93, 0x00, 0xa1, 0x93, 0x6c, - 0xc4, 0x97, 0xb6, 0xdd, 0x38, 0x11, 0x55, 0x68, 0xc6, 0xf8, 0xd9, 0x95, 0x6c, 0xc5, 0x06, 0x06, - 0x65, 0xc7, 0xfe, 0xcd, 0x06, 0xd7, 0x83, 0x84, 0x3f, 0xc4, 0xb7, 0x11, 0xa7, 0xe5, 0x9d, 0x1d, - 0x06, 0x08, 0x67, 0x71, 0x29, 0x3b, 0x76, 0x3a, 0xca, 0x3b, 0xca, 0xf7, 0x17, 0x8c, 0xdd, 0x82, - 0x6a, 0xc5, 0x06, 0x46, 0x36, 0xff, 0xb0, 0xb2, 0x7f, 0xfe, 0xa1, 0xfd, 0x4f, 0x4a, 0x70, 0xae, - 0xa7, 0x29, 0xd7, 0xdf, 0x02, 0x7c, 0xf8, 0x72, 0x06, 0x0f, 0x37, 0x77, 0x0e, 0x98, 0xdb, 0xf6, - 0xc7, 0x3d, 0x66, 0x9a, 0xc8, 0x6d, 0x3b, 0x7c, 0x72, 0xf8, 0xc3, 0x37, 0x9e, 0x5d, 0xe9, 0x6c, - 0x03, 0x07, 0x48, 0x67, 0xcb, 0x7c, 0x8c, 0x4a, 0x9f, 0x0b, 0xf9, 0xcf, 0xcb, 0x3d, 0x87, 0x97, - 0x6e, 0xfd, 0xfa, 0xf2, 0xd3, 0xce, 0xc2, 0x49, 0xd7, 0x67, 0xf7, 0x37, 0xad, 0x74, 0xd6, 0x44, - 0x61, 0x92, 0x52, 0xfa, 0xf6, 0xf4, 0xf9, 0x0c, 0x1c, 0x77, 0x3d, 0xf1, 0x10, 0xa6, 0x17, 0x1e, - 0x6e, 0x48, 0x0f, 0x96, 0xe0, 0x8a, 0x96, 0xe0, 0xac, 0x1c, 0x8a, 0x0d, 0x27, 0x22, 0x4d, 0xa1, - 0x46, 0x62, 0x91, 0x50, 0x71, 0x8e, 0x27, 0x65, 0xe4, 0x20, 0xe0, 0xfc, 0xe7, 0xd8, 0x95, 0x39, - 0x41, 0xe8, 0x36, 0xc4, 0x26, 0x47, 0x5f, 0x99, 0x43, 0x1b, 0x31, 0x87, 0xd9, 0x1f, 0x82, 0x9a, - 0x7a, 0x7f, 0x1e, 0xd6, 0xad, 0x26, 0x5d, 0x57, 0x58, 0xb7, 0x9a, 0x71, 0x06, 0x16, 0xfd, 0x5a, - 0xd4, 0x24, 0xce, 0xac, 0x9e, 0x6b, 0x64, 0x87, 0xd9, 0xc7, 0xf6, 0x0f, 0xc1, 0x88, 0xf2, 0xb3, - 0xf4, 0x7b, 0x91, 0x90, 0xfd, 0xc5, 0x41, 0x18, 0x4d, 0x15, 0x07, 0x4c, 0x39, 0x58, 0xad, 0x7d, - 0x1d, 0xac, 0x2c, 0x4c, 0xbf, 0xe3, 0xcb, 0x5b, 0xc6, 0x8c, 0x30, 0xfd, 0x8e, 0x4f, 0x30, 0x87, - 0x51, 0xf3, 0xb6, 0x19, 0xed, 0xe0, 0x8e, 0x2f, 0xc2, 0x69, 0x95, 0x79, 0x3b, 0xcb, 0x5a, 0xb1, - 0x80, 0xa2, 0x8f, 0x5b, 0x30, 0x12, 0x33, 0xef, 0x3d, 0x77, 0x4f, 0x8b, 0x49, 0x77, 0xf5, 0xe8, - 0xb5, 0x0f, 0x55, 0x21, 0x4c, 0x16, 0x21, 0x63, 0xb6, 0xe0, 0x14, 0x47, 0xf4, 0x29, 0x0b, 0x6a, - 0xea, 0x32, 0x14, 0x71, 0x15, 0xe0, 0x4a, 0xb1, 0xb5, 0x17, 0xb9, 0x5f, 0x53, 0x1d, 0x84, 0xa8, - 0x22, 0x78, 0x58, 0x33, 0x46, 0xb1, 0xf2, 0x1d, 0x0f, 0x1d, 0x8f, 0xef, 0x18, 0x72, 0xfc, 0xc6, - 0xef, 0x86, 0x5a, 0xdb, 0xf1, 0xdd, 0x75, 0x12, 0x27, 0xdc, 0x9d, 0x2b, 0x4b, 0xc2, 0xca, 0x46, - 0xac, 0xe1, 0x54, 0x21, 0xc7, 0xec, 0xc5, 0x12, 0xc3, 0xff, 0xca, 0x14, 0xf2, 0x8a, 0x6e, 0xc6, - 0x26, 0x8e, 0xe9, 0x2c, 0x86, 0x07, 0xea, 0x2c, 0x1e, 0xde, 0xdb, 0x59, 0x6c, 0xff, 0x43, 0x0b, - 0xce, 0xe6, 0x7e, 0xb5, 0x87, 0x37, 0xf0, 0xd1, 0xfe, 0x52, 0x05, 0x4e, 0xe7, 0x54, 0xf9, 0x44, - 0x3b, 0xe6, 0x7c, 0xb6, 0x8a, 0x88, 0x21, 0x48, 0x1f, 0x89, 0xcb, 0x61, 0xcc, 0x99, 0xc4, 0x07, - 0x3b, 0xaa, 0xd1, 0xc7, 0x25, 0xe5, 0xfb, 0x7b, 0x5c, 0x62, 0x4c, 0xcb, 0x81, 0x07, 0x3a, 0x2d, - 0x2b, 0xfb, 0x9c, 0x61, 0xfc, 0x9a, 0x05, 0xe3, 0xed, 0x1e, 0xa5, 0xe5, 0x85, 0xe3, 0xf1, 0xe6, - 0xf1, 0x14, 0xae, 0xaf, 0x3f, 0x76, 0x77, 0x77, 0xa2, 0x67, 0x45, 0x7f, 0xdc, 0xb3, 0x57, 0xf6, - 0xb7, 0xcb, 0xc0, 0x4a, 0xcc, 0xb2, 0x4a, 0x6e, 0x3b, 0xe8, 0x63, 0x66, 0xb1, 0x60, 0xab, 0xa8, - 0xc2, 0xb6, 0x9c, 0xb8, 0x2a, 0x36, 0xcc, 0x47, 0x30, 0xaf, 0xf6, 0x70, 0x56, 0x68, 0x95, 0xfa, - 0x10, 0x5a, 0x9e, 0xac, 0xca, 0x5c, 0x2e, 0xbe, 0x2a, 0x73, 0x2d, 0x5b, 0x91, 0x79, 0xef, 0x4f, - 0x3c, 0xf0, 0x50, 0x7e, 0xe2, 0xbf, 0x65, 0x71, 0xc1, 0x93, 0xf9, 0x0a, 0xda, 0x32, 0xb0, 0xf6, - 0xb0, 0x0c, 0x9e, 0x81, 0x6a, 0x4c, 0xbc, 0xf5, 0x2b, 0xc4, 0xf1, 0x84, 0x05, 0xa1, 0xcf, 0xaf, - 0x45, 0x3b, 0x56, 0x18, 0xec, 0xda, 0x56, 0xcf, 0x0b, 0xee, 0x5c, 0x6a, 0x87, 0xc9, 0x8e, 0xb0, - 0x25, 0xf4, 0xb5, 0xad, 0x0a, 0x82, 0x0d, 0x2c, 0xfb, 0x6f, 0x97, 0xf8, 0x0c, 0x14, 0x41, 0x10, - 0x2f, 0x66, 0x2e, 0xda, 0xeb, 0x3f, 0x7e, 0xe0, 0x23, 0x00, 0x0d, 0x75, 0x45, 0xbd, 0x38, 0x13, - 0xba, 0x72, 0xe4, 0xfb, 0xb3, 0x05, 0x3d, 0xfd, 0x1a, 0xba, 0x0d, 0x1b, 0xfc, 0x52, 0xb2, 0xb4, - 0xbc, 0xaf, 0x2c, 0x4d, 0x89, 0x95, 0x81, 0x7d, 0xb4, 0xdd, 0x9f, 0x5a, 0x90, 0xb2, 0x88, 0x50, - 0x08, 0x15, 0xda, 0xdd, 0x9d, 0x62, 0x6e, 0xdf, 0x37, 0x49, 0x53, 0xd1, 0x28, 0xa6, 0x3d, 0xfb, - 0x89, 0x39, 0x23, 0xe4, 0x89, 0x58, 0x09, 0x3e, 0xaa, 0xd7, 0x8b, 0x63, 0x78, 0x25, 0x08, 0x36, - 0xf9, 0xc1, 0xa6, 0x8e, 0xbb, 0xb0, 0x5f, 0x84, 0x53, 0x5d, 0x9d, 0x62, 0x77, 0x6a, 0x05, 0x54, - 0xfb, 0x64, 0xa6, 0x2b, 0x4b, 0xe0, 0xc4, 0x1c, 0x66, 0x7f, 0xdd, 0x82, 0x93, 0x59, 0xf2, 0xe8, - 0x2d, 0x0b, 0x4e, 0xc5, 0x59, 0x7a, 0xc7, 0x35, 0x76, 0x2a, 0xde, 0xb1, 0x0b, 0x84, 0xbb, 0x3b, - 0x61, 0xff, 0x5f, 0x31, 0xf9, 0x6f, 0xb9, 0x7e, 0x33, 0xb8, 0xa3, 0x0c, 0x13, 0xab, 0xa7, 0x61, - 0x42, 0xd7, 0x63, 0x63, 0x83, 0x34, 0x3b, 0x5e, 0x57, 0xe6, 0xe8, 0x8a, 0x68, 0xc7, 0x0a, 0x83, - 0x25, 0xca, 0x75, 0x44, 0xd9, 0xf6, 0xcc, 0xa4, 0x9c, 0x15, 0xed, 0x58, 0x61, 0xa0, 0xe7, 0x61, - 0xc4, 0x78, 0x49, 0x39, 0x2f, 0x99, 0x41, 0x6e, 0xa8, 0xcc, 0x18, 0xa7, 0xb0, 0xd0, 0x24, 0x80, - 0x32, 0x72, 0xa4, 0x8a, 0x64, 0x8e, 0x22, 0x25, 0x89, 0x62, 0x6c, 0x60, 0xb0, 0xb4, 0x54, 0xaf, - 0x13, 0x33, 0x1f, 0xff, 0xa0, 0x2e, 0x25, 0x3a, 0x23, 0xda, 0xb0, 0x82, 0x52, 0x69, 0xd2, 0x76, - 0xfc, 0x8e, 0xe3, 0xd1, 0x11, 0x12, 0x5b, 0x3f, 0xb5, 0x0c, 0x17, 0x15, 0x04, 0x1b, 0x58, 0xf4, - 0x8d, 0x13, 0xb7, 0x4d, 0x5e, 0x09, 0x7c, 0x19, 0xa7, 0xa6, 0x8f, 0x7d, 0x44, 0x3b, 0x56, 0x18, - 0xf6, 0x7f, 0xb5, 0xe0, 0x84, 0x4e, 0x72, 0xe7, 0xb7, 0x67, 0x9b, 0x3b, 0x55, 0x6b, 0xdf, 0x9d, - 0x6a, 0x3a, 0xfb, 0xb7, 0xd4, 0x57, 0xf6, 0xaf, 0x99, 0x98, 0x5b, 0xde, 0x33, 0x31, 0xf7, 0xfb, - 0xf5, 0xcd, 0xac, 0x3c, 0x83, 0x77, 0x38, 0xef, 0x56, 0x56, 0x64, 0xc3, 0x60, 0xc3, 0x51, 0x15, - 0x5e, 0x46, 0xf8, 0xde, 0x61, 0x66, 0x9a, 0x21, 0x09, 0x88, 0xbd, 0x04, 0x35, 0x75, 0xfa, 0x21, - 0x37, 0xaa, 0x56, 0xfe, 0x46, 0xb5, 0xaf, 0x04, 0xc1, 0xfa, 0xda, 0x37, 0xbe, 0xf3, 0xc4, 0x3b, - 0x7e, 0xef, 0x3b, 0x4f, 0xbc, 0xe3, 0x8f, 0xbe, 0xf3, 0xc4, 0x3b, 0x3e, 0x7e, 0xf7, 0x09, 0xeb, - 0x1b, 0x77, 0x9f, 0xb0, 0x7e, 0xef, 0xee, 0x13, 0xd6, 0x1f, 0xdd, 0x7d, 0xc2, 0xfa, 0xf6, 0xdd, - 0x27, 0xac, 0x2f, 0xfc, 0xa7, 0x27, 0xde, 0xf1, 0x4a, 0x6e, 0xa0, 0x22, 0xfd, 0xf1, 0x6c, 0xa3, - 0x39, 0xb5, 0x75, 0x91, 0xc5, 0xca, 0xd1, 0xe5, 0x35, 0x65, 0xcc, 0xa9, 0x29, 0xb9, 0xbc, 0xfe, - 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2b, 0x8e, 0xba, 0x30, 0x2f, 0xe1, 0x00, 0x00, + // 11006 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x6d, 0x70, 0x24, 0xc7, + 0x75, 0x98, 0x66, 0x17, 0x0b, 0xec, 0x3e, 0x7c, 0xdc, 0x5d, 0xdf, 0x1d, 0x09, 0x9e, 0x48, 0xe2, + 0x3c, 0x8c, 0x29, 0x2a, 0x22, 0x01, 0xf3, 0x44, 0xca, 0x8c, 0x68, 0x4b, 0xc6, 0x02, 0x77, 0x38, + 0xdc, 0x01, 0x07, 0xb0, 0x81, 0xbb, 0x93, 0x28, 0x53, 0xd4, 0x60, 0xb7, 0xb1, 0x98, 0xc3, 0xec, + 0xcc, 0x70, 0x66, 0x16, 0x07, 0xd0, 0x92, 0x2c, 0x59, 0xb2, 0xad, 0x44, 0x1f, 0x54, 0xa4, 0xa4, + 0x4c, 0x27, 0x96, 0x22, 0x5b, 0x4e, 0xca, 0xae, 0x44, 0x15, 0x27, 0xf9, 0x11, 0x27, 0x4e, 0xca, + 0x65, 0x3b, 0x95, 0x52, 0x4a, 0x49, 0xd9, 0xe5, 0x72, 0x59, 0x4e, 0x62, 0x23, 0xd2, 0xa5, 0x52, + 0x49, 0xa5, 0x2a, 0xae, 0x72, 0xe2, 0x1f, 0xc9, 0x25, 0x3f, 0x52, 0xfd, 0xdd, 0x33, 0x3b, 0x0b, + 0x2c, 0x80, 0xc1, 0xdd, 0x49, 0xe6, 0xbf, 0xdd, 0x7e, 0x6f, 0xde, 0xeb, 0xe9, 0xe9, 0x7e, 0xef, + 0xf5, 0xeb, 0xf7, 0x5e, 0xc3, 0x42, 0xcb, 0x4d, 0x36, 0x3a, 0x6b, 0x93, 0x8d, 0xa0, 0x3d, 0xe5, + 0x44, 0xad, 0x20, 0x8c, 0x82, 0x5b, 0xec, 0xc7, 0x33, 0x8d, 0xe6, 0xd4, 0xd6, 0x85, 0xa9, 0x70, + 0xb3, 0x35, 0xe5, 0x84, 0x6e, 0x3c, 0xe5, 0x84, 0xa1, 0xe7, 0x36, 0x9c, 0xc4, 0x0d, 0xfc, 0xa9, + 0xad, 0x67, 0x1d, 0x2f, 0xdc, 0x70, 0x9e, 0x9d, 0x6a, 0x11, 0x9f, 0x44, 0x4e, 0x42, 0x9a, 0x93, + 0x61, 0x14, 0x24, 0x01, 0xfa, 0x11, 0x4d, 0x6d, 0x52, 0x52, 0x63, 0x3f, 0x5e, 0x6d, 0x34, 0x27, + 0xb7, 0x2e, 0x4c, 0x86, 0x9b, 0xad, 0x49, 0x4a, 0x6d, 0xd2, 0xa0, 0x36, 0x29, 0xa9, 0x9d, 0x7b, + 0xc6, 0xe8, 0x4b, 0x2b, 0x68, 0x05, 0x53, 0x8c, 0xe8, 0x5a, 0x67, 0x9d, 0xfd, 0x63, 0x7f, 0xd8, + 0x2f, 0xce, 0xec, 0x9c, 0xbd, 0xf9, 0x42, 0x3c, 0xe9, 0x06, 0xb4, 0x7b, 0x53, 0x8d, 0x20, 0x22, + 0x53, 0x5b, 0x5d, 0x1d, 0x3a, 0x77, 0x59, 0xe3, 0x90, 0xed, 0x84, 0xf8, 0xb1, 0x1b, 0xf8, 0xf1, + 0x33, 0xb4, 0x0b, 0x24, 0xda, 0x22, 0x91, 0xf9, 0x7a, 0x06, 0x42, 0x1e, 0xa5, 0xe7, 0x34, 0xa5, + 0xb6, 0xd3, 0xd8, 0x70, 0x7d, 0x12, 0xed, 0xe8, 0xc7, 0xdb, 0x24, 0x71, 0xf2, 0x9e, 0x9a, 0xea, + 0xf5, 0x54, 0xd4, 0xf1, 0x13, 0xb7, 0x4d, 0xba, 0x1e, 0x78, 0xcf, 0x7e, 0x0f, 0xc4, 0x8d, 0x0d, + 0xd2, 0x76, 0xba, 0x9e, 0x7b, 0x77, 0xaf, 0xe7, 0x3a, 0x89, 0xeb, 0x4d, 0xb9, 0x7e, 0x12, 0x27, + 0x51, 0xf6, 0x21, 0xfb, 0x17, 0x2c, 0x18, 0x9d, 0xbe, 0xb9, 0x32, 0xdd, 0x49, 0x36, 0x66, 0x02, + 0x7f, 0xdd, 0x6d, 0xa1, 0xe7, 0x61, 0xb8, 0xe1, 0x75, 0xe2, 0x84, 0x44, 0xd7, 0x9c, 0x36, 0x19, + 0xb7, 0xce, 0x5b, 0x4f, 0xd5, 0xea, 0xa7, 0xbf, 0xb9, 0x3b, 0xf1, 0xb6, 0x3b, 0xbb, 0x13, 0xc3, + 0x33, 0x1a, 0x84, 0x4d, 0x3c, 0xf4, 0x4e, 0x18, 0x8a, 0x02, 0x8f, 0x4c, 0xe3, 0x6b, 0xe3, 0x25, + 0xf6, 0xc8, 0x09, 0xf1, 0xc8, 0x10, 0xe6, 0xcd, 0x58, 0xc2, 0x29, 0x6a, 0x18, 0x05, 0xeb, 0xae, + 0x47, 0xc6, 0xcb, 0x69, 0xd4, 0x65, 0xde, 0x8c, 0x25, 0xdc, 0xfe, 0xc3, 0x12, 0xc0, 0x74, 0x18, + 0x2e, 0x47, 0xc1, 0x2d, 0xd2, 0x48, 0xd0, 0x47, 0xa0, 0x4a, 0x87, 0xb9, 0xe9, 0x24, 0x0e, 0xeb, + 0xd8, 0xf0, 0x85, 0x1f, 0x9a, 0xe4, 0x6f, 0x3d, 0x69, 0xbe, 0xb5, 0x9e, 0x64, 0x14, 0x7b, 0x72, + 0xeb, 0xd9, 0xc9, 0xa5, 0x35, 0xfa, 0xfc, 0x22, 0x49, 0x9c, 0x3a, 0x12, 0xcc, 0x40, 0xb7, 0x61, + 0x45, 0x15, 0xf9, 0x30, 0x10, 0x87, 0xa4, 0xc1, 0xde, 0x61, 0xf8, 0xc2, 0xc2, 0xe4, 0x51, 0x66, + 0xf3, 0xa4, 0xee, 0xf9, 0x4a, 0x48, 0x1a, 0xf5, 0x11, 0xc1, 0x79, 0x80, 0xfe, 0xc3, 0x8c, 0x0f, + 0xda, 0x82, 0xc1, 0x38, 0x71, 0x92, 0x4e, 0xcc, 0x86, 0x62, 0xf8, 0xc2, 0xb5, 0xc2, 0x38, 0x32, + 0xaa, 0xf5, 0x31, 0xc1, 0x73, 0x90, 0xff, 0xc7, 0x82, 0x9b, 0xfd, 0x27, 0x16, 0x8c, 0x69, 0xe4, + 0x05, 0x37, 0x4e, 0xd0, 0x8f, 0x77, 0x0d, 0xee, 0x64, 0x7f, 0x83, 0x4b, 0x9f, 0x66, 0x43, 0x7b, + 0x52, 0x30, 0xab, 0xca, 0x16, 0x63, 0x60, 0xdb, 0x50, 0x71, 0x13, 0xd2, 0x8e, 0xc7, 0x4b, 0xe7, + 0xcb, 0x4f, 0x0d, 0x5f, 0xb8, 0x5c, 0xd4, 0x7b, 0xd6, 0x47, 0x05, 0xd3, 0xca, 0x3c, 0x25, 0x8f, + 0x39, 0x17, 0xfb, 0x57, 0x47, 0xcc, 0xf7, 0xa3, 0x03, 0x8e, 0x9e, 0x85, 0xe1, 0x38, 0xe8, 0x44, + 0x0d, 0x82, 0x49, 0x18, 0xc4, 0xe3, 0xd6, 0xf9, 0x32, 0x9d, 0x7a, 0x74, 0x52, 0xaf, 0xe8, 0x66, + 0x6c, 0xe2, 0xa0, 0x2f, 0x58, 0x30, 0xd2, 0x24, 0x71, 0xe2, 0xfa, 0x8c, 0xbf, 0xec, 0xfc, 0xea, + 0x91, 0x3b, 0x2f, 0x1b, 0x67, 0x35, 0xf1, 0xfa, 0x19, 0xf1, 0x22, 0x23, 0x46, 0x63, 0x8c, 0x53, + 0xfc, 0xe9, 0xe2, 0x6c, 0x92, 0xb8, 0x11, 0xb9, 0x21, 0xfd, 0x2f, 0x96, 0x8f, 0x5a, 0x9c, 0xb3, + 0x1a, 0x84, 0x4d, 0x3c, 0xe4, 0x43, 0x85, 0x2e, 0xbe, 0x78, 0x7c, 0x80, 0xf5, 0x7f, 0xfe, 0x68, + 0xfd, 0x17, 0x83, 0x4a, 0xd7, 0xb5, 0x1e, 0x7d, 0xfa, 0x2f, 0xc6, 0x9c, 0x0d, 0xfa, 0xbc, 0x05, + 0xe3, 0x42, 0x38, 0x60, 0xc2, 0x07, 0xf4, 0xe6, 0x86, 0x9b, 0x10, 0xcf, 0x8d, 0x93, 0xf1, 0x0a, + 0xeb, 0xc3, 0x54, 0x7f, 0x73, 0x6b, 0x2e, 0x0a, 0x3a, 0xe1, 0x55, 0xd7, 0x6f, 0xd6, 0xcf, 0x0b, + 0x4e, 0xe3, 0x33, 0x3d, 0x08, 0xe3, 0x9e, 0x2c, 0xd1, 0x97, 0x2d, 0x38, 0xe7, 0x3b, 0x6d, 0x12, + 0x87, 0x0e, 0xfd, 0xb4, 0x1c, 0x5c, 0xf7, 0x9c, 0xc6, 0x26, 0xeb, 0xd1, 0xe0, 0xe1, 0x7a, 0x64, + 0x8b, 0x1e, 0x9d, 0xbb, 0xd6, 0x93, 0x34, 0xde, 0x83, 0x2d, 0xfa, 0xba, 0x05, 0xa7, 0x82, 0x28, + 0xdc, 0x70, 0x7c, 0xd2, 0x94, 0xd0, 0x78, 0x7c, 0x88, 0x2d, 0xbd, 0x0f, 0x1f, 0xed, 0x13, 0x2d, + 0x65, 0xc9, 0x2e, 0x06, 0xbe, 0x9b, 0x04, 0xd1, 0x0a, 0x49, 0x12, 0xd7, 0x6f, 0xc5, 0xf5, 0xb3, + 0x77, 0x76, 0x27, 0x4e, 0x75, 0x61, 0xe1, 0xee, 0xfe, 0xa0, 0x9f, 0x80, 0xe1, 0x78, 0xc7, 0x6f, + 0xdc, 0x74, 0xfd, 0x66, 0x70, 0x3b, 0x1e, 0xaf, 0x16, 0xb1, 0x7c, 0x57, 0x14, 0x41, 0xb1, 0x00, + 0x35, 0x03, 0x6c, 0x72, 0xcb, 0xff, 0x70, 0x7a, 0x2a, 0xd5, 0x8a, 0xfe, 0x70, 0x7a, 0x32, 0xed, + 0xc1, 0x16, 0xfd, 0xac, 0x05, 0xa3, 0xb1, 0xdb, 0xf2, 0x9d, 0xa4, 0x13, 0x91, 0xab, 0x64, 0x27, + 0x1e, 0x07, 0xd6, 0x91, 0x2b, 0x47, 0x1c, 0x15, 0x83, 0x64, 0xfd, 0xac, 0xe8, 0xe3, 0xa8, 0xd9, + 0x1a, 0xe3, 0x34, 0xdf, 0xbc, 0x85, 0xa6, 0xa7, 0xf5, 0x70, 0xb1, 0x0b, 0x4d, 0x4f, 0xea, 0x9e, + 0x2c, 0xd1, 0x8f, 0xc1, 0x49, 0xde, 0xa4, 0x46, 0x36, 0x1e, 0x1f, 0x61, 0x82, 0xf6, 0xcc, 0x9d, + 0xdd, 0x89, 0x93, 0x2b, 0x19, 0x18, 0xee, 0xc2, 0x46, 0xaf, 0xc1, 0x44, 0x48, 0xa2, 0xb6, 0x9b, + 0x2c, 0xf9, 0xde, 0x8e, 0x14, 0xdf, 0x8d, 0x20, 0x24, 0x4d, 0xd1, 0x9d, 0x78, 0x7c, 0xf4, 0xbc, + 0xf5, 0x54, 0xb5, 0xfe, 0x0e, 0xd1, 0xcd, 0x89, 0xe5, 0xbd, 0xd1, 0xf1, 0x7e, 0xf4, 0xec, 0x7f, + 0x53, 0x82, 0x93, 0x59, 0xc5, 0x89, 0xfe, 0x9e, 0x05, 0x27, 0x6e, 0xdd, 0x4e, 0x56, 0x83, 0x4d, + 0xe2, 0xc7, 0xf5, 0x1d, 0x2a, 0xde, 0x98, 0xca, 0x18, 0xbe, 0xd0, 0x28, 0x56, 0x45, 0x4f, 0x5e, + 0x49, 0x73, 0xb9, 0xe8, 0x27, 0xd1, 0x4e, 0xfd, 0x61, 0xf1, 0x76, 0x27, 0xae, 0xdc, 0x5c, 0x35, + 0xa1, 0x38, 0xdb, 0xa9, 0x73, 0x9f, 0xb5, 0xe0, 0x4c, 0x1e, 0x09, 0x74, 0x12, 0xca, 0x9b, 0x64, + 0x87, 0x1b, 0x70, 0x98, 0xfe, 0x44, 0xaf, 0x40, 0x65, 0xcb, 0xf1, 0x3a, 0x44, 0x58, 0x37, 0x73, + 0x47, 0x7b, 0x11, 0xd5, 0x33, 0xcc, 0xa9, 0xbe, 0xb7, 0xf4, 0x82, 0x65, 0xff, 0x6e, 0x19, 0x86, + 0x0d, 0xfd, 0x76, 0x0f, 0x2c, 0xb6, 0x20, 0x65, 0xb1, 0x2d, 0x16, 0xa6, 0x9a, 0x7b, 0x9a, 0x6c, + 0xb7, 0x33, 0x26, 0xdb, 0x52, 0x71, 0x2c, 0xf7, 0xb4, 0xd9, 0x50, 0x02, 0xb5, 0x20, 0xa4, 0xd6, + 0x3b, 0x55, 0xfd, 0x03, 0x45, 0x7c, 0xc2, 0x25, 0x49, 0xae, 0x3e, 0x7a, 0x67, 0x77, 0xa2, 0xa6, + 0xfe, 0x62, 0xcd, 0xc8, 0xfe, 0xb6, 0x05, 0x67, 0x8c, 0x3e, 0xce, 0x04, 0x7e, 0xd3, 0x65, 0x9f, + 0xf6, 0x3c, 0x0c, 0x24, 0x3b, 0xa1, 0xdc, 0x21, 0xa8, 0x91, 0x5a, 0xdd, 0x09, 0x09, 0x66, 0x10, + 0x6a, 0xe8, 0xb7, 0x49, 0x1c, 0x3b, 0x2d, 0x92, 0xdd, 0x13, 0x2c, 0xf2, 0x66, 0x2c, 0xe1, 0x28, + 0x02, 0xe4, 0x39, 0x71, 0xb2, 0x1a, 0x39, 0x7e, 0xcc, 0xc8, 0xaf, 0xba, 0x6d, 0x22, 0x06, 0xf8, + 0x2f, 0xf7, 0x37, 0x63, 0xe8, 0x13, 0xf5, 0x87, 0xee, 0xec, 0x4e, 0xa0, 0x85, 0x2e, 0x4a, 0x38, + 0x87, 0xba, 0xfd, 0x65, 0x0b, 0x1e, 0xca, 0xb7, 0xc5, 0xd0, 0x93, 0x30, 0xc8, 0xb7, 0x87, 0xe2, + 0xed, 0xf4, 0x27, 0x61, 0xad, 0x58, 0x40, 0xd1, 0x14, 0xd4, 0x94, 0x9e, 0x10, 0xef, 0x78, 0x4a, + 0xa0, 0xd6, 0xb4, 0x72, 0xd1, 0x38, 0x74, 0xd0, 0xe8, 0x1f, 0x61, 0xb9, 0xa9, 0x41, 0x63, 0xfb, + 0x29, 0x06, 0xb1, 0xff, 0x93, 0x05, 0x27, 0x8c, 0x5e, 0xdd, 0x03, 0xd3, 0xdc, 0x4f, 0x9b, 0xe6, + 0xf3, 0x85, 0xcd, 0xe7, 0x1e, 0xb6, 0xf9, 0xe7, 0x2d, 0x38, 0x67, 0x60, 0x2d, 0x3a, 0x49, 0x63, + 0xe3, 0xe2, 0x76, 0x18, 0x91, 0x98, 0x6e, 0xbd, 0xd1, 0x63, 0x86, 0xdc, 0xaa, 0x0f, 0x0b, 0x0a, + 0xe5, 0xab, 0x64, 0x87, 0x0b, 0xb1, 0xa7, 0xa1, 0xca, 0x27, 0x67, 0x10, 0x89, 0x11, 0x57, 0xef, + 0xb6, 0x24, 0xda, 0xb1, 0xc2, 0x40, 0x36, 0x0c, 0x32, 0xe1, 0x44, 0x17, 0x2b, 0x55, 0x43, 0x40, + 0x3f, 0xe2, 0x0d, 0xd6, 0x82, 0x05, 0xc4, 0x8e, 0x53, 0xdd, 0x59, 0x8e, 0x08, 0xfb, 0xb8, 0xcd, + 0x4b, 0x2e, 0xf1, 0x9a, 0x31, 0xdd, 0x36, 0x38, 0xbe, 0x1f, 0x24, 0x62, 0x07, 0x60, 0x6c, 0x1b, + 0xa6, 0x75, 0x33, 0x36, 0x71, 0x28, 0x53, 0xcf, 0x59, 0x23, 0x1e, 0x1f, 0x51, 0xc1, 0x74, 0x81, + 0xb5, 0x60, 0x01, 0xb1, 0xef, 0x94, 0xd8, 0x06, 0x45, 0x2d, 0x7d, 0x72, 0x2f, 0x76, 0xb7, 0x51, + 0x4a, 0x56, 0x2e, 0x17, 0x27, 0xb8, 0x48, 0xef, 0x1d, 0xee, 0xeb, 0x19, 0x71, 0x89, 0x0b, 0xe5, + 0xba, 0xf7, 0x2e, 0xf7, 0xb7, 0x4a, 0x30, 0x91, 0x7e, 0xa0, 0x4b, 0xda, 0xd2, 0x2d, 0x95, 0xc1, + 0x28, 0xeb, 0xef, 0x30, 0xf0, 0xb1, 0x89, 0xd7, 0x43, 0x60, 0x95, 0x8e, 0x53, 0x60, 0x99, 0xf2, + 0xb4, 0xbc, 0x8f, 0x3c, 0x7d, 0x52, 0x8d, 0xfa, 0x40, 0x46, 0x80, 0xa5, 0x75, 0xca, 0x79, 0x18, + 0x88, 0x13, 0x12, 0x8e, 0x57, 0xd2, 0xf2, 0x68, 0x25, 0x21, 0x21, 0x66, 0x10, 0xfb, 0xbf, 0x97, + 0xe0, 0xe1, 0xf4, 0x18, 0x6a, 0x15, 0xf0, 0xfe, 0x94, 0x0a, 0x78, 0x97, 0xa9, 0x02, 0xee, 0xee, + 0x4e, 0xbc, 0xbd, 0xc7, 0x63, 0xdf, 0x33, 0x1a, 0x02, 0xcd, 0x65, 0x46, 0x71, 0x2a, 0x3d, 0x8a, + 0x77, 0x77, 0x27, 0x1e, 0xeb, 0xf1, 0x8e, 0x99, 0x61, 0x7e, 0x12, 0x06, 0x23, 0xe2, 0xc4, 0x81, + 0x2f, 0x06, 0x5a, 0x7d, 0x0e, 0xcc, 0x5a, 0xb1, 0x80, 0xda, 0xbf, 0x5f, 0xcb, 0x0e, 0xf6, 0x1c, + 0x77, 0xd8, 0x05, 0x11, 0x72, 0x61, 0x80, 0x99, 0xf5, 0x5c, 0x34, 0x5c, 0x3d, 0xda, 0x32, 0xa2, + 0x6a, 0x40, 0x91, 0xae, 0x57, 0xe9, 0x57, 0xa3, 0x4d, 0x98, 0xb1, 0x40, 0xdb, 0x50, 0x6d, 0x48, + 0x6b, 0xbb, 0x54, 0x84, 0x5f, 0x4a, 0xd8, 0xda, 0x9a, 0xe3, 0x08, 0x95, 0xd7, 0xca, 0x44, 0x57, + 0xdc, 0x10, 0x81, 0x72, 0xcb, 0x4d, 0xc4, 0x67, 0x3d, 0xe2, 0x7e, 0x6a, 0xce, 0x35, 0x5e, 0x71, + 0x88, 0x2a, 0x91, 0x39, 0x37, 0xc1, 0x94, 0x3e, 0xfa, 0x69, 0x0b, 0x86, 0xe3, 0x46, 0x7b, 0x39, + 0x0a, 0xb6, 0xdc, 0x26, 0x89, 0x84, 0x35, 0x75, 0x44, 0xd1, 0xb4, 0x32, 0xb3, 0x28, 0x09, 0x6a, + 0xbe, 0x7c, 0x7f, 0xab, 0x21, 0xd8, 0xe4, 0x4b, 0x77, 0x19, 0x0f, 0x8b, 0x77, 0x9f, 0x25, 0x0d, + 0x97, 0xea, 0x3f, 0xb9, 0xa9, 0x62, 0x33, 0xe5, 0xc8, 0xd6, 0xe5, 0x6c, 0xa7, 0xb1, 0x49, 0xd7, + 0x9b, 0xee, 0xd0, 0xdb, 0xef, 0xec, 0x4e, 0x3c, 0x3c, 0x93, 0xcf, 0x13, 0xf7, 0xea, 0x0c, 0x1b, + 0xb0, 0xb0, 0xe3, 0x79, 0x98, 0xbc, 0xd6, 0x21, 0xcc, 0x65, 0x52, 0xc0, 0x80, 0x2d, 0x6b, 0x82, + 0x99, 0x01, 0x33, 0x20, 0xd8, 0xe4, 0x8b, 0x5e, 0x83, 0xc1, 0xb6, 0x93, 0x44, 0xee, 0xb6, 0xf0, + 0x93, 0x1c, 0xd1, 0xde, 0x5f, 0x64, 0xb4, 0x34, 0x73, 0xa6, 0xa9, 0x79, 0x23, 0x16, 0x8c, 0x50, + 0x1b, 0x2a, 0x6d, 0x12, 0xb5, 0xc8, 0x78, 0xb5, 0x08, 0x9f, 0xf0, 0x22, 0x25, 0xa5, 0x19, 0xd6, + 0xa8, 0x75, 0xc4, 0xda, 0x30, 0xe7, 0x82, 0x5e, 0x81, 0x6a, 0x4c, 0x3c, 0xd2, 0xa0, 0xf6, 0x4d, + 0x8d, 0x71, 0x7c, 0x77, 0x9f, 0xb6, 0x1e, 0x35, 0x2c, 0x56, 0xc4, 0xa3, 0x7c, 0x81, 0xc9, 0x7f, + 0x58, 0x91, 0xa4, 0x03, 0x18, 0x7a, 0x9d, 0x96, 0xeb, 0x8f, 0x43, 0x11, 0x03, 0xb8, 0xcc, 0x68, + 0x65, 0x06, 0x90, 0x37, 0x62, 0xc1, 0xc8, 0xfe, 0x2f, 0x16, 0xa0, 0xb4, 0x50, 0xbb, 0x07, 0x46, + 0xed, 0x6b, 0x69, 0xa3, 0x76, 0xa1, 0x48, 0xab, 0xa3, 0x87, 0x5d, 0xfb, 0x1b, 0x35, 0xc8, 0xa8, + 0x83, 0x6b, 0x24, 0x4e, 0x48, 0xf3, 0x2d, 0x11, 0xfe, 0x96, 0x08, 0x7f, 0x4b, 0x84, 0x2b, 0x11, + 0xbe, 0x96, 0x11, 0xe1, 0xef, 0x33, 0x56, 0xbd, 0x3e, 0x80, 0x7d, 0x55, 0x9d, 0xd0, 0x9a, 0x3d, + 0x30, 0x10, 0xa8, 0x24, 0xb8, 0xb2, 0xb2, 0x74, 0x2d, 0x57, 0x66, 0xbf, 0x9a, 0x96, 0xd9, 0x47, + 0x65, 0xf1, 0x17, 0x41, 0x4a, 0xff, 0x6b, 0x0b, 0xde, 0x91, 0x96, 0x5e, 0x72, 0xe6, 0xcc, 0xb7, + 0xfc, 0x20, 0x22, 0xb3, 0xee, 0xfa, 0x3a, 0x89, 0x88, 0xdf, 0x20, 0xb1, 0xf2, 0x62, 0x58, 0xbd, + 0xbc, 0x18, 0xe8, 0x39, 0x18, 0xb9, 0x15, 0x07, 0xfe, 0x72, 0xe0, 0xfa, 0x42, 0x04, 0xd1, 0x8d, + 0xf0, 0xc9, 0x3b, 0xbb, 0x13, 0x23, 0x74, 0x44, 0x65, 0x3b, 0x4e, 0x61, 0xa1, 0x19, 0x38, 0x75, + 0xeb, 0xb5, 0x65, 0x27, 0x31, 0xdc, 0x01, 0x72, 0xe3, 0xce, 0x0e, 0x2c, 0xae, 0xbc, 0x94, 0x01, + 0xe2, 0x6e, 0x7c, 0xfb, 0x6f, 0x97, 0xe0, 0x91, 0xcc, 0x8b, 0x04, 0x9e, 0x17, 0x74, 0x12, 0xba, + 0xa9, 0x41, 0x5f, 0xb5, 0xe0, 0x64, 0x3b, 0xed, 0x71, 0x88, 0x85, 0x63, 0xf7, 0x03, 0x85, 0xe9, + 0x88, 0x8c, 0x4b, 0xa3, 0x3e, 0x2e, 0x46, 0xe8, 0x64, 0x06, 0x10, 0xe3, 0xae, 0xbe, 0xa0, 0x57, + 0xa0, 0xd6, 0x76, 0xb6, 0xaf, 0x87, 0x4d, 0x27, 0x91, 0xfb, 0xc9, 0xde, 0x6e, 0x80, 0x4e, 0xe2, + 0x7a, 0x93, 0xfc, 0x68, 0x7f, 0x72, 0xde, 0x4f, 0x96, 0xa2, 0x95, 0x24, 0x72, 0xfd, 0x16, 0x77, + 0xe7, 0x2d, 0x4a, 0x32, 0x58, 0x53, 0xb4, 0xbf, 0x62, 0x65, 0x95, 0x94, 0x1a, 0x9d, 0xc8, 0x49, + 0x48, 0x6b, 0x07, 0x7d, 0x14, 0x2a, 0x74, 0xe3, 0x27, 0x47, 0xe5, 0x66, 0x91, 0x9a, 0xd3, 0xf8, + 0x12, 0x5a, 0x89, 0xd2, 0x7f, 0x31, 0xe6, 0x4c, 0xed, 0xaf, 0xd6, 0xb2, 0xc6, 0x02, 0x3b, 0xbc, + 0xbd, 0x00, 0xd0, 0x0a, 0x56, 0x49, 0x3b, 0xf4, 0xe8, 0xb0, 0x58, 0xec, 0x04, 0x40, 0xf9, 0x3a, + 0xe6, 0x14, 0x04, 0x1b, 0x58, 0xe8, 0xaf, 0x5a, 0x00, 0x2d, 0x39, 0xe7, 0xa5, 0x21, 0x70, 0xbd, + 0xc8, 0xd7, 0xd1, 0x2b, 0x4a, 0xf7, 0x45, 0x31, 0xc4, 0x06, 0x73, 0xf4, 0x53, 0x16, 0x54, 0x13, + 0xd9, 0x7d, 0xae, 0x1a, 0x57, 0x8b, 0xec, 0x89, 0x7c, 0x69, 0x6d, 0x13, 0xa9, 0x21, 0x51, 0x7c, + 0xd1, 0xcf, 0x58, 0x00, 0xf1, 0x8e, 0xdf, 0x58, 0x0e, 0x3c, 0xb7, 0xb1, 0x23, 0x34, 0xe6, 0x8d, + 0x42, 0xfd, 0x31, 0x8a, 0x7a, 0x7d, 0x8c, 0x8e, 0x86, 0xfe, 0x8f, 0x0d, 0xce, 0xe8, 0xe3, 0x50, + 0x8d, 0xc5, 0x74, 0x13, 0x3a, 0x72, 0xb5, 0x58, 0xaf, 0x10, 0xa7, 0x2d, 0xc4, 0xab, 0xf8, 0x87, + 0x15, 0x4f, 0xf4, 0x73, 0x16, 0x9c, 0x08, 0xd3, 0x7e, 0x3e, 0xa1, 0x0e, 0x8b, 0x93, 0x01, 0x19, + 0x3f, 0x62, 0xfd, 0xf4, 0x9d, 0xdd, 0x89, 0x13, 0x99, 0x46, 0x9c, 0xed, 0x05, 0x95, 0x80, 0x7a, + 0x06, 0x2f, 0x85, 0xdc, 0xe7, 0x38, 0xa4, 0x25, 0xe0, 0x5c, 0x16, 0x88, 0xbb, 0xf1, 0xd1, 0x32, + 0x9c, 0xa1, 0xbd, 0xdb, 0xe1, 0xe6, 0xa7, 0x54, 0x2f, 0x31, 0x53, 0x86, 0xd5, 0xfa, 0xa3, 0x62, + 0x86, 0x30, 0xaf, 0x7e, 0x16, 0x07, 0xe7, 0x3e, 0x89, 0x7e, 0xd7, 0x82, 0x47, 0x5d, 0xa6, 0x06, + 0x4c, 0x87, 0xb9, 0xd6, 0x08, 0xe2, 0x24, 0x96, 0x14, 0x2a, 0x2b, 0x7a, 0xa9, 0x9f, 0xfa, 0x5f, + 0x12, 0x6f, 0xf0, 0xe8, 0xfc, 0x1e, 0x5d, 0xc2, 0x7b, 0x76, 0x18, 0xfd, 0x30, 0x8c, 0xca, 0x75, + 0xb1, 0x4c, 0x45, 0x30, 0x53, 0xb4, 0xb5, 0xfa, 0xa9, 0x3b, 0xbb, 0x13, 0xa3, 0xab, 0x26, 0x00, + 0xa7, 0xf1, 0xec, 0x6f, 0x95, 0x52, 0xe7, 0x21, 0xca, 0x09, 0xc9, 0xc4, 0x4d, 0x43, 0xfa, 0x7f, + 0xa4, 0xf4, 0x2c, 0x54, 0xdc, 0x28, 0xef, 0x92, 0x16, 0x37, 0xaa, 0x29, 0xc6, 0x06, 0x73, 0x6a, + 0x94, 0x9e, 0x72, 0xb2, 0xae, 0x4e, 0x21, 0x01, 0x5f, 0x29, 0xb2, 0x4b, 0xdd, 0xa7, 0x57, 0x8f, + 0x88, 0xae, 0x9d, 0xea, 0x02, 0xe1, 0xee, 0x2e, 0xd9, 0xdf, 0x4a, 0x9f, 0xc1, 0x18, 0x8b, 0xb7, + 0x8f, 0xf3, 0xa5, 0x2f, 0x58, 0x30, 0x1c, 0x05, 0x9e, 0xe7, 0xfa, 0x2d, 0x2a, 0x68, 0x84, 0xb6, + 0xfc, 0xd0, 0xb1, 0x28, 0x2c, 0x21, 0x51, 0x98, 0x69, 0x8b, 0x35, 0x4f, 0x6c, 0x76, 0xc0, 0xfe, + 0x13, 0x0b, 0xc6, 0x7b, 0x09, 0x44, 0x44, 0xe0, 0xed, 0x72, 0xb5, 0xab, 0xe8, 0x8a, 0x25, 0x7f, + 0x96, 0x78, 0x44, 0x39, 0x9e, 0xab, 0xf5, 0x27, 0xc4, 0x6b, 0xbe, 0x7d, 0xb9, 0x37, 0x2a, 0xde, + 0x8b, 0x0e, 0x7a, 0x19, 0x4e, 0x1a, 0xef, 0x15, 0xab, 0x81, 0xa9, 0xd5, 0x27, 0xa9, 0x05, 0x32, + 0x9d, 0x81, 0xdd, 0xdd, 0x9d, 0x78, 0x28, 0xdb, 0x26, 0x24, 0x76, 0x17, 0x1d, 0xfb, 0x97, 0x4b, + 0xd9, 0xaf, 0xa5, 0x94, 0xed, 0x9b, 0x56, 0xd7, 0x76, 0xfe, 0x03, 0xc7, 0xa1, 0xe0, 0xd8, 0xc6, + 0x5f, 0x05, 0x70, 0xf4, 0xc6, 0xb9, 0x8f, 0x27, 0xc4, 0xf6, 0xbf, 0x1d, 0x80, 0x3d, 0x7a, 0xd6, + 0x87, 0xf5, 0x7c, 0xe0, 0x63, 0xc5, 0xcf, 0x59, 0xea, 0xc8, 0xa9, 0xcc, 0x16, 0x79, 0xf3, 0xb8, + 0xc6, 0x9e, 0x6f, 0x60, 0x62, 0x1e, 0xa5, 0xa0, 0xdc, 0xd8, 0xe9, 0xc3, 0x2d, 0xf4, 0x35, 0x2b, + 0x7d, 0x68, 0xc6, 0xc3, 0xce, 0xdc, 0x63, 0xeb, 0x93, 0x71, 0x12, 0xc7, 0x3b, 0xa6, 0xcf, 0x6f, + 0x7a, 0x9d, 0xd1, 0x4d, 0x02, 0xac, 0xbb, 0xbe, 0xe3, 0xb9, 0xaf, 0xd3, 0xed, 0x49, 0x85, 0x69, + 0x58, 0x66, 0xb2, 0x5c, 0x52, 0xad, 0xd8, 0xc0, 0x38, 0xf7, 0x57, 0x60, 0xd8, 0x78, 0xf3, 0x9c, + 0xe0, 0x8a, 0x33, 0x66, 0x70, 0x45, 0xcd, 0x88, 0x89, 0x38, 0xf7, 0x3e, 0x38, 0x99, 0xed, 0xe0, + 0x41, 0x9e, 0xb7, 0xff, 0xf7, 0x50, 0xf6, 0x14, 0x6b, 0x95, 0x44, 0x6d, 0xda, 0xb5, 0xb7, 0x3c, + 0x4b, 0x6f, 0x79, 0x96, 0xde, 0xf2, 0x2c, 0x99, 0x87, 0x03, 0xc2, 0x6b, 0x32, 0x74, 0x8f, 0xbc, + 0x26, 0x29, 0x3f, 0x50, 0xb5, 0x70, 0x3f, 0x90, 0x7d, 0xa7, 0x02, 0x29, 0x3b, 0x8a, 0x8f, 0xf7, + 0x3b, 0x61, 0x28, 0x22, 0x61, 0x70, 0x1d, 0x2f, 0x08, 0x1d, 0xa2, 0x63, 0xed, 0x79, 0x33, 0x96, + 0x70, 0xaa, 0x6b, 0x42, 0x27, 0xd9, 0x10, 0x4a, 0x44, 0xe9, 0x9a, 0x65, 0x27, 0xd9, 0xc0, 0x0c, + 0x82, 0xde, 0x07, 0x63, 0x89, 0x13, 0xb5, 0xa8, 0xbd, 0xbd, 0xc5, 0x3e, 0xab, 0x38, 0xeb, 0x7c, + 0x48, 0xe0, 0x8e, 0xad, 0xa6, 0xa0, 0x38, 0x83, 0x8d, 0x5e, 0x83, 0x81, 0x0d, 0xe2, 0xb5, 0xc5, + 0x90, 0xaf, 0x14, 0x27, 0xe3, 0xd9, 0xbb, 0x5e, 0x26, 0x5e, 0x9b, 0x4b, 0x20, 0xfa, 0x0b, 0x33, + 0x56, 0x74, 0xbe, 0xd5, 0x36, 0x3b, 0x71, 0x12, 0xb4, 0xdd, 0xd7, 0xa5, 0x8b, 0xef, 0x03, 0x05, + 0x33, 0xbe, 0x2a, 0xe9, 0x73, 0x5f, 0x8a, 0xfa, 0x8b, 0x35, 0x67, 0xd6, 0x8f, 0xa6, 0x1b, 0xb1, + 0x4f, 0xb5, 0x23, 0x3c, 0x75, 0x45, 0xf7, 0x63, 0x56, 0xd2, 0xe7, 0xfd, 0x50, 0x7f, 0xb1, 0xe6, + 0x8c, 0x76, 0xd4, 0xbc, 0x1f, 0x66, 0x7d, 0xb8, 0x5e, 0x70, 0x1f, 0xf8, 0x9c, 0xcf, 0x9d, 0xff, + 0x4f, 0x40, 0xa5, 0xb1, 0xe1, 0x44, 0xc9, 0xf8, 0x08, 0x9b, 0x34, 0xca, 0xa7, 0x33, 0x43, 0x1b, + 0x31, 0x87, 0xa1, 0xc7, 0xa0, 0x1c, 0x91, 0x75, 0x16, 0xb7, 0x69, 0x44, 0xf4, 0x60, 0xb2, 0x8e, + 0x69, 0xbb, 0xfd, 0x8b, 0xa5, 0xb4, 0xb9, 0x94, 0x7e, 0x6f, 0x3e, 0xdb, 0x1b, 0x9d, 0x28, 0x96, + 0x7e, 0x1f, 0x63, 0xb6, 0xb3, 0x66, 0x2c, 0xe1, 0xe8, 0x93, 0x16, 0x0c, 0xdd, 0x8a, 0x03, 0xdf, + 0x27, 0x89, 0x50, 0x4d, 0x37, 0x0a, 0x1e, 0x8a, 0x2b, 0x9c, 0xba, 0xee, 0x83, 0x68, 0xc0, 0x92, + 0x2f, 0xed, 0x2e, 0xd9, 0x6e, 0x78, 0x9d, 0x66, 0x57, 0x90, 0xc6, 0x45, 0xde, 0x8c, 0x25, 0x9c, + 0xa2, 0xba, 0x3e, 0x47, 0x1d, 0x48, 0xa3, 0xce, 0xfb, 0x02, 0x55, 0xc0, 0xed, 0xbf, 0x39, 0x08, + 0x67, 0x73, 0x17, 0x07, 0x35, 0x64, 0x98, 0xa9, 0x70, 0xc9, 0xf5, 0x88, 0x0c, 0x4f, 0x62, 0x86, + 0xcc, 0x0d, 0xd5, 0x8a, 0x0d, 0x0c, 0xf4, 0x93, 0x00, 0xa1, 0x13, 0x39, 0x6d, 0xa2, 0xfc, 0xb2, + 0x47, 0xb6, 0x17, 0x68, 0x3f, 0x96, 0x25, 0x4d, 0xbd, 0x37, 0x55, 0x4d, 0x31, 0x36, 0x58, 0xa2, + 0xe7, 0x61, 0x38, 0x22, 0x1e, 0x71, 0x62, 0x16, 0xf6, 0x9b, 0xcd, 0x61, 0xc0, 0x1a, 0x84, 0x4d, + 0x3c, 0xf4, 0xa4, 0x8a, 0xe4, 0xca, 0x44, 0xb4, 0xa4, 0xa3, 0xb9, 0xd0, 0x1b, 0x16, 0x8c, 0xad, + 0xbb, 0x1e, 0xd1, 0xdc, 0x45, 0xc6, 0xc1, 0xd2, 0xd1, 0x5f, 0xf2, 0x92, 0x49, 0x57, 0x4b, 0xc8, + 0x54, 0x73, 0x8c, 0x33, 0xec, 0xe9, 0x67, 0xde, 0x22, 0x11, 0x13, 0xad, 0x83, 0xe9, 0xcf, 0x7c, + 0x83, 0x37, 0x63, 0x09, 0x47, 0xd3, 0x70, 0x22, 0x74, 0xe2, 0x78, 0x26, 0x22, 0x4d, 0xe2, 0x27, + 0xae, 0xe3, 0xf1, 0x7c, 0x80, 0xaa, 0x8e, 0x07, 0x5e, 0x4e, 0x83, 0x71, 0x16, 0x1f, 0x7d, 0x10, + 0x1e, 0xe6, 0x8e, 0x8f, 0x45, 0x37, 0x8e, 0x5d, 0xbf, 0xa5, 0xa7, 0x81, 0xf0, 0xff, 0x4c, 0x08, + 0x52, 0x0f, 0xcf, 0xe7, 0xa3, 0xe1, 0x5e, 0xcf, 0xa3, 0xa7, 0xa1, 0x1a, 0x6f, 0xba, 0xe1, 0x4c, + 0xd4, 0x8c, 0xd9, 0xa1, 0x47, 0x55, 0x7b, 0x1b, 0x57, 0x44, 0x3b, 0x56, 0x18, 0xa8, 0x01, 0x23, + 0xfc, 0x93, 0xf0, 0x50, 0x34, 0x21, 0x1f, 0x9f, 0xe9, 0xa9, 0x1e, 0x45, 0x7a, 0xdb, 0x24, 0x76, + 0x6e, 0x5f, 0x94, 0x47, 0x30, 0xfc, 0xc4, 0xe0, 0x86, 0x41, 0x06, 0xa7, 0x88, 0xda, 0x3f, 0x5f, + 0x4a, 0xef, 0xb8, 0xcd, 0x45, 0x8a, 0x62, 0xba, 0x14, 0x93, 0x1b, 0x4e, 0x24, 0xbd, 0x31, 0x47, + 0x4c, 0x5b, 0x10, 0x74, 0x6f, 0x38, 0x91, 0xb9, 0xa8, 0x19, 0x03, 0x2c, 0x39, 0xa1, 0x5b, 0x30, + 0x90, 0x78, 0x4e, 0x41, 0x79, 0x4e, 0x06, 0x47, 0xed, 0x00, 0x59, 0x98, 0x8e, 0x31, 0xe3, 0x81, + 0x1e, 0xa5, 0x56, 0xff, 0x9a, 0x3c, 0x22, 0x11, 0x86, 0xfa, 0x5a, 0x8c, 0x59, 0xab, 0xfd, 0x2b, + 0x90, 0x23, 0x57, 0x95, 0x22, 0x43, 0x17, 0x00, 0xe8, 0x06, 0x72, 0x39, 0x22, 0xeb, 0xee, 0xb6, + 0x30, 0x24, 0xd4, 0xda, 0xbd, 0xa6, 0x20, 0xd8, 0xc0, 0x92, 0xcf, 0xac, 0x74, 0xd6, 0xe9, 0x33, + 0xa5, 0xee, 0x67, 0x38, 0x04, 0x1b, 0x58, 0xe8, 0x39, 0x18, 0x74, 0xdb, 0x4e, 0x4b, 0x85, 0x60, + 0x3e, 0x4a, 0x17, 0xed, 0x3c, 0x6b, 0xb9, 0xbb, 0x3b, 0x31, 0xa6, 0x3a, 0xc4, 0x9a, 0xb0, 0xc0, + 0x45, 0xbf, 0x6c, 0xc1, 0x48, 0x23, 0x68, 0xb7, 0x03, 0x9f, 0x6f, 0xbb, 0xc4, 0x1e, 0xf2, 0xd6, + 0x71, 0xa9, 0xf9, 0xc9, 0x19, 0x83, 0x19, 0xdf, 0x44, 0xaa, 0x84, 0x2c, 0x13, 0x84, 0x53, 0xbd, + 0x32, 0xd7, 0x76, 0x65, 0x9f, 0xb5, 0xfd, 0xeb, 0x16, 0x9c, 0xe2, 0xcf, 0x1a, 0xbb, 0x41, 0x91, + 0x7b, 0x14, 0x1c, 0xf3, 0x6b, 0x75, 0x6d, 0x90, 0x95, 0x97, 0xae, 0x0b, 0x8e, 0xbb, 0x3b, 0x89, + 0xe6, 0xe0, 0xd4, 0x7a, 0x10, 0x35, 0x88, 0x39, 0x10, 0x42, 0x30, 0x29, 0x42, 0x97, 0xb2, 0x08, + 0xb8, 0xfb, 0x19, 0x74, 0x03, 0x1e, 0x32, 0x1a, 0xcd, 0x71, 0xe0, 0xb2, 0xe9, 0x71, 0x41, 0xed, + 0xa1, 0x4b, 0xb9, 0x58, 0xb8, 0xc7, 0xd3, 0x69, 0x87, 0x49, 0xad, 0x0f, 0x87, 0xc9, 0xab, 0xf0, + 0x48, 0xa3, 0x7b, 0x64, 0xb6, 0xe2, 0xce, 0x5a, 0xcc, 0x25, 0x55, 0xb5, 0xfe, 0x03, 0x82, 0xc0, + 0x23, 0x33, 0xbd, 0x10, 0x71, 0x6f, 0x1a, 0xe8, 0xa3, 0x50, 0x8d, 0x08, 0xfb, 0x2a, 0xb1, 0x48, + 0xc4, 0x39, 0xe2, 0x2e, 0x59, 0x5b, 0xa0, 0x9c, 0xac, 0x96, 0xbd, 0xa2, 0x21, 0xc6, 0x8a, 0x23, + 0xba, 0x0d, 0x43, 0xa1, 0x93, 0x34, 0x36, 0x44, 0xfa, 0xcd, 0x91, 0xe3, 0x5f, 0x14, 0x73, 0xe6, + 0x03, 0x37, 0x12, 0x76, 0x39, 0x13, 0x2c, 0xb9, 0x51, 0x6b, 0xa4, 0x11, 0xb4, 0xc3, 0xc0, 0x27, + 0x7e, 0x12, 0x8f, 0x8f, 0x6a, 0x6b, 0x64, 0x46, 0xb5, 0x62, 0x03, 0xe3, 0xdc, 0xfb, 0xe1, 0x54, + 0xd7, 0xc2, 0x3b, 0x90, 0x73, 0x65, 0x16, 0x1e, 0xca, 0x9f, 0xe2, 0x07, 0x72, 0xb1, 0xfc, 0x93, + 0x4c, 0x90, 0xab, 0x61, 0xf6, 0xf6, 0xe1, 0xae, 0x73, 0xa0, 0x4c, 0xfc, 0x2d, 0x21, 0xf1, 0x2f, + 0x1d, 0x6d, 0xa4, 0x2f, 0xfa, 0x5b, 0x7c, 0x85, 0x32, 0x9f, 0xc4, 0x45, 0x7f, 0x0b, 0x53, 0xda, + 0xe8, 0x4b, 0x56, 0xca, 0x6c, 0xe3, 0x4e, 0xbe, 0x0f, 0x1f, 0x8b, 0x9d, 0xdf, 0xb7, 0x25, 0x67, + 0xff, 0xbb, 0x12, 0x9c, 0xdf, 0x8f, 0x48, 0x1f, 0xc3, 0xf7, 0x04, 0x0c, 0xc6, 0xec, 0xd8, 0x5a, + 0x88, 0xd0, 0x61, 0x3a, 0xb3, 0xf8, 0x41, 0xf6, 0xab, 0x58, 0x80, 0x90, 0x07, 0xe5, 0xb6, 0x13, + 0x0a, 0xdf, 0xcf, 0xfc, 0x51, 0xd3, 0x5e, 0xe8, 0x7f, 0xc7, 0x5b, 0x74, 0x42, 0xee, 0x51, 0x30, + 0x1a, 0x30, 0x65, 0x83, 0x12, 0xa8, 0x38, 0x51, 0xe4, 0xc8, 0x33, 0xd2, 0xab, 0xc5, 0xf0, 0x9b, + 0xa6, 0x24, 0xf9, 0x11, 0x53, 0xaa, 0x09, 0x73, 0x66, 0xf6, 0xe7, 0x86, 0x52, 0xa9, 0x1f, 0xec, + 0xe0, 0x3b, 0x86, 0x41, 0xe1, 0xf2, 0xb1, 0x8a, 0xce, 0x36, 0xe2, 0xb9, 0x7b, 0x6c, 0x57, 0x27, + 0x32, 0xa0, 0x05, 0x2b, 0xf4, 0x59, 0x8b, 0xe5, 0x19, 0xcb, 0x74, 0x18, 0xb1, 0x97, 0x3a, 0x9e, + 0xb4, 0x67, 0x33, 0x7b, 0x59, 0x36, 0x62, 0x93, 0xbb, 0xa8, 0x17, 0xc0, 0x6c, 0xc8, 0xee, 0x7a, + 0x01, 0xcc, 0x26, 0x94, 0x70, 0xb4, 0x9d, 0x73, 0xc0, 0x5d, 0x40, 0xae, 0x6a, 0x1f, 0x47, 0xda, + 0x5f, 0xb3, 0xe0, 0x94, 0x9b, 0x3d, 0xa9, 0x14, 0x3b, 0x8f, 0x23, 0x86, 0x50, 0xf4, 0x3e, 0x08, + 0x55, 0xca, 0xb7, 0x0b, 0x84, 0xbb, 0x3b, 0x83, 0x9a, 0x30, 0xe0, 0xfa, 0xeb, 0x81, 0x30, 0x39, + 0xea, 0x47, 0xeb, 0xd4, 0xbc, 0xbf, 0x1e, 0xe8, 0xd5, 0x4c, 0xff, 0x61, 0x46, 0x1d, 0x2d, 0xc0, + 0x99, 0x48, 0xf8, 0x86, 0x2e, 0xbb, 0x31, 0xdd, 0xc1, 0x2f, 0xb8, 0x6d, 0x37, 0x61, 0xe6, 0x42, + 0xb9, 0x3e, 0x7e, 0x67, 0x77, 0xe2, 0x0c, 0xce, 0x81, 0xe3, 0xdc, 0xa7, 0xd0, 0xeb, 0x30, 0x24, + 0x13, 0xa3, 0xab, 0x45, 0xec, 0xe2, 0xba, 0xe7, 0xbf, 0x9a, 0x4c, 0x2b, 0x22, 0x07, 0x5a, 0x32, + 0xb4, 0xdf, 0x18, 0x86, 0xee, 0x43, 0x4c, 0xf4, 0x31, 0xa8, 0x45, 0x2a, 0x59, 0xdb, 0x2a, 0x42, + 0xb9, 0xca, 0xef, 0x2b, 0x0e, 0x50, 0x95, 0xe1, 0xa2, 0xd3, 0xb2, 0x35, 0x47, 0xba, 0xbd, 0x88, + 0xf5, 0x59, 0x67, 0x01, 0x73, 0x5b, 0x70, 0xd5, 0xe7, 0x58, 0x3b, 0x7e, 0x03, 0x33, 0x1e, 0x28, + 0x82, 0xc1, 0x0d, 0xe2, 0x78, 0xc9, 0x46, 0x31, 0x2e, 0xf7, 0xcb, 0x8c, 0x56, 0x36, 0x65, 0x87, + 0xb7, 0x62, 0xc1, 0x09, 0x6d, 0xc3, 0xd0, 0x06, 0x9f, 0x00, 0xc2, 0xe2, 0x5f, 0x3c, 0xea, 0xe0, + 0xa6, 0x66, 0x95, 0xfe, 0xdc, 0xa2, 0x01, 0x4b, 0x76, 0x2c, 0x3a, 0xc6, 0x38, 0xbf, 0xe7, 0x4b, + 0xb7, 0xb8, 0x6c, 0xa5, 0xfe, 0x0f, 0xef, 0x3f, 0x02, 0x23, 0x11, 0x69, 0x04, 0x7e, 0xc3, 0xf5, + 0x48, 0x73, 0x5a, 0xba, 0xd3, 0x0f, 0x92, 0xe3, 0xc2, 0x76, 0xcd, 0xd8, 0xa0, 0x81, 0x53, 0x14, + 0xd1, 0x67, 0x2c, 0x18, 0x53, 0x19, 0x9e, 0xf4, 0x83, 0x10, 0xe1, 0xbe, 0x5d, 0x28, 0x28, 0x9f, + 0x94, 0xd1, 0xac, 0xa3, 0x3b, 0xbb, 0x13, 0x63, 0xe9, 0x36, 0x9c, 0xe1, 0x8b, 0x5e, 0x06, 0x08, + 0xd6, 0x78, 0x08, 0xcc, 0x74, 0x22, 0x7c, 0xb9, 0x07, 0x79, 0xd5, 0x31, 0x9e, 0xec, 0x26, 0x29, + 0x60, 0x83, 0x1a, 0xba, 0x0a, 0xc0, 0x97, 0xcd, 0xea, 0x4e, 0x28, 0xb7, 0x05, 0x32, 0x49, 0x09, + 0x56, 0x14, 0xe4, 0xee, 0xee, 0x44, 0xb7, 0x6f, 0x8d, 0x85, 0x19, 0x18, 0x8f, 0xa3, 0x9f, 0x80, + 0xa1, 0xb8, 0xd3, 0x6e, 0x3b, 0xca, 0xd3, 0x5b, 0x60, 0xfa, 0x1c, 0xa7, 0x6b, 0x88, 0x22, 0xde, + 0x80, 0x25, 0x47, 0x74, 0x8b, 0x0a, 0xd5, 0x58, 0x38, 0xfd, 0xd8, 0x2a, 0xe2, 0x36, 0xc1, 0x30, + 0x7b, 0xa7, 0xf7, 0xc8, 0x88, 0x1e, 0x9c, 0x83, 0x73, 0x77, 0x77, 0xe2, 0xa1, 0x74, 0xfb, 0x42, + 0x20, 0x12, 0xda, 0x72, 0x69, 0xa2, 0x2b, 0xb2, 0x4e, 0x0a, 0x7d, 0x6d, 0x99, 0xbe, 0xff, 0x94, + 0xae, 0x93, 0xc2, 0x9a, 0x7b, 0x8f, 0x99, 0xf9, 0x30, 0x5a, 0x84, 0xd3, 0x8d, 0xc0, 0x4f, 0xa2, + 0xc0, 0xf3, 0x78, 0x9d, 0x20, 0xbe, 0x43, 0xe3, 0x9e, 0xe0, 0xb7, 0x8b, 0x6e, 0x9f, 0x9e, 0xe9, + 0x46, 0xc1, 0x79, 0xcf, 0xd9, 0x7e, 0x3a, 0x36, 0x50, 0x0c, 0xce, 0x73, 0x30, 0x42, 0xb6, 0x13, + 0x12, 0xf9, 0x8e, 0x77, 0x1d, 0x2f, 0x48, 0x1f, 0x28, 0x5b, 0x03, 0x17, 0x8d, 0x76, 0x9c, 0xc2, + 0x42, 0xb6, 0x72, 0x4b, 0x18, 0x49, 0x9a, 0xdc, 0x2d, 0x21, 0x9d, 0x10, 0xf6, 0xff, 0x29, 0xa5, + 0x0c, 0xb2, 0xd5, 0x88, 0x10, 0x14, 0x40, 0xc5, 0x0f, 0x9a, 0x4a, 0xf6, 0x5f, 0x29, 0x46, 0xf6, + 0x5f, 0x0b, 0x9a, 0x46, 0x31, 0x15, 0xfa, 0x2f, 0xc6, 0x9c, 0x0f, 0xab, 0x36, 0x21, 0xcb, 0x72, + 0x30, 0x80, 0xd8, 0x68, 0x14, 0xc9, 0x59, 0x55, 0x9b, 0x58, 0x32, 0x19, 0xe1, 0x34, 0x5f, 0xb4, + 0x09, 0x95, 0x8d, 0x20, 0x4e, 0xe4, 0xf6, 0xe3, 0x88, 0x3b, 0x9d, 0xcb, 0x41, 0x9c, 0x30, 0x2b, + 0x42, 0xbd, 0x36, 0x6d, 0x89, 0x31, 0xe7, 0x61, 0xff, 0x57, 0x2b, 0xe5, 0xf1, 0xbe, 0xc9, 0xe2, + 0x64, 0xb7, 0x88, 0x4f, 0x97, 0xb5, 0x19, 0x18, 0xf4, 0xc3, 0x99, 0xac, 0xc3, 0x77, 0xf4, 0x2a, + 0x83, 0x75, 0x9b, 0x52, 0x98, 0x64, 0x24, 0x8c, 0x18, 0xa2, 0x4f, 0x58, 0xe9, 0xfc, 0xcf, 0x52, + 0x11, 0x1b, 0x0c, 0x33, 0x07, 0x7a, 0xdf, 0x54, 0x52, 0xfb, 0x4b, 0x16, 0x0c, 0xd5, 0x9d, 0xc6, + 0x66, 0xb0, 0xbe, 0x8e, 0x9e, 0x86, 0x6a, 0xb3, 0x13, 0x99, 0xa9, 0xa8, 0x6a, 0x9b, 0x3f, 0x2b, + 0xda, 0xb1, 0xc2, 0xa0, 0x73, 0x78, 0xdd, 0x69, 0xc8, 0x4c, 0xe8, 0x32, 0x9f, 0xc3, 0x97, 0x58, + 0x0b, 0x16, 0x10, 0xf4, 0x3c, 0x0c, 0xb7, 0x9d, 0x6d, 0xf9, 0x70, 0xd6, 0xdd, 0xbe, 0xa8, 0x41, + 0xd8, 0xc4, 0xb3, 0xff, 0x95, 0x05, 0xe3, 0x75, 0x27, 0x76, 0x1b, 0xd3, 0x9d, 0x64, 0xa3, 0xee, + 0x26, 0x6b, 0x9d, 0xc6, 0x26, 0x49, 0x78, 0xfa, 0x3b, 0xed, 0x65, 0x27, 0xa6, 0x4b, 0x49, 0xed, + 0xeb, 0x54, 0x2f, 0xaf, 0x8b, 0x76, 0xac, 0x30, 0xd0, 0xeb, 0x30, 0x1c, 0x3a, 0x71, 0x7c, 0x3b, + 0x88, 0x9a, 0x98, 0xac, 0x17, 0x53, 0x7c, 0x62, 0x85, 0x34, 0x22, 0x92, 0x60, 0xb2, 0x2e, 0x8e, + 0x84, 0x35, 0x7d, 0x6c, 0x32, 0xb3, 0xbf, 0x60, 0xc1, 0x23, 0x75, 0xe2, 0x44, 0x24, 0x62, 0xb5, + 0x2a, 0xd4, 0x8b, 0xcc, 0x78, 0x41, 0xa7, 0x89, 0x5e, 0x83, 0x6a, 0x42, 0x9b, 0x69, 0xb7, 0xac, + 0x62, 0xbb, 0xc5, 0x4e, 0x74, 0x57, 0x05, 0x71, 0xac, 0xd8, 0xd8, 0x7f, 0xcb, 0x82, 0x11, 0x76, + 0x38, 0x36, 0x4b, 0x12, 0xc7, 0xf5, 0xba, 0x4a, 0x3a, 0x59, 0x7d, 0x96, 0x74, 0x3a, 0x0f, 0x03, + 0x1b, 0x41, 0x9b, 0x64, 0x0f, 0x76, 0x2f, 0x07, 0x74, 0x5b, 0x4d, 0x21, 0xe8, 0x59, 0xfa, 0xe1, + 0x5d, 0x3f, 0x71, 0xe8, 0x12, 0x90, 0xce, 0xd7, 0x13, 0xfc, 0xa3, 0xab, 0x66, 0x6c, 0xe2, 0xd8, + 0xbf, 0x55, 0x83, 0x21, 0x71, 0xfa, 0xdf, 0x77, 0x09, 0x04, 0xb9, 0xbf, 0x2f, 0xf5, 0xdc, 0xdf, + 0xc7, 0x30, 0xd8, 0x60, 0xb5, 0xe5, 0x84, 0x19, 0x79, 0xb5, 0x90, 0x70, 0x11, 0x5e, 0xae, 0x4e, + 0x77, 0x8b, 0xff, 0xc7, 0x82, 0x15, 0xfa, 0xa2, 0x05, 0x27, 0x1a, 0x81, 0xef, 0x93, 0x86, 0xb6, + 0x71, 0x06, 0x8a, 0x88, 0x0a, 0x98, 0x49, 0x13, 0xd5, 0x27, 0x33, 0x19, 0x00, 0xce, 0xb2, 0x47, + 0x2f, 0xc2, 0x28, 0x1f, 0xb3, 0x1b, 0x29, 0x8f, 0xb1, 0xae, 0xf4, 0x63, 0x02, 0x71, 0x1a, 0x17, + 0x4d, 0x72, 0xcf, 0xbb, 0xa8, 0xa9, 0x33, 0xa8, 0x1d, 0x6b, 0x46, 0x35, 0x1d, 0x03, 0x03, 0x45, + 0x80, 0x22, 0xb2, 0x1e, 0x91, 0x78, 0x43, 0x44, 0x47, 0x30, 0xfb, 0x6a, 0xe8, 0x70, 0xe9, 0xd2, + 0xb8, 0x8b, 0x12, 0xce, 0xa1, 0x8e, 0x36, 0xc5, 0x06, 0xb3, 0x5a, 0x84, 0x0c, 0x15, 0x9f, 0xb9, + 0xe7, 0x3e, 0x73, 0x02, 0x2a, 0xf1, 0x86, 0x13, 0x35, 0x99, 0x5d, 0x57, 0xe6, 0x29, 0x3a, 0x2b, + 0xb4, 0x01, 0xf3, 0x76, 0x34, 0x0b, 0x27, 0x33, 0x75, 0x8a, 0x62, 0xe1, 0xd9, 0x55, 0xe9, 0x18, + 0x99, 0x0a, 0x47, 0x31, 0xee, 0x7a, 0xc2, 0x74, 0x3e, 0x0c, 0xef, 0xe3, 0x7c, 0xd8, 0x51, 0x31, + 0x78, 0xdc, 0xe7, 0xfa, 0x52, 0x21, 0x03, 0xd0, 0x57, 0xc0, 0xdd, 0xe7, 0x33, 0x01, 0x77, 0xa3, + 0xac, 0x03, 0x37, 0x8a, 0xe9, 0xc0, 0xc1, 0xa3, 0xeb, 0xee, 0x67, 0xb4, 0xdc, 0x9f, 0x5b, 0x20, + 0xbf, 0xeb, 0x8c, 0xd3, 0xd8, 0x20, 0x74, 0xca, 0xa0, 0xf7, 0xc1, 0x98, 0xda, 0x42, 0xcf, 0x04, + 0x1d, 0x9f, 0x07, 0xca, 0x95, 0xf5, 0x11, 0x2e, 0x4e, 0x41, 0x71, 0x06, 0x1b, 0x4d, 0x41, 0x8d, + 0x8e, 0x13, 0x7f, 0x94, 0xeb, 0x5a, 0xb5, 0x4d, 0x9f, 0x5e, 0x9e, 0x17, 0x4f, 0x69, 0x1c, 0x14, + 0xc0, 0x29, 0xcf, 0x89, 0x13, 0xd6, 0x03, 0xba, 0xa3, 0x3e, 0x64, 0xb1, 0x02, 0x16, 0xf3, 0xbf, + 0x90, 0x25, 0x84, 0xbb, 0x69, 0xdb, 0xdf, 0x1e, 0x80, 0xd1, 0x94, 0x64, 0x3c, 0xa0, 0x92, 0x7e, + 0x1a, 0xaa, 0x52, 0x6f, 0x66, 0xcb, 0xaa, 0x28, 0xe5, 0xaa, 0x30, 0xa8, 0xd2, 0x5a, 0xd3, 0x5a, + 0x35, 0x6b, 0x54, 0x18, 0x0a, 0x17, 0x9b, 0x78, 0x4c, 0x28, 0x27, 0x5e, 0x3c, 0xe3, 0xb9, 0xc4, + 0x4f, 0x78, 0x37, 0x8b, 0x11, 0xca, 0xab, 0x0b, 0x2b, 0x26, 0x51, 0x2d, 0x94, 0x33, 0x00, 0x9c, + 0x65, 0x8f, 0x3e, 0x6d, 0xc1, 0xa8, 0x73, 0x3b, 0xd6, 0x05, 0x50, 0x45, 0x68, 0xdd, 0x11, 0x95, + 0x54, 0xaa, 0xa6, 0x2a, 0x77, 0xf9, 0xa6, 0x9a, 0x70, 0x9a, 0x29, 0x7a, 0xd3, 0x02, 0x44, 0xb6, + 0x49, 0x43, 0x06, 0xff, 0x89, 0xbe, 0x0c, 0x16, 0xb1, 0xd3, 0xbc, 0xd8, 0x45, 0x97, 0x4b, 0xf5, + 0xee, 0x76, 0x9c, 0xd3, 0x07, 0xfb, 0x9f, 0x97, 0xd5, 0x82, 0xd2, 0xf1, 0xa6, 0x8e, 0x11, 0xf7, + 0x66, 0x1d, 0x3e, 0xee, 0x4d, 0xc7, 0x0f, 0x74, 0xe7, 0x40, 0xa6, 0x52, 0xa6, 0x4a, 0xf7, 0x29, + 0x65, 0xea, 0xa7, 0xac, 0x54, 0x01, 0xa1, 0xe1, 0x0b, 0x2f, 0x17, 0x1b, 0xeb, 0x3a, 0xc9, 0x63, + 0x1b, 0x32, 0xd2, 0x3d, 0x1d, 0xd2, 0x42, 0xa5, 0xa9, 0x81, 0x76, 0x20, 0x69, 0xf8, 0x1f, 0xca, + 0x30, 0x6c, 0x68, 0xd2, 0x5c, 0xb3, 0xc8, 0x7a, 0xc0, 0xcc, 0xa2, 0xd2, 0x01, 0xcc, 0xa2, 0x9f, + 0x84, 0x5a, 0x43, 0x4a, 0xf9, 0x62, 0x4a, 0xe8, 0x66, 0x75, 0x87, 0x16, 0xf4, 0xaa, 0x09, 0x6b, + 0x9e, 0x68, 0x2e, 0x95, 0x68, 0x23, 0x34, 0xc4, 0x00, 0xd3, 0x10, 0x79, 0x99, 0x30, 0x42, 0x53, + 0x74, 0x3f, 0xc3, 0xea, 0x4c, 0x85, 0xae, 0x78, 0x2f, 0x19, 0x91, 0xce, 0xeb, 0x4c, 0x2d, 0xcf, + 0xcb, 0x66, 0x6c, 0xe2, 0xd8, 0xdf, 0xb6, 0xd4, 0xc7, 0xbd, 0x07, 0x15, 0x15, 0x6e, 0xa5, 0x2b, + 0x2a, 0x5c, 0x2c, 0x64, 0x98, 0x7b, 0x94, 0x52, 0xb8, 0x06, 0x43, 0x33, 0x41, 0xbb, 0xed, 0xf8, + 0x4d, 0xf4, 0x83, 0x30, 0xd4, 0xe0, 0x3f, 0x85, 0x63, 0x87, 0x1d, 0x0f, 0x0a, 0x28, 0x96, 0x30, + 0xf4, 0x28, 0x0c, 0x38, 0x51, 0x4b, 0x3a, 0x73, 0x58, 0x28, 0xcc, 0x74, 0xd4, 0x8a, 0x31, 0x6b, + 0xb5, 0xff, 0xf1, 0x00, 0xb0, 0x13, 0x68, 0x27, 0x22, 0xcd, 0xd5, 0x80, 0x95, 0xf0, 0x3b, 0xd6, + 0x43, 0x35, 0xbd, 0x59, 0x7a, 0x90, 0x0f, 0xd6, 0x8c, 0xc3, 0x95, 0xf2, 0x3d, 0x3e, 0x5c, 0xe9, + 0x71, 0x5e, 0x36, 0xf0, 0x00, 0x9d, 0x97, 0xd9, 0x9f, 0xb3, 0x00, 0xa9, 0xb0, 0x05, 0x7d, 0xa0, + 0x3d, 0x05, 0x35, 0x15, 0xc0, 0x20, 0x0c, 0x2b, 0x2d, 0x22, 0x24, 0x00, 0x6b, 0x9c, 0x3e, 0x76, + 0xc8, 0x4f, 0x48, 0xf9, 0x5d, 0x4e, 0x47, 0xd1, 0x32, 0xa9, 0x2f, 0xc4, 0xb9, 0xfd, 0xdb, 0x25, + 0x78, 0x88, 0xab, 0xe4, 0x45, 0xc7, 0x77, 0x5a, 0xa4, 0x4d, 0x7b, 0xd5, 0x6f, 0x88, 0x42, 0x83, + 0x6e, 0xcd, 0x5c, 0x19, 0x15, 0x7b, 0xd4, 0xb5, 0xcb, 0xd7, 0x1c, 0x5f, 0x65, 0xf3, 0xbe, 0x9b, + 0x60, 0x46, 0x1c, 0xc5, 0x50, 0x95, 0xf5, 0xe5, 0x85, 0x2c, 0x2e, 0x88, 0x91, 0x12, 0x4b, 0x42, + 0x6f, 0x12, 0xac, 0x18, 0x51, 0xc3, 0xd5, 0x0b, 0x1a, 0x9b, 0x98, 0x84, 0x01, 0x93, 0xbb, 0x46, + 0x50, 0xe2, 0x82, 0x68, 0xc7, 0x0a, 0xc3, 0xfe, 0x6d, 0x0b, 0xb2, 0x1a, 0xc9, 0xa8, 0x95, 0x66, + 0xed, 0x59, 0x2b, 0xed, 0x00, 0xc5, 0xca, 0x7e, 0x1c, 0x86, 0x9d, 0x84, 0x1a, 0x11, 0x7c, 0xdb, + 0x5d, 0x3e, 0xdc, 0xb1, 0xc6, 0x62, 0xd0, 0x74, 0xd7, 0x5d, 0xb6, 0xdd, 0x36, 0xc9, 0xd9, 0xff, + 0x73, 0x00, 0x4e, 0x75, 0xe5, 0x6e, 0xa0, 0x17, 0x60, 0xa4, 0x21, 0xa6, 0x47, 0x28, 0x1d, 0x5a, + 0x35, 0x33, 0x88, 0x4d, 0xc3, 0x70, 0x0a, 0xb3, 0x8f, 0x09, 0x3a, 0x0f, 0xa7, 0x23, 0xba, 0xd1, + 0xef, 0x90, 0xe9, 0xf5, 0x84, 0x44, 0x2b, 0xa4, 0x11, 0xf8, 0x4d, 0x5e, 0xd1, 0xaf, 0x5c, 0x7f, + 0xf8, 0xce, 0xee, 0xc4, 0x69, 0xdc, 0x0d, 0xc6, 0x79, 0xcf, 0xa0, 0x10, 0x46, 0x3d, 0xd3, 0x06, + 0x14, 0x1b, 0x80, 0x43, 0x99, 0x8f, 0xca, 0x46, 0x48, 0x35, 0xe3, 0x34, 0x83, 0xb4, 0x21, 0x59, + 0xb9, 0x4f, 0x86, 0xe4, 0xa7, 0xb4, 0x21, 0xc9, 0xcf, 0xdf, 0x3f, 0x54, 0x70, 0xee, 0xce, 0x71, + 0x5b, 0x92, 0x2f, 0x41, 0x55, 0xc6, 0x26, 0xf5, 0x15, 0xd3, 0x63, 0xd2, 0xe9, 0x21, 0xd1, 0xee, + 0x96, 0x20, 0x67, 0x13, 0x42, 0xd7, 0x99, 0xd6, 0xf8, 0xa9, 0x75, 0x76, 0x30, 0xad, 0x8f, 0xb6, + 0x79, 0x5c, 0x16, 0xd7, 0x6d, 0x1f, 0x2c, 0x7a, 0x13, 0xa5, 0x43, 0xb5, 0x54, 0x4a, 0x83, 0x0a, + 0xd7, 0xba, 0x00, 0xa0, 0x0d, 0x35, 0x11, 0xb0, 0xae, 0x8e, 0x7d, 0xb5, 0x3d, 0x87, 0x0d, 0x2c, + 0xba, 0xa7, 0x76, 0xfd, 0x38, 0x71, 0x3c, 0xef, 0xb2, 0xeb, 0x27, 0xc2, 0x39, 0xa8, 0x94, 0xf8, + 0xbc, 0x06, 0x61, 0x13, 0xef, 0xdc, 0x7b, 0x8c, 0xef, 0x72, 0x90, 0xef, 0xb9, 0x01, 0x8f, 0xcc, + 0xb9, 0x89, 0x4a, 0xb3, 0x50, 0xf3, 0x88, 0xda, 0x61, 0x2a, 0x6d, 0xc8, 0xea, 0x99, 0x36, 0x64, + 0xa4, 0x39, 0x94, 0xd2, 0x59, 0x19, 0xd9, 0x34, 0x07, 0xfb, 0x05, 0x38, 0x33, 0xe7, 0x26, 0x97, + 0x5c, 0x8f, 0x1c, 0x90, 0x89, 0xfd, 0x9b, 0x83, 0x30, 0x62, 0x26, 0xea, 0x1d, 0x24, 0xf3, 0xe9, + 0x0b, 0xd4, 0xd4, 0x12, 0x6f, 0xe7, 0xaa, 0x43, 0xb3, 0x9b, 0x47, 0xce, 0x1a, 0xcc, 0x1f, 0x31, + 0xc3, 0xda, 0xd2, 0x3c, 0xb1, 0xd9, 0x01, 0x74, 0x1b, 0x2a, 0xeb, 0x2c, 0x0c, 0xbf, 0x5c, 0x44, + 0x64, 0x41, 0xde, 0x88, 0xea, 0x65, 0xc6, 0x03, 0xf9, 0x39, 0x3f, 0xaa, 0x21, 0xa3, 0x74, 0x6e, + 0x97, 0x11, 0x3a, 0x2a, 0xb2, 0xba, 0x14, 0x46, 0x2f, 0x51, 0x5f, 0x39, 0x84, 0xa8, 0x4f, 0x09, + 0xde, 0xc1, 0xfb, 0x24, 0x78, 0x59, 0x4a, 0x45, 0xb2, 0xc1, 0xec, 0x37, 0x11, 0xeb, 0x3e, 0xc4, + 0x06, 0xc1, 0x48, 0xa9, 0x48, 0x81, 0x71, 0x16, 0x1f, 0x7d, 0x5c, 0x89, 0xee, 0x6a, 0x11, 0x7e, + 0x55, 0x73, 0x46, 0x1f, 0xb7, 0xd4, 0xfe, 0x5c, 0x09, 0xc6, 0xe6, 0xfc, 0xce, 0xf2, 0xdc, 0x72, + 0x67, 0xcd, 0x73, 0x1b, 0x57, 0xc9, 0x0e, 0x15, 0xcd, 0x9b, 0x64, 0x67, 0x7e, 0x56, 0xac, 0x20, + 0x35, 0x67, 0xae, 0xd2, 0x46, 0xcc, 0x61, 0x54, 0x18, 0xad, 0xbb, 0x7e, 0x8b, 0x44, 0x61, 0xe4, + 0x0a, 0x97, 0xa7, 0x21, 0x8c, 0x2e, 0x69, 0x10, 0x36, 0xf1, 0x28, 0xed, 0xe0, 0xb6, 0x4f, 0xa2, + 0xac, 0x21, 0xbb, 0x44, 0x1b, 0x31, 0x87, 0x51, 0xa4, 0x24, 0xea, 0xc4, 0x89, 0x98, 0x8c, 0x0a, + 0x69, 0x95, 0x36, 0x62, 0x0e, 0xa3, 0x2b, 0x3d, 0xee, 0xac, 0xb1, 0xc0, 0x8d, 0x4c, 0x60, 0xfd, + 0x0a, 0x6f, 0xc6, 0x12, 0x4e, 0x51, 0x37, 0xc9, 0xce, 0x2c, 0xdd, 0xf5, 0x66, 0xf2, 0x6b, 0xae, + 0xf2, 0x66, 0x2c, 0xe1, 0xac, 0x14, 0x61, 0x7a, 0x38, 0xbe, 0xe7, 0x4a, 0x11, 0xa6, 0xbb, 0xdf, + 0x63, 0xff, 0xfc, 0x4b, 0x16, 0x8c, 0x98, 0xe1, 0x56, 0xa8, 0x95, 0xb1, 0x71, 0x97, 0xba, 0x2a, + 0xd9, 0xfe, 0x68, 0xde, 0x35, 0x60, 0x2d, 0x37, 0x09, 0xc2, 0xf8, 0x19, 0xe2, 0xb7, 0x5c, 0x9f, + 0xb0, 0x53, 0x74, 0x1e, 0xa6, 0x95, 0x8a, 0xe5, 0x9a, 0x09, 0x9a, 0xe4, 0x10, 0x46, 0xb2, 0x7d, + 0x13, 0x4e, 0x75, 0x25, 0x55, 0xf5, 0x61, 0x5a, 0xec, 0x9b, 0xd2, 0x6a, 0x63, 0x18, 0xa6, 0x84, + 0x65, 0x39, 0x9c, 0x19, 0x38, 0xc5, 0x17, 0x12, 0xe5, 0xb4, 0xd2, 0xd8, 0x20, 0x6d, 0x95, 0x28, + 0xc7, 0xfc, 0xeb, 0x37, 0xb2, 0x40, 0xdc, 0x8d, 0x6f, 0x7f, 0xde, 0x82, 0xd1, 0x54, 0x9e, 0x5b, + 0x41, 0x46, 0x10, 0x5b, 0x69, 0x01, 0x8b, 0xfe, 0x63, 0x21, 0xd0, 0x65, 0xa6, 0x4c, 0xf5, 0x4a, + 0xd3, 0x20, 0x6c, 0xe2, 0xd9, 0x5f, 0x2a, 0x41, 0x55, 0x46, 0x50, 0xf4, 0xd1, 0x95, 0xcf, 0x5a, + 0x30, 0xaa, 0xce, 0x34, 0x98, 0xb3, 0xac, 0x54, 0x44, 0x52, 0x02, 0xed, 0x81, 0xda, 0x6e, 0xfb, + 0xeb, 0x81, 0xb6, 0xc8, 0xb1, 0xc9, 0x0c, 0xa7, 0x79, 0xa3, 0x1b, 0x00, 0xf1, 0x4e, 0x9c, 0x90, + 0xb6, 0xe1, 0xb6, 0xb3, 0x8d, 0x15, 0x37, 0xd9, 0x08, 0x22, 0x42, 0xd7, 0xd7, 0xb5, 0xa0, 0x49, + 0x56, 0x14, 0xa6, 0x36, 0xa1, 0x74, 0x1b, 0x36, 0x28, 0xd9, 0xff, 0xb0, 0x04, 0x27, 0xb3, 0x5d, + 0x42, 0x1f, 0x82, 0x11, 0xc9, 0xdd, 0xb8, 0xd1, 0x4c, 0x86, 0x8d, 0x8c, 0x60, 0x03, 0x76, 0x77, + 0x77, 0x62, 0xa2, 0xfb, 0x4a, 0xb9, 0x49, 0x13, 0x05, 0xa7, 0x88, 0xf1, 0x83, 0x25, 0x71, 0x02, + 0x5a, 0xdf, 0x99, 0x0e, 0x43, 0x71, 0x3a, 0x64, 0x1c, 0x2c, 0x99, 0x50, 0x9c, 0xc1, 0x46, 0xcb, + 0x70, 0xc6, 0x68, 0xb9, 0x46, 0xdc, 0xd6, 0xc6, 0x5a, 0x10, 0xc9, 0x9d, 0xd5, 0xa3, 0x3a, 0xb0, + 0xab, 0x1b, 0x07, 0xe7, 0x3e, 0x49, 0xb5, 0x7d, 0xc3, 0x09, 0x9d, 0x86, 0x9b, 0xec, 0x08, 0x3f, + 0xa4, 0x92, 0x4d, 0x33, 0xa2, 0x1d, 0x2b, 0x0c, 0x7b, 0x11, 0x06, 0xfa, 0x9c, 0x41, 0x7d, 0x59, + 0xf4, 0x2f, 0x41, 0x95, 0x92, 0x93, 0xe6, 0x5d, 0x11, 0x24, 0x03, 0xa8, 0xca, 0x9b, 0x46, 0x90, + 0x0d, 0x65, 0xd7, 0x91, 0x67, 0x77, 0xea, 0xb5, 0xe6, 0xe3, 0xb8, 0xc3, 0x36, 0xc9, 0x14, 0x88, + 0x9e, 0x80, 0x32, 0xd9, 0x0e, 0xb3, 0x87, 0x74, 0x17, 0xb7, 0x43, 0x37, 0x22, 0x31, 0x45, 0x22, + 0xdb, 0x21, 0x3a, 0x07, 0x25, 0xb7, 0x29, 0x94, 0x14, 0x08, 0x9c, 0xd2, 0xfc, 0x2c, 0x2e, 0xb9, + 0x4d, 0x7b, 0x1b, 0x6a, 0xea, 0x6a, 0x13, 0xb4, 0x29, 0x65, 0xb7, 0x55, 0x44, 0xc8, 0x93, 0xa4, + 0xdb, 0x43, 0x6a, 0x77, 0x00, 0x74, 0xc2, 0x5f, 0x51, 0xf2, 0xe5, 0x3c, 0x0c, 0x34, 0x02, 0x91, + 0x8c, 0x5c, 0xd5, 0x64, 0x98, 0xd0, 0x66, 0x10, 0xfb, 0x26, 0x8c, 0x5d, 0xf5, 0x83, 0xdb, 0xac, + 0x2e, 0x3b, 0x2b, 0x43, 0x46, 0x09, 0xaf, 0xd3, 0x1f, 0x59, 0x13, 0x81, 0x41, 0x31, 0x87, 0xa9, + 0xfa, 0x4c, 0xa5, 0x5e, 0xf5, 0x99, 0xec, 0x4f, 0x58, 0x30, 0xa2, 0x32, 0x87, 0xe6, 0xb6, 0x36, + 0x29, 0xdd, 0x56, 0x14, 0x74, 0xc2, 0x2c, 0x5d, 0x76, 0xf9, 0x10, 0xe6, 0x30, 0x33, 0xa5, 0xae, + 0xb4, 0x4f, 0x4a, 0xdd, 0x79, 0x18, 0xd8, 0x74, 0xfd, 0x66, 0xf6, 0x36, 0x8d, 0xab, 0xae, 0xdf, + 0xc4, 0x0c, 0x42, 0xbb, 0x70, 0x52, 0x75, 0x41, 0x2a, 0x84, 0x17, 0x60, 0x64, 0xad, 0xe3, 0x7a, + 0x4d, 0x59, 0x5f, 0x2d, 0xe3, 0x29, 0xa9, 0x1b, 0x30, 0x9c, 0xc2, 0xa4, 0xfb, 0xba, 0x35, 0xd7, + 0x77, 0xa2, 0x9d, 0x65, 0xad, 0x81, 0x94, 0x50, 0xaa, 0x2b, 0x08, 0x36, 0xb0, 0xec, 0x37, 0xca, + 0x30, 0x96, 0xce, 0x9f, 0xea, 0x63, 0x7b, 0xf5, 0x04, 0x54, 0x58, 0x4a, 0x55, 0xf6, 0xd3, 0xf2, + 0x92, 0x64, 0x1c, 0x86, 0x62, 0x18, 0xe4, 0xc5, 0x18, 0x8a, 0xb9, 0x89, 0x46, 0x75, 0x52, 0xf9, + 0x57, 0x58, 0x3c, 0x99, 0xa8, 0xff, 0x20, 0x58, 0xa1, 0x4f, 0x5b, 0x30, 0x14, 0x84, 0x66, 0x5d, + 0x9f, 0x0f, 0x16, 0x99, 0x5b, 0x26, 0x92, 0x65, 0x84, 0x45, 0xac, 0x3e, 0xbd, 0xfc, 0x1c, 0x92, + 0xf5, 0xb9, 0xf7, 0xc2, 0x88, 0x89, 0xb9, 0x9f, 0x51, 0x5c, 0x35, 0x8d, 0xe2, 0xcf, 0x9a, 0x93, + 0x42, 0x64, 0xcf, 0xf5, 0xb1, 0xdc, 0xae, 0x43, 0xa5, 0xa1, 0x02, 0x00, 0x0e, 0x55, 0x95, 0x53, + 0x55, 0x47, 0x60, 0x87, 0x40, 0x9c, 0x9a, 0xfd, 0x6d, 0xcb, 0x98, 0x1f, 0x98, 0xc4, 0xf3, 0x4d, + 0x14, 0x41, 0xb9, 0xb5, 0xb5, 0x29, 0x4c, 0xd1, 0x2b, 0x05, 0x0d, 0xef, 0xdc, 0xd6, 0xa6, 0x9e, + 0xe3, 0x66, 0x2b, 0xa6, 0xcc, 0xfa, 0x70, 0x02, 0xa6, 0x92, 0x2c, 0xcb, 0xfb, 0x27, 0x59, 0xda, + 0x6f, 0x96, 0xe0, 0x54, 0xd7, 0xa4, 0x42, 0xaf, 0x43, 0x25, 0xa2, 0x6f, 0x29, 0x5e, 0x6f, 0xa1, + 0xb0, 0xb4, 0xc8, 0x78, 0xbe, 0xa9, 0xf5, 0x6e, 0xba, 0x1d, 0x73, 0x96, 0xe8, 0x0a, 0x20, 0x1d, + 0xa6, 0xa2, 0x3c, 0x90, 0xfc, 0x95, 0xcf, 0x89, 0x47, 0xd1, 0x74, 0x17, 0x06, 0xce, 0x79, 0x0a, + 0xbd, 0x98, 0x75, 0x64, 0x96, 0xd3, 0xe7, 0x96, 0x7b, 0xf9, 0x24, 0xed, 0x7f, 0x51, 0x82, 0xd1, + 0x54, 0x99, 0x25, 0xe4, 0x41, 0x95, 0x78, 0xcc, 0xa9, 0x2f, 0x95, 0xcd, 0x51, 0xab, 0x16, 0x2b, + 0x05, 0x79, 0x51, 0xd0, 0xc5, 0x8a, 0xc3, 0x83, 0x71, 0xb8, 0xfe, 0x02, 0x8c, 0xc8, 0x0e, 0x7d, + 0xd0, 0x69, 0x7b, 0x62, 0x00, 0xd5, 0x1c, 0xbd, 0x68, 0xc0, 0x70, 0x0a, 0xd3, 0xfe, 0x9d, 0x32, + 0x8c, 0xf3, 0x53, 0x90, 0xa6, 0x9a, 0x79, 0x8b, 0x72, 0xbf, 0xf5, 0xd7, 0x74, 0x31, 0x34, 0x3e, + 0x90, 0x6b, 0x47, 0xbd, 0x24, 0x20, 0x9f, 0x51, 0x5f, 0x91, 0x59, 0x5f, 0xcd, 0x44, 0x66, 0x71, + 0xb3, 0xbb, 0x75, 0x4c, 0x3d, 0xfa, 0xde, 0x0a, 0xd5, 0xfa, 0x95, 0x12, 0x9c, 0xc8, 0xdc, 0xc0, + 0x80, 0xde, 0x48, 0x17, 0xed, 0xb5, 0x8a, 0xf0, 0x95, 0xef, 0x59, 0x94, 0xff, 0x60, 0xa5, 0x7b, + 0xef, 0xd3, 0x52, 0xb1, 0xff, 0xa0, 0x04, 0x63, 0xe9, 0xab, 0x23, 0x1e, 0xc0, 0x91, 0x7a, 0x17, + 0xd4, 0x58, 0x75, 0x74, 0x76, 0x25, 0x26, 0x77, 0xc9, 0xf3, 0x42, 0xd4, 0xb2, 0x11, 0x6b, 0xf8, + 0x03, 0x51, 0x11, 0xd9, 0xfe, 0xfb, 0x16, 0x9c, 0xe5, 0x6f, 0x99, 0x9d, 0x87, 0x7f, 0x3d, 0x6f, + 0x74, 0x5f, 0x29, 0xb6, 0x83, 0x99, 0x22, 0x7e, 0xfb, 0x8d, 0x2f, 0xbb, 0x8a, 0x4f, 0xf4, 0x36, + 0x3d, 0x15, 0x1e, 0xc0, 0xce, 0x1e, 0x68, 0x32, 0xd8, 0x7f, 0x50, 0x06, 0x7d, 0xfb, 0x20, 0x72, + 0x45, 0x8e, 0x63, 0x21, 0xc5, 0x0c, 0x57, 0x76, 0xfc, 0x86, 0xbe, 0xe7, 0xb0, 0x9a, 0x49, 0x71, + 0xfc, 0x59, 0x0b, 0x86, 0x5d, 0xdf, 0x4d, 0x5c, 0x87, 0x6d, 0xa3, 0x8b, 0xb9, 0x19, 0x4d, 0xb1, + 0x9b, 0xe7, 0x94, 0x83, 0xc8, 0x3c, 0xc7, 0x51, 0xcc, 0xb0, 0xc9, 0x19, 0x7d, 0x44, 0x04, 0x4f, + 0x97, 0x0b, 0xcb, 0xce, 0xad, 0x66, 0x22, 0xa6, 0x43, 0x6a, 0x78, 0x25, 0x51, 0x41, 0x49, 0xed, + 0x98, 0x92, 0x52, 0x75, 0x71, 0xf5, 0x3d, 0xd0, 0xb4, 0x19, 0x73, 0x46, 0x76, 0x0c, 0xa8, 0x7b, + 0x2c, 0x0e, 0x18, 0x98, 0x3a, 0x05, 0x35, 0xa7, 0x93, 0x04, 0x6d, 0x3a, 0x4c, 0xe2, 0xa8, 0x49, + 0x87, 0xde, 0x4a, 0x00, 0xd6, 0x38, 0xf6, 0x1b, 0x15, 0xc8, 0x24, 0x1d, 0xa2, 0x6d, 0xf3, 0xe6, + 0x4c, 0xab, 0xd8, 0x9b, 0x33, 0x55, 0x67, 0xf2, 0x6e, 0xcf, 0x44, 0x2d, 0xa8, 0x84, 0x1b, 0x4e, + 0x2c, 0xcd, 0xea, 0x97, 0xd4, 0x3e, 0x8e, 0x36, 0xde, 0xdd, 0x9d, 0xf8, 0xb1, 0xfe, 0xbc, 0xae, + 0x74, 0xae, 0x4e, 0xf1, 0x62, 0x23, 0x9a, 0x35, 0xa3, 0x81, 0x39, 0xfd, 0x83, 0xdc, 0x0d, 0xf7, + 0x49, 0x51, 0x06, 0x1e, 0x93, 0xb8, 0xe3, 0x25, 0x62, 0x36, 0xbc, 0x54, 0xe0, 0x2a, 0xe3, 0x84, + 0x75, 0xba, 0x3c, 0xff, 0x8f, 0x0d, 0xa6, 0xe8, 0x43, 0x50, 0x8b, 0x13, 0x27, 0x4a, 0x0e, 0x99, + 0xe0, 0xaa, 0x06, 0x7d, 0x45, 0x12, 0xc1, 0x9a, 0x1e, 0x7a, 0x99, 0xd5, 0x76, 0x75, 0xe3, 0x8d, + 0x43, 0xe6, 0x3c, 0xc8, 0x3a, 0xb0, 0x82, 0x02, 0x36, 0xa8, 0xa1, 0x0b, 0x00, 0x6c, 0x6e, 0xf3, + 0x40, 0xbf, 0x2a, 0xf3, 0x32, 0x29, 0x51, 0x88, 0x15, 0x04, 0x1b, 0x58, 0xf6, 0x0f, 0x41, 0xba, + 0xde, 0x03, 0x9a, 0x90, 0xe5, 0x25, 0xb8, 0x17, 0x9a, 0xe5, 0x2e, 0xa4, 0x2a, 0x41, 0xfc, 0xba, + 0x05, 0x66, 0x51, 0x0a, 0xf4, 0x1a, 0xaf, 0x7e, 0x61, 0x15, 0x71, 0x72, 0x68, 0xd0, 0x9d, 0x5c, + 0x74, 0xc2, 0xcc, 0x11, 0xb6, 0x2c, 0x81, 0x71, 0xee, 0x3d, 0x50, 0x95, 0xd0, 0x03, 0x19, 0x75, + 0x1f, 0x87, 0xd3, 0xd9, 0x7b, 0xc5, 0xc5, 0xa9, 0xd3, 0xfe, 0xae, 0x1f, 0xe9, 0xcf, 0x29, 0xf5, + 0xf2, 0xe7, 0xf4, 0x71, 0x7f, 0xea, 0x6f, 0x58, 0x70, 0x7e, 0xbf, 0xeb, 0xcf, 0xd1, 0xa3, 0x30, + 0x70, 0xdb, 0x89, 0x64, 0xd1, 0x6d, 0x26, 0x28, 0x6f, 0x3a, 0x91, 0x8f, 0x59, 0x2b, 0xda, 0x81, + 0x41, 0x1e, 0x0d, 0x26, 0xac, 0xf5, 0x97, 0x8a, 0xbd, 0x8c, 0xfd, 0x2a, 0x31, 0xb6, 0x0b, 0x3c, + 0x12, 0x0d, 0x0b, 0x86, 0xf6, 0x77, 0x2c, 0x40, 0x4b, 0x5b, 0x24, 0x8a, 0xdc, 0xa6, 0x11, 0xbf, + 0xc6, 0xae, 0x53, 0x31, 0xae, 0x4d, 0x31, 0x53, 0x5c, 0x33, 0xd7, 0xa9, 0x18, 0xff, 0xf2, 0xaf, + 0x53, 0x29, 0x1d, 0xec, 0x3a, 0x15, 0xb4, 0x04, 0x67, 0xdb, 0x7c, 0xbb, 0xc1, 0xaf, 0x28, 0xe0, + 0x7b, 0x0f, 0x95, 0x50, 0xf6, 0xc8, 0x9d, 0xdd, 0x89, 0xb3, 0x8b, 0x79, 0x08, 0x38, 0xff, 0x39, + 0xfb, 0x3d, 0x80, 0x78, 0xd8, 0xda, 0x4c, 0x5e, 0x0c, 0x52, 0x4f, 0xf7, 0x8b, 0xfd, 0x95, 0x0a, + 0x9c, 0xc8, 0x94, 0x64, 0xa5, 0x5b, 0xbd, 0xee, 0xa0, 0xa7, 0x23, 0xeb, 0xef, 0xee, 0xee, 0xf5, + 0x15, 0x46, 0xe5, 0x43, 0xc5, 0xf5, 0xc3, 0x4e, 0x52, 0x4c, 0x0e, 0x29, 0xef, 0xc4, 0x3c, 0x25, + 0x68, 0xb8, 0x8b, 0xe9, 0x5f, 0xcc, 0xd9, 0x14, 0x19, 0x94, 0x95, 0x32, 0xc6, 0x07, 0xee, 0x93, + 0x3b, 0xe0, 0x93, 0x3a, 0x44, 0xaa, 0x52, 0x84, 0x63, 0x31, 0x33, 0x59, 0x8e, 0xfb, 0xa8, 0xfd, + 0xd7, 0x4a, 0x30, 0x6c, 0x7c, 0x34, 0xf4, 0x8b, 0xe9, 0x92, 0x4d, 0x56, 0x71, 0xaf, 0xc4, 0xe8, + 0x4f, 0xea, 0xa2, 0x4c, 0xfc, 0x95, 0x9e, 0xec, 0xae, 0xd6, 0x74, 0x77, 0x77, 0xe2, 0x64, 0xa6, + 0x1e, 0x53, 0xaa, 0x82, 0xd3, 0xb9, 0x8f, 0xc1, 0x89, 0x0c, 0x99, 0x9c, 0x57, 0x5e, 0x4d, 0x5f, + 0x1b, 0x7f, 0x44, 0xb7, 0x94, 0x39, 0x64, 0xdf, 0xa0, 0x43, 0x26, 0xd2, 0xe8, 0x02, 0x8f, 0xf4, + 0xe1, 0x83, 0xcd, 0x64, 0xcb, 0x96, 0xfa, 0xcc, 0x96, 0x7d, 0x0a, 0xaa, 0x61, 0xe0, 0xb9, 0x0d, + 0x57, 0x55, 0x21, 0x64, 0xf9, 0xb9, 0xcb, 0xa2, 0x0d, 0x2b, 0x28, 0xba, 0x0d, 0x35, 0x75, 0xc3, + 0xbe, 0xf0, 0x6f, 0x17, 0x75, 0xe8, 0xa3, 0x8c, 0x16, 0x7d, 0x73, 0xbe, 0xe6, 0x85, 0x6c, 0x18, + 0x64, 0x4a, 0x50, 0x86, 0xfe, 0x33, 0xdf, 0x3b, 0xd3, 0x8e, 0x31, 0x16, 0x10, 0xfb, 0xeb, 0x35, + 0x38, 0x93, 0x57, 0x17, 0x1b, 0x7d, 0x14, 0x06, 0x79, 0x1f, 0x8b, 0xb9, 0x7a, 0x21, 0x8f, 0xc7, + 0x1c, 0x23, 0x28, 0xba, 0xc5, 0x7e, 0x63, 0xc1, 0x53, 0x70, 0xf7, 0x9c, 0x35, 0x31, 0x43, 0x8e, + 0x87, 0xfb, 0x82, 0xa3, 0xb9, 0x2f, 0x38, 0x9c, 0xbb, 0xe7, 0xac, 0xa1, 0x6d, 0xa8, 0xb4, 0xdc, + 0x84, 0x38, 0xc2, 0x89, 0x70, 0xf3, 0x58, 0x98, 0x13, 0x87, 0x5b, 0x69, 0xec, 0x27, 0xe6, 0x0c, + 0xd1, 0xd7, 0x2c, 0x38, 0xb1, 0x96, 0x4e, 0x8d, 0x17, 0xc2, 0xd3, 0x39, 0x86, 0xda, 0xe7, 0x69, + 0x46, 0xfc, 0x3e, 0xa1, 0x4c, 0x23, 0xce, 0x76, 0x07, 0x7d, 0xca, 0x82, 0xa1, 0x75, 0xd7, 0x33, + 0xca, 0xe0, 0x1e, 0xc3, 0xc7, 0xb9, 0xc4, 0x18, 0xe8, 0x1d, 0x07, 0xff, 0x1f, 0x63, 0xc9, 0xb9, + 0x97, 0xa6, 0x1a, 0x3c, 0xaa, 0xa6, 0x1a, 0xba, 0x4f, 0x9a, 0xea, 0x33, 0x16, 0xd4, 0xd4, 0x48, + 0x8b, 0x74, 0xe7, 0x0f, 0x1d, 0xe3, 0x27, 0xe7, 0x9e, 0x13, 0xf5, 0x17, 0x6b, 0xe6, 0xe8, 0x8b, + 0x16, 0x0c, 0x3b, 0xaf, 0x77, 0x22, 0xd2, 0x24, 0x5b, 0x41, 0x18, 0x8b, 0xcb, 0x08, 0x5f, 0x29, + 0xbe, 0x33, 0xd3, 0x94, 0xc9, 0x2c, 0xd9, 0x5a, 0x0a, 0x63, 0x91, 0x96, 0xa4, 0x1b, 0xb0, 0xd9, + 0x05, 0x7b, 0xb7, 0x04, 0x13, 0xfb, 0x50, 0x40, 0x2f, 0xc0, 0x48, 0x10, 0xb5, 0x1c, 0xdf, 0x7d, + 0xdd, 0xac, 0x75, 0xa1, 0xac, 0xac, 0x25, 0x03, 0x86, 0x53, 0x98, 0x66, 0x42, 0x76, 0x69, 0x9f, + 0x84, 0xec, 0xf3, 0x30, 0x10, 0x91, 0x30, 0xc8, 0x6e, 0x16, 0x58, 0x4a, 0x00, 0x83, 0xa0, 0xc7, + 0xa0, 0xec, 0x84, 0xae, 0x08, 0x44, 0x53, 0x7b, 0xa0, 0xe9, 0xe5, 0x79, 0x4c, 0xdb, 0x53, 0xf5, + 0x21, 0x2a, 0xf7, 0xa4, 0x3e, 0x04, 0x55, 0x03, 0xe2, 0xec, 0x62, 0x50, 0xab, 0x81, 0xf4, 0x99, + 0x82, 0xfd, 0x66, 0x19, 0x1e, 0xdb, 0x73, 0xbe, 0xe8, 0x38, 0x3c, 0x6b, 0x8f, 0x38, 0x3c, 0x39, + 0x3c, 0xa5, 0xfd, 0x86, 0xa7, 0xdc, 0x63, 0x78, 0x3e, 0x45, 0x97, 0x81, 0xac, 0x11, 0x52, 0xcc, + 0x75, 0x72, 0xbd, 0x4a, 0x8e, 0x88, 0x15, 0x20, 0xa1, 0x58, 0xf3, 0xa5, 0x7b, 0x80, 0x54, 0x32, + 0x72, 0xa5, 0x08, 0x35, 0xd0, 0xb3, 0x66, 0x08, 0x9f, 0xfb, 0xbd, 0x32, 0x9c, 0xed, 0x9f, 0x2b, + 0xc1, 0x13, 0x7d, 0x48, 0x6f, 0x73, 0x16, 0x5b, 0x7d, 0xce, 0xe2, 0xef, 0xed, 0xcf, 0x64, 0xff, + 0x0d, 0x0b, 0xce, 0xf5, 0x56, 0x1e, 0xe8, 0x59, 0x18, 0x5e, 0x8b, 0x1c, 0xbf, 0xb1, 0xc1, 0xae, + 0xc8, 0x94, 0x83, 0xc2, 0xc6, 0x5a, 0x37, 0x63, 0x13, 0x87, 0x6e, 0x6f, 0x79, 0x4c, 0x82, 0x81, + 0x21, 0x93, 0x47, 0xe9, 0xf6, 0x76, 0x35, 0x0b, 0xc4, 0xdd, 0xf8, 0xf6, 0x9f, 0x95, 0xf2, 0xbb, + 0xc5, 0x8d, 0x8c, 0x83, 0x7c, 0x27, 0xf1, 0x15, 0x4a, 0x7d, 0xc8, 0x92, 0xf2, 0xbd, 0x96, 0x25, + 0x03, 0xbd, 0x64, 0x09, 0x9a, 0x85, 0x93, 0xc6, 0x15, 0x2a, 0x3c, 0x21, 0x98, 0x07, 0xdc, 0xaa, + 0x2a, 0x19, 0xcb, 0x19, 0x38, 0xee, 0x7a, 0x02, 0x3d, 0x0d, 0x55, 0xd7, 0x8f, 0x49, 0xa3, 0x13, + 0xf1, 0x40, 0x6f, 0x23, 0x09, 0x6b, 0x5e, 0xb4, 0x63, 0x85, 0x61, 0xff, 0x52, 0x09, 0x1e, 0xe9, + 0x69, 0x67, 0xdd, 0x23, 0xd9, 0x65, 0x7e, 0x8e, 0x81, 0x7b, 0xf3, 0x39, 0xcc, 0x41, 0xaa, 0xec, + 0x3b, 0x48, 0x7f, 0xd8, 0x7b, 0x62, 0x52, 0x9b, 0xfb, 0xfb, 0x76, 0x94, 0x5e, 0x84, 0x51, 0x27, + 0x0c, 0x39, 0x1e, 0x8b, 0xd7, 0xcc, 0x54, 0xc9, 0x99, 0x36, 0x81, 0x38, 0x8d, 0xdb, 0x97, 0xf6, + 0xfc, 0x63, 0x0b, 0x6a, 0x98, 0xac, 0x73, 0xe9, 0x80, 0x6e, 0x89, 0x21, 0xb2, 0x8a, 0xa8, 0xa7, + 0x49, 0x07, 0x36, 0x76, 0x59, 0x9d, 0xc9, 0xbc, 0xc1, 0xee, 0xbe, 0x6a, 0xa7, 0x74, 0xa0, 0xab, + 0x76, 0xd4, 0x65, 0x2b, 0xe5, 0xde, 0x97, 0xad, 0xd8, 0xdf, 0x18, 0xa2, 0xaf, 0x17, 0x06, 0x33, + 0x11, 0x69, 0xc6, 0xf4, 0xfb, 0x76, 0x22, 0x4f, 0x4c, 0x12, 0xf5, 0x7d, 0xaf, 0xe3, 0x05, 0x4c, + 0xdb, 0x53, 0x47, 0x31, 0xa5, 0x03, 0xd5, 0x08, 0x29, 0xef, 0x5b, 0x23, 0xe4, 0x45, 0x18, 0x8d, + 0xe3, 0x8d, 0xe5, 0xc8, 0xdd, 0x72, 0x12, 0x72, 0x95, 0xec, 0x08, 0x2b, 0x4b, 0xe7, 0xf5, 0xaf, + 0x5c, 0xd6, 0x40, 0x9c, 0xc6, 0x45, 0x73, 0x70, 0x4a, 0x57, 0xea, 0x20, 0x51, 0xc2, 0xa2, 0xfb, + 0xf9, 0x4c, 0x50, 0x49, 0xbc, 0xba, 0xb6, 0x87, 0x40, 0xc0, 0xdd, 0xcf, 0x50, 0xf9, 0x96, 0x6a, + 0xa4, 0x1d, 0x19, 0x4c, 0xcb, 0xb7, 0x14, 0x1d, 0xda, 0x97, 0xae, 0x27, 0xd0, 0x22, 0x9c, 0xe6, + 0x13, 0x63, 0x3a, 0x0c, 0x8d, 0x37, 0x1a, 0x4a, 0xd7, 0x31, 0x9c, 0xeb, 0x46, 0xc1, 0x79, 0xcf, + 0xa1, 0xe7, 0x61, 0x58, 0x35, 0xcf, 0xcf, 0x8a, 0x53, 0x04, 0xe5, 0xc5, 0x50, 0x64, 0xe6, 0x9b, + 0xd8, 0xc4, 0x43, 0x1f, 0x84, 0x87, 0xf5, 0x5f, 0x9e, 0x02, 0xc6, 0x8f, 0xd6, 0x66, 0x45, 0x11, + 0x24, 0x75, 0xb5, 0xc7, 0x5c, 0x2e, 0x5a, 0x13, 0xf7, 0x7a, 0x1e, 0xad, 0xc1, 0x39, 0x05, 0xba, + 0xe8, 0x27, 0x2c, 0x9f, 0x23, 0x26, 0x75, 0x27, 0x26, 0xd7, 0x23, 0x4f, 0xdc, 0x8d, 0xaa, 0x6e, + 0x5d, 0x9c, 0x73, 0x93, 0xcb, 0x79, 0x98, 0x78, 0x01, 0xef, 0x41, 0x05, 0x4d, 0x41, 0x8d, 0xf8, + 0xce, 0x9a, 0x47, 0x96, 0x66, 0xe6, 0x59, 0x31, 0x25, 0xe3, 0x24, 0xef, 0xa2, 0x04, 0x60, 0x8d, + 0xa3, 0x22, 0x4c, 0x47, 0x7a, 0xde, 0x00, 0xba, 0x0c, 0x67, 0x5a, 0x8d, 0x90, 0xda, 0x1e, 0x6e, + 0x83, 0x4c, 0x37, 0x58, 0x40, 0x1d, 0xfd, 0x30, 0xbc, 0xc0, 0xa4, 0x0a, 0x9f, 0x9e, 0x9b, 0x59, + 0xee, 0xc2, 0xc1, 0xb9, 0x4f, 0xb2, 0xc0, 0xcb, 0x28, 0xd8, 0xde, 0x19, 0x3f, 0x9d, 0x09, 0xbc, + 0xa4, 0x8d, 0x98, 0xc3, 0xd0, 0x15, 0x40, 0x2c, 0x16, 0xff, 0x72, 0x92, 0x84, 0xca, 0xd8, 0x19, + 0x3f, 0xc3, 0x5e, 0x49, 0x85, 0x91, 0x5d, 0xea, 0xc2, 0xc0, 0x39, 0x4f, 0xd9, 0xff, 0xd1, 0x82, + 0x51, 0xb5, 0x5e, 0xef, 0x41, 0x36, 0x8a, 0x97, 0xce, 0x46, 0x99, 0x3b, 0xba, 0xc4, 0x63, 0x3d, + 0xef, 0x11, 0xd2, 0xfc, 0xd3, 0xc3, 0x00, 0x5a, 0x2a, 0x2a, 0x85, 0x64, 0xf5, 0x54, 0x48, 0x0f, + 0xac, 0x44, 0xca, 0xab, 0x9c, 0x52, 0xb9, 0xbf, 0x95, 0x53, 0x56, 0xe0, 0xac, 0x34, 0x17, 0xf8, + 0x59, 0xd1, 0xe5, 0x20, 0x56, 0x02, 0xae, 0x5a, 0x7f, 0x4c, 0x10, 0x3a, 0x3b, 0x9f, 0x87, 0x84, + 0xf3, 0x9f, 0x4d, 0x59, 0x29, 0x43, 0xfb, 0x59, 0x29, 0x7a, 0x4d, 0x2f, 0xac, 0xcb, 0x3b, 0x3c, + 0x32, 0x6b, 0x7a, 0xe1, 0xd2, 0x0a, 0xd6, 0x38, 0xf9, 0x82, 0xbd, 0x56, 0x90, 0x60, 0x87, 0x03, + 0x0b, 0x76, 0x29, 0x62, 0x86, 0x7b, 0x8a, 0x18, 0xe9, 0x93, 0x1e, 0xe9, 0xe9, 0x93, 0x7e, 0x1f, + 0x8c, 0xb9, 0xfe, 0x06, 0x89, 0xdc, 0x84, 0x34, 0xd9, 0x5a, 0x60, 0xe2, 0xa7, 0xaa, 0xd5, 0xfa, + 0x7c, 0x0a, 0x8a, 0x33, 0xd8, 0x69, 0xb9, 0x38, 0xd6, 0x87, 0x5c, 0xec, 0xa1, 0x8d, 0x4e, 0x14, + 0xa3, 0x8d, 0x4e, 0x1e, 0x5d, 0x1b, 0x9d, 0x3a, 0x56, 0x6d, 0x84, 0x0a, 0xd1, 0x46, 0x7d, 0x09, + 0x7a, 0x63, 0xfb, 0x77, 0x66, 0x9f, 0xed, 0x5f, 0x2f, 0x55, 0x74, 0xf6, 0xd0, 0xaa, 0x28, 0x5f, + 0xcb, 0x3c, 0x74, 0x28, 0x2d, 0xf3, 0x99, 0x12, 0x9c, 0xd5, 0x72, 0x98, 0xce, 0x7e, 0x77, 0x9d, + 0x4a, 0x22, 0x76, 0x0d, 0x14, 0x3f, 0xb7, 0x31, 0x92, 0xa3, 0x74, 0x9e, 0x95, 0x82, 0x60, 0x03, + 0x8b, 0xe5, 0x18, 0x91, 0x88, 0x95, 0xd1, 0xcd, 0x0a, 0xe9, 0x19, 0xd1, 0x8e, 0x15, 0x06, 0x9d, + 0x5f, 0xf4, 0xb7, 0xc8, 0xdb, 0xcc, 0x16, 0x8b, 0x9b, 0xd1, 0x20, 0x6c, 0xe2, 0xa1, 0xa7, 0x38, + 0x13, 0x26, 0x20, 0xa8, 0xa0, 0x1e, 0x11, 0xf7, 0xc2, 0x4a, 0x99, 0xa0, 0xa0, 0xb2, 0x3b, 0x2c, + 0x99, 0xac, 0xd2, 0xdd, 0x1d, 0x16, 0x02, 0xa5, 0x30, 0xec, 0xff, 0x65, 0xc1, 0x23, 0xb9, 0x43, + 0x71, 0x0f, 0x94, 0xef, 0x76, 0x5a, 0xf9, 0xae, 0x14, 0xb5, 0xdd, 0x30, 0xde, 0xa2, 0x87, 0x22, + 0xfe, 0xf7, 0x16, 0x8c, 0x69, 0xfc, 0x7b, 0xf0, 0xaa, 0x6e, 0xfa, 0x55, 0x8b, 0xdb, 0x59, 0xd5, + 0xba, 0xde, 0xed, 0x77, 0x4a, 0xa0, 0x0a, 0x38, 0x4e, 0x37, 0x64, 0x79, 0xdc, 0x7d, 0x4e, 0x12, + 0x77, 0x60, 0x90, 0x1d, 0x84, 0xc6, 0xc5, 0x04, 0x79, 0xa4, 0xf9, 0xb3, 0x43, 0x55, 0x7d, 0xc8, + 0xcc, 0xfe, 0xc6, 0x58, 0x30, 0x64, 0x45, 0x9e, 0xdd, 0x98, 0x4a, 0xf3, 0xa6, 0x48, 0xcb, 0xd2, + 0x45, 0x9e, 0x45, 0x3b, 0x56, 0x18, 0x54, 0x3d, 0xb8, 0x8d, 0xc0, 0x9f, 0xf1, 0x9c, 0x58, 0xde, + 0x7d, 0xa8, 0xd4, 0xc3, 0xbc, 0x04, 0x60, 0x8d, 0xc3, 0xce, 0x48, 0xdd, 0x38, 0xf4, 0x9c, 0x1d, + 0x63, 0xff, 0x6c, 0xd4, 0x27, 0x50, 0x20, 0x6c, 0xe2, 0xd9, 0x6d, 0x18, 0x4f, 0xbf, 0xc4, 0x2c, + 0x59, 0x67, 0x01, 0x8a, 0x7d, 0x0d, 0xe7, 0x14, 0xd4, 0x1c, 0xf6, 0xd4, 0x42, 0xc7, 0xc9, 0x5e, + 0x59, 0x3e, 0x2d, 0x01, 0x58, 0xe3, 0xd8, 0xbf, 0x6a, 0xc1, 0xe9, 0x9c, 0x41, 0x2b, 0x30, 0xed, + 0x2d, 0xd1, 0xd2, 0x26, 0x4f, 0xb1, 0xbf, 0x13, 0x86, 0x9a, 0x64, 0xdd, 0x91, 0x21, 0x70, 0x86, + 0x6c, 0x9f, 0xe5, 0xcd, 0x58, 0xc2, 0xed, 0xff, 0x61, 0xc1, 0x89, 0x74, 0x5f, 0x63, 0x96, 0x4a, + 0xc2, 0x87, 0xc9, 0x8d, 0x1b, 0xc1, 0x16, 0x89, 0x76, 0xe8, 0x9b, 0x5b, 0x99, 0x54, 0x92, 0x2e, + 0x0c, 0x9c, 0xf3, 0x14, 0x2b, 0xdf, 0xda, 0x54, 0xa3, 0x2d, 0x67, 0xe4, 0x8d, 0x22, 0x67, 0xa4, + 0xfe, 0x98, 0xe6, 0x71, 0xb9, 0x62, 0x89, 0x4d, 0xfe, 0xf6, 0x77, 0x06, 0x40, 0xe5, 0xc5, 0xb2, + 0xf8, 0xa3, 0x82, 0xa2, 0xb7, 0x0e, 0x9a, 0x41, 0xa4, 0x26, 0xc3, 0xc0, 0x5e, 0x01, 0x01, 0xdc, + 0x4b, 0x62, 0xba, 0x2e, 0xd5, 0x1b, 0xae, 0x6a, 0x10, 0x36, 0xf1, 0x68, 0x4f, 0x3c, 0x77, 0x8b, + 0xf0, 0x87, 0x06, 0xd3, 0x3d, 0x59, 0x90, 0x00, 0xac, 0x71, 0x68, 0x4f, 0x9a, 0xee, 0xfa, 0xba, + 0xd8, 0xf2, 0xab, 0x9e, 0xd0, 0xd1, 0xc1, 0x0c, 0xc2, 0x2b, 0x72, 0x07, 0x9b, 0xc2, 0x0a, 0x36, + 0x2a, 0x72, 0x07, 0x9b, 0x98, 0x41, 0xa8, 0xdd, 0xe6, 0x07, 0x51, 0x9b, 0x5d, 0x29, 0xdf, 0x54, + 0x5c, 0x84, 0xf5, 0xab, 0xec, 0xb6, 0x6b, 0xdd, 0x28, 0x38, 0xef, 0x39, 0x3a, 0x03, 0xc3, 0x88, + 0x34, 0xdd, 0x46, 0x62, 0x52, 0x83, 0xf4, 0x0c, 0x5c, 0xee, 0xc2, 0xc0, 0x39, 0x4f, 0xa1, 0x69, + 0x38, 0x21, 0xf3, 0x9a, 0x65, 0xd5, 0x9a, 0xe1, 0x74, 0x95, 0x0c, 0x9c, 0x06, 0xe3, 0x2c, 0x3e, + 0x95, 0x6a, 0x6d, 0x51, 0xb0, 0x8a, 0x19, 0xcb, 0x86, 0x54, 0x93, 0x85, 0xac, 0xb0, 0xc2, 0xb0, + 0x3f, 0x59, 0xa6, 0x5a, 0xb8, 0x47, 0xa1, 0xb6, 0x7b, 0x16, 0x2d, 0x98, 0x9e, 0x91, 0x03, 0x7d, + 0xcc, 0xc8, 0xe7, 0x60, 0xe4, 0x56, 0x1c, 0xf8, 0x2a, 0x12, 0xaf, 0xd2, 0x33, 0x12, 0xcf, 0xc0, + 0xca, 0x8f, 0xc4, 0x1b, 0x2c, 0x2a, 0x12, 0x6f, 0xe8, 0x90, 0x91, 0x78, 0xdf, 0xaa, 0x80, 0xba, + 0x1a, 0xe4, 0x1a, 0x49, 0x6e, 0x07, 0xd1, 0xa6, 0xeb, 0xb7, 0x58, 0x3e, 0xf8, 0xd7, 0x2c, 0x18, + 0xe1, 0xeb, 0x65, 0xc1, 0xcc, 0xa4, 0x5a, 0x2f, 0xe8, 0xce, 0x89, 0x14, 0xb3, 0xc9, 0x55, 0x83, + 0x51, 0xe6, 0xea, 0x4d, 0x13, 0x84, 0x53, 0x3d, 0x42, 0x1f, 0x03, 0x90, 0xfe, 0xd1, 0x75, 0x29, + 0x32, 0xe7, 0x8b, 0xe9, 0x1f, 0x26, 0xeb, 0xda, 0x06, 0x5e, 0x55, 0x4c, 0xb0, 0xc1, 0x10, 0x7d, + 0x46, 0x67, 0x99, 0xf1, 0x90, 0xfd, 0x8f, 0x1c, 0xcb, 0xd8, 0xf4, 0x93, 0x63, 0x86, 0x61, 0xc8, + 0xf5, 0x5b, 0x74, 0x9e, 0x88, 0x88, 0xa5, 0x77, 0xe4, 0xd5, 0x52, 0x58, 0x08, 0x9c, 0x66, 0xdd, + 0xf1, 0x1c, 0xbf, 0x41, 0xa2, 0x79, 0x8e, 0x6e, 0x5e, 0x38, 0xcd, 0x1a, 0xb0, 0x24, 0xd4, 0x75, + 0xa9, 0x4a, 0xa5, 0x9f, 0x4b, 0x55, 0xce, 0xbd, 0x1f, 0x4e, 0x75, 0x7d, 0xcc, 0x03, 0xa5, 0x94, + 0x1d, 0x3e, 0x1b, 0xcd, 0xfe, 0x97, 0x83, 0x5a, 0x69, 0x5d, 0x0b, 0x9a, 0xfc, 0x6a, 0x8f, 0x48, + 0x7f, 0x51, 0x61, 0xe3, 0x16, 0x38, 0x45, 0x8c, 0x4b, 0xab, 0x55, 0x23, 0x36, 0x59, 0xd2, 0x39, + 0x1a, 0x3a, 0x11, 0xf1, 0x8f, 0x7b, 0x8e, 0x2e, 0x2b, 0x26, 0xd8, 0x60, 0x88, 0x36, 0x52, 0x39, + 0x25, 0x97, 0x8e, 0x9e, 0x53, 0xc2, 0xaa, 0x4c, 0xe5, 0x55, 0xe3, 0xff, 0xa2, 0x05, 0x63, 0x7e, + 0x6a, 0xe6, 0x16, 0x13, 0x46, 0x9a, 0xbf, 0x2a, 0xf8, 0xcd, 0x52, 0xe9, 0x36, 0x9c, 0xe1, 0x9f, + 0xa7, 0xd2, 0x2a, 0x07, 0x54, 0x69, 0xfa, 0x8e, 0xa0, 0xc1, 0x5e, 0x77, 0x04, 0x21, 0x5f, 0x5d, + 0x92, 0x36, 0x54, 0xf8, 0x25, 0x69, 0x90, 0x73, 0x41, 0xda, 0x4d, 0xa8, 0x35, 0x22, 0xe2, 0x24, + 0x87, 0xbc, 0x2f, 0x8b, 0x1d, 0xd0, 0xcf, 0x48, 0x02, 0x58, 0xd3, 0xb2, 0xff, 0xef, 0x00, 0x9c, + 0x94, 0x23, 0x22, 0x43, 0xd0, 0xa9, 0x7e, 0xe4, 0x7c, 0xb5, 0x71, 0xab, 0xf4, 0xe3, 0x65, 0x09, + 0xc0, 0x1a, 0x87, 0xda, 0x63, 0x9d, 0x98, 0x2c, 0x85, 0xc4, 0x5f, 0x70, 0xd7, 0x62, 0x71, 0xce, + 0xa9, 0x16, 0xca, 0x75, 0x0d, 0xc2, 0x26, 0x1e, 0x35, 0xc6, 0xb9, 0x5d, 0x1c, 0x67, 0xd3, 0x57, + 0x84, 0xbd, 0x8d, 0x25, 0x1c, 0xfd, 0x7c, 0x6e, 0xe5, 0xd8, 0x62, 0x12, 0xb7, 0xba, 0x22, 0xef, + 0x0f, 0x78, 0xc5, 0xe2, 0xdf, 0xb5, 0xe0, 0x2c, 0x6f, 0x95, 0x23, 0x79, 0x3d, 0x6c, 0x3a, 0x09, + 0x89, 0x8b, 0xa9, 0xe4, 0x9e, 0xd3, 0x3f, 0xed, 0xe4, 0xcd, 0x63, 0x8b, 0xf3, 0x7b, 0x83, 0xde, + 0xb0, 0xe0, 0xc4, 0x66, 0xaa, 0xe6, 0x87, 0x54, 0x1d, 0x47, 0x4d, 0xc7, 0x4f, 0x11, 0xd5, 0x4b, + 0x2d, 0xdd, 0x1e, 0xe3, 0x2c, 0x77, 0xfb, 0xcf, 0x2c, 0x30, 0xc5, 0xe8, 0xbd, 0x2f, 0x15, 0x72, + 0x70, 0x53, 0x50, 0x5a, 0x97, 0x95, 0x9e, 0xd6, 0xe5, 0x63, 0x50, 0xee, 0xb8, 0x4d, 0xb1, 0xbf, + 0xd0, 0xa7, 0xaf, 0xf3, 0xb3, 0x98, 0xb6, 0xdb, 0xff, 0xac, 0xa2, 0xfd, 0x16, 0x22, 0x2f, 0xea, + 0xfb, 0xe2, 0xb5, 0xd7, 0x55, 0xb1, 0x31, 0xfe, 0xe6, 0xd7, 0xba, 0x8a, 0x8d, 0xfd, 0xc8, 0xc1, + 0xd3, 0xde, 0xf8, 0x00, 0xf5, 0xaa, 0x35, 0x36, 0xb4, 0x4f, 0xce, 0xdb, 0x2d, 0xa8, 0xd2, 0x2d, + 0x18, 0x73, 0x40, 0x56, 0x53, 0x9d, 0xaa, 0x5e, 0x16, 0xed, 0x77, 0x77, 0x27, 0xde, 0x7b, 0xf0, + 0x6e, 0xc9, 0xa7, 0xb1, 0xa2, 0x8f, 0x62, 0xa8, 0xd1, 0xdf, 0x2c, 0x3d, 0x4f, 0x6c, 0xee, 0xae, + 0x2b, 0x99, 0x29, 0x01, 0x85, 0xe4, 0xfe, 0x69, 0x3e, 0xc8, 0x87, 0x1a, 0xbb, 0x8d, 0x96, 0x31, + 0xe5, 0x7b, 0xc0, 0x65, 0x95, 0x24, 0x27, 0x01, 0x77, 0x77, 0x27, 0x5e, 0x3c, 0x38, 0x53, 0xf5, + 0x38, 0xd6, 0x2c, 0xec, 0x2f, 0x0d, 0xe8, 0xb9, 0x2b, 0x6a, 0xcc, 0x7d, 0x5f, 0xcc, 0xdd, 0x17, + 0x32, 0x73, 0xf7, 0x7c, 0xd7, 0xdc, 0x1d, 0xd3, 0xb7, 0xa6, 0xa6, 0x66, 0xe3, 0xbd, 0x36, 0x04, + 0xf6, 0xf7, 0x37, 0x30, 0x0b, 0xe8, 0xb5, 0x8e, 0x1b, 0x91, 0x78, 0x39, 0xea, 0xf8, 0xae, 0xdf, + 0x62, 0xd3, 0xb1, 0x6a, 0x5a, 0x40, 0x29, 0x30, 0xce, 0xe2, 0xd3, 0x4d, 0x3d, 0xfd, 0xe6, 0x37, + 0x9d, 0x2d, 0x3e, 0xab, 0x8c, 0xb2, 0x5b, 0x2b, 0xa2, 0x1d, 0x2b, 0x0c, 0xfb, 0x1b, 0xec, 0x2c, + 0xdb, 0xc8, 0x0b, 0xa6, 0x73, 0xc2, 0x63, 0xd7, 0xff, 0xf2, 0x9a, 0x5d, 0x6a, 0x4e, 0xf0, 0x3b, + 0x7f, 0x39, 0x0c, 0xdd, 0x86, 0xa1, 0x35, 0x7e, 0xff, 0x5d, 0x31, 0xf5, 0xc9, 0xc5, 0x65, 0x7a, + 0xec, 0x96, 0x13, 0x79, 0xb3, 0xde, 0x5d, 0xfd, 0x13, 0x4b, 0x6e, 0xf6, 0xef, 0x57, 0xe0, 0x44, + 0xe6, 0x82, 0xd8, 0x54, 0xb5, 0xd4, 0xd2, 0xbe, 0xd5, 0x52, 0x3f, 0x0c, 0xd0, 0x24, 0xa1, 0x17, + 0xec, 0x30, 0x73, 0x6c, 0xe0, 0xc0, 0xe6, 0x98, 0xb2, 0xe0, 0x67, 0x15, 0x15, 0x6c, 0x50, 0x14, + 0x85, 0xca, 0x78, 0xf1, 0xd5, 0x4c, 0xa1, 0x32, 0xe3, 0x16, 0x83, 0xc1, 0x7b, 0x7b, 0x8b, 0x81, + 0x0b, 0x27, 0x78, 0x17, 0x55, 0xf6, 0xed, 0x21, 0x92, 0x6c, 0x59, 0xfe, 0xc2, 0x6c, 0x9a, 0x0c, + 0xce, 0xd2, 0xbd, 0x9f, 0xf7, 0x3f, 0xa3, 0x77, 0x41, 0x4d, 0x7e, 0xe7, 0x78, 0xbc, 0xa6, 0x2b, + 0x18, 0xc8, 0x69, 0xc0, 0xee, 0x65, 0x16, 0x3f, 0xbb, 0x0a, 0x09, 0xc0, 0xfd, 0x2a, 0x24, 0x60, + 0x7f, 0xa1, 0x44, 0xed, 0x78, 0xde, 0x2f, 0x55, 0x13, 0xe7, 0x49, 0x18, 0x74, 0x3a, 0xc9, 0x46, + 0xd0, 0x75, 0x9b, 0xdf, 0x34, 0x6b, 0xc5, 0x02, 0x8a, 0x16, 0x60, 0xa0, 0xa9, 0xeb, 0x9c, 0x1c, + 0xe4, 0x7b, 0x6a, 0x97, 0xa8, 0x93, 0x10, 0xcc, 0xa8, 0xa0, 0x47, 0x61, 0x20, 0x71, 0x5a, 0x32, + 0xe5, 0x8a, 0xa5, 0xd9, 0xae, 0x3a, 0xad, 0x18, 0xb3, 0x56, 0x53, 0x7d, 0x0f, 0xec, 0xa3, 0xbe, + 0x5f, 0x84, 0xd1, 0xd8, 0x6d, 0xf9, 0x4e, 0xd2, 0x89, 0x88, 0x71, 0xcc, 0xa7, 0x23, 0x37, 0x4c, + 0x20, 0x4e, 0xe3, 0xda, 0xbf, 0x39, 0x02, 0x67, 0x56, 0x66, 0x16, 0x65, 0xf5, 0xee, 0x63, 0xcb, + 0x9a, 0xca, 0xe3, 0x71, 0xef, 0xb2, 0xa6, 0x7a, 0x70, 0xf7, 0x8c, 0xac, 0x29, 0xcf, 0xc8, 0x9a, + 0x4a, 0xa7, 0xb0, 0x94, 0x8b, 0x48, 0x61, 0xc9, 0xeb, 0x41, 0x3f, 0x29, 0x2c, 0xc7, 0x96, 0x46, + 0xb5, 0x67, 0x87, 0x0e, 0x94, 0x46, 0xa5, 0x72, 0xcc, 0x0a, 0x49, 0x2e, 0xe8, 0xf1, 0xa9, 0x72, + 0x73, 0xcc, 0x54, 0x7e, 0x0f, 0x4f, 0x9c, 0x11, 0xa2, 0xfe, 0x95, 0xe2, 0x3b, 0xd0, 0x47, 0x7e, + 0x8f, 0xc8, 0xdd, 0x31, 0x73, 0xca, 0x86, 0x8a, 0xc8, 0x29, 0xcb, 0xeb, 0xce, 0xbe, 0x39, 0x65, + 0x2f, 0xc2, 0x68, 0xc3, 0x0b, 0x7c, 0xb2, 0x1c, 0x05, 0x49, 0xd0, 0x08, 0x3c, 0x61, 0xd6, 0x2b, + 0x91, 0x30, 0x63, 0x02, 0x71, 0x1a, 0xb7, 0x57, 0x42, 0x5a, 0xed, 0xa8, 0x09, 0x69, 0x70, 0x9f, + 0x12, 0xd2, 0x7e, 0x46, 0xa7, 0x4e, 0x0f, 0xb3, 0x2f, 0xf2, 0xe1, 0xe2, 0xbf, 0x48, 0x3f, 0xf9, + 0xd3, 0xe8, 0x4d, 0x7e, 0x9d, 0x1e, 0x35, 0x8c, 0x67, 0x82, 0x36, 0x35, 0xfc, 0x46, 0xd8, 0x90, + 0xbc, 0x7a, 0x0c, 0x13, 0xf6, 0xe6, 0x8a, 0x66, 0xa3, 0xae, 0xd8, 0xd3, 0x4d, 0x38, 0xdd, 0x91, + 0xa3, 0xa4, 0x76, 0x7f, 0xa5, 0x04, 0x3f, 0xb0, 0x6f, 0x17, 0xd0, 0x6d, 0x80, 0xc4, 0x69, 0x89, + 0x89, 0x2a, 0x0e, 0x4c, 0x8e, 0x18, 0x5e, 0xb9, 0x2a, 0xe9, 0xf1, 0x9a, 0x24, 0xea, 0x2f, 0x3b, + 0x8a, 0x90, 0xbf, 0x59, 0x54, 0x65, 0xe0, 0x75, 0x95, 0x6e, 0xc4, 0x81, 0x47, 0x30, 0x83, 0x50, + 0xf5, 0x1f, 0x91, 0x96, 0xbe, 0xff, 0x59, 0x7d, 0x3e, 0xcc, 0x5a, 0xb1, 0x80, 0xa2, 0xe7, 0x61, + 0xd8, 0xf1, 0x3c, 0x9e, 0x1f, 0x43, 0x62, 0x71, 0x9f, 0x8e, 0xae, 0x21, 0xa7, 0x41, 0xd8, 0xc4, + 0xb3, 0xff, 0xb4, 0x04, 0x13, 0xfb, 0xc8, 0x94, 0xae, 0x8c, 0xbf, 0x4a, 0xdf, 0x19, 0x7f, 0x22, + 0x47, 0x61, 0xb0, 0x47, 0x8e, 0xc2, 0xf3, 0x30, 0x9c, 0x10, 0xa7, 0x2d, 0x02, 0xb2, 0x84, 0x27, + 0x40, 0x9f, 0x00, 0x6b, 0x10, 0x36, 0xf1, 0xa8, 0x14, 0x1b, 0x73, 0x1a, 0x0d, 0x12, 0xc7, 0x32, + 0x09, 0x41, 0x78, 0x53, 0x0b, 0xcb, 0x70, 0x60, 0x4e, 0xea, 0xe9, 0x14, 0x0b, 0x9c, 0x61, 0x99, + 0x1d, 0xf0, 0x5a, 0x9f, 0x03, 0xfe, 0xf5, 0x12, 0x3c, 0xb6, 0xa7, 0x76, 0xeb, 0x3b, 0x3f, 0xa4, + 0x13, 0x93, 0x28, 0x3b, 0x71, 0xae, 0xc7, 0x24, 0xc2, 0x0c, 0xc2, 0x47, 0x29, 0x0c, 0x8d, 0xfb, + 0xb5, 0x8b, 0x4e, 0x5e, 0xe2, 0xa3, 0x94, 0x62, 0x81, 0x33, 0x2c, 0x0f, 0x3b, 0x2d, 0xff, 0x41, + 0x09, 0x9e, 0xe8, 0xc3, 0x06, 0x28, 0x30, 0xc9, 0x2b, 0x9d, 0x6a, 0x57, 0xbe, 0x4f, 0x19, 0x91, + 0x87, 0x1c, 0xae, 0x6f, 0x94, 0xe0, 0x5c, 0x6f, 0x55, 0x8c, 0x7e, 0x14, 0x4e, 0x44, 0x2a, 0x0a, + 0xcb, 0xcc, 0xd2, 0x3b, 0xcd, 0x3d, 0x09, 0x29, 0x10, 0xce, 0xe2, 0xa2, 0x49, 0x80, 0xd0, 0x49, + 0x36, 0xe2, 0x8b, 0xdb, 0x6e, 0x9c, 0x88, 0x2a, 0x34, 0x63, 0xfc, 0xec, 0x4a, 0xb6, 0x62, 0x03, + 0x83, 0xb2, 0x63, 0xff, 0x66, 0x83, 0x6b, 0x41, 0xc2, 0x1f, 0xe2, 0xdb, 0x88, 0xd3, 0xf2, 0xce, + 0x0e, 0x03, 0x84, 0xb3, 0xb8, 0x94, 0x1d, 0x3b, 0x1d, 0xe5, 0x1d, 0xe5, 0xfb, 0x0b, 0xc6, 0x6e, + 0x41, 0xb5, 0x62, 0x03, 0x23, 0x9b, 0x7f, 0x58, 0xd9, 0x3f, 0xff, 0xd0, 0xfe, 0xa7, 0x25, 0x78, + 0xa4, 0xa7, 0x29, 0xd7, 0xdf, 0x02, 0x7c, 0xf0, 0x72, 0x06, 0x0f, 0x37, 0x77, 0x0e, 0x98, 0xdb, + 0xf6, 0xc7, 0x3d, 0x66, 0x9a, 0xc8, 0x6d, 0x3b, 0x7c, 0x72, 0xf8, 0x83, 0x37, 0x9e, 0x5d, 0xe9, + 0x6c, 0x03, 0x07, 0x48, 0x67, 0xcb, 0x7c, 0x8c, 0x4a, 0x9f, 0x0b, 0xf9, 0xcf, 0xcb, 0x3d, 0x87, + 0x97, 0x6e, 0xfd, 0xfa, 0xf2, 0xd3, 0xce, 0xc2, 0x49, 0xd7, 0x67, 0xf7, 0x37, 0xad, 0x74, 0xd6, + 0x44, 0x61, 0x92, 0x52, 0xfa, 0xf6, 0xf4, 0xf9, 0x0c, 0x1c, 0x77, 0x3d, 0xf1, 0x00, 0xa6, 0x17, + 0x1e, 0x6e, 0x48, 0x0f, 0x96, 0xe0, 0x8a, 0x96, 0xe0, 0xac, 0x1c, 0x8a, 0x0d, 0x27, 0x22, 0x4d, + 0xa1, 0x46, 0x62, 0x91, 0x50, 0xf1, 0x08, 0x4f, 0xca, 0xc8, 0x41, 0xc0, 0xf9, 0xcf, 0xb1, 0x2b, + 0x73, 0x82, 0xd0, 0x6d, 0x88, 0x4d, 0x8e, 0xbe, 0x32, 0x87, 0x36, 0x62, 0x0e, 0xb3, 0x3f, 0x0c, + 0x35, 0xf5, 0xfe, 0x3c, 0xac, 0x5b, 0x4d, 0xba, 0xae, 0xb0, 0x6e, 0x35, 0xe3, 0x0c, 0x2c, 0xfa, + 0xb5, 0xa8, 0x49, 0x9c, 0x59, 0x3d, 0x57, 0xc9, 0x0e, 0xb3, 0x8f, 0xed, 0x77, 0xc3, 0x88, 0xf2, + 0xb3, 0xf4, 0x7b, 0x91, 0x90, 0xfd, 0xa5, 0x41, 0x18, 0x4d, 0x15, 0x07, 0x4c, 0x39, 0x58, 0xad, + 0x7d, 0x1d, 0xac, 0x2c, 0x4c, 0xbf, 0xe3, 0xcb, 0x5b, 0xc6, 0x8c, 0x30, 0xfd, 0x8e, 0x4f, 0x30, + 0x87, 0x51, 0xf3, 0xb6, 0x19, 0xed, 0xe0, 0x8e, 0x2f, 0xc2, 0x69, 0x95, 0x79, 0x3b, 0xcb, 0x5a, + 0xb1, 0x80, 0xa2, 0x4f, 0x58, 0x30, 0x12, 0x33, 0xef, 0x3d, 0x77, 0x4f, 0x8b, 0x49, 0x77, 0xe5, + 0xe8, 0xb5, 0x0f, 0x55, 0x21, 0x4c, 0x16, 0x21, 0x63, 0xb6, 0xe0, 0x14, 0x47, 0xf4, 0x69, 0x0b, + 0x6a, 0xea, 0x32, 0x14, 0x71, 0x15, 0xe0, 0x4a, 0xb1, 0xb5, 0x17, 0xb9, 0x5f, 0x53, 0x1d, 0x84, + 0xa8, 0x22, 0x78, 0x58, 0x33, 0x46, 0xb1, 0xf2, 0x1d, 0x0f, 0x1d, 0x8f, 0xef, 0x18, 0x72, 0xfc, + 0xc6, 0xef, 0x82, 0x5a, 0xdb, 0xf1, 0xdd, 0x75, 0x12, 0x27, 0xdc, 0x9d, 0x2b, 0x4b, 0xc2, 0xca, + 0x46, 0xac, 0xe1, 0x54, 0x21, 0xc7, 0xec, 0xc5, 0x12, 0xc3, 0xff, 0xca, 0x14, 0xf2, 0x8a, 0x6e, + 0xc6, 0x26, 0x8e, 0xe9, 0x2c, 0x86, 0xfb, 0xea, 0x2c, 0x1e, 0xde, 0xdb, 0x59, 0x6c, 0xff, 0x23, + 0x0b, 0xce, 0xe6, 0x7e, 0xb5, 0x07, 0x37, 0xf0, 0xd1, 0xfe, 0x72, 0x05, 0x4e, 0xe7, 0x54, 0xf9, + 0x44, 0x3b, 0xe6, 0x7c, 0xb6, 0x8a, 0x88, 0x21, 0x48, 0x1f, 0x89, 0xcb, 0x61, 0xcc, 0x99, 0xc4, + 0x07, 0x3b, 0xaa, 0xd1, 0xc7, 0x25, 0xe5, 0x7b, 0x7b, 0x5c, 0x62, 0x4c, 0xcb, 0x81, 0xfb, 0x3a, + 0x2d, 0x2b, 0xfb, 0x9c, 0x61, 0xfc, 0x9a, 0x05, 0xe3, 0xed, 0x1e, 0xa5, 0xe5, 0x85, 0xe3, 0xf1, + 0xc6, 0xf1, 0x14, 0xae, 0xaf, 0x3f, 0x7a, 0x67, 0x77, 0xa2, 0x67, 0x45, 0x7f, 0xdc, 0xb3, 0x57, + 0xf6, 0x77, 0xca, 0xc0, 0x4a, 0xcc, 0xb2, 0x4a, 0x6e, 0x3b, 0xe8, 0xe3, 0x66, 0xb1, 0x60, 0xab, + 0xa8, 0xc2, 0xb6, 0x9c, 0xb8, 0x2a, 0x36, 0xcc, 0x47, 0x30, 0xaf, 0xf6, 0x70, 0x56, 0x68, 0x95, + 0xfa, 0x10, 0x5a, 0x9e, 0xac, 0xca, 0x5c, 0x2e, 0xbe, 0x2a, 0x73, 0x2d, 0x5b, 0x91, 0x79, 0xef, + 0x4f, 0x3c, 0xf0, 0x40, 0x7e, 0xe2, 0x5f, 0xb0, 0xb8, 0xe0, 0xc9, 0x7c, 0x05, 0x6d, 0x19, 0x58, + 0x7b, 0x58, 0x06, 0x4f, 0x43, 0x35, 0x26, 0xde, 0xfa, 0x65, 0xe2, 0x78, 0xc2, 0x82, 0xd0, 0xe7, + 0xd7, 0xa2, 0x1d, 0x2b, 0x0c, 0x76, 0x6d, 0xab, 0xe7, 0x05, 0xb7, 0x2f, 0xb6, 0xc3, 0x64, 0x47, + 0xd8, 0x12, 0xfa, 0xda, 0x56, 0x05, 0xc1, 0x06, 0x96, 0xfd, 0x77, 0x4a, 0x7c, 0x06, 0x8a, 0x20, + 0x88, 0x17, 0x32, 0x17, 0xed, 0xf5, 0x1f, 0x3f, 0xf0, 0x51, 0x80, 0x86, 0xba, 0xa2, 0x5e, 0x9c, + 0x09, 0x5d, 0x3e, 0xf2, 0xfd, 0xd9, 0x82, 0x9e, 0x7e, 0x0d, 0xdd, 0x86, 0x0d, 0x7e, 0x29, 0x59, + 0x5a, 0xde, 0x57, 0x96, 0xa6, 0xc4, 0xca, 0xc0, 0x3e, 0xda, 0xee, 0x4f, 0x2d, 0x48, 0x59, 0x44, + 0x28, 0x84, 0x0a, 0xed, 0xee, 0x4e, 0x31, 0xb7, 0xef, 0x9b, 0xa4, 0xa9, 0x68, 0x14, 0xd3, 0x9e, + 0xfd, 0xc4, 0x9c, 0x11, 0xf2, 0x44, 0xac, 0x04, 0x1f, 0xd5, 0x6b, 0xc5, 0x31, 0xbc, 0x1c, 0x04, + 0x9b, 0xfc, 0x60, 0x53, 0xc7, 0x5d, 0xd8, 0x2f, 0xc0, 0xa9, 0xae, 0x4e, 0xb1, 0x3b, 0xb5, 0x02, + 0xaa, 0x7d, 0x32, 0xd3, 0x95, 0x25, 0x70, 0x62, 0x0e, 0xb3, 0xbf, 0x61, 0xc1, 0xc9, 0x2c, 0x79, + 0xf4, 0xa6, 0x05, 0xa7, 0xe2, 0x2c, 0xbd, 0xe3, 0x1a, 0x3b, 0x15, 0xef, 0xd8, 0x05, 0xc2, 0xdd, + 0x9d, 0xb0, 0xff, 0x9f, 0x98, 0xfc, 0x37, 0x5d, 0xbf, 0x19, 0xdc, 0x56, 0x86, 0x89, 0xd5, 0xd3, + 0x30, 0xa1, 0xeb, 0xb1, 0xb1, 0x41, 0x9a, 0x1d, 0xaf, 0x2b, 0x73, 0x74, 0x45, 0xb4, 0x63, 0x85, + 0xc1, 0x12, 0xe5, 0x3a, 0xa2, 0x6c, 0x7b, 0x66, 0x52, 0xce, 0x8a, 0x76, 0xac, 0x30, 0xd0, 0x73, + 0x30, 0x62, 0xbc, 0xa4, 0x9c, 0x97, 0xcc, 0x20, 0x37, 0x54, 0x66, 0x8c, 0x53, 0x58, 0x68, 0x12, + 0x40, 0x19, 0x39, 0x52, 0x45, 0x32, 0x47, 0x91, 0x92, 0x44, 0x31, 0x36, 0x30, 0x58, 0x5a, 0xaa, + 0xd7, 0x89, 0x99, 0x8f, 0x7f, 0x50, 0x97, 0x12, 0x9d, 0x11, 0x6d, 0x58, 0x41, 0xa9, 0x34, 0x69, + 0x3b, 0x7e, 0xc7, 0xf1, 0xe8, 0x08, 0x89, 0xad, 0x9f, 0x5a, 0x86, 0x8b, 0x0a, 0x82, 0x0d, 0x2c, + 0xfa, 0xc6, 0x89, 0xdb, 0x26, 0x2f, 0x07, 0xbe, 0x8c, 0x53, 0xd3, 0xc7, 0x3e, 0xa2, 0x1d, 0x2b, + 0x0c, 0xfb, 0xbf, 0x59, 0x70, 0x42, 0x27, 0xb9, 0xf3, 0xdb, 0xb3, 0xcd, 0x9d, 0xaa, 0xb5, 0xef, + 0x4e, 0x35, 0x9d, 0xfd, 0x5b, 0xea, 0x2b, 0xfb, 0xd7, 0x4c, 0xcc, 0x2d, 0xef, 0x99, 0x98, 0xfb, + 0x83, 0xfa, 0x66, 0x56, 0x9e, 0xc1, 0x3b, 0x9c, 0x77, 0x2b, 0x2b, 0xb2, 0x61, 0xb0, 0xe1, 0xa8, + 0x0a, 0x2f, 0x23, 0x7c, 0xef, 0x30, 0x33, 0xcd, 0x90, 0x04, 0xc4, 0x5e, 0x82, 0x9a, 0x3a, 0xfd, + 0x90, 0x1b, 0x55, 0x2b, 0x7f, 0xa3, 0xda, 0x57, 0x82, 0x60, 0x7d, 0xed, 0x9b, 0xdf, 0x7d, 0xfc, + 0x6d, 0xbf, 0xf7, 0xdd, 0xc7, 0xdf, 0xf6, 0x47, 0xdf, 0x7d, 0xfc, 0x6d, 0x9f, 0xb8, 0xf3, 0xb8, + 0xf5, 0xcd, 0x3b, 0x8f, 0x5b, 0xbf, 0x77, 0xe7, 0x71, 0xeb, 0x8f, 0xee, 0x3c, 0x6e, 0x7d, 0xe7, + 0xce, 0xe3, 0xd6, 0x17, 0xff, 0xf3, 0xe3, 0x6f, 0x7b, 0x39, 0x37, 0x50, 0x91, 0xfe, 0x78, 0xa6, + 0xd1, 0x9c, 0xda, 0xba, 0xc0, 0x62, 0xe5, 0xe8, 0xf2, 0x9a, 0x32, 0xe6, 0xd4, 0x94, 0x5c, 0x5e, + 0xff, 0x3f, 0x00, 0x00, 0xff, 0xff, 0xe2, 0x8b, 0xe4, 0x9e, 0x5b, 0xe1, 0x00, 0x00, } func (m *AWSAuthConfig) Marshal() (dAtA []byte, err error) { @@ -5158,6 +5159,11 @@ func (m *AWSAuthConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.Profile) + copy(dAtA[i:], m.Profile) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Profile))) + i-- + dAtA[i] = 0x1a i -= len(m.RoleARN) copy(dAtA[i:], m.RoleARN) i = encodeVarintGenerated(dAtA, i, uint64(len(m.RoleARN))) @@ -14357,6 +14363,8 @@ func (m *AWSAuthConfig) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) l = len(m.RoleARN) n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Profile) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -17806,6 +17814,7 @@ func (this *AWSAuthConfig) String() string { s := strings.Join([]string{`&AWSAuthConfig{`, `ClusterName:` + fmt.Sprintf("%v", this.ClusterName) + `,`, `RoleARN:` + fmt.Sprintf("%v", this.RoleARN) + `,`, + `Profile:` + fmt.Sprintf("%v", this.Profile) + `,`, `}`, }, "") return s @@ -20456,6 +20465,38 @@ func (m *AWSAuthConfig) Unmarshal(dAtA []byte) error { } m.RoleARN = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Profile", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Profile = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index a2b17373de259..8a6fa85d9ad1b 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -22,6 +22,9 @@ message AWSAuthConfig { // RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain. optional string roleARN = 2; + + // Profile contains optional role ARN. If set then AWS IAM Authenticator uses the profile to perform cluster operations instead of the default AWS credential provider chain. + optional string profile = 3; } // AppProject provides a logical grouping of applications, providing controls for: diff --git a/pkg/apis/application/v1alpha1/openapi_generated.go b/pkg/apis/application/v1alpha1/openapi_generated.go index 2274e252a4148..ae07404f60f2c 100644 --- a/pkg/apis/application/v1alpha1/openapi_generated.go +++ b/pkg/apis/application/v1alpha1/openapi_generated.go @@ -191,6 +191,13 @@ func schema_pkg_apis_application_v1alpha1_AWSAuthConfig(ref common.ReferenceCall Format: "", }, }, + "profile": { + SchemaProps: spec.SchemaProps{ + Description: "Profile contains optional role ARN. If set then AWS IAM Authenticator uses the profile to perform cluster operations instead of the default AWS credential provider chain.", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index e271003ad6ad0..18829dbcf940d 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -1856,6 +1856,9 @@ type AWSAuthConfig struct { // RoleARN contains optional role ARN. If set then AWS IAM Authenticator assume a role to perform cluster operations instead of the default AWS credential provider chain. RoleARN string `json:"roleARN,omitempty" protobuf:"bytes,2,opt,name=roleARN"` + + // Profile contains optional role ARN. If set then AWS IAM Authenticator uses the profile to perform cluster operations instead of the default AWS credential provider chain. + Profile string `json:"profile,omitempty" protobuf:"bytes,3,opt,name=profile"` } // ExecProviderConfig is config used to call an external command to perform cluster authentication @@ -2987,6 +2990,9 @@ func (c *Cluster) RawRestConfig() *rest.Config { if c.Config.AWSAuthConfig.RoleARN != "" { args = append(args, "--role-arn", c.Config.AWSAuthConfig.RoleARN) } + if c.Config.AWSAuthConfig.Profile != "" { + args = append(args, "--profile", c.Config.AWSAuthConfig.Profile) + } config = &rest.Config{ Host: c.Server, TLSClientConfig: tlsClientConfig, From 7ec9999b01b26e760ff8f96ce7fac20c02fab6c8 Mon Sep 17 00:00:00 2001 From: Alexander Matyushentsev Date: Tue, 16 Jan 2024 10:54:13 -0800 Subject: [PATCH 193/269] fix: enforce content type header for API requests (#16860) Signed-off-by: Alexander Matyushentsev --- cmd/argocd-server/commands/argocd_server.go | 4 ++++ .../server-commands/argocd-server.md | 1 + server/server.go | 18 ++++++++++++++++++ test/e2e/fixture/http.go | 1 + 4 files changed, 24 insertions(+) diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 72fe765c32c56..6ec66801cc317 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "math" + "strings" "time" "github.com/argoproj/pkg/stats" @@ -63,6 +64,7 @@ func NewCommand() *cobra.Command { repoServerAddress string dexServerAddress string disableAuth bool + contentTypes string enableGZip bool tlsConfigCustomizerSrc func() (tls.ConfigCustomizer, error) cacheSrc func() (*servercache.Cache, error) @@ -185,6 +187,7 @@ func NewCommand() *cobra.Command { DexServerAddr: dexServerAddress, DexTLSConfig: dexTlsConfig, DisableAuth: disableAuth, + ContentTypes: strings.Split(contentTypes, ";"), EnableGZip: enableGZip, TLSConfigCustomizer: tlsConfigCustomizer, Cache: cache, @@ -240,6 +243,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_SERVER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address") command.Flags().StringVar(&dexServerAddress, "dex-server", env.StringFromEnv("ARGOCD_SERVER_DEX_SERVER", common.DefaultDexServerAddr), "Dex server address") command.Flags().BoolVar(&disableAuth, "disable-auth", env.ParseBoolFromEnv("ARGOCD_SERVER_DISABLE_AUTH", false), "Disable client authentication") + command.Flags().StringVar(&contentTypes, "api-content-types", "application/json", "Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty.") command.Flags().BoolVar(&enableGZip, "enable-gzip", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_GZIP", true), "Enable GZIP compression") command.AddCommand(cli.NewVersionCmd(cliName)) command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_SERVER_LISTEN_ADDRESS", common.DefaultAddressAPIServer), "Listen on given address") diff --git a/docs/operator-manual/server-commands/argocd-server.md b/docs/operator-manual/server-commands/argocd-server.md index 1da27d735e1cd..a72cc041299ad 100644 --- a/docs/operator-manual/server-commands/argocd-server.md +++ b/docs/operator-manual/server-commands/argocd-server.md @@ -26,6 +26,7 @@ argocd-server [flags] ``` --address string Listen on given address (default "0.0.0.0") + --api-content-types string Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty. (default "application/json") --app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s) --application-namespaces strings List of additional namespaces where application resources can be managed in --as string Username to impersonate for the operation diff --git a/server/server.go b/server/server.go index 6ebbc9723167f..8de2ecb9eff9c 100644 --- a/server/server.go +++ b/server/server.go @@ -197,6 +197,7 @@ type ArgoCDServer struct { type ArgoCDServerOpts struct { DisableAuth bool + ContentTypes []string EnableGZip bool Insecure bool StaticAssetsDir string @@ -990,6 +991,9 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl if a.EnableGZip { handler = compressHandler(handler) } + if len(a.ContentTypes) > 0 { + handler = enforceContentTypes(handler, a.ContentTypes) + } mux.Handle("/api/", handler) terminal := application.NewHandler(a.appLister, a.Namespace, a.ApplicationNamespaces, a.db, a.enf, a.Cache, appResourceTreeFn, a.settings.ExecShells, *a.sessionMgr). @@ -1056,6 +1060,20 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl return &httpS } +func enforceContentTypes(handler http.Handler, types []string) http.Handler { + allowedTypes := map[string]bool{} + for _, t := range types { + allowedTypes[strings.ToLower(t)] = true + } + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodGet || allowedTypes[strings.ToLower(r.Header.Get("Content-Type"))] { + handler.ServeHTTP(w, r) + } else { + http.Error(w, "Invalid content type", http.StatusUnsupportedMediaType) + } + }) +} + // registerExtensions will try to register all configured extensions // in the given mux. If any error is returned while registering // extensions handlers, no route will be added in the given mux. diff --git a/test/e2e/fixture/http.go b/test/e2e/fixture/http.go index 1e818f5262024..00c123ab5d893 100644 --- a/test/e2e/fixture/http.go +++ b/test/e2e/fixture/http.go @@ -28,6 +28,7 @@ func DoHttpRequest(method string, path string, data ...byte) (*http.Response, er return nil, err } req.AddCookie(&http.Cookie{Name: common.AuthCookieName, Value: token}) + req.Header.Set("Content-Type", "application/json") httpClient := &http.Client{ Transport: &http.Transport{ From 15060e1d73498b2b9d8f8c72b0f807bbd56ef851 Mon Sep 17 00:00:00 2001 From: Zubair Haque Date: Tue, 16 Jan 2024 22:27:20 -0500 Subject: [PATCH 194/269] adding tests for githandlers (#16678) Signed-off-by: zhaque44 --- reposerver/metrics/githandlers_test.go | 122 +++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 reposerver/metrics/githandlers_test.go diff --git a/reposerver/metrics/githandlers_test.go b/reposerver/metrics/githandlers_test.go new file mode 100644 index 0000000000000..6eaeeca82cc36 --- /dev/null +++ b/reposerver/metrics/githandlers_test.go @@ -0,0 +1,122 @@ +package metrics + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "golang.org/x/sync/semaphore" +) + +func TestMain(m *testing.M) { + os.Exit(m.Run()) +} + +func TestEdgeCasesAndErrorHandling(t *testing.T) { + tests := []struct { + name string + setup func() + teardown func() + testFunc func(t *testing.T) + }{ + { + name: "lsRemoteParallelismLimitSemaphore is nil", + testFunc: func(t *testing.T) { + lsRemoteParallelismLimitSemaphore = nil + assert.NotPanics(t, func() { + NewGitClientEventHandlers(&MetricsServer{}) + }) + }, + }, + { + name: "lsRemoteParallelismLimitSemaphore is not nil", + setup: func() { + lsRemoteParallelismLimitSemaphore = semaphore.NewWeighted(1) + }, + teardown: func() { + lsRemoteParallelismLimitSemaphore = nil + }, + testFunc: func(t *testing.T) { + assert.NotPanics(t, func() { + NewGitClientEventHandlers(&MetricsServer{}) + }) + }, + }, + { + name: "lsRemoteParallelismLimitSemaphore is not nil and Acquire returns error", + setup: func() { + lsRemoteParallelismLimitSemaphore = semaphore.NewWeighted(1) + }, + teardown: func() { + lsRemoteParallelismLimitSemaphore = nil + }, + testFunc: func(t *testing.T) { + assert.NotPanics(t, func() { + NewGitClientEventHandlers(&MetricsServer{}) + }) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.setup != nil { + tt.setup() + } + if tt.teardown != nil { + defer tt.teardown() + } + tt.testFunc(t) + }) + } +} + +func TestSemaphoreFunctionality(t *testing.T) { + os.Setenv("ARGOCD_GIT_LSREMOTE_PARALLELISM_LIMIT", "1") + + tests := []struct { + name string + setup func() + teardown func() + testFunc func(t *testing.T) + }{ + { + name: "lsRemoteParallelismLimitSemaphore is not nil", + setup: func() { + lsRemoteParallelismLimitSemaphore = semaphore.NewWeighted(1) + }, + teardown: func() { + lsRemoteParallelismLimitSemaphore = nil + }, + testFunc: func(t *testing.T) { + assert.NotPanics(t, func() { + NewGitClientEventHandlers(&MetricsServer{}) + }) + }, + }, + { + name: "lsRemoteParallelismLimitSemaphore is not nil and Acquire returns error", + setup: func() { + lsRemoteParallelismLimitSemaphore = semaphore.NewWeighted(1) + }, + teardown: func() { + lsRemoteParallelismLimitSemaphore = nil + }, + testFunc: func(t *testing.T) { + assert.NotPanics(t, func() { + NewGitClientEventHandlers(&MetricsServer{}) + }) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if tt.setup != nil { + tt.setup() + } + if tt.teardown != nil { + defer tt.teardown() + } + tt.testFunc(t) + }) + } +} From 180b99010e07372bc3d600c4c81ee722470cc0c3 Mon Sep 17 00:00:00 2001 From: doxsch <28098153+doxsch@users.noreply.github.com> Date: Wed, 17 Jan 2024 04:51:03 +0100 Subject: [PATCH 195/269] fix: added logging if repo credentials collide (#16833) Signed-off-by: doxsch <28098153+doxsch@users.noreply.github.com> --- util/db/repository_secrets.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util/db/repository_secrets.go b/util/db/repository_secrets.go index 31152300b0b8b..2d96c1c3a99eb 100644 --- a/util/db/repository_secrets.go +++ b/util/db/repository_secrets.go @@ -489,6 +489,9 @@ func (s *secretsRepositoryBackend) getRepositoryCredentialIndex(repoCredentials for i, cred := range repoCredentials { credUrl := git.NormalizeGitURL(string(cred.Data["url"])) if strings.HasPrefix(repoURL, credUrl) { + if len(credUrl) == max { + log.Warnf("Found multiple credentials for repoURL: %s", repoURL) + } if len(credUrl) > max { max = len(credUrl) idx = i From 256c2ae5dc7f1df90a78e57ece4c9b94e0501150 Mon Sep 17 00:00:00 2001 From: Sergiy Kulanov Date: Wed, 17 Jan 2024 05:51:54 +0200 Subject: [PATCH 196/269] fix(cli): add support for Application in any namespace for app wait (argoproj#16812) (#16816) Use fully qualified application names in ApplicationWaitCommand Closes: #16812 Signed-off-by: Sergiy Kulanov --- cmd/argocd/commands/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 0a54c517ca696..ccd60d1b20cf1 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -1624,7 +1624,7 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: pointer.String(selector)}) errors.CheckError(err) for _, i := range list.Items { - appNames = append(appNames, i.Name) + appNames = append(appNames, i.QualifiedName()) } } for _, appName := range appNames { From c7bf0648e5441a90ed7de85e08f5f0ba31722dca Mon Sep 17 00:00:00 2001 From: Yuan Tang Date: Wed, 17 Jan 2024 00:45:17 -0500 Subject: [PATCH 197/269] docs: Add LinkedIn badge to README.md (#16889) Signed-off-by: Yuan Tang --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ef5664de5b5b7..3374ddcfa9e1c 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ **Social:** [![Twitter Follow](https://img.shields.io/twitter/follow/argoproj?style=social)](https://twitter.com/argoproj) [![Slack](https://img.shields.io/badge/slack-argoproj-brightgreen.svg?logo=slack)](https://argoproj.github.io/community/join-slack) +[![LinkedIn](https://img.shields.io/badge/LinkedIn-argoproj-blue.svg?logo=linkedin)](https://www.linkedin.com/company/argoproj/) # Argo CD - Declarative Continuous Delivery for Kubernetes From 3997dbef8e3f9c6eb43a1aae6906a64e43514c41 Mon Sep 17 00:00:00 2001 From: Regina Scott <50851526+reginapizza@users.noreply.github.com> Date: Wed, 17 Jan 2024 14:08:41 +0000 Subject: [PATCH 198/269] update follow-redirects to 1.15.5 (#16899) Signed-off-by: Regina Scott --- ui-test/yarn.lock | 6 +++--- ui/yarn.lock | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ui-test/yarn.lock b/ui-test/yarn.lock index b80910028fb7f..c9cf7265fffe0 100644 --- a/ui-test/yarn.lock +++ b/ui-test/yarn.lock @@ -540,9 +540,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== follow-redirects@^1.14.0: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== foreach@^2.0.5: version "2.0.5" diff --git a/ui/yarn.lock b/ui/yarn.lock index 604bdfb107b04..346e47b078610 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -4520,9 +4520,9 @@ find-up@^4.0.0, find-up@^4.1.0: path-exists "^4.0.0" follow-redirects@^1.0.0: - version "1.14.9" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" - integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== for-in@^1.0.2: version "1.0.2" From d367b727c8a3cc444b356cfef495a35b01adce39 Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Wed, 17 Jan 2024 15:09:43 +0100 Subject: [PATCH 199/269] chore: allow @approvers-docs to approve readme.md (#16897) Signed-off-by: Blake Pettersson --- CODEOWNERS | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index ec72eccbf416e..83bb38871d96d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -2,9 +2,10 @@ ** @argoproj/argocd-approvers # Docs -/docs/** @argoproj/argocd-approvers @argoproj/argocd-approvers-docs -/USERS.md @argoproj/argocd-approvers @argoproj/argocd-approvers-docs -/mkdocs.yml @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/docs/** @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/USERS.md @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/README.md @argoproj/argocd-approvers @argoproj/argocd-approvers-docs +/mkdocs.yml @argoproj/argocd-approvers @argoproj/argocd-approvers-docs # CI /.github/** @argoproj/argocd-approvers @argoproj/argocd-approvers-ci From d5e119c251738afcb5c51296d00cc48e6459b6c8 Mon Sep 17 00:00:00 2001 From: Chetan Deshmukh <60215917+chetanpdeshmukh@users.noreply.github.com> Date: Wed, 17 Jan 2024 19:42:34 +0530 Subject: [PATCH 200/269] Adding CNCF blog to readme file (#16893) Signed-off-by: Chetan Deshmukh --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3374ddcfa9e1c..707848191c830 100644 --- a/README.md +++ b/README.md @@ -86,4 +86,5 @@ Participation in the Argo CD project is governed by the [CNCF Code of Conduct](h 1. [Getting Started with ArgoCD for GitOps Deployments](https://youtu.be/AvLuplh1skA) 1. [Using Argo CD & Datree for Stable Kubernetes CI/CD Deployments](https://youtu.be/17894DTru2Y) 1. [How to create Argo CD Applications Automatically using ApplicationSet? "Automation of GitOps"](https://amralaayassen.medium.com/how-to-create-argocd-applications-automatically-using-applicationset-automation-of-the-gitops-59455eaf4f72) +1. [Progressive Delivery with Service Mesh – Argo Rollouts with Istio](https://www.cncf.io/blog/2022/12/16/progressive-delivery-with-service-mesh-argo-rollouts-with-istio/) From 2b95bc0d3e3357f6571ec715496d70ba5f5f733c Mon Sep 17 00:00:00 2001 From: Ryan Flynn Date: Wed, 17 Jan 2024 12:55:27 -1000 Subject: [PATCH 201/269] docs: Update Azure AD to Entra ID (#16869) * Update Azure AD to Entra ID https://learn.microsoft.com/en-us/entra/fundamentals/new-name Signed-off-by: Ryan Flynn * Add formerly known as azuread Signed-off-by: Ryan Flynn --------- Signed-off-by: Ryan Flynn --- .../user-management/microsoft.md | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/docs/operator-manual/user-management/microsoft.md b/docs/operator-manual/user-management/microsoft.md index 33a6b3e945940..486d647fde3d0 100644 --- a/docs/operator-manual/user-management/microsoft.md +++ b/docs/operator-manual/user-management/microsoft.md @@ -1,13 +1,16 @@ # Microsoft -* [Azure AD SAML Enterprise App Auth using Dex](#azure-ad-saml-enterprise-app-auth-using-dex) -* [Azure AD App Registration Auth using OIDC](#azure-ad-app-registration-auth-using-oidc) -* [Azure AD App Registration Auth using Dex](#azure-ad-app-registration-auth-using-dex) +!!! note "" + Entra ID was formerly known as Azure AD. -## Azure AD SAML Enterprise App Auth using Dex -### Configure a new Azure AD Enterprise App +* [Entra ID SAML Enterprise App Auth using Dex](#entra-id-saml-enterprise-app-auth-using-dex) +* [Entra ID App Registration Auth using OIDC](#entra-id-app-registration-auth-using-oidc) +* [Entra ID App Registration Auth using Dex](#entra-id-app-registration-auth-using-dex) -1. From the `Azure Active Directory` > `Enterprise applications` menu, choose `+ New application` +## Entra ID SAML Enterprise App Auth using Dex +### Configure a new Entra ID Enterprise App + +1. From the `Microsoft Entra ID` > `Enterprise applications` menu, choose `+ New application` 2. Select `Non-gallery application` 3. Enter a `Name` for the application (e.g. `Argo CD`), then choose `Add` 4. Once the application is created, open it from the `Enterprise applications` menu. @@ -31,9 +34,9 @@ - *Keep a copy of the encoded output to be used in the next section.* 9. From the `Single sign-on` menu, copy the `Login URL` parameter, to be used in the next section. -### Configure Argo to use the new Azure AD Enterprise App +### Configure Argo to use the new Entra ID Enterprise App -1. Edit `argocd-cm` and add the following `dex.config` to the data section, replacing the `caData`, `my-argo-cd-url` and `my-login-url` your values from the Azure AD App: +1. Edit `argocd-cm` and add the following `dex.config` to the data section, replacing the `caData`, `my-argo-cd-url` and `my-login-url` your values from the Entra ID App: data: url: https://my-argo-cd-url @@ -56,7 +59,7 @@ groupsAttr: Group 2. Edit `argocd-rbac-cm` to configure permissions, similar to example below. - - Use Azure AD `Group IDs` for assigning roles. + - Use Entra ID `Group IDs` for assigning roles. - See [RBAC Configurations](../rbac.md) for more detailed scenarios. # example policy @@ -70,11 +73,11 @@ p, role:org-admin, repositories, delete, *, allow g, "84ce98d1-e359-4f3b-85af-985b458de3c6", role:org-admin # (azure group assigned to role) -## Azure AD App Registration Auth using OIDC -### Configure a new Azure AD App registration -#### Add a new Azure AD App registration +## Entra ID App Registration Auth using OIDC +### Configure a new Entra ID App registration +#### Add a new Entra ID App registration -1. From the `Azure Active Directory` > `App registrations` menu, choose `+ New registration` +1. From the `Microsoft Entra ID` > `App registrations` menu, choose `+ New registration` 2. Enter a `Name` for the application (e.g. `Argo CD`). 3. Specify who can use the application (e.g. `Accounts in this organizational directory only`). 4. Enter Redirect URI (optional) as follows (replacing `my-argo-cd-url` with your Argo URL), then choose `Add`. @@ -92,29 +95,29 @@ - **Redirect URI:** `http://localhost:8085/auth/callback` ![Azure App registration's Authentication](../../assets/azure-app-registration-authentication.png "Azure App registration's Authentication") -#### Add credentials a new Azure AD App registration +#### Add credentials a new Entra ID App registration 1. From the `Certificates & secrets` menu, choose `+ New client secret` 2. Enter a `Name` for the secret (e.g. `ArgoCD-SSO`). - Make sure to copy and save generated value. This is a value for the `client_secret`. ![Azure App registration's Secret](../../assets/azure-app-registration-secret.png "Azure App registration's Secret") -#### Setup permissions for Azure AD Application +#### Setup permissions for Entra ID Application 1. From the `API permissions` menu, choose `+ Add a permission` 2. Find `User.Read` permission (under `Microsoft Graph`) and grant it to the created application: - ![Azure AD API permissions](../../assets/azure-api-permissions.png "Azure AD API permissions") + ![Entra ID API permissions](../../assets/azure-api-permissions.png "Entra ID API permissions") 3. From the `Token Configuration` menu, choose `+ Add groups claim` - ![Azure AD token configuration](../../assets/azure-token-configuration.png "Azure AD token configuration") + ![Entra ID token configuration](../../assets/azure-token-configuration.png "Entra ID token configuration") -### Associate an Azure AD group to your Azure AD App registration +### Associate an Entra ID group to your Entra ID App registration -1. From the `Azure Active Directory` > `Enterprise applications` menu, search the App that you created (e.g. `Argo CD`). - - An Enterprise application with the same name of the Azure AD App registration is created when you add a new Azure AD App registration. +1. From the `Microsoft Entra ID` > `Enterprise applications` menu, search the App that you created (e.g. `Argo CD`). + - An Enterprise application with the same name of the Entra ID App registration is created when you add a new Entra ID App registration. 2. From the `Users and groups` menu of the app, add any users or groups requiring access to the service. ![Azure Enterprise SAML Users](../../assets/azure-enterprise-users.png "Azure Enterprise SAML Users") -### Configure Argo to use the new Azure AD App registration +### Configure Argo to use the new Entra ID App registration 1. Edit `argocd-cm` and configure the `data.oidc.config` and `data.url` section: @@ -173,7 +176,7 @@ Refer to [operator-manual/argocd-rbac-cm.yaml](https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-rbac-cm.yaml) for all of the available variables. -## Azure AD App Registration Auth using Dex +## Entra ID App Registration Auth using Dex Configure a new AD App Registration, as above. Then, add the `dex.config` to `argocd-cm`: @@ -200,9 +203,9 @@ data: 1. Open a new browser tab and enter your ArgoCD URI: https://`` ![Azure SSO Web Log In](../../assets/azure-sso-web-log-in-via-azure.png "Azure SSO Web Log In") -3. Click `LOGIN VIA AZURE` button to log in with your Azure Active Directory account. You’ll see the ArgoCD applications screen. +3. Click `LOGIN VIA AZURE` button to log in with your Microsoft Entra ID account. You’ll see the ArgoCD applications screen. ![Azure SSO Web Application](../../assets/azure-sso-web-application.png "Azure SSO Web Application") -4. Navigate to User Info and verify Group ID. Groups will have your group’s Object ID that you added in the `Setup permissions for Azure AD Application` step. +4. Navigate to User Info and verify Group ID. Groups will have your group’s Object ID that you added in the `Setup permissions for Entra ID Application` step. ![Azure SSO Web User Info](../../assets/azure-sso-web-user-info.png "Azure SSO Web User Info") ### Log in to ArgoCD using CLI From 65869a3860c7555b3ea7a962db44cc9b05f7e333 Mon Sep 17 00:00:00 2001 From: Aymen Ben Tanfous Date: Thu, 18 Jan 2024 10:27:14 +0100 Subject: [PATCH 202/269] chore: Preventing runnings jobs when updating documentation (#16706) * Preventing runnings jobs when updating documentation Signed-off-by: Aymen Ben Tanfous * Empty line added to .md file Signed-off-by: Aymen Ben Tanfous --------- Signed-off-by: Aymen Ben Tanfous Co-authored-by: Aymen Ben Tanfous --- .github/pull_request_template.md | 2 +- .github/workflows/ci-build.yaml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c1a3f42508aaa..fb499c253f365 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -21,4 +21,4 @@ Checklist: * [ ] Optional. My organization is added to USERS.md. * [ ] Optional. For bug fixes, I've indicated what older releases this fix should be cherry-picked into (this may or may not happen depending on risk/complexity). - + \ No newline at end of file diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 3a596a9552d70..f9dff564ff594 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -1,12 +1,17 @@ name: Integration tests + on: push: + paths-ignore: + - '*.md' branches: - 'master' - 'release-*' - '!release-1.4' - '!release-1.5' pull_request: + paths-ignore: + - '*.md' branches: - 'master' - 'release-*' From f0cbf516fc72396db23b5920a0855364f7707a4a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 10:25:06 -0500 Subject: [PATCH 203/269] chore(deps): bump github.com/go-git/go-git/v5 from 5.8.1 to 5.11.0 (#16711) Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git) from 5.8.1 to 5.11.0. - [Release notes](https://github.com/go-git/go-git/releases) - [Commits](https://github.com/go-git/go-git/compare/v5.8.1...v5.11.0) --- updated-dependencies: - dependency-name: github.com/go-git/go-git/v5 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 07dd99e4beff1..57fd30124afc1 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/evanphx/json-patch v5.6.0+incompatible github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e - github.com/go-git/go-git/v5 v5.10.1 + github.com/go-git/go-git/v5 v5.11.0 github.com/go-logr/logr v1.3.0 github.com/go-openapi/loads v0.21.2 github.com/go-openapi/runtime v0.26.0 @@ -267,7 +267,7 @@ require ( go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.18.0 + golang.org/x/net v0.19.0 golang.org/x/sys v0.15.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.3.0 diff --git a/go.sum b/go.sum index 0c5e889f6bdf6..14b7b57c1f2ac 100644 --- a/go.sum +++ b/go.sum @@ -927,8 +927,8 @@ github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+ github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.10.1 h1:tu8/D8i+TWxgKpzQ3Vc43e+kkhXqtsZCKI/egajKnxk= -github.com/go-git/go-git/v5 v5.10.1/go.mod h1:uEuHjxkHap8kAl//V5F/nNWwqIYtP/402ddd05mp0wg= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -1960,8 +1960,8 @@ golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= 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= From 8a0bf41863bafbd8d81c6a97491b0501042e34ac Mon Sep 17 00:00:00 2001 From: Sergiy Kulanov Date: Thu, 18 Jan 2024 17:57:16 +0200 Subject: [PATCH 204/269] fix(cli): add support for Application in any namespace for `app delete` cmd (#16898) Use fully qualified application names when operate with Applications Closes: #16896 Signed-off-by: Sergiy Kulanov --- cmd/argocd/commands/app.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index ccd60d1b20cf1..8e49fbc0e29e1 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -1995,7 +1995,7 @@ func getAppNamesBySelector(ctx context.Context, appIf application.ApplicationSer return []string{}, fmt.Errorf("no apps match selector %v", selector) } for _, i := range list.Items { - appNames = append(appNames, i.Name) + appNames = append(appNames, i.QualifiedName()) } } return appNames, nil From 80683acb71ff49f439c838418ec7752115d37076 Mon Sep 17 00:00:00 2001 From: Aymen Ben Tanfous Date: Fri, 19 Jan 2024 16:12:22 +0100 Subject: [PATCH 205/269] docs: Fixed Slugify doc in GoTemplate.md (#16685) * docs: Fixed Slugify doc in GoTemplate.md Signed-off-by: Aymen Ben Tanfous * Update docs/operator-manual/applicationset/GoTemplate.md Co-authored-by: Blake Pettersson Signed-off-by: Aymen Ben Tanfous * Update docs/operator-manual/applicationset/GoTemplate.md Co-authored-by: Blake Pettersson Signed-off-by: Aymen Ben Tanfous --------- Signed-off-by: Aymen Ben Tanfous Co-authored-by: Blake Pettersson --- docs/operator-manual/applicationset/GoTemplate.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/operator-manual/applicationset/GoTemplate.md b/docs/operator-manual/applicationset/GoTemplate.md index 4a2b6cf55140b..1d62eeea9f93a 100644 --- a/docs/operator-manual/applicationset/GoTemplate.md +++ b/docs/operator-manual/applicationset/GoTemplate.md @@ -12,7 +12,7 @@ An additional `normalize` function makes any string parameter usable as a valid with hyphens and truncating at 253 characters. This is useful when making parameters safe for things like Application names. -Another function has `slugify` function has been added which, by default, sanitizes and smart truncate (means doesn't cut a word into 2). This function accepts a couple of arguments: +Another `slugify` function has been added which, by default, sanitizes and smart truncates (it doesn't cut a word into 2). This function accepts a couple of arguments: - The first argument (if provided) is an integer specifying the maximum length of the slug. - The second argument (if provided) is a boolean indicating whether smart truncation is enabled. - The last argument (if provided) is the input name that needs to be slugified. @@ -206,6 +206,8 @@ ApplicationSet controller provides: 1. contains no more than 253 characters 2. contains only lowercase alphanumeric characters, '-' or '.' 3. starts and ends with an alphanumeric character + +- `slugify`: sanitizes like `normalize` and smart truncates (it doesn't cut a word into 2) like described in the [introduction](#introduction) section. - `toYaml` / `fromYaml` / `fromYamlArray` helm like functions From 32e373829ba3e69dea216056c80f490ecd2c6264 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Fri, 19 Jan 2024 20:44:38 +0530 Subject: [PATCH 206/269] Initialize & send forceHttpBasicAuth & enableOCI params correctly during repo update from UI (#16794) --- .../app/settings/components/repo-details/repo-details.tsx | 3 ++- ui/src/app/shared/services/repo-service.ts | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ui/src/app/settings/components/repo-details/repo-details.tsx b/ui/src/app/settings/components/repo-details/repo-details.tsx index 6075dfbde3b22..25fa983172700 100644 --- a/ui/src/app/settings/components/repo-details/repo-details.tsx +++ b/ui/src/app/settings/components/repo-details/repo-details.tsx @@ -65,7 +65,8 @@ export const RepoDetails = (props: {repo: models.Repository; save?: (params: New enableLfs: repo.enableLfs || false, proxy: repo.proxy || '', project: repo.project || '', - enableOCI: repo.enableOCI || false + enableOCI: repo.enableOCI || false, + forceHttpBasicAuth: repo.forceHttpBasicAuth || false }; return ( diff --git a/ui/src/app/shared/services/repo-service.ts b/ui/src/app/shared/services/repo-service.ts index 09f8c169ac9ae..94378bee8352b 100644 --- a/ui/src/app/shared/services/repo-service.ts +++ b/ui/src/app/shared/services/repo-service.ts @@ -62,7 +62,9 @@ export class RepositoriesService { insecure, enableLfs, proxy, - project + project, + forceHttpBasicAuth, + enableOCI }: { type: string; name: string; @@ -75,10 +77,12 @@ export class RepositoriesService { enableLfs: boolean; proxy: string; project?: string; + forceHttpBasicAuth?: boolean; + enableOCI: boolean; }): Promise { return requests .put(`/repositories/${encodeURIComponent(url)}`) - .send({type, name, repo: url, username, password, tlsClientCertData, tlsClientCertKey, insecure, enableLfs, proxy, project}) + .send({type, name, repo: url, username, password, tlsClientCertData, tlsClientCertKey, insecure, enableLfs, proxy, project, forceHttpBasicAuth, enableOCI}) .then(res => res.body as models.Repository); } From 21c384f42354ada2b94c18773104527eb27f86bc Mon Sep 17 00:00:00 2001 From: 1102 <90682513+nueavv@users.noreply.github.com> Date: Sat, 20 Jan 2024 01:20:10 +0900 Subject: [PATCH 207/269] feat(health): support for distribution aws.crossplane.io resource (#16827) Signed-off-by: nueavv --- .../Distribution/health.lua | 42 ++++++++ .../Distribution/health_test.yaml | 37 +++++++ .../testdata/degraded_reconcileError.yaml | 96 +++++++++++++++++++ .../Distribution/testdata/healthy.yaml | 92 ++++++++++++++++++ .../Distribution/testdata/progressing.yaml | 92 ++++++++++++++++++ .../testdata/progressing_creating.yaml | 92 ++++++++++++++++++ .../testdata/progressing_noStatus.yaml | 82 ++++++++++++++++ .../testdata/progressing_noavailable.yaml | 88 +++++++++++++++++ .../Distribution/testdata/suspended.yaml | 94 ++++++++++++++++++ 9 files changed, 715 insertions(+) create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/health.lua create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/health_test.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/degraded_reconcileError.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/healthy.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_creating.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noStatus.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noavailable.yaml create mode 100644 resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/suspended.yaml diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/health.lua b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/health.lua new file mode 100644 index 0000000000000..3e07226b3cf89 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/health.lua @@ -0,0 +1,42 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for distribution to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for distribution to be created" +return hs \ No newline at end of file diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/health_test.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/health_test.yaml new file mode 100644 index 0000000000000..981a6000ecb88 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/health_test.yaml @@ -0,0 +1,37 @@ +tests: +- healthStatus: + status: Progressing + message: Waiting for distribution to be available + inputPath: testdata/progressing_creating.yaml +- healthStatus: + status: Progressing + message: Waiting for distribution to be available + inputPath: testdata/progressing_noavailable.yaml +- healthStatus: + status: Progressing + message: Waiting for distribution to be available + inputPath: testdata/progressing.yaml +- healthStatus: + status: Progressing + message: Waiting for distribution to be created + inputPath: testdata/progressing_noStatus.yaml +- healthStatus: + status: Degraded + message: > + update failed: cannot update Distribution in AWS: InvalidParameter: 2 + validation error(s) found. + + - missing required field, + UpdateDistributionInput.DistributionConfig.Origins.Items[0].DomainName. + + - missing required field, + UpdateDistributionInput.DistributionConfig.Origins.Items[0].Id. + inputPath: testdata/degraded_reconcileError.yaml +- healthStatus: + status: Suspended + message: ReconcilePaused + inputPath: testdata/suspended.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/degraded_reconcileError.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/degraded_reconcileError.yaml new file mode 100644 index 0000000000000..80ea7930574ac --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/degraded_reconcileError.yaml @@ -0,0 +1,96 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + creationTimestamp: '2024-01-17T07:26:02Z' + generation: 2 + name: crossplane.io + resourceVersion: '261942288' + uid: 4b50c88b-165c-4176-be8e-aa28fdec0a94 +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - HEAD + - GET + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: '' + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: '' + enabled: false + includeCookies: false + prefix: '' + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane +status: + conditions: + - lastTransitionTime: '2024-01-17T07:26:02Z' + message: > + update failed: cannot update Distribution in AWS: InvalidParameter: 2 + validation error(s) found. + + - missing required field, + UpdateDistributionInput.DistributionConfig.Origins.Items[0].DomainName. + + - missing required field, + UpdateDistributionInput.DistributionConfig.Origins.Items[0].Id. + reason: ReconcileError + status: 'False' + type: Synced + - lastTransitionTime: '2024-01-17T07:26:03Z' + reason: Available + status: 'True' + type: Ready diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/healthy.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/healthy.yaml new file mode 100644 index 0000000000000..23d0287445e83 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/healthy.yaml @@ -0,0 +1,92 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + creationTimestamp: "2023-09-07T01:01:16Z" + generation: 121 + name: crossplane.io + resourceVersion: "254225966" + uid: 531d989c-a3d2-4ab4-841d-ab380cce0bdb +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - HEAD + - GET + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: '' + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: '' + enabled: false + includeCookies: false + prefix: '' + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customHeaders: {} + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + domainName: crossplane.io + id: crossplane.io + originShield: + enabled: false + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane +status: + conditions: + - lastTransitionTime: "2024-01-11T06:23:18Z" + reason: ReconcileSuccess + status: "True" + type: Synced + - lastTransitionTime: "2024-01-10T03:23:02Z" + reason: Available + status: "True" + type: Ready diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing.yaml new file mode 100644 index 0000000000000..3dbde7e040867 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing.yaml @@ -0,0 +1,92 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + creationTimestamp: '2023-06-16T04:42:04Z' + generation: 37 + name: crossplane.io + resourceVersion: '254326453' + uid: fd357670-b762-4285-ae83-00859c40dd6b +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - GET + - HEAD + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: "" + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: "" + enabled: false + includeCookies: false + prefix: "" + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customHeaders: {} + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + domainName: crossplane.io + id: crossplane.io + originShield: + enabled: false + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane +status: + conditions: + - lastTransitionTime: '2024-01-11T08:11:27Z' + reason: Unavailable + status: 'False' + type: Ready + - lastTransitionTime: '2024-01-11T08:11:02Z' + reason: ReconcileSuccess + status: 'True' + type: Synced diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_creating.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_creating.yaml new file mode 100644 index 0000000000000..122ab330d593b --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_creating.yaml @@ -0,0 +1,92 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + creationTimestamp: "2023-09-07T01:01:16Z" + generation: 121 + name: crossplane.io + resourceVersion: "254225966" + uid: 531d989c-a3d2-4ab4-841d-ab380cce0bdb +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - GET + - HEAD + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: "" + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: "" + enabled: false + includeCookies: false + prefix: "" + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customHeaders: {} + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + domainName: crossplane.io + id: crossplane.io + originShield: + enabled: false + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane +status: + conditions: + - lastTransitionTime: "2023-11-16T04:44:27Z" + reason: Creating + status: "False" + type: Ready + - lastTransitionTime: "2023-11-16T04:44:25Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noStatus.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noStatus.yaml new file mode 100644 index 0000000000000..2985ec2dea657 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noStatus.yaml @@ -0,0 +1,82 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + creationTimestamp: "2023-09-07T01:01:16Z" + generation: 121 + name: crossplane.io + resourceVersion: "254225966" + uid: 531d989c-a3d2-4ab4-841d-ab380cce0bdb +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - GET + - HEAD + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: "" + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: "" + enabled: false + includeCookies: false + prefix: "" + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customHeaders: {} + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + domainName: crossplane.io + id: crossplane.io + originShield: + enabled: false + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noavailable.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noavailable.yaml new file mode 100644 index 0000000000000..7a47b0f48eea7 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/progressing_noavailable.yaml @@ -0,0 +1,88 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + generation: 1 + name: crossplane.io + resourceVersion: "261937039" + uid: a52c105f-b0e1-4027-aa19-7e93f269f2a6 +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - GET + - HEAD + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: "" + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: "" + enabled: false + includeCookies: false + prefix: "" + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customHeaders: {} + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + domainName: crossplane.io + id: crossplane.io + originShield: + enabled: false + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane +status: + atProvider: {} + conditions: + - lastTransitionTime: "2024-01-17T07:20:35Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/suspended.yaml b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/suspended.yaml new file mode 100644 index 0000000000000..d15713737ff72 --- /dev/null +++ b/resource_customizations/cloudfront.aws.crossplane.io/Distribution/testdata/suspended.yaml @@ -0,0 +1,94 @@ +apiVersion: cloudfront.aws.crossplane.io/v1alpha1 +kind: Distribution +metadata: + annotations: + crossplane.io/paused: "true" + creationTimestamp: "2023-06-16T04:42:04Z" + generation: 34 + name: crossplane.io + resourceVersion: "254259056" + uid: fd357670-b762-4285-ae83-00859c40dd6b +spec: + deletionPolicy: Orphan + forProvider: + distributionConfig: + comment: 'crossplane' + customErrorResponses: + items: [] + defaultCacheBehavior: + allowedMethods: + cachedMethods: + items: + - HEAD + - GET + items: + - GET + - HEAD + compress: false + defaultTTL: 600 + fieldLevelEncryptionID: "" + forwardedValues: + cookies: + forward: none + headers: + items: [] + queryString: false + queryStringCacheKeys: {} + functionAssociations: {} + lambdaFunctionAssociations: {} + maxTTL: 600 + minTTL: 0 + smoothStreaming: false + targetOriginID: crossplane.io + trustedKeyGroups: + enabled: false + trustedSigners: + enabled: false + viewerProtocolPolicy: allow-all + defaultRootObject: index.html + enabled: true + httpVersion: http2 + isIPV6Enabled: true + logging: + bucket: "" + enabled: false + includeCookies: false + prefix: "" + originGroups: {} + origins: + items: + - connectionAttempts: 3 + connectionTimeout: 10 + customHeaders: {} + customOriginConfig: + httpPort: 8080 + httpSPort: 443 + originKeepaliveTimeout: 5 + originProtocolPolicy: http-only + originReadTimeout: 10 + originSSLProtocols: + items: + - TLSv1 + - TLSv1.1 + - TLSv1.2 + domainName: crossplane.io + id: crossplane.io + originShield: + enabled: false + priceClass: PriceClass_200 + restrictions: + geoRestriction: + restrictionType: none + region: ap-northeast-2 + providerConfigRef: + name: crossplane +status: + conditions: + - lastTransitionTime: "2023-10-16T07:40:47Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2024-01-11T06:59:47Z" + reason: ReconcilePaused + status: "False" + type: Synced From 9ecc5aec2a4dba485eb8b5b0ab75fff8927b3418 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:47:14 -0500 Subject: [PATCH 208/269] fix(ui): set content-type for certain UI requests (#16923) (#16930) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- ui/src/app/shared/services/requests.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/src/app/shared/services/requests.ts b/ui/src/app/shared/services/requests.ts index 207917a318529..4df6d1e4ddf19 100644 --- a/ui/src/app/shared/services/requests.ts +++ b/ui/src/app/shared/services/requests.ts @@ -51,19 +51,19 @@ export default { }, post(url: string) { - return initHandlers(agent.post(`${apiRoot()}${url}`)); + return initHandlers(agent.post(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); }, put(url: string) { - return initHandlers(agent.put(`${apiRoot()}${url}`)); + return initHandlers(agent.put(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); }, patch(url: string) { - return initHandlers(agent.patch(`${apiRoot()}${url}`)); + return initHandlers(agent.patch(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); }, delete(url: string) { - return initHandlers(agent.del(`${apiRoot()}${url}`)); + return initHandlers(agent.del(`${apiRoot()}${url}`)).set('Content-Type', 'application/json'); }, loadEventSource(url: string): Observable { From 7302a52ea13dd54d56d4657612d74dc652e48f5b Mon Sep 17 00:00:00 2001 From: Alexandre Gaudreault Date: Sun, 21 Jan 2024 01:22:32 -0500 Subject: [PATCH 209/269] feat(controller): add sync jitter(#14241) (#16820) * feat(controller): add sync jitter Signed-off-by: Alexandre Gaudreault * convert to duration for simplicity Signed-off-by: Alexandre Gaudreault * docs Signed-off-by: Alexandre Gaudreault * add config to manifests Signed-off-by: Alexandre Gaudreault * fix tests Signed-off-by: Alexandre Gaudreault --------- Signed-off-by: Alexandre Gaudreault --- .../commands/argocd_application_controller.go | 3 ++ controller/appcontroller.go | 26 +++++++++++--- controller/appcontroller_test.go | 2 ++ docs/faq.md | 14 ++++---- docs/operator-manual/high_availability.md | 35 ++++++++++++------- .../argocd-application-controller.md | 1 + ...ocd-application-controller-deployment.yaml | 6 ++++ ...cd-application-controller-statefulset.yaml | 6 ++++ manifests/core-install.yaml | 6 ++++ manifests/ha/install.yaml | 6 ++++ manifests/ha/namespace-install.yaml | 6 ++++ manifests/install.yaml | 6 ++++ manifests/namespace-install.yaml | 6 ++++ 13 files changed, 99 insertions(+), 24 deletions(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 135bcab3a7298..8004340250611 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -50,6 +50,7 @@ func NewCommand() *cobra.Command { clientConfig clientcmd.ClientConfig appResyncPeriod int64 appHardResyncPeriod int64 + appResyncJitter int64 repoErrorGracePeriod int64 repoServerAddress string repoServerTimeoutSeconds int @@ -157,6 +158,7 @@ func NewCommand() *cobra.Command { kubectl, resyncDuration, hardResyncDuration, + time.Duration(appResyncJitter)*time.Second, time.Duration(selfHealTimeoutSeconds)*time.Second, time.Duration(repoErrorGracePeriod)*time.Second, metricsPort, @@ -194,6 +196,7 @@ func NewCommand() *cobra.Command { clientConfig = cli.AddKubectlFlagsToCmd(&command) command.Flags().Int64Var(&appResyncPeriod, "app-resync", int64(env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_TIMEOUT", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Time period in seconds for application resync.") command.Flags().Int64Var(&appHardResyncPeriod, "app-hard-resync", int64(env.ParseDurationFromEnv("ARGOCD_HARD_RECONCILIATION_TIMEOUT", defaultAppHardResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Time period in seconds for application hard resync.") + command.Flags().Int64Var(&appResyncJitter, "app-resync-jitter", int64(env.ParseDurationFromEnv("ARGOCD_RECONCILIATION_JITTER", 0*time.Second, 0, math.MaxInt64).Seconds()), "Maximum time period in seconds to add as a delay jitter for application resync.") command.Flags().Int64Var(&repoErrorGracePeriod, "repo-error-grace-period-seconds", int64(env.ParseDurationFromEnv("ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS", defaultAppResyncPeriod*time.Second, 0, math.MaxInt64).Seconds()), "Grace period in seconds for ignoring consecutive errors while communicating with repo server.") command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address.") command.Flags().IntVar(&repoServerTimeoutSeconds, "repo-server-timeout-seconds", env.ParseNumFromEnv("ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS", 60, 0, math.MaxInt64), "Repo server RPC call timeout seconds.") diff --git a/controller/appcontroller.go b/controller/appcontroller.go index c3498f831566c..e6dbda4194f02 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -6,6 +6,7 @@ import ( goerrors "errors" "fmt" "math" + "math/rand" "net/http" "reflect" "runtime/debug" @@ -118,6 +119,7 @@ type ApplicationController struct { stateCache statecache.LiveStateCache statusRefreshTimeout time.Duration statusHardRefreshTimeout time.Duration + statusRefreshJitter time.Duration selfHealTimeout time.Duration repoClientset apiclient.Clientset db db.ArgoDB @@ -142,6 +144,7 @@ func NewApplicationController( kubectl kube.Kubectl, appResyncPeriod time.Duration, appHardResyncPeriod time.Duration, + appResyncJitter time.Duration, selfHealTimeout time.Duration, repoErrorGracePeriod time.Duration, metricsPort int, @@ -154,7 +157,7 @@ func NewApplicationController( rateLimiterConfig *ratelimiter.AppControllerRateLimiterConfig, serverSideDiff bool, ) (*ApplicationController, error) { - log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v", appResyncPeriod, appHardResyncPeriod) + log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter) db := db.NewDB(namespace, settingsMgr, kubeClientset) if rateLimiterConfig == nil { rateLimiterConfig = ratelimiter.GetDefaultAppRateLimiterConfig() @@ -174,6 +177,7 @@ func NewApplicationController( db: db, statusRefreshTimeout: appResyncPeriod, statusHardRefreshTimeout: appHardResyncPeriod, + statusRefreshJitter: appResyncJitter, refreshRequestedApps: make(map[string]CompareWith), refreshRequestedAppsMutex: &sync.Mutex{}, auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController), @@ -1643,6 +1647,7 @@ func (ctrl *ApplicationController) needRefreshAppStatus(app *appv1.Application, var reason string compareWith := CompareWithLatest refreshType := appv1.RefreshTypeNormal + softExpired := app.Status.ReconciledAt == nil || app.Status.ReconciledAt.Add(statusRefreshTimeout).Before(time.Now().UTC()) hardExpired := (app.Status.ReconciledAt == nil || app.Status.ReconciledAt.Add(statusHardRefreshTimeout).Before(time.Now().UTC())) && statusHardRefreshTimeout.Seconds() != 0 @@ -2095,14 +2100,25 @@ func (ctrl *ApplicationController) newApplicationInformerAndLister() (cache.Shar if err != nil { return } + var compareWith *CompareWith + var delay *time.Duration + oldApp, oldOK := old.(*appv1.Application) newApp, newOK := new.(*appv1.Application) - if oldOK && newOK && automatedSyncEnabled(oldApp, newApp) { - log.WithField("application", newApp.QualifiedName()).Info("Enabled automated sync") - compareWith = CompareWithLatest.Pointer() + if oldOK && newOK { + if automatedSyncEnabled(oldApp, newApp) { + log.WithField("application", newApp.QualifiedName()).Info("Enabled automated sync") + compareWith = CompareWithLatest.Pointer() + } + if ctrl.statusRefreshJitter != 0 && oldApp.ResourceVersion == newApp.ResourceVersion { + // Handler is refreshing the apps, add a random jitter to spread the load and avoid spikes + jitter := time.Duration(float64(ctrl.statusRefreshJitter) * rand.Float64()) + delay = &jitter + } } - ctrl.requestAppRefresh(newApp.QualifiedName(), compareWith, nil) + + ctrl.requestAppRefresh(newApp.QualifiedName(), compareWith, delay) ctrl.appOperationQueue.AddRateLimited(key) }, DeleteFunc: func(obj interface{}) { diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 131c1deab99b0..4162a9983e941 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -144,6 +144,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { kubectl, time.Minute, time.Hour, + time.Second, time.Minute, time.Second*10, common.DefaultPortArgoCDMetrics, @@ -154,6 +155,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { nil, data.applicationNamespaces, nil, + false, ) db := &dbmocks.ArgoDB{} diff --git a/docs/faq.md b/docs/faq.md index 95205ae6bbb4e..83bdf8d7d38b5 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -36,7 +36,7 @@ which might cause health check to return `Progressing` state instead of `Healthy As workaround Argo CD allows providing [health check](operator-manual/health.md) customization which overrides default behavior. -If you are using Traefik for your Ingress, you can update the Traefik config to publish the loadBalancer IP using [publishedservice](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice), which will resolve this issue. +If you are using Traefik for your Ingress, you can update the Traefik config to publish the loadBalancer IP using [publishedservice](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#publishedservice), which will resolve this issue. ```yaml providers: @@ -97,7 +97,7 @@ data: ## After deploying my Helm application with Argo CD I cannot see it with `helm ls` and other Helm commands -When deploying a Helm application Argo CD is using Helm +When deploying a Helm application Argo CD is using Helm only as a template mechanism. It runs `helm template` and then deploys the resulting manifests on the cluster instead of doing `helm install`. This means that you cannot use any Helm command to view/verify the application. It is fully managed by Argo CD. @@ -140,15 +140,15 @@ Argo CD automatically sets the `app.kubernetes.io/instance` label and uses it to If the tool does this too, this causes confusion. You can change this label by setting the `application.instanceLabelKey` value in the `argocd-cm`. We recommend that you use `argocd.argoproj.io/instance`. -!!! note +!!! note When you make this change your applications will become out of sync and will need re-syncing. See [#1482](https://github.com/argoproj/argo-cd/issues/1482). ## How often does Argo CD check for changes to my Git or Helm repository ? -The default polling interval is 3 minutes (180 seconds). -You can change the setting by updating the `timeout.reconciliation` value in the [argocd-cm](https://github.com/argoproj/argo-cd/blob/2d6ce088acd4fb29271ffb6f6023dbb27594d59b/docs/operator-manual/argocd-cm.yaml#L279-L282) config map. If there are any Git changes, Argo CD will only update applications with the [auto-sync setting](user-guide/auto_sync.md) enabled. If you set it to `0` then Argo CD will stop polling Git repositories automatically and you can only use alternative methods such as [webhooks](operator-manual/webhook.md) and/or manual syncs for deploying applications. +The default polling interval is 3 minutes (180 seconds) with a configurable jitter. +You can change the setting by updating the `timeout.reconciliation` value and the `timeout.reconciliation.jitter` in the [argocd-cm](https://github.com/argoproj/argo-cd/blob/2d6ce088acd4fb29271ffb6f6023dbb27594d59b/docs/operator-manual/argocd-cm.yaml#L279-L282) config map. If there are any Git changes, Argo CD will only update applications with the [auto-sync setting](user-guide/auto_sync.md) enabled. If you set it to `0` then Argo CD will stop polling Git repositories automatically and you can only use alternative methods such as [webhooks](operator-manual/webhook.md) and/or manual syncs for deploying applications. ## Why Are My Resource Limits `Out Of Sync`? @@ -250,7 +250,7 @@ There are two parts to the message: > map[name:**KEY_BC** value:150] map[name:**KEY_BC** value:500] map[name:**KEY_BD** value:250] map[name:**KEY_BD** value:500] map[name:KEY_BI value:something] - You'll want to identify the keys that are duplicated -- you can focus on the first part, as each duplicated key will appear, once for each of its value with its value in the first list. The second list is really just + You'll want to identify the keys that are duplicated -- you can focus on the first part, as each duplicated key will appear, once for each of its value with its value in the first list. The second list is really just `]` @@ -259,7 +259,7 @@ There are two parts to the message: This includes all of the keys. It's included for debugging purposes -- you don't need to pay much attention to it. It will give you a hint about the precise location in the list for the duplicated keys: > map[name:KEY_AA] map[name:KEY_AB] map[name:KEY_AC] map[name:KEY_AD] map[name:KEY_AE] map[name:KEY_AF] map[name:KEY_AG] map[name:KEY_AH] map[name:KEY_AI] map[name:KEY_AJ] map[name:KEY_AK] map[name:KEY_AL] map[name:KEY_AM] map[name:KEY_AN] map[name:KEY_AO] map[name:KEY_AP] map[name:KEY_AQ] map[name:KEY_AR] map[name:KEY_AS] map[name:KEY_AT] map[name:KEY_AU] map[name:KEY_AV] map[name:KEY_AW] map[name:KEY_AX] map[name:KEY_AY] map[name:KEY_AZ] map[name:KEY_BA] map[name:KEY_BB] map[name:**KEY_BC**] map[name:**KEY_BD**] map[name:KEY_BE] map[name:KEY_BF] map[name:KEY_BG] map[name:KEY_BH] map[name:KEY_BI] map[name:**KEY_BC**] map[name:**KEY_BD**] - + `]` In this case, the duplicated keys have been **emphasized** to help you identify the problematic keys. Many editors have the ability to highlight all instances of a string, using such an editor can help with such problems. diff --git a/docs/operator-manual/high_availability.md b/docs/operator-manual/high_availability.md index b2051ad1a152c..0a011104967f1 100644 --- a/docs/operator-manual/high_availability.md +++ b/docs/operator-manual/high_availability.md @@ -57,7 +57,7 @@ performance. For performance reasons the controller monitors and caches only the preferred version into a version of the resource stored in Git. If `kubectl convert` fails because the conversion is not supported then the controller falls back to Kubernetes API query which slows down reconciliation. In this case, we advise to use the preferred resource version in Git. -* The controller polls Git every 3m by default. You can change this duration using the `timeout.reconciliation` setting in the `argocd-cm` ConfigMap. The value of `timeout.reconciliation` is a duration string e.g `60s`, `1m`, `1h` or `1d`. +* The controller polls Git every 3m by default. You can change this duration using the `timeout.reconciliation` and `timeout.reconciliation.jitter` setting in the `argocd-cm` ConfigMap. The value of the fields is a duration string e.g `60s`, `1m`, `1h` or `1d`. * If the controller is managing too many clusters and uses too much memory then you can shard clusters across multiple controller replicas. To enable sharding, increase the number of replicas in `argocd-application-controller` `StatefulSet` @@ -244,30 +244,41 @@ spec: # ... ``` +### Application Sync Timeout & Jitter + +Argo CD has a timeout for application syncs. It will trigger a refresh for each application periodically when the timeout expires. +With a large number of applications, this will cause a spike in the refresh queue and can cause a spike to the repo-server component. To avoid this, you can set a jitter to the sync timeout which will spread out the refreshes and give time to the repo-server to catch up. + +The jitter is the maximum duration that can be added to the sync timeout, so if the sync timeout is 5 minutes and the jitter is 1 minute, then the actual timeout will be between 5 and 6 minutes. + +To configure the jitter you can set the following environment variables: + +* `ARGOCD_RECONCILIATION_JITTER` - The jitter to apply to the sync timeout. Disabled when value is 0. Defaults to 0. + ## Rate Limiting Application Reconciliations -To prevent high controller resource usage or sync loops caused either due to misbehaving apps or other environment specific factors, +To prevent high controller resource usage or sync loops caused either due to misbehaving apps or other environment specific factors, we can configure rate limits on the workqueues used by the application controller. There are two types of rate limits that can be configured: * Global rate limits * Per item rate limits -The final rate limiter uses a combination of both and calculates the final backoff as `max(globalBackoff, perItemBackoff)`. +The final rate limiter uses a combination of both and calculates the final backoff as `max(globalBackoff, perItemBackoff)`. ### Global rate limits This is enabled by default, it is a simple bucket based rate limiter that limits the number of items that can be queued per second. -This is useful to prevent a large number of apps from being queued at the same time. - +This is useful to prevent a large number of apps from being queued at the same time. + To configure the bucket limiter you can set the following environment variables: * `WORKQUEUE_BUCKET_SIZE` - The number of items that can be queued in a single burst. Defaults to 500. * `WORKQUEUE_BUCKET_QPS` - The number of items that can be queued per second. Defaults to 50. -### Per item rate limits +### Per item rate limits - This by default returns a fixed base delay/backoff value but can be configured to return exponential values, read further to understand it's working. -Per item rate limiter limits the number of times a particular item can be queued. This is based on exponential backoff where the backoff time for an item keeps increasing exponentially + This by default returns a fixed base delay/backoff value but can be configured to return exponential values. +Per item rate limiter limits the number of times a particular item can be queued. This is based on exponential backoff where the backoff time for an item keeps increasing exponentially if it is queued multiple times in a short period, but the backoff is reset automatically if a configured `cool down` period has elapsed since the last time the item was queued. To configure the per item limiter you can set the following environment variables: @@ -277,16 +288,16 @@ To configure the per item limiter you can set the following environment variable * `WORKQUEUE_MAX_DELAY_NS` : The max delay in nanoseconds, this is the max backoff limit. Defaults to 3 * 10^9 (=3s) * `WORKQUEUE_BACKOFF_FACTOR` : The backoff factor, this is the factor by which the backoff is increased for each retry. Defaults to 1.5 -The formula used to calculate the backoff time for an item, where `numRequeue` is the number of times the item has been queued +The formula used to calculate the backoff time for an item, where `numRequeue` is the number of times the item has been queued and `lastRequeueTime` is the time at which the item was last queued: - When `WORKQUEUE_FAILURE_COOLDOWN_NS` != 0 : ``` -backoff = time.Since(lastRequeueTime) >= WORKQUEUE_FAILURE_COOLDOWN_NS ? - WORKQUEUE_BASE_DELAY_NS : +backoff = time.Since(lastRequeueTime) >= WORKQUEUE_FAILURE_COOLDOWN_NS ? + WORKQUEUE_BASE_DELAY_NS : min( - WORKQUEUE_MAX_DELAY_NS, + WORKQUEUE_MAX_DELAY_NS, WORKQUEUE_BASE_DELAY_NS * WORKQUEUE_BACKOFF_FACTOR ^ (numRequeue) ) ``` diff --git a/docs/operator-manual/server-commands/argocd-application-controller.md b/docs/operator-manual/server-commands/argocd-application-controller.md index 1d71fc6494445..f4057bf7b04cc 100644 --- a/docs/operator-manual/server-commands/argocd-application-controller.md +++ b/docs/operator-manual/server-commands/argocd-application-controller.md @@ -17,6 +17,7 @@ argocd-application-controller [flags] ``` --app-hard-resync int Time period in seconds for application hard resync. --app-resync int Time period in seconds for application resync. (default 180) + --app-resync-jitter int Maximum time period in seconds to add as a delay jitter for application resync. --app-state-cache-expiration duration Cache expiration for app state (default 1h0m0s) --application-namespaces strings List of additional namespaces that applications are allowed to be reconciled from --as string Username to impersonate for the operation diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index 0fbf979809c97..bcaf2d4bb5894 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -34,6 +34,12 @@ spec: name: argocd-cm key: timeout.hard.reconciliation optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: diff --git a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml index 62f98a1449215..d974edffdd618 100644 --- a/manifests/base/application-controller/argocd-application-controller-statefulset.yaml +++ b/manifests/base/application-controller/argocd-application-controller-statefulset.yaml @@ -35,6 +35,12 @@ spec: name: argocd-cm key: timeout.hard.reconciliation optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 08d7d972e6362..254cd6e22044f 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -21514,6 +21514,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index 2029be1e07e12..e343330050855 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -23453,6 +23453,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 01a8da2ffd7b9..ccac170de7e19 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2719,6 +2719,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: diff --git a/manifests/install.yaml b/manifests/install.yaml index 83ac4f903fb7b..b571be4bdb1c7 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -22497,6 +22497,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index 76301680f195a..ab6e3b63348fd 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1763,6 +1763,12 @@ spec: key: timeout.hard.reconciliation name: argocd-cm optional: true + - name: ARGOCD_RECONCILIATION_JITTER + valueFrom: + configMapKeyRef: + key: timeout.reconciliation.jitter + name: argocd-cm + optional: true - name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS valueFrom: configMapKeyRef: From 397063fea4d08d08fec7f63339d8e65058db3d69 Mon Sep 17 00:00:00 2001 From: Sergey Lanzman Date: Sun, 21 Jan 2024 08:48:36 +0200 Subject: [PATCH 210/269] fix(action): Add validation for Kustomize Build Options white space (#16704) Signed-off-by: Sergey Lanzman --- util/kustomize/kustomize.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/kustomize/kustomize.go b/util/kustomize/kustomize.go index 2487b14b4903b..f3d2246899d12 100644 --- a/util/kustomize/kustomize.go +++ b/util/kustomize/kustomize.go @@ -315,7 +315,7 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp } func parseKustomizeBuildOptions(path, buildOptions string) []string { - return append([]string{"build", path}, strings.Split(buildOptions, " ")...) + return append([]string{"build", path}, strings.Fields(buildOptions)...) } var KustomizationNames = []string{"kustomization.yaml", "kustomization.yml", "Kustomization"} From 9042f415b7bd7e4cd15473b2d13ed2316aa30e3d Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Mon, 22 Jan 2024 14:49:50 +0100 Subject: [PATCH 211/269] Revert "chore: Preventing runnings jobs when updating documentation (#16706)" (#16943) This reverts commit 65869a3860c7555b3ea7a962db44cc9b05f7e333. Signed-off-by: Blake Pettersson --- .github/pull_request_template.md | 2 +- .github/workflows/ci-build.yaml | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index fb499c253f365..c1a3f42508aaa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -21,4 +21,4 @@ Checklist: * [ ] Optional. My organization is added to USERS.md. * [ ] Optional. For bug fixes, I've indicated what older releases this fix should be cherry-picked into (this may or may not happen depending on risk/complexity). - \ No newline at end of file + diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index f9dff564ff594..3a596a9552d70 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -1,17 +1,12 @@ name: Integration tests - on: push: - paths-ignore: - - '*.md' branches: - 'master' - 'release-*' - '!release-1.4' - '!release-1.5' pull_request: - paths-ignore: - - '*.md' branches: - 'master' - 'release-*' From f7236d794b923b9efccb6af6745ea3274a575952 Mon Sep 17 00:00:00 2001 From: Arnold <87698848+arnoldberlin@users.noreply.github.com> Date: Mon, 22 Jan 2024 10:26:26 -0500 Subject: [PATCH 212/269] feat: Add PITS Globale Datenrettungsdienste to user list (#16765) * Add PITS Globale Datenrettungsdienste to user list Signed-off-by: Arnold <87698848+arnoldberlin@users.noreply.github.com> * Update USERS.md Signed-off-by: Arnold <87698848+arnoldberlin@users.noreply.github.com> --------- Signed-off-by: Arnold <87698848+arnoldberlin@users.noreply.github.com> Co-authored-by: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> --- USERS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/USERS.md b/USERS.md index 60dd3b881c10b..cdf4406b7f296 100644 --- a/USERS.md +++ b/USERS.md @@ -220,6 +220,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Pigment](https://www.gopigment.com/) 1. [Pipefy](https://www.pipefy.com/) 1. [Pismo](https://pismo.io/) +1. [PITS Globale Datenrettungsdienste](https://www.pitsdatenrettung.de/) 1. [Platform9 Systems](https://platform9.com/) 1. [Polarpoint.io](https://polarpoint.io) 1. [PostFinance](https://github.com/postfinance) From c29f6da00cabc46238652bd10c589955a1c4a976 Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Mon, 22 Jan 2024 15:39:56 -0500 Subject: [PATCH 213/269] separate application controller roles into a separate manifests directory (#16884) Signed-off-by: ishitasequeira --- .../argocd-application-controller-service.yaml | 4 ++-- ...argocd-application-controller-statefulset.yaml | 15 +++++++++++++++ .../kustomization.yaml | 3 +++ .../argocd-application-controller-role.yaml | 0 ...argocd-application-controller-rolebinding.yaml | 0 .../argocd-application-controller-sa.yaml | 0 .../kustomization.yaml | 7 +++++++ .../application-controller/kustomization.yaml | 4 +--- .../base/controller-deployment/kustomization.yaml | 5 +---- 9 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 manifests/base/application-controller-deployment/argocd-application-controller-statefulset.yaml rename manifests/base/{application-controller => application-controller-roles}/argocd-application-controller-role.yaml (100%) rename manifests/base/{application-controller => application-controller-roles}/argocd-application-controller-rolebinding.yaml (100%) rename manifests/base/{application-controller => application-controller-roles}/argocd-application-controller-sa.yaml (100%) create mode 100644 manifests/base/application-controller-roles/kustomization.yaml diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml index a769e75468483..f66c8055247f3 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml @@ -14,7 +14,7 @@ spec: targetPort: 8082 - name: metrics protocol: TCP - port: 8084 - targetPort: 8084 + port: 8082 + targetPort: 8082 selector: app.kubernetes.io/name: argocd-application-controller \ No newline at end of file diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-statefulset.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-statefulset.yaml new file mode 100644 index 0000000000000..10e4ea2ac7e3e --- /dev/null +++ b/manifests/base/application-controller-deployment/argocd-application-controller-statefulset.yaml @@ -0,0 +1,15 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: argocd-application-controller +spec: + replicas: 0 + template: + spec: + containers: + - name: argocd-application-controller + args: + - /usr/local/bin/argocd-application-controller + env: + - name: ARGOCD_CONTROLLER_REPLICAS + value: "0" \ No newline at end of file diff --git a/manifests/base/application-controller-deployment/kustomization.yaml b/manifests/base/application-controller-deployment/kustomization.yaml index 8f35ec8bd388f..733a378e013e0 100644 --- a/manifests/base/application-controller-deployment/kustomization.yaml +++ b/manifests/base/application-controller-deployment/kustomization.yaml @@ -2,5 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: +- ../application-controller-roles - argocd-application-controller-service.yaml +- argocd-application-controller-statefulset.yaml - argocd-application-controller-deployment.yaml + diff --git a/manifests/base/application-controller/argocd-application-controller-role.yaml b/manifests/base/application-controller-roles/argocd-application-controller-role.yaml similarity index 100% rename from manifests/base/application-controller/argocd-application-controller-role.yaml rename to manifests/base/application-controller-roles/argocd-application-controller-role.yaml diff --git a/manifests/base/application-controller/argocd-application-controller-rolebinding.yaml b/manifests/base/application-controller-roles/argocd-application-controller-rolebinding.yaml similarity index 100% rename from manifests/base/application-controller/argocd-application-controller-rolebinding.yaml rename to manifests/base/application-controller-roles/argocd-application-controller-rolebinding.yaml diff --git a/manifests/base/application-controller/argocd-application-controller-sa.yaml b/manifests/base/application-controller-roles/argocd-application-controller-sa.yaml similarity index 100% rename from manifests/base/application-controller/argocd-application-controller-sa.yaml rename to manifests/base/application-controller-roles/argocd-application-controller-sa.yaml diff --git a/manifests/base/application-controller-roles/kustomization.yaml b/manifests/base/application-controller-roles/kustomization.yaml new file mode 100644 index 0000000000000..f834d2ef3dbc4 --- /dev/null +++ b/manifests/base/application-controller-roles/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- argocd-application-controller-sa.yaml +- argocd-application-controller-role.yaml +- argocd-application-controller-rolebinding.yaml diff --git a/manifests/base/application-controller/kustomization.yaml b/manifests/base/application-controller/kustomization.yaml index 9a801ad877bd2..616977fb9b08b 100644 --- a/manifests/base/application-controller/kustomization.yaml +++ b/manifests/base/application-controller/kustomization.yaml @@ -2,9 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- argocd-application-controller-sa.yaml -- argocd-application-controller-role.yaml -- argocd-application-controller-rolebinding.yaml +- ../application-controller-roles - argocd-application-controller-statefulset.yaml - argocd-metrics.yaml - argocd-application-controller-network-policy.yaml \ No newline at end of file diff --git a/manifests/ha/base/controller-deployment/kustomization.yaml b/manifests/ha/base/controller-deployment/kustomization.yaml index d6d20d99b4516..e98bd250d699e 100644 --- a/manifests/ha/base/controller-deployment/kustomization.yaml +++ b/manifests/ha/base/controller-deployment/kustomization.yaml @@ -1,20 +1,17 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization - patches: +- path: argocd-application-controller-statefulset.yaml - path: argocd-repo-server-deployment.yaml - path: argocd-server-deployment.yaml -- path: argocd-application-controller-statefulset.yaml - path: argocd-cmd-params-cm.yaml - images: - name: quay.io/argoproj/argocd newName: quay.io/argoproj/argocd newTag: latest resources: -- ../../../base/application-controller - ../../../base/application-controller-deployment - ../../../base/applicationset-controller - ../../../base/dex From b234264d792e8c94def8e7f8eb65d49b3a172818 Mon Sep 17 00:00:00 2001 From: Linghao Su Date: Wed, 24 Jan 2024 01:09:00 +0800 Subject: [PATCH 214/269] fix(ui): fix display banner when not explicit set position (#16741) Signed-off-by: linghaoSu --- ui/src/app/ui-banner/ui-banner.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/ui-banner/ui-banner.tsx b/ui/src/app/ui-banner/ui-banner.tsx index 29dbc45eadfbc..ac097bca55163 100644 --- a/ui/src/app/ui-banner/ui-banner.tsx +++ b/ui/src/app/ui-banner/ui-banner.tsx @@ -116,7 +116,7 @@ export const Banner = (props: React.Props) => { chatUrl = 'invalid-url'; } } - const shouldRenderTop = position === 'top' || position === 'both'; + const shouldRenderTop = position === 'top' || position === 'both' || (!position && content); const shouldRenderBottom = position === 'bottom' || position === 'both'; return ( From 97727cbb59348a81c97ea18e1e50d4443a88eb13 Mon Sep 17 00:00:00 2001 From: Anand Francis Joseph Date: Tue, 23 Jan 2024 23:25:30 +0530 Subject: [PATCH 215/269] fix(appcontroller): Uptake fix in gitops engine which fixes application sync with auto create ns and server side apply (#16942) * Uptake fix in gitops engine to fix auto create ns with server side apply Signed-off-by: anandf * Moved the new e2e test to different location Signed-off-by: anandf * Fix test name to be less than 63 char for creating ns Signed-off-by: anandf * update gitops-engine with latest master Signed-off-by: Leonardo Luz Almeida --------- Signed-off-by: anandf Signed-off-by: Leonardo Luz Almeida Co-authored-by: Leonardo Luz Almeida --- go.mod | 2 +- go.sum | 4 +- test/e2e/app_sync_options_test.go | 61 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 test/e2e/app_sync_options_test.go diff --git a/go.mod b/go.mod index 57fd30124afc1..19715e16d7d76 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 - github.com/argoproj/gitops-engine v0.7.1-0.20231218194513-aba38192fb16 + github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 diff --git a/go.sum b/go.sum index 14b7b57c1f2ac..5320a5e243486 100644 --- a/go.sum +++ b/go.sum @@ -694,8 +694,8 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20231218194513-aba38192fb16 h1:kR15L8UsSVr7oitABKU88msQirMT0/RO/KRla1jkq/s= -github.com/argoproj/gitops-engine v0.7.1-0.20231218194513-aba38192fb16/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= +github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc h1:Fv94Mi2WvtvPkEH5WoWC3iy/VoQRLeSsE0hyg0n2UkY= +github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 h1:1lt0VXzmLK7Vv0kaeal3S6/JIfzPyBORkUWXhiqF3l0= github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9/go.mod h1:E/vv4+by868m0mmflaRfGBmKBtAupoF+mmyfekP8QCk= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= diff --git a/test/e2e/app_sync_options_test.go b/test/e2e/app_sync_options_test.go new file mode 100644 index 0000000000000..7d0a0ffeabb99 --- /dev/null +++ b/test/e2e/app_sync_options_test.go @@ -0,0 +1,61 @@ +package e2e + +import ( + "testing" + + "github.com/argoproj/gitops-engine/pkg/health" + . "github.com/argoproj/gitops-engine/pkg/sync/common" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + + . "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture" + . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/app" +) + +// Given application is set with --sync-option CreateNamespace=true and --sync-option ServerSideApply=true +// +// application --dest-namespace exists +// +// Then, --dest-namespace is created with server side apply +// application is synced and healthy with resource +// application resources created with server side apply in the newly created namespace. +func TestNamespaceCreationWithSSA(t *testing.T) { + SkipOnEnv(t, "OPENSHIFT") + namespace := "guestbook-ui-with-ssa" + defer func() { + if !t.Skipped() { + _, err := Run("", "kubectl", "delete", "namespace", namespace) + assert.NoError(t, err) + } + }() + + ctx := Given(t) + ctx. + SetAppNamespace(AppNamespace()). + Timeout(30). + Path("guestbook"). + When(). + CreateFromFile(func(app *Application) { + app.Spec.SyncPolicy = &SyncPolicy{ + SyncOptions: SyncOptions{"CreateNamespace=true", "ServerSideApply=true"}, + } + }). + Then(). + Expect(NoNamespace(namespace)). + When(). + AppSet("--dest-namespace", namespace). + Sync(). + Then(). + Expect(Success("")). + Expect(Namespace(namespace, func(app *Application, ns *v1.Namespace) { + assert.NotContains(t, ns.Annotations, "kubectl.kubernetes.io/last-applied-configuration") + })). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(ResourceHealthWithNamespaceIs("Deployment", "guestbook-ui", namespace, health.HealthStatusHealthy)). + Expect(ResourceSyncStatusWithNamespaceIs("Deployment", "guestbook-ui", namespace, SyncStatusCodeSynced)). + Expect(ResourceHealthWithNamespaceIs("Service", "guestbook-ui", namespace, health.HealthStatusHealthy)). + Expect(ResourceSyncStatusWithNamespaceIs("Service", "guestbook-ui", namespace, SyncStatusCodeSynced)) +} From fec5708ea516d21b5908b89275a8e1137fe2f59c Mon Sep 17 00:00:00 2001 From: Keith Chong Date: Tue, 23 Jan 2024 18:32:52 -0500 Subject: [PATCH 216/269] docs: Update argocd-cm.yaml bannerposition description (#16961) (#16962) Signed-off-by: Keith Chong --- docs/operator-manual/argocd-cm.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml index 5e4ed095be56d..ddc47ffc936d0 100644 --- a/docs/operator-manual/argocd-cm.yaml +++ b/docs/operator-manual/argocd-cm.yaml @@ -308,8 +308,10 @@ data: # have either a permanent banner or a regular closeable banner, and NOT both. eg. A user can't dismiss a # notification message (closeable) banner, to then immediately see a permanent banner. # ui.bannerpermanent: "true" - # An option to specify the position of the banner, either the top or bottom of the page. The default is at the top. - # Uncomment to make the banner appear at the bottom of the page. Any value other than "bottom" will make the banner appear at the top. + # An option to specify the position of the banner, either the top or bottom of the page, or both. The valid values + # are: "top", "bottom" and "both". The default (if the option is not provided), is "top". If "both" is specified, then + # the content appears both at the top and the bottom of the page. Uncomment the following line to make the banner appear + # at the bottom of the page. Change the value as needed. # ui.bannerposition: "bottom" # Application reconciliation timeout is the max amount of time required to discover if a new manifests version got From 0012e787f3c9f308af1db45c2689c9cec93645c8 Mon Sep 17 00:00:00 2001 From: Christian Hernandez Date: Tue, 23 Jan 2024 22:32:29 -0500 Subject: [PATCH 217/269] docs: Added an example of downloading the latest stable version (#16968) * added an example of downloading the latest stable version Signed-off-by: Christian Hernandez * Update docs/cli_installation.md Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Signed-off-by: Christian Hernandez --------- Signed-off-by: Christian Hernandez Signed-off-by: Christian Hernandez Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- docs/cli_installation.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/cli_installation.md b/docs/cli_installation.md index 42938bcd751ba..5a314d4ce6be2 100644 --- a/docs/cli_installation.md +++ b/docs/cli_installation.md @@ -37,6 +37,17 @@ sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd rm argocd-linux-amd64 ``` +#### Download latest stable version + +You can download the latest stable release by executing below steps: + +```bash +VERSION=$(curl -L -s https://raw.githubusercontent.com/argoproj/argo-cd/stable/VERSION) +curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/download/v$VERSION/argocd-linux-amd64 +sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd +rm argocd-linux-amd64 +``` + You should now be able to run `argocd` commands. From 666499f6108124ef7bfa0c6cc616770c6dc4f42c Mon Sep 17 00:00:00 2001 From: 1102 <90682513+nueavv@users.noreply.github.com> Date: Wed, 24 Jan 2024 14:23:58 +0900 Subject: [PATCH 218/269] feat(health): support for resourcerecordsets aws.crossplane.io resource (#16823) Signed-off-by: nueavv --- .../ResourceRecordSet/health_test.yaml | 25 +++++++++++ .../ResourceRecordSet/heatlh.lua | 41 +++++++++++++++++++ .../testdata/degraded_reconcileError.yaml | 35 ++++++++++++++++ .../ResourceRecordSet/testdata/healthy.yaml | 29 +++++++++++++ .../testdata/progressing_creating.yaml | 29 +++++++++++++ .../testdata/progressing_noStatus.yaml | 19 +++++++++ .../testdata/suspended_reconcilePaused.yaml | 27 ++++++++++++ 7 files changed, 205 insertions(+) create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/health_test.yaml create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/degraded_reconcileError.yaml create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/healthy.yaml create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_creating.yaml create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_noStatus.yaml create mode 100644 resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/suspended_reconcilePaused.yaml diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/health_test.yaml b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/health_test.yaml new file mode 100644 index 0000000000000..aa83951d5a2db --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/health_test.yaml @@ -0,0 +1,25 @@ +tests: +- healthStatus: + status: Progressing + message: Waiting for resourcrecordset to be available + inputPath: testdata/progressing_creating.yaml +- healthStatus: + status: Progressing + message: Waiting for resourcrecordset to be created + inputPath: testdata/progressing_noStatus.yaml +- healthStatus: + status: Degraded + message: >- + create failed: failed to create the ResourceRecordSet resource: + InvalidChangeBatch: [RRSet of type CNAME with DNS name + www.crossplane.io. is not permitted as it conflicts with other + records with the same DNS name in zone crossplane.io.] + inputPath: testdata/degraded_reconcileError.yaml +- healthStatus: + status: Suspended + message: ReconcilePaused + inputPath: testdata/suspended_reconcilePaused.yaml +- healthStatus: + status: Healthy + message: Available + inputPath: testdata/healthy.yaml diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua new file mode 100644 index 0000000000000..0cf5253e910ff --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/heatlh.lua @@ -0,0 +1,41 @@ +local hs = {} +if obj.status ~= nil then + if obj.status.conditions ~= nil then + local ready = false + local synced = false + local suspended = false + for i, condition in ipairs(obj.status.conditions) do + + if condition.type == "Ready" then + ready = condition.status == "True" + ready_message = condition.reason + elseif condition.type == "Synced" then + synced = condition.status == "True" + if condition.reason == "ReconcileError" then + synced_message = condition.message + elseif condition.reason == "ReconcilePaused" then + suspended = true + suspended_message = condition.reason + end + end + end + if ready and synced then + hs.status = "Healthy" + hs.message = ready_message + elseif synced == false and suspended == true then + hs.status = "Suspended" + hs.message = suspended_message + elseif ready == false and synced == true and suspended == false then + hs.status = "Progressing" + hs.message = "Waiting for resourcrecordset to be available" + else + hs.status = "Degraded" + hs.message = synced_message + end + return hs + end +end + +hs.status = "Progressing" +hs.message = "Waiting for resourcrecordset to be created" +return hs diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/degraded_reconcileError.yaml b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/degraded_reconcileError.yaml new file mode 100644 index 0000000000000..31bc5123c7bfd --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/degraded_reconcileError.yaml @@ -0,0 +1,35 @@ +apiVersion: route53.aws.crossplane.io/v1alpha1 +kind: ResourceRecordSet +metadata: + creationTimestamp: '2024-01-11T03:48:32Z' + generation: 1 + name: www-domain + resourceVersion: '187731157' + selfLink: /apis/route53.aws.crossplane.io/v1alpha1/resourcerecordsets/www-domain + uid: c9c85395-0830-4549-b255-e9e426663547 +spec: + providerConfigRef: + name: crossplane + forProvider: + resourceRecords: + - value: www.crossplane.io + setIdentifier: www + ttl: 60 + type: CNAME + weight: 0 + zoneId: ABCDEFGAB07CD +status: + conditions: + - lastTransitionTime: '2024-01-11T03:48:57Z' + message: >- + create failed: failed to create the ResourceRecordSet resource: + InvalidChangeBatch: [RRSet of type CNAME with DNS name + www.crossplane.io. is not permitted as it conflicts with other + records with the same DNS name in zone crossplane.io.] + reason: ReconcileError + status: 'False' + type: Synced + - lastTransitionTime: '2024-01-11T03:48:34Z' + reason: Creating + status: 'False' + type: Ready diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/healthy.yaml b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/healthy.yaml new file mode 100644 index 0000000000000..f808e46cc8c92 --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/healthy.yaml @@ -0,0 +1,29 @@ +apiVersion: route53.aws.crossplane.io/v1alpha1 +kind: ResourceRecordSet +metadata: + creationTimestamp: "2023-11-16T04:44:19Z" + generation: 4 + name: www-domain + resourceVersion: "140397563" + selfLink: /apis/route53.aws.crossplane.io/v1alpha1/resourcerecordsets/www-domain + uid: 11f0d48d-134f-471b-9340-b6d45d953fcb +spec: + providerConfigRef: + name: crossplane + forProvider: + zoneId: A1B2C3D4 + type: A + aliasTarget: + dnsName: abcdefg.cloudfront.net. + evaluateTargetHealth: false + hostedZoneId: AZBZCZDEFG +status: + conditions: + - lastTransitionTime: "2023-11-16T04:44:27Z" + reason: Available + status: "True" + type: Ready + - lastTransitionTime: "2023-11-16T04:44:25Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_creating.yaml b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_creating.yaml new file mode 100644 index 0000000000000..abf59775fb8e0 --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_creating.yaml @@ -0,0 +1,29 @@ +apiVersion: route53.aws.crossplane.io/v1alpha1 +kind: ResourceRecordSet +metadata: + creationTimestamp: "2023-11-16T04:44:19Z" + generation: 4 + name: www-domain + resourceVersion: "140397563" + selfLink: /apis/route53.aws.crossplane.io/v1alpha1/resourcerecordsets/www-domain + uid: 11f0d48d-134f-471b-9340-b6d45d953fcb +spec: + providerConfigRef: + name: crossplane + forProvider: + zoneId: A1B2C3D4 + type: A + aliasTarget: + dnsName: abcdefg.cloudfront.net. + evaluateTargetHealth: false + hostedZoneId: AZBZCZDEFG +status: + conditions: + - lastTransitionTime: "2023-11-16T04:44:27Z" + reason: Creating + status: "False" + type: Ready + - lastTransitionTime: "2023-11-16T04:44:25Z" + reason: ReconcileSuccess + status: "True" + type: Synced diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_noStatus.yaml b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_noStatus.yaml new file mode 100644 index 0000000000000..28d778d055050 --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/progressing_noStatus.yaml @@ -0,0 +1,19 @@ +apiVersion: route53.aws.crossplane.io/v1alpha1 +kind: ResourceRecordSet +metadata: + creationTimestamp: "2023-11-16T04:44:19Z" + generation: 4 + name: www-domain + resourceVersion: "140397563" + selfLink: /apis/route53.aws.crossplane.io/v1alpha1/resourcerecordsets/www-domain + uid: 11f0d48d-134f-471b-9340-b6d45d953fcb +spec: + providerConfigRef: + name: crossplane + forProvider: + zoneId: A1B2C3D4 + type: A + aliasTarget: + dnsName: abcdefg.cloudfront.net. + evaluateTargetHealth: false + hostedZoneId: AZBZCZDEFG diff --git a/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/suspended_reconcilePaused.yaml b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/suspended_reconcilePaused.yaml new file mode 100644 index 0000000000000..522c0e878dcf8 --- /dev/null +++ b/resource_customizations/route53.aws.crossplane.io/ResourceRecordSet/testdata/suspended_reconcilePaused.yaml @@ -0,0 +1,27 @@ +apiVersion: route53.aws.crossplane.io/v1alpha1 +kind: ResourceRecordSet +metadata: + annotations: + crossplane.io/paused: "true" + creationTimestamp: "2024-01-11T04:16:15Z" + generation: 1 + name: www-domain + resourceVersion: "187746011" + uid: 5517b419-5052-43d9-941e-c32f60d8c7e5 +spec: + providerConfigRef: + name: crossplane + forProvider: + resourceRecords: + - value: www.crossplane.io + setIdentifier: www + ttl: 60 + type: CNAME + weight: 0 + zoneId: ABCDEFGAB07CD +status: + conditions: + - lastTransitionTime: "2024-01-11T04:16:16Z" + reason: ReconcilePaused + status: "False" + type: Synced From 6d0850749b62621ef951387d3d4b75148916063f Mon Sep 17 00:00:00 2001 From: fsl <1171313930@qq.com> Date: Wed, 24 Jan 2024 22:42:42 +0800 Subject: [PATCH 219/269] chore(deps): rm go-jose Cxb6dee8d5-b814 high vuln (#16947) Signed-off-by: fengshunli <1171313930@qq.com> --- go.mod | 3 +-- go.sum | 2 -- util/test/testutil.go | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 19715e16d7d76..06a286c35c242 100644 --- a/go.mod +++ b/go.mod @@ -29,6 +29,7 @@ require ( github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.11.0 + github.com/go-jose/go-jose/v3 v3.0.1 github.com/go-logr/logr v1.3.0 github.com/go-openapi/loads v0.21.2 github.com/go-openapi/runtime v0.26.0 @@ -88,7 +89,6 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 - gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.26.11 @@ -184,7 +184,6 @@ require ( github.com/go-errors/errors v1.4.2 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.21.4 // indirect github.com/go-openapi/errors v0.20.3 // indirect diff --git a/go.sum b/go.sum index 5320a5e243486..78a085ec08a73 100644 --- a/go.sum +++ b/go.sum @@ -2597,8 +2597,6 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= gopkg.in/retry.v1 v1.0.3/go.mod h1:FJkXmWiMaAo7xB+xhvDF59zhfjDWyzmyAxiT4dB688g= -gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= -gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= diff --git a/util/test/testutil.go b/util/test/testutil.go index 1cb23bc08bb3e..bb6c43313358c 100644 --- a/util/test/testutil.go +++ b/util/test/testutil.go @@ -8,9 +8,9 @@ import ( "net/http/httptest" "testing" + "github.com/go-jose/go-jose/v3" "github.com/golang-jwt/jwt/v4" "github.com/stretchr/testify/require" - "gopkg.in/square/go-jose.v2" ) // Cert is a certificate for tests. It was generated like this: From 8932036d5327c10b3e01447b61c5352cf3930a2f Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Wed, 24 Jan 2024 14:45:09 -0500 Subject: [PATCH 220/269] fix(server): allow disabling content-type check (#16959) * fix(server): allow disabling content-type check Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * fix spacing Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- cmd/argocd-server/commands/argocd_server.go | 9 +- .../operator-manual/argocd-cmd-params-cm.yaml | 3 + .../base/server/argocd-server-deployment.yaml | 294 +++++++++--------- manifests/ha/install.yaml | 6 + manifests/ha/namespace-install.yaml | 6 + manifests/install.yaml | 6 + manifests/namespace-install.yaml | 6 + server/server.go | 2 + server/server_test.go | 43 +++ 9 files changed, 229 insertions(+), 146 deletions(-) diff --git a/cmd/argocd-server/commands/argocd_server.go b/cmd/argocd-server/commands/argocd_server.go index 6ec66801cc317..646ecd6a2aabe 100644 --- a/cmd/argocd-server/commands/argocd_server.go +++ b/cmd/argocd-server/commands/argocd_server.go @@ -172,6 +172,11 @@ func NewCommand() *cobra.Command { baseHRef = rootPath } + var contentTypesList []string + if contentTypes != "" { + contentTypesList = strings.Split(contentTypes, ";") + } + argoCDOpts := server.ArgoCDServerOpts{ Insecure: insecure, ListenPort: listenPort, @@ -187,7 +192,7 @@ func NewCommand() *cobra.Command { DexServerAddr: dexServerAddress, DexTLSConfig: dexTlsConfig, DisableAuth: disableAuth, - ContentTypes: strings.Split(contentTypes, ";"), + ContentTypes: contentTypesList, EnableGZip: enableGZip, TLSConfigCustomizer: tlsConfigCustomizer, Cache: cache, @@ -243,7 +248,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&repoServerAddress, "repo-server", env.StringFromEnv("ARGOCD_SERVER_REPO_SERVER", common.DefaultRepoServerAddr), "Repo server address") command.Flags().StringVar(&dexServerAddress, "dex-server", env.StringFromEnv("ARGOCD_SERVER_DEX_SERVER", common.DefaultDexServerAddr), "Dex server address") command.Flags().BoolVar(&disableAuth, "disable-auth", env.ParseBoolFromEnv("ARGOCD_SERVER_DISABLE_AUTH", false), "Disable client authentication") - command.Flags().StringVar(&contentTypes, "api-content-types", "application/json", "Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty.") + command.Flags().StringVar(&contentTypes, "api-content-types", env.StringFromEnv("ARGOCD_API_CONTENT_TYPES", "application/json"), "Semicolon separated list of allowed content types for non GET api requests. Any content type is allowed if empty.") command.Flags().BoolVar(&enableGZip, "enable-gzip", env.ParseBoolFromEnv("ARGOCD_SERVER_ENABLE_GZIP", true), "Enable GZIP compression") command.AddCommand(cli.NewVersionCmd(cliName)) command.Flags().StringVar(&listenHost, "address", env.StringFromEnv("ARGOCD_SERVER_LISTEN_ADDRESS", common.DefaultAddressAPIServer), "Listen on given address") diff --git a/docs/operator-manual/argocd-cmd-params-cm.yaml b/docs/operator-manual/argocd-cmd-params-cm.yaml index dac955a9662de..3cb79d85f3150 100644 --- a/docs/operator-manual/argocd-cmd-params-cm.yaml +++ b/docs/operator-manual/argocd-cmd-params-cm.yaml @@ -90,6 +90,9 @@ data: server.k8sclient.retry.max: "0" # The initial backoff delay on the first retry attempt in ms. Subsequent retries will double this backoff time up to a maximum threshold server.k8sclient.retry.base.backoff: "100" + # Semicolon-separated list of content types allowed on non-GET requests. Set an empty string to allow all. Be aware + # that allowing content types besides application/json may make your API more vulnerable to CSRF attacks. + server.api.content.types: "application/json" # Set the logging format. One of: text|json (default "text") server.log.format: "text" diff --git a/manifests/base/server/argocd-server-deployment.yaml b/manifests/base/server/argocd-server-deployment.yaml index 6df5f9701713f..0ebeb70e08531 100644 --- a/manifests/base/server/argocd-server-deployment.yaml +++ b/manifests/base/server/argocd-server-deployment.yaml @@ -25,136 +25,136 @@ spec: env: - name: ARGOCD_SERVER_INSECURE valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.insecure - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.insecure + optional: true - name: ARGOCD_SERVER_BASEHREF valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.basehref - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.basehref + optional: true - name: ARGOCD_SERVER_ROOTPATH valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.rootpath - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.rootpath + optional: true - name: ARGOCD_SERVER_LOGFORMAT valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.log.format - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.log.format + optional: true - name: ARGOCD_SERVER_LOG_LEVEL valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.log.level - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.log.level + optional: true - name: ARGOCD_SERVER_REPO_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: repo.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true - name: ARGOCD_SERVER_DEX_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.dex.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server + optional: true - name: ARGOCD_SERVER_DISABLE_AUTH valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.disable.auth - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.disable.auth + optional: true - name: ARGOCD_SERVER_ENABLE_GZIP valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.enable.gzip - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.enable.gzip + optional: true - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.repo.server.timeout.seconds - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.timeout.seconds + optional: true - name: ARGOCD_SERVER_X_FRAME_OPTIONS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.x.frame.options - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.x.frame.options + optional: true - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.content.security.policy - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.content.security.policy + optional: true - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.repo.server.plaintext - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.plaintext + optional: true - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.repo.server.strict.tls - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.strict.tls + optional: true - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.dex.server.plaintext - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server.plaintext + optional: true - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.dex.server.strict.tls - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server.strict.tls + optional: true - name: ARGOCD_TLS_MIN_VERSION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.tls.minversion - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.minversion + optional: true - name: ARGOCD_TLS_MAX_VERSION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.tls.maxversion - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.maxversion + optional: true - name: ARGOCD_TLS_CIPHERS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.tls.ciphers - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.ciphers + optional: true - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.connection.status.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.connection.status.cache.expiration + optional: true - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.oidc.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.oidc.cache.expiration + optional: true - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.login.attempts.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.login.attempts.expiration + optional: true - name: ARGOCD_SERVER_STATIC_ASSETS valueFrom: configMapKeyRef: @@ -163,16 +163,16 @@ spec: optional: true - name: ARGOCD_APP_STATE_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.app.state.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.app.state.cache.expiration + optional: true - name: REDIS_SERVER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.server - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true - name: REDIS_COMPRESSION valueFrom: configMapKeyRef: @@ -181,76 +181,82 @@ spec: optional: true - name: REDISDB valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: redis.db - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true - name: ARGOCD_DEFAULT_CACHE_EXPIRATION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.default.cache.expiration - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.default.cache.expiration + optional: true - name: ARGOCD_MAX_COOKIE_NUMBER valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.http.cookie.maxnumber - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.http.cookie.maxnumber + optional: true - name: ARGOCD_SERVER_LISTEN_ADDRESS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.listen.address - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.listen.address + optional: true - name: ARGOCD_SERVER_METRICS_LISTEN_ADDRESS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.metrics.listen.address - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.metrics.listen.address + optional: true - name: ARGOCD_SERVER_OTLP_ADDRESS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.address - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true - name: ARGOCD_SERVER_OTLP_INSECURE valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.insecure - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.insecure + optional: true - name: ARGOCD_SERVER_OTLP_HEADERS valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: otlp.headers - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.headers + optional: true - name: ARGOCD_APPLICATION_NAMESPACES valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: application.namespaces - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.enable.proxy.extension - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.enable.proxy.extension + optional: true - name: ARGOCD_K8SCLIENT_RETRY_MAX valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.k8sclient.retry.max - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.k8sclient.retry.max + optional: true - name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF valueFrom: - configMapKeyRef: - name: argocd-cmd-params-cm - key: server.k8sclient.retry.base.backoff - optional: true + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.k8sclient.retry.base.backoff + optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.api.content.types + optional: true volumeMounts: - name: ssh-known-hosts mountPath: /app/config/ssh diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index e343330050855..a092e4d205efd 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -23327,6 +23327,12 @@ spec: key: server.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index ccac170de7e19..2c1def5603cc8 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -2593,6 +2593,12 @@ spec: key: server.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/manifests/install.yaml b/manifests/install.yaml index b571be4bdb1c7..40331559f3959 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -22371,6 +22371,12 @@ spec: key: server.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index ab6e3b63348fd..d9cc590df7861 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -1637,6 +1637,12 @@ spec: key: server.k8sclient.retry.base.backoff name: argocd-cmd-params-cm optional: true + - name: ARGOCD_API_CONTENT_TYPES + valueFrom: + configMapKeyRef: + key: server.api.content.types + name: argocd-cmd-params-cm + optional: true image: quay.io/argoproj/argocd:latest imagePullPolicy: Always livenessProbe: diff --git a/server/server.go b/server/server.go index 8de2ecb9eff9c..8f6aafc689e94 100644 --- a/server/server.go +++ b/server/server.go @@ -993,6 +993,8 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl } if len(a.ContentTypes) > 0 { handler = enforceContentTypes(handler, a.ContentTypes) + } else { + log.WithField(common.SecurityField, common.SecurityHigh).Warnf("Content-Type enforcement is disabled, which may make your API vulnerable to CSRF attacks") } mux.Handle("/api/", handler) diff --git a/server/server_test.go b/server/server_test.go index acfb32e57e5d4..c4f4153f24d89 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -1526,3 +1526,46 @@ func TestReplaceBaseHRef(t *testing.T) { }) } } + +func Test_enforceContentTypes(t *testing.T) { + getBaseHandler := func(t *testing.T, allow bool) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + assert.True(t, allow, "http handler was hit when it should have been blocked by content type enforcement") + writer.WriteHeader(200) + }) + } + + t.Parallel() + + t.Run("GET - not providing a content type, should still succeed", func(t *testing.T) { + handler := enforceContentTypes(getBaseHandler(t, true), []string{"application/json"}).(http.HandlerFunc) + req := httptest.NewRequest("GET", "/", nil) + w := httptest.NewRecorder() + handler(w, req) + resp := w.Result() + assert.Equal(t, 200, resp.StatusCode) + }) + + t.Run("POST", func(t *testing.T) { + handler := enforceContentTypes(getBaseHandler(t, true), []string{"application/json"}).(http.HandlerFunc) + req := httptest.NewRequest("POST", "/", nil) + w := httptest.NewRecorder() + handler(w, req) + resp := w.Result() + assert.Equal(t, 415, resp.StatusCode, "didn't provide a content type, should have gotten an error") + + req = httptest.NewRequest("POST", "/", nil) + req.Header = map[string][]string{"Content-Type": {"application/json"}} + w = httptest.NewRecorder() + handler(w, req) + resp = w.Result() + assert.Equal(t, 200, resp.StatusCode, "should have passed, since an allowed content type was provided") + + req = httptest.NewRequest("POST", "/", nil) + req.Header = map[string][]string{"Content-Type": {"not-allowed"}} + w = httptest.NewRecorder() + handler(w, req) + resp = w.Result() + assert.Equal(t, 415, resp.StatusCode, "should not have passed, since a disallowed content type was provided") + }) +} From 85009d941c012383d89aa3548f200de7d5d859a0 Mon Sep 17 00:00:00 2001 From: Fish-pro Date: Thu, 25 Jan 2024 22:51:43 +0800 Subject: [PATCH 221/269] Clean up repeated package import (#16987) Signed-off-by: Zechun Chen --- cmd/argocd/commands/admin/cluster.go | 13 ++++++------- controller/appcontroller.go | 5 ++--- test/e2e/fixture/applicationsets/context.go | 3 +-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/cmd/argocd/commands/admin/cluster.go b/cmd/argocd/commands/admin/cluster.go index 24d45828c86c1..abb055cdfa354 100644 --- a/cmd/argocd/commands/admin/cluster.go +++ b/cmd/argocd/commands/admin/cluster.go @@ -26,7 +26,6 @@ import ( "github.com/argoproj/argo-cd/v2/controller/sharding" argocdclient "github.com/argoproj/argo-cd/v2/pkg/apiclient" "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - argoappv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/util/argo" cacheutil "github.com/argoproj/argo-cd/v2/util/cache" @@ -72,7 +71,7 @@ argocd admin cluster namespaces my-cluster `, } type ClusterWithInfo struct { - argoappv1.Cluster + v1alpha1.Cluster // Shard holds controller shard number that handles the cluster Shard int // Namespaces holds list of namespaces managed by Argo CD in the cluster @@ -626,16 +625,16 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command errors.CheckError(err) kubeClientset := fake.NewSimpleClientset() - var awsAuthConf *argoappv1.AWSAuthConfig - var execProviderConf *argoappv1.ExecProviderConfig + var awsAuthConf *v1alpha1.AWSAuthConfig + var execProviderConf *v1alpha1.ExecProviderConfig if clusterOpts.AwsClusterName != "" { - awsAuthConf = &argoappv1.AWSAuthConfig{ + awsAuthConf = &v1alpha1.AWSAuthConfig{ ClusterName: clusterOpts.AwsClusterName, RoleARN: clusterOpts.AwsRoleArn, Profile: clusterOpts.AwsProfile, } } else if clusterOpts.ExecProviderCommand != "" { - execProviderConf = &argoappv1.ExecProviderConfig{ + execProviderConf = &v1alpha1.ExecProviderConfig{ Command: clusterOpts.ExecProviderCommand, Args: clusterOpts.ExecProviderArgs, Env: clusterOpts.ExecProviderEnv, @@ -659,7 +658,7 @@ func NewGenClusterConfigCommand(pathOpts *clientcmd.PathOptions) *cobra.Command clst := cmdutil.NewCluster(contextName, clusterOpts.Namespaces, clusterOpts.ClusterResources, conf, bearerToken, awsAuthConf, execProviderConf, labelsMap, annotationsMap) if clusterOpts.InClusterEndpoint() { - clst.Server = argoappv1.KubernetesInternalAPIServerAddr + clst.Server = v1alpha1.KubernetesInternalAPIServerAddr } if clusterOpts.ClusterEndpoint == string(cmdutil.KubePublicEndpoint) { // Ignore `kube-public` cluster endpoints, since this command is intended to run without invoking any network connections. diff --git a/controller/appcontroller.go b/controller/appcontroller.go index e6dbda4194f02..e6dee507caa2e 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -48,7 +48,6 @@ import ( "github.com/argoproj/argo-cd/v2/controller/sharding" "github.com/argoproj/argo-cd/v2/pkg/apis/application" appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" - argov1alpha "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1" appclientset "github.com/argoproj/argo-cd/v2/pkg/client/clientset/versioned" "github.com/argoproj/argo-cd/v2/pkg/client/informers/externalversions/application/v1alpha1" applisters "github.com/argoproj/argo-cd/v2/pkg/client/listers/application/v1alpha1" @@ -1034,7 +1033,7 @@ func (ctrl *ApplicationController) getPermittedAppLiveObjects(app *appv1.Applica return objsMap, nil } -func (ctrl *ApplicationController) isValidDestination(app *appv1.Application) (bool, *argov1alpha.Cluster) { +func (ctrl *ApplicationController) isValidDestination(app *appv1.Application) (bool, *appv1.Cluster) { // Validate the cluster using the Application destination's `name` field, if applicable, // and set the Server field, if needed. if err := argo.ValidateDestination(context.Background(), &app.Spec.Destination, ctrl.db); err != nil { @@ -2207,4 +2206,4 @@ func (ctrl *ApplicationController) toAppQualifiedName(appName, appNamespace stri return fmt.Sprintf("%s/%s", appNamespace, appName) } -type ClusterFilterFunction func(c *argov1alpha.Cluster, distributionFunction sharding.DistributionFunction) bool +type ClusterFilterFunction func(c *appv1.Cluster, distributionFunction sharding.DistributionFunction) bool diff --git a/test/e2e/fixture/applicationsets/context.go b/test/e2e/fixture/applicationsets/context.go index c10b2c99bfe5f..a7e91f4d0c8ff 100644 --- a/test/e2e/fixture/applicationsets/context.go +++ b/test/e2e/fixture/applicationsets/context.go @@ -5,7 +5,6 @@ import ( "time" "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" - . "github.com/argoproj/argo-cd/v2/test/e2e/fixture/applicationsets/utils" ) // Context implements the "given" part of given/when/then @@ -19,7 +18,7 @@ type Context struct { } func Given(t *testing.T) *Context { - EnsureCleanState(t) + utils.EnsureCleanState(t) return &Context{t: t} } From 344f23b5e8d4a1359c6973ff2f6aa9d6899bfbe6 Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Fri, 26 Jan 2024 10:42:52 -0500 Subject: [PATCH 222/269] docs(helm): add example of public oci chart (#17000) There doesn't appear to be an example of using an OCI helm chart repository, so this adds a simple declarative example. This is a common question from the community. Signed-off-by: Nicholas Morey --- docs/user-guide/helm.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/user-guide/helm.md b/docs/user-guide/helm.md index 866f9c6d935aa..6d7bce13ba9ab 100644 --- a/docs/user-guide/helm.md +++ b/docs/user-guide/helm.md @@ -25,6 +25,23 @@ spec: namespace: kubeseal ``` +Another example using a public OCI helm chart: +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: nginx +spec: + project: default + source: + chart: nginx + repoURL: registry-1.docker.io/bitnamicharts # note: the oci:// syntax is not included. + targetRevision: 15.9.0 + destination: + name: "in-cluster" + namespace: nginx +``` + !!! note "When using multiple ways to provide values" Order of precedence is `parameters > valuesObject > values > valueFiles > helm repository values.yaml` (see [Here](./helm.md#helm-value-precedence) for a more detailed example) From 8c9abb27ef4d5936f1d50f80015b0440f8c86e7a Mon Sep 17 00:00:00 2001 From: Sonam <49382298+sonamkshenoy@users.noreply.github.com> Date: Sat, 27 Jan 2024 01:31:30 +0530 Subject: [PATCH 223/269] Badge for apps in any namespace (#16739) Signed-off-by: sshenoy6 Co-authored-by: sshenoy6 --- .../components/application-summary/application-summary.tsx | 5 +++-- ui/src/app/shared/components/badge-panel/badge-panel.tsx | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ui/src/app/applications/components/application-summary/application-summary.tsx b/ui/src/app/applications/components/application-summary/application-summary.tsx index 5e8fa2db22ba1..37e6cc62ff0e9 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -15,7 +15,7 @@ import { RevisionHelpIcon } from '../../../shared/components'; import {BadgePanel, Spinner} from '../../../shared/components'; -import {Consumer, ContextApis} from '../../../shared/context'; +import {AuthSettingsCtx, Consumer, ContextApis} from '../../../shared/context'; import * as models from '../../../shared/models'; import {services} from '../../../shared/services'; @@ -47,6 +47,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { const source = getAppDefaultSource(app); const isHelm = source.hasOwnProperty('chart'); const initialState = app.spec.destination.server === undefined ? 'NAME' : 'URL'; + const useAuthSettingsCtx = React.useContext(AuthSettingsCtx); const [destFormat, setDestFormat] = React.useState(initialState); const [changeSync, setChangeSync] = React.useState(false); @@ -589,7 +590,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => {
    )} - + { +export const BadgePanel = ({app, project, appNamespace, nsEnabled}: {app?: string; project?: string; appNamespace?: string; nsEnabled?: boolean}) => { const [badgeType, setBadgeType] = React.useState('URL'); const context = React.useContext(Context); if (!app && !project) { @@ -20,6 +20,9 @@ export const BadgePanel = ({app, project}: {app?: string; project?: string}) => let alt = ''; if (app) { badgeURL = `${root}api/badge?name=${app}&revision=true`; + if (nsEnabled) { + badgeURL += `&namespace=${appNamespace}`; + } entityURL = `${root}applications/${app}`; alt = 'App Status'; } else if (project) { From 4e084ace8c815f225252fe7b8c770a5a1629461a Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Fri, 26 Jan 2024 15:38:49 -0500 Subject: [PATCH 224/269] docs(helm): fix yaml formatting on code block (#17001) Signed-off-by: Nicholas Morey --- docs/user-guide/helm.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/helm.md b/docs/user-guide/helm.md index 6d7bce13ba9ab..ae6422f46382a 100644 --- a/docs/user-guide/helm.md +++ b/docs/user-guide/helm.md @@ -26,7 +26,7 @@ spec: ``` Another example using a public OCI helm chart: -``` +```yaml apiVersion: argoproj.io/v1alpha1 kind: Application metadata: From be1f0eafb80335aa100ecf7175a93be95bab49e6 Mon Sep 17 00:00:00 2001 From: Yudi A Phanama <11147376+phanama@users.noreply.github.com> Date: Mon, 29 Jan 2024 22:31:15 +0700 Subject: [PATCH 225/269] fix(redis): go-redis v9 regression missing metrics and reconnect hook (#13415) (#15275) * fix(redis): go-redis v9 regression missing metrics and reconnect hook Signed-off-by: phanama * fix: golangci lint return values not checked in tests Signed-off-by: phanama * chore: move dnsError var locally into func Signed-off-by: phanama --------- Signed-off-by: phanama --- go.mod | 2 +- util/cache/redis.go | 41 ++++++---------- util/cache/redis_hook.go | 40 ++++++--------- util/cache/redis_hook_test.go | 33 +++++++++---- util/cache/redis_test.go | 92 +++++++++++++++++++++++++++++++++++ 5 files changed, 146 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index 06a286c35c242..b8acf2282cdb1 100644 --- a/go.mod +++ b/go.mod @@ -241,7 +241,7 @@ require ( github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.3.0 github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/rivo/uniseg v0.4.4 // indirect diff --git a/util/cache/redis.go b/util/cache/redis.go index 7d5303bb3a9fa..4648a553f08cc 100644 --- a/util/cache/redis.go +++ b/util/cache/redis.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "net" "time" ioutil "github.com/argoproj/argo-cd/v2/util/io" @@ -159,41 +160,27 @@ type MetricsRegistry interface { ObserveRedisRequestDuration(duration time.Duration) } -var metricStartTimeKey = struct{}{} - type redisHook struct { registry MetricsRegistry } -func (rh *redisHook) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) { - return context.WithValue(ctx, metricStartTimeKey, time.Now()), nil -} - -func (rh *redisHook) AfterProcess(ctx context.Context, cmd redis.Cmder) error { - cmdErr := cmd.Err() - rh.registry.IncRedisRequest(cmdErr != nil && cmdErr != redis.Nil) - - startTime := ctx.Value(metricStartTimeKey).(time.Time) - duration := time.Since(startTime) - rh.registry.ObserveRedisRequestDuration(duration) - - return nil -} - -func (redisHook) BeforeProcessPipeline(ctx context.Context, _ []redis.Cmder) (context.Context, error) { - return ctx, nil +func (rh *redisHook) DialHook(next redis.DialHook) redis.DialHook { + return func(ctx context.Context, network, addr string) (net.Conn, error) { + conn, err := next(ctx, network, addr) + return conn, err + } } -func (redisHook) AfterProcessPipeline(_ context.Context, _ []redis.Cmder) error { - return nil -} +func (rh *redisHook) ProcessHook(next redis.ProcessHook) redis.ProcessHook { + return func(ctx context.Context, cmd redis.Cmder) error { + startTime := time.Now() -func (redisHook) DialHook(next redis.DialHook) redis.DialHook { - return nil -} + err := next(ctx, cmd) + rh.registry.IncRedisRequest(err != nil && err != redis.Nil) + rh.registry.ObserveRedisRequestDuration(time.Since(startTime)) -func (redisHook) ProcessHook(next redis.ProcessHook) redis.ProcessHook { - return nil + return err + } } func (redisHook) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook { diff --git a/util/cache/redis_hook.go b/util/cache/redis_hook.go index 455ad03eb5bbf..e7cc3f4bcc68e 100644 --- a/util/cache/redis_hook.go +++ b/util/cache/redis_hook.go @@ -2,14 +2,13 @@ package cache import ( "context" - "strings" + "errors" + "net" "github.com/redis/go-redis/v9" log "github.com/sirupsen/logrus" ) -const NoSuchHostErr = "no such host" - type argoRedisHooks struct { reconnectCallback func() } @@ -18,32 +17,23 @@ func NewArgoRedisHook(reconnectCallback func()) *argoRedisHooks { return &argoRedisHooks{reconnectCallback: reconnectCallback} } -func (hook *argoRedisHooks) BeforeProcess(ctx context.Context, cmd redis.Cmder) (context.Context, error) { - return ctx, nil -} - -func (hook *argoRedisHooks) AfterProcess(ctx context.Context, cmd redis.Cmder) error { - if cmd.Err() != nil && strings.Contains(cmd.Err().Error(), NoSuchHostErr) { - log.Warnf("Reconnect to redis because error: \"%v\"", cmd.Err()) - hook.reconnectCallback() - } - return nil -} - -func (hook *argoRedisHooks) BeforeProcessPipeline(ctx context.Context, cmds []redis.Cmder) (context.Context, error) { - return ctx, nil -} - -func (hook *argoRedisHooks) AfterProcessPipeline(ctx context.Context, cmds []redis.Cmder) error { - return nil -} - func (hook *argoRedisHooks) DialHook(next redis.DialHook) redis.DialHook { - return nil + return func(ctx context.Context, network, addr string) (net.Conn, error) { + conn, err := next(ctx, network, addr) + return conn, err + } } func (hook *argoRedisHooks) ProcessHook(next redis.ProcessHook) redis.ProcessHook { - return nil + return func(ctx context.Context, cmd redis.Cmder) error { + var dnsError *net.DNSError + err := next(ctx, cmd) + if err != nil && errors.As(err, &dnsError) { + log.Warnf("Reconnect to redis because error: \"%v\"", err) + hook.reconnectCallback() + } + return err + } } func (hook *argoRedisHooks) ProcessPipelineHook(next redis.ProcessPipelineHook) redis.ProcessPipelineHook { diff --git a/util/cache/redis_hook_test.go b/util/cache/redis_hook_test.go index ef9e6a1c85537..4d7d9b7aaf41d 100644 --- a/util/cache/redis_hook_test.go +++ b/util/cache/redis_hook_test.go @@ -1,38 +1,53 @@ package cache import ( - "context" - "errors" "testing" + "time" + "github.com/alicebob/miniredis/v2" "github.com/stretchr/testify/assert" "github.com/redis/go-redis/v9" ) func Test_ReconnectCallbackHookCalled(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + panic(err) + } + defer mr.Close() + called := false hook := NewArgoRedisHook(func() { called = true }) - cmd := &redis.StringCmd{} - cmd.SetErr(errors.New("Failed to resync revoked tokens. retrying again in 1 minute: dial tcp: lookup argocd-redis on 10.179.0.10:53: no such host")) - - _ = hook.AfterProcess(context.Background(), cmd) + faultyDNSRedisClient := redis.NewClient(&redis.Options{Addr: "invalidredishost.invalid:12345"}) + faultyDNSRedisClient.AddHook(hook) + faultyDNSClient := NewRedisCache(faultyDNSRedisClient, 60*time.Second, RedisCompressionNone) + err = faultyDNSClient.Set(&Item{Key: "baz", Object: "foo"}) assert.Equal(t, called, true) + assert.Error(t, err) } func Test_ReconnectCallbackHookNotCalled(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + panic(err) + } + defer mr.Close() + called := false hook := NewArgoRedisHook(func() { called = true }) - cmd := &redis.StringCmd{} - cmd.SetErr(errors.New("Something wrong")) - _ = hook.AfterProcess(context.Background(), cmd) + redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + redisClient.AddHook(hook) + client := NewRedisCache(redisClient, 60*time.Second, RedisCompressionNone) + err = client.Set(&Item{Key: "foo", Object: "bar"}) assert.Equal(t, called, false) + assert.NoError(t, err) } diff --git a/util/cache/redis_test.go b/util/cache/redis_test.go index 3800753cee3ec..e05c7541f5ff1 100644 --- a/util/cache/redis_test.go +++ b/util/cache/redis_test.go @@ -2,14 +2,59 @@ package cache import ( "context" + "strconv" "testing" "time" + promcm "github.com/prometheus/client_model/go" + "github.com/alicebob/miniredis/v2" + "github.com/prometheus/client_golang/prometheus" "github.com/redis/go-redis/v9" "github.com/stretchr/testify/assert" ) +var ( + redisRequestCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "argocd_redis_request_total", + }, + []string{"initiator", "failed"}, + ) + redisRequestHistogram = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_redis_request_duration", + Buckets: []float64{0.1, 0.25, .5, 1, 2}, + }, + []string{"initiator"}, + ) +) + +type MockMetricsServer struct { + registry *prometheus.Registry + redisRequestCounter *prometheus.CounterVec + redisRequestHistogram *prometheus.HistogramVec +} + +func NewMockMetricsServer() *MockMetricsServer { + registry := prometheus.NewRegistry() + registry.MustRegister(redisRequestCounter) + registry.MustRegister(redisRequestHistogram) + return &MockMetricsServer{ + registry: registry, + redisRequestCounter: redisRequestCounter, + redisRequestHistogram: redisRequestHistogram, + } +} + +func (m *MockMetricsServer) IncRedisRequest(failed bool) { + m.redisRequestCounter.WithLabelValues("mock", strconv.FormatBool(failed)).Inc() +} + +func (m *MockMetricsServer) ObserveRedisRequestDuration(duration time.Duration) { + m.redisRequestHistogram.WithLabelValues("mock").Observe(duration.Seconds()) +} + func TestRedisSetCache(t *testing.T) { mr, err := miniredis.Run() if err != nil { @@ -70,3 +115,50 @@ func TestRedisSetCacheCompressed(t *testing.T) { assert.Equal(t, testValue, result) } + +func TestRedisMetrics(t *testing.T) { + mr, err := miniredis.Run() + if err != nil { + panic(err) + } + defer mr.Close() + + metric := &promcm.Metric{} + ms := NewMockMetricsServer() + redisClient := redis.NewClient(&redis.Options{Addr: mr.Addr()}) + faultyRedisClient := redis.NewClient(&redis.Options{Addr: "invalidredishost.invalid:12345"}) + CollectMetrics(redisClient, ms) + CollectMetrics(faultyRedisClient, ms) + + client := NewRedisCache(redisClient, 60*time.Second, RedisCompressionNone) + faultyClient := NewRedisCache(faultyRedisClient, 60*time.Second, RedisCompressionNone) + var res string + + //client successful request + err = client.Set(&Item{Key: "foo", Object: "bar"}) + assert.NoError(t, err) + err = client.Get("foo", &res) + assert.NoError(t, err) + + c, err := ms.redisRequestCounter.GetMetricWithLabelValues("mock", "false") + assert.NoError(t, err) + err = c.Write(metric) + assert.NoError(t, err) + assert.Equal(t, metric.Counter.GetValue(), float64(2)) + + //faulty client failed request + err = faultyClient.Get("foo", &res) + assert.Error(t, err) + c, err = ms.redisRequestCounter.GetMetricWithLabelValues("mock", "true") + assert.NoError(t, err) + err = c.Write(metric) + assert.NoError(t, err) + assert.Equal(t, metric.Counter.GetValue(), float64(1)) + + //both clients histogram count + o, err := ms.redisRequestHistogram.GetMetricWithLabelValues("mock") + assert.NoError(t, err) + err = o.(prometheus.Metric).Write(metric) + assert.NoError(t, err) + assert.Equal(t, int(metric.Histogram.GetSampleCount()), 3) +} From 3c2124235619d8451e2d24c7873e5a6da17354af Mon Sep 17 00:00:00 2001 From: saeedhosseini Date: Mon, 29 Jan 2024 19:04:01 +0330 Subject: [PATCH 226/269] Fix typo in documentation (#17022) Signed-off-by: saeedhosseini --- docs/user-guide/sync-options.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/sync-options.md b/docs/user-guide/sync-options.md index e5b1fe55e8e66..985f9fcf3c974 100644 --- a/docs/user-guide/sync-options.md +++ b/docs/user-guide/sync-options.md @@ -270,7 +270,7 @@ spec: - RespectIgnoreDifferences=true ``` -The example above shows how an Argo CD Application can be configured so it will ignore the `spec.replicas` field from the desired state (git) during the sync stage. This is achieve by calculating and pre-patching the desired state before applying it in the cluster. Note that the `RespectIgnoreDifferences` sync option is only effective when the resource is already created in the cluster. If the Application is being created and no live state exists, the desired state is applied as-is. +The example above shows how an Argo CD Application can be configured so it will ignore the `spec.replicas` field from the desired state (git) during the sync stage. This is achieved by calculating and pre-patching the desired state before applying it in the cluster. Note that the `RespectIgnoreDifferences` sync option is only effective when the resource is already created in the cluster. If the Application is being created and no live state exists, the desired state is applied as-is. ## Create Namespace From e5c88c914b73e455f3f36dc24583e65c743da792 Mon Sep 17 00:00:00 2001 From: Siddhesh Ghadi <61187612+svghadi@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:38:59 +0530 Subject: [PATCH 227/269] feat: Prune resources in reverse order of syncwave during sync (#15074) (#16748) * Add e2e & doc for prune order during sync Signed-off-by: Siddhesh Ghadi * Point gitops-engine to fork with reverse prune changes Signed-off-by: Siddhesh Ghadi * Fix ci linting failures Signed-off-by: Siddhesh Ghadi * Update gitops-engine commit ref Signed-off-by: Siddhesh Ghadi --------- Signed-off-by: Siddhesh Ghadi --- docs/user-guide/sync-waves.md | 4 +- go.mod | 2 +- go.sum | 4 +- test/e2e/sync_waves_test.go | 45 +++++++++++++++++++ .../testdata/syncwaves-prune-order/README.md | 15 +++++++ .../testdata/syncwaves-prune-order/pod.yaml | 41 +++++++++++++++++ .../testdata/syncwaves-prune-order/rbac.yaml | 37 +++++++++++++++ 7 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 test/e2e/testdata/syncwaves-prune-order/README.md create mode 100644 test/e2e/testdata/syncwaves-prune-order/pod.yaml create mode 100644 test/e2e/testdata/syncwaves-prune-order/rbac.yaml diff --git a/docs/user-guide/sync-waves.md b/docs/user-guide/sync-waves.md index 932ba396d68d2..8b17237c87571 100644 --- a/docs/user-guide/sync-waves.md +++ b/docs/user-guide/sync-waves.md @@ -37,7 +37,7 @@ Hooks and resources are assigned to wave zero by default. The wave can be negati When Argo CD starts a sync, it orders the resources in the following precedence: * The phase -* The wave they are in (lower values first) +* The wave they are in (lower values first for creation & updation and higher values first for deletion) * By kind (e.g. [namespaces first and then other Kubernetes resources, followed by custom resources](https://github.com/argoproj/gitops-engine/blob/bc9ce5764fa306f58cf59199a94f6c968c775a2d/pkg/sync/sync_tasks.go#L27-L66)) * By name @@ -49,6 +49,8 @@ It repeats this process until all phases and waves are in-sync and healthy. Because an application can have resources that are unhealthy in the first wave, it may be that the app can never get to healthy. +During pruning of resources, resources from higher waves are processed first before moving to lower waves. If, for any reason, a resource isn't removed/pruned in a wave, the resources in next waves won't be processed. This is to ensure proper resource cleanup between waves. + Note that there's currently a delay between each sync wave in order give other controllers a chance to react to the spec change that we just applied. This also prevent Argo CD from assessing resource health too quickly (against the stale object), causing hooks to fire prematurely. The current delay between each sync wave is 2 seconds and can be configured via environment diff --git a/go.mod b/go.mod index b8acf2282cdb1..d781c91b47ee5 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 - github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc + github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.44.317 diff --git a/go.sum b/go.sum index 78a085ec08a73..4c7aefc9e7fdf 100644 --- a/go.sum +++ b/go.sum @@ -694,8 +694,8 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= -github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc h1:Fv94Mi2WvtvPkEH5WoWC3iy/VoQRLeSsE0hyg0n2UkY= -github.com/argoproj/gitops-engine v0.7.1-0.20240122213038-792124280fcc/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= +github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 h1:5fKAhTQcTBom0vin56cz/UTPx2GMuvdb+lJRAUOPbHA= +github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 h1:1lt0VXzmLK7Vv0kaeal3S6/JIfzPyBORkUWXhiqF3l0= github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9/go.mod h1:E/vv4+by868m0mmflaRfGBmKBtAupoF+mmyfekP8QCk= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= diff --git a/test/e2e/sync_waves_test.go b/test/e2e/sync_waves_test.go index ac5db15eee57d..8d0ee14e487d1 100644 --- a/test/e2e/sync_waves_test.go +++ b/test/e2e/sync_waves_test.go @@ -9,6 +9,8 @@ import ( "github.com/argoproj/gitops-engine/pkg/health" . "github.com/argoproj/gitops-engine/pkg/sync/common" + + v1 "k8s.io/api/core/v1" ) func TestFixingDegradedApp(t *testing.T) { @@ -100,3 +102,46 @@ func TestDegradedDeploymentIsSucceededAndSynced(t *testing.T) { Expect(SyncStatusIs(SyncStatusCodeSynced)). Expect(ResourceResultNumbering(1)) } + +// resources should be pruned in reverse of creation order(syncwaves order) +func TestSyncPruneOrderWithSyncWaves(t *testing.T) { + ctx := Given(t).Timeout(60) + + // remove finalizer to ensure proper cleanup if test fails at early stage + defer func() { + _, _ = RunCli("app", "patch-resource", ctx.AppQualifiedName(), + "--kind", "Pod", + "--resource-name", "pod-with-finalizers", + "--patch", `[{"op": "remove", "path": "/metadata/finalizers"}]`, + "--patch-type", "application/json-patch+json", "--all", + ) + }() + + ctx.Path("syncwaves-prune-order"). + When(). + CreateApp(). + // creation order: sa & role -> rolebinding -> pod + Sync(). + Wait(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + When(). + // delete files to remove resources + DeleteFile("pod.yaml"). + DeleteFile("rbac.yaml"). + Refresh(RefreshTypeHard). + IgnoreErrors(). + Then(). + Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). + When(). + // prune order: pod -> rolebinding -> sa & role + Sync("--prune"). + Wait(). + Then(). + Expect(OperationPhaseIs(OperationSucceeded)). + Expect(SyncStatusIs(SyncStatusCodeSynced)). + Expect(HealthIs(health.HealthStatusHealthy)). + Expect(NotPod(func(p v1.Pod) bool { return p.Name == "pod-with-finalizers" })). + Expect(ResourceResultNumbering(4)) +} diff --git a/test/e2e/testdata/syncwaves-prune-order/README.md b/test/e2e/testdata/syncwaves-prune-order/README.md new file mode 100644 index 0000000000000..92a62fdfe109d --- /dev/null +++ b/test/e2e/testdata/syncwaves-prune-order/README.md @@ -0,0 +1,15 @@ +## Test Scenario + +This test example is for testing the reverse pruning of resources with syncwaves during sync operation. + +Resource creation happens in below order +- wave 0: sa & role +- wave 1: rolebinding +- wave 2: pod + +They are setup in such a way that the resources will be cleaned up properly only if they are deleted in the reverse order of creation i.e +- wave 0: pod +- wave 1: rolebinding +- wave 2: sa & role + +If above delete order is not followed the pod gets stuck in terminating state due to a finalizer which is supposed to be removed by k8s container lifecycle hook on delete if delete order is correct. \ No newline at end of file diff --git a/test/e2e/testdata/syncwaves-prune-order/pod.yaml b/test/e2e/testdata/syncwaves-prune-order/pod.yaml new file mode 100644 index 0000000000000..f801a3992aa37 --- /dev/null +++ b/test/e2e/testdata/syncwaves-prune-order/pod.yaml @@ -0,0 +1,41 @@ +apiVersion: v1 +kind: Pod +metadata: + name: pod-with-finalizers + annotations: + argocd.argoproj.io/sync-wave: "2" + # remove this finalizers using container preStop lifecycle hook on delete + finalizers: + - example.com/block-delete +spec: + serviceAccountName: modify-pods-sa # sa with permissions to modify pods + terminationGracePeriodSeconds: 15 + containers: + - name: container + image: nginx:alpine + command: ["/bin/sh", "-c"] + args: ["sleep 10h"] + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + lifecycle: + # remove finalizers for successful delete of pod + preStop: + exec: + command: + - /bin/sh + - -c + - | + set -e + + SERVICE_ACCOUNT_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) + POD_URL="https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods/$POD_NAME" + PATCH_PAYLOAD='[{"op": "remove", "path": "/metadata/finalizers"}]' + + curl -k -v -H "Authorization: Bearer $SERVICE_ACCOUNT_TOKEN" -H "Content-Type: application/json-patch+json" -X PATCH --data "$PATCH_PAYLOAD" $POD_URL diff --git a/test/e2e/testdata/syncwaves-prune-order/rbac.yaml b/test/e2e/testdata/syncwaves-prune-order/rbac.yaml new file mode 100644 index 0000000000000..9512644b731db --- /dev/null +++ b/test/e2e/testdata/syncwaves-prune-order/rbac.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: modify-pods-sa + annotations: + argocd.argoproj.io/sync-wave: "0" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: modify-pods-role + annotations: + argocd.argoproj.io/sync-wave: "0" +rules: + - apiGroups: [""] + resources: + - pods + verbs: + - get + - list + - delete + - update + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: modify-pods-rolebinding + annotations: + argocd.argoproj.io/sync-wave: "1" +subjects: + - kind: ServiceAccount + name: modify-pods-sa +roleRef: + kind: Role + name: modify-pods-role + apiGroup: rbac.authorization.k8s.io \ No newline at end of file From 981bceecb06aa0adc6275cff860c1aad9056f724 Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Tue, 30 Jan 2024 12:55:50 -0500 Subject: [PATCH 228/269] docs(applicationset): explain impact of empty spec in templatePatch (#17042) * docs: explain impact of empty spec in templatePatch Signed-off-by: Nicholas Morey * fix: not conditional helm values Signed-off-by: Nicholas Morey --------- Signed-off-by: Nicholas Morey --- docs/operator-manual/applicationset/Template.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/operator-manual/applicationset/Template.md b/docs/operator-manual/applicationset/Template.md index 573e297bff2e2..9a7cd574453b4 100644 --- a/docs/operator-manual/applicationset/Template.md +++ b/docs/operator-manual/applicationset/Template.md @@ -111,16 +111,15 @@ In this example, the ApplicationSet controller will generate an `Application` re ## Template Patch -Templating is only available on string type. However, some uses cases may require to apply templating on other types. +Templating is only available on string type. However, some use cases may require applying templating on other types. Example: -- Set the automated sync policy -- Switch prune boolean to true -- Add multiple helm value files - -Argo CD has a `templatePatch` feature to allow advanced templating. It supports both json and yaml. +- Conditionally set the automated sync policy. +- Conditionally switch prune boolean to `true`. +- Add multiple helm value files from a list. +The `templatePatch` feature enables advanced templating, with support for `json` and `yaml`. ```yaml apiVersion: argoproj.io/v1alpha1 @@ -174,3 +173,6 @@ spec: The `spec.project` field is not supported in `templatePatch`. If you need to change the project, you can use the `spec.project` field in the `template` field. + +!!! important + When writing a `templatePatch`, you're crafting a patch. So, if the patch includes an empty `spec: # nothing in here`, it will effectively clear out existing fields. See [#17040](https://github.com/argoproj/argo-cd/issues/17040) for an example of this behavior. From 4d53d36268289891f80ba12620287b7ae11c9499 Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Tue, 30 Jan 2024 13:21:29 -0500 Subject: [PATCH 229/269] docs(kustomize): add components yaml example (#17043) Signed-off-by: Nicholas Morey --- docs/user-guide/kustomize.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/user-guide/kustomize.md b/docs/user-guide/kustomize.md index 647e753649cce..3da35b7eede76 100644 --- a/docs/user-guide/kustomize.md +++ b/docs/user-guide/kustomize.md @@ -106,6 +106,37 @@ spec: namespace: default ``` +## Components +Kustomize [components](https://github.com/kubernetes-sigs/kustomize/blob/master/examples/components.md) encapsulate both resources and patches together. They provide a powerful way to modularize and reuse configuration in Kubernetes applications. + +Outside of Argo CD, to utilize components, you must add the following to the `kustomization.yaml` that the Application references. For example: +```yaml +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +... +components: +- ../component +``` + +With support added for components in `v2.10.0`, you can now reference a component directly in the Application: +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: application-kustomize-components +spec: + ... + source: + path: examples/application-kustomize-components/base + repoURL: https://github.com/my-user/my-repo + targetRevision: main + + # This! + kustomize: + components: + - ../component # relative to the kustomization.yaml (`source.path`). +``` + ## Private Remote Bases If you have remote bases that are either (a) HTTPS and need username/password (b) SSH and need SSH private key, then they'll inherit that from the app's repo. From 55918abd77e88ea713d4391be363b6e7accc034e Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Tue, 30 Jan 2024 13:21:49 -0500 Subject: [PATCH 230/269] docs(argocd-cm): add timeout.reconciliation.jitter example (#17044) Signed-off-by: Nicholas Morey --- docs/operator-manual/argocd-cm.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/operator-manual/argocd-cm.yaml b/docs/operator-manual/argocd-cm.yaml index ddc47ffc936d0..4355354d2faef 100644 --- a/docs/operator-manual/argocd-cm.yaml +++ b/docs/operator-manual/argocd-cm.yaml @@ -318,6 +318,12 @@ data: # published to the repository. Reconciliation by timeout is disabled if timeout is set to 0. Three minutes by default. # > Note: argocd-repo-server deployment must be manually restarted after changing the setting. timeout.reconciliation: 180s + # With a large number of applications, the periodic refresh for each application can cause a spike in the refresh queue + # and can cause a spike in the repo-server component. To avoid this, you can set a jitter to the sync timeout, which will + # spread out the refreshes and give time to the repo-server to catch up. The jitter is the maximum duration that can be + # added to the sync timeout. So, if the sync timeout is 3 minutes and the jitter is 1 minute, then the actual timeout will + # be between 3 and 4 minutes. Disabled when the value is 0, defaults to 0. + timeout.reconciliation.jitter: 0 # cluster.inClusterEnabled indicates whether to allow in-cluster server address. This is enabled by default. cluster.inClusterEnabled: "true" From 7f749c62b803b1d043ba835b5648ea9e967b8b59 Mon Sep 17 00:00:00 2001 From: Nicholas Morey Date: Tue, 30 Jan 2024 20:51:25 -0500 Subject: [PATCH 231/269] docs(hooks): add postdelete to table (#17048) Add `PostDelete` to the hooks table, and clean up wording and old availability statement (all the way back to v1, probably irrelevant). Signed-off-by: Nicholas Morey --- docs/user-guide/resource_hooks.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/user-guide/resource_hooks.md b/docs/user-guide/resource_hooks.md index a6fdaf8bd2e05..6e15a55bb20c2 100644 --- a/docs/user-guide/resource_hooks.md +++ b/docs/user-guide/resource_hooks.md @@ -8,9 +8,9 @@ and after a Sync operation. Hooks can also be run if a Sync operation fails at a * Using a `Sync` hook to orchestrate a complex deployment requiring more sophistication than the Kubernetes rolling update strategy. * Using a `PostSync` hook to run integration and health checks after a deployment. -* Using a `SyncFail` hook to run clean-up or finalizer logic if a Sync operation fails. _`SyncFail` hooks are only available starting in v1.2_ -* Using a `PostDelete` hook to run clean-up or finalizer logic after an all Application resources are deleted. Please note that - `PostDelete` hooks are only deleted if delete policy matches to the aggregated deletion hooks status and not garbage collected after the application is deleted. +* Using a `SyncFail` hook to run clean-up or finalizer logic if a Sync operation fails. +* Using a `PostDelete` hook to run clean-up or finalizer logic after all Application resources are deleted. Please note that + `PostDelete` hooks are only deleted if the delete policy matches the aggregated deletion hooks status and not garbage collected after the application is deleted. ## Usage @@ -39,7 +39,8 @@ The following hooks are defined: | `Sync` | Executes after all `PreSync` hooks completed and were successful, at the same time as the application of the manifests. | | `Skip` | Indicates to Argo CD to skip the application of the manifest. | | `PostSync` | Executes after all `Sync` hooks completed and were successful, a successful application, and all resources in a `Healthy` state. | -| `SyncFail` | Executes when the sync operation fails. _Available starting in v1.2_ | +| `SyncFail` | Executes when the sync operation fails. | +| `PostDelete` | Executes after all Application resources are deleted. _Available starting in v2.10._ | ### Generate Name From c691d366a5b63e66587f0f5cf0b132f9c1995d5d Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Tue, 30 Jan 2024 20:45:11 -0600 Subject: [PATCH 232/269] Corrected certificate managment for OCI helm charts (#16656) Signed-off-by: Andrew Block Co-authored-by: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> --- util/helm/cmd.go | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/util/helm/cmd.go b/util/helm/cmd.go index 419c7daff5d3c..cc2a1388d65a2 100644 --- a/util/helm/cmd.go +++ b/util/helm/cmd.go @@ -91,6 +91,28 @@ func (c *Cmd) RegistryLogin(repo string, creds Creds) (string, error) { args = append(args, "--password", creds.Password) } + if creds.CAPath != "" { + args = append(args, "--ca-file", creds.CAPath) + } + + if len(creds.CertData) > 0 { + filePath, closer, err := writeToTmp(creds.CertData) + if err != nil { + return "", err + } + defer argoio.Close(closer) + args = append(args, "--cert-file", filePath) + } + + if len(creds.KeyData) > 0 { + filePath, closer, err := writeToTmp(creds.KeyData) + if err != nil { + return "", err + } + defer argoio.Close(closer) + args = append(args, "--key-file", filePath) + } + if creds.InsecureSkipVerify { args = append(args, "--insecure") } @@ -238,6 +260,25 @@ func (c *Cmd) PullOCI(repo string, chart string, version string, destination str if creds.CAPath != "" { args = append(args, "--ca-file", creds.CAPath) } + + if len(creds.CertData) > 0 { + filePath, closer, err := writeToTmp(creds.CertData) + if err != nil { + return "", err + } + defer argoio.Close(closer) + args = append(args, "--cert-file", filePath) + } + + if len(creds.KeyData) > 0 { + filePath, closer, err := writeToTmp(creds.KeyData) + if err != nil { + return "", err + } + defer argoio.Close(closer) + args = append(args, "--key-file", filePath) + } + if creds.InsecureSkipVerify && c.insecureSkipVerifySupported { args = append(args, "--insecure-skip-tls-verify") } From 291445f1321039f482dbf55827b24fac82e8eff5 Mon Sep 17 00:00:00 2001 From: Shyukri Shyukriev Date: Wed, 31 Jan 2024 22:23:45 +0200 Subject: [PATCH 233/269] chore: use kubernetes 1.29.0 in CI (#17050) Keeping 1.25 for now. Signed-off-by: Shyukri Shyukriev --- .github/workflows/ci-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 3a596a9552d70..a08299a223a6b 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -362,7 +362,7 @@ jobs: strategy: fail-fast: false matrix: - k3s-version: [v1.28.2, v1.27.6, v1.26.9, v1.25.14] + k3s-version: [v1.29.0, v1.28.2, v1.27.6, v1.26.9, v1.25.14] needs: - build-go env: From f4019b7657ed06715ab6e148c831850a5affa7f0 Mon Sep 17 00:00:00 2001 From: Simon HEGE Date: Wed, 31 Jan 2024 21:26:28 +0100 Subject: [PATCH 234/269] chore(deps): bump Helm to 3.14.0 (#17031) (#17032) * bump helm to 3.14.0 Signed-off-by: Simon HEGE * Add a note about helm bump in upgrade instructions Signed-off-by: Simon HEGE --------- Signed-off-by: Simon HEGE --- docs/operator-manual/upgrading/2.9-2.10.md | 4 ++++ .../checksums/helm-v3.14.0-linux-amd64.tar.gz.sha256 | 1 + .../checksums/helm-v3.14.0-linux-arm64.tar.gz.sha256 | 1 + .../checksums/helm-v3.14.0-linux-ppc64le.tar.gz.sha256 | 1 + .../checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 | 1 + hack/tool-versions.sh | 2 +- 6 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 hack/installers/checksums/helm-v3.14.0-linux-amd64.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.14.0-linux-arm64.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.14.0-linux-ppc64le.tar.gz.sha256 create mode 100644 hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 diff --git a/docs/operator-manual/upgrading/2.9-2.10.md b/docs/operator-manual/upgrading/2.9-2.10.md index 4cd7c379bdc81..cfb3e286649ac 100644 --- a/docs/operator-manual/upgrading/2.9-2.10.md +++ b/docs/operator-manual/upgrading/2.9-2.10.md @@ -10,3 +10,7 @@ removed. To avoid unexpected behavior, follow the [client-side to server-side resource upgrade guide](https://kubernetes.io/docs/reference/using-api/server-side-apply/#upgrading-from-client-side-apply-to-server-side-apply) before enabling `managedNamespaceMetadata` on an existing namespace. + +## Upgraded Helm Version + +Note that bundled Helm version has been upgraded from 3.13.2 to 3.14.0. diff --git a/hack/installers/checksums/helm-v3.14.0-linux-amd64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.14.0-linux-amd64.tar.gz.sha256 new file mode 100644 index 0000000000000..6f9aaf5a270d5 --- /dev/null +++ b/hack/installers/checksums/helm-v3.14.0-linux-amd64.tar.gz.sha256 @@ -0,0 +1 @@ +f43e1c3387de24547506ab05d24e5309c0ce0b228c23bd8aa64e9ec4b8206651 helm-v3.14.0-linux-amd64.tar.gz diff --git a/hack/installers/checksums/helm-v3.14.0-linux-arm64.tar.gz.sha256 b/hack/installers/checksums/helm-v3.14.0-linux-arm64.tar.gz.sha256 new file mode 100644 index 0000000000000..d0e09bd4b41f7 --- /dev/null +++ b/hack/installers/checksums/helm-v3.14.0-linux-arm64.tar.gz.sha256 @@ -0,0 +1 @@ +b29e61674731b15f6ad3d1a3118a99d3cc2ab25a911aad1b8ac8c72d5a9d2952 helm-v3.14.0-linux-arm64.tar.gz diff --git a/hack/installers/checksums/helm-v3.14.0-linux-ppc64le.tar.gz.sha256 b/hack/installers/checksums/helm-v3.14.0-linux-ppc64le.tar.gz.sha256 new file mode 100644 index 0000000000000..d179322b99dd5 --- /dev/null +++ b/hack/installers/checksums/helm-v3.14.0-linux-ppc64le.tar.gz.sha256 @@ -0,0 +1 @@ +f1f9d3561724863edd4c06d89acb2e2fd8ae0f1b72058ceb891fa1c346ce5dbc helm-v3.14.0-linux-ppc64le.tar.gz diff --git a/hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 b/hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 new file mode 100644 index 0000000000000..31ff04397b29e --- /dev/null +++ b/hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 @@ -0,0 +1 @@ +82298ef39936f1bef848959a29f77bff92d1309d8646657e3a7733702e81288c helm-v3.14.0-linux-s390x.tar.gz diff --git a/hack/tool-versions.sh b/hack/tool-versions.sh index ecc1c424febfa..3cd1bc15aa4c4 100644 --- a/hack/tool-versions.sh +++ b/hack/tool-versions.sh @@ -11,7 +11,7 @@ # Use ./hack/installers/checksums/add-helm-checksums.sh and # add-kustomize-checksums.sh to help download checksums. ############################################################################### -helm3_version=3.13.2 +helm3_version=3.14.0 kubectl_version=1.17.8 kubectx_version=0.6.3 kustomize5_version=5.2.1 From 28f362b88671ff4c2ec30af1eabbb220177cd91a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 15:29:36 -0500 Subject: [PATCH 235/269] chore(deps): bump github.com/evanphx/json-patch (#17021) Bumps [github.com/evanphx/json-patch](https://github.com/evanphx/json-patch) from 5.6.0+incompatible to 5.9.0+incompatible. - [Release notes](https://github.com/evanphx/json-patch/releases) - [Commits](https://github.com/evanphx/json-patch/compare/v5.6.0...v5.9.0) --- updated-dependencies: - dependency-name: github.com/evanphx/json-patch 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 | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d781c91b47ee5..5459ef6666ec0 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/coreos/go-oidc/v3 v3.6.0 github.com/cyphar/filepath-securejoin v0.2.4 github.com/dustin/go-humanize v1.0.1 - github.com/evanphx/json-patch v5.6.0+incompatible + github.com/evanphx/json-patch v5.9.0+incompatible github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.11.0 diff --git a/go.sum b/go.sum index 4c7aefc9e7fdf..6da3e899b9581 100644 --- a/go.sum +++ b/go.sum @@ -875,8 +875,8 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBF github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE= github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= -github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= From 0c8bc1d61e8c9501c5aaabb2aafecc20aa43e1bb Mon Sep 17 00:00:00 2001 From: Carlos Santana Date: Wed, 31 Jan 2024 21:30:32 -0500 Subject: [PATCH 236/269] chore(deps): Upgrade aws-sdk-go to support eks pod identity (#17063) * chore: Upgrade aws-sdk-go to support eks pod identity --------- Signed-off-by: Carlos Santana Co-authored-by: Mathieu Bruneau * add cogen for notifications Signed-off-by: Carlos Santana --------- Signed-off-by: Carlos Santana Co-authored-by: Mathieu Bruneau --- .../notifications/services/opsgenie.md | 4 +- .../notifications/services/pagerduty.md | 12 ++-- .../notifications/services/pagerduty_v2.md | 2 +- go.mod | 31 +++++----- go.sum | 62 ++++++++++--------- 5 files changed, 57 insertions(+), 54 deletions(-) diff --git a/docs/operator-manual/notifications/services/opsgenie.md b/docs/operator-manual/notifications/services/opsgenie.md index 665d0081e7c73..c590a4ac979b6 100755 --- a/docs/operator-manual/notifications/services/opsgenie.md +++ b/docs/operator-manual/notifications/services/opsgenie.md @@ -12,8 +12,8 @@ To be able to send notifications with argocd-notifications you have to create an 8. Give your integration a name, copy the "API key" and safe it somewhere for later 9. Make sure the checkboxes for "Create and Update Access" and "enable" are selected, disable the other checkboxes to remove unnecessary permissions 10. Click "Safe Integration" at the bottom -11. Check your browser for the correct server apiURL. If it is "app.opsgenie.com" then use the us/international api url `api.opsgenie.com` in the next step, otherwise use `api.eu.opsgenie.com` (european api). -12. You are finished with configuring opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the opsgenie integration in the `argocd-notifications-secret` secret. +11. Check your browser for the correct server apiURL. If it is "app.opsgenie.com" then use the US/international api url `api.opsgenie.com` in the next step, otherwise use `api.eu.opsgenie.com` (European API). +12. You are finished with configuring opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret. ```yaml apiVersion: v1 diff --git a/docs/operator-manual/notifications/services/pagerduty.md b/docs/operator-manual/notifications/services/pagerduty.md index 0e1ab965332e1..3b507e7fdba58 100755 --- a/docs/operator-manual/notifications/services/pagerduty.md +++ b/docs/operator-manual/notifications/services/pagerduty.md @@ -1,17 +1,17 @@ -# Pagerduty +# PagerDuty ## Parameters -The Pagerduty notification service is used to create pagerduty incidents and requires specifying the following settings: +The PagerDuty notification service is used to create PagerDuty incidents and requires specifying the following settings: -* `pagerdutyToken` - the pagerduty auth token +* `pagerdutyToken` - the PagerDuty auth token * `from` - email address of a valid user associated with the account making the request. * `serviceID` - The ID of the resource. ## Example -The following snippet contains sample Pagerduty service configuration: +The following snippet contains sample PagerDuty service configuration: ```yaml apiVersion: v1 @@ -35,7 +35,7 @@ data: ## Template -[Notification templates](../templates.md) support specifying subject for pagerduty notifications: +[Notification templates](../templates.md) support specifying subject for PagerDuty notifications: ```yaml apiVersion: v1 @@ -62,5 +62,5 @@ apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: annotations: - notifications.argoproj.io/subscribe.on-rollout-aborted.pagerduty: "" + notifications.argoproj.io/subscribe.on-rollout-aborted.pagerduty: "" ``` diff --git a/docs/operator-manual/notifications/services/pagerduty_v2.md b/docs/operator-manual/notifications/services/pagerduty_v2.md index 21e8d942e4e93..01eee28fc0c9b 100755 --- a/docs/operator-manual/notifications/services/pagerduty_v2.md +++ b/docs/operator-manual/notifications/services/pagerduty_v2.md @@ -74,5 +74,5 @@ apiVersion: argoproj.io/v1alpha1 kind: Rollout metadata: annotations: - notifications.argoproj.io/subscribe.on-rollout-aborted.pagerdutyv2: "" + notifications.argoproj.io/subscribe.on-rollout-aborted.pagerdutyv2: "" ``` diff --git a/go.mod b/go.mod index 5459ef6666ec0..f306c51c1722b 100644 --- a/go.mod +++ b/go.mod @@ -14,9 +14,9 @@ require ( github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 - github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 + github.com/argoproj/notifications-engine v0.4.1-0.20240126143042-84b9f7913604 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 - github.com/aws/aws-sdk-go v1.44.317 + github.com/aws/aws-sdk-go v1.50.8 github.com/bmatcuk/doublestar/v4 v4.6.0 github.com/bombsimon/logrusr/v2 v2.0.1 github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 @@ -114,19 +114,20 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v0.5.2 // indirect - github.com/aws/aws-sdk-go-v2 v1.17.3 // indirect - github.com/aws/aws-sdk-go-v2/config v1.18.8 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.8 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 // indirect - github.com/aws/aws-sdk-go-v2/service/sqs v1.20.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.12.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.18.0 // indirect - github.com/aws/smithy-go v1.13.5 // indirect + github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect + github.com/aws/aws-sdk-go-v2/config v1.25.12 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sqs v1.29.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect + github.com/aws/smithy-go v1.19.0 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/google/s2a-go v0.1.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect diff --git a/go.sum b/go.sum index 6da3e899b9581..8ab6ead977d19 100644 --- a/go.sum +++ b/go.sum @@ -696,8 +696,8 @@ github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2 github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 h1:5fKAhTQcTBom0vin56cz/UTPx2GMuvdb+lJRAUOPbHA= github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= -github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9 h1:1lt0VXzmLK7Vv0kaeal3S6/JIfzPyBORkUWXhiqF3l0= -github.com/argoproj/notifications-engine v0.4.1-0.20231027194313-a8d185ecc0a9/go.mod h1:E/vv4+by868m0mmflaRfGBmKBtAupoF+mmyfekP8QCk= +github.com/argoproj/notifications-engine v0.4.1-0.20240126143042-84b9f7913604 h1:pMfBao6Vm1Ax0xGIp9BWEia2nKkccHwV0dTEdrsFOpo= +github.com/argoproj/notifications-engine v0.4.1-0.20240126143042-84b9f7913604/go.mod h1:TsyusmXQWIL0ST7YMRG/ered7WlWDmbmnPpXnS2LJmM= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -713,35 +713,37 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go v1.44.317 h1:+8XWrLmGMwPPXSRSLPzhgcGnzJ2mYkgkrcB9C/GnSOU= -github.com/aws/aws-sdk-go v1.44.317/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.50.8 h1:gY0WoOW+/Wz6XmYSgDH9ge3wnAevYDSQWPxxJvqAkP4= +github.com/aws/aws-sdk-go v1.50.8/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/aws/aws-sdk-go-v2 v1.17.3 h1:shN7NlnVzvDUgPQ+1rLMSxY8OWRNDRYtiqe0p/PgrhY= -github.com/aws/aws-sdk-go-v2 v1.17.3/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2/config v1.18.8 h1:lDpy0WM8AHsywOnVrOHaSMfpaiV2igOw8D7svkFkXVA= -github.com/aws/aws-sdk-go-v2/config v1.18.8/go.mod h1:5XCmmyutmzzgkpk/6NYTjeWb6lgo9N170m1j6pQkIBs= -github.com/aws/aws-sdk-go-v2/credentials v1.13.8 h1:vTrwTvv5qAwjWIGhZDSBH/oQHuIQjGmD232k01FUh6A= -github.com/aws/aws-sdk-go-v2/credentials v1.13.8/go.mod h1:lVa4OHbvgjVot4gmh1uouF1ubgexSCN92P6CJQpT0t8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21 h1:j9wi1kQ8b+e0FBVHxCqCGo4kxDU175hoDHcWAi0sauU= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.21/go.mod h1:ugwW57Z5Z48bpvUyZuaPy4Kv+vEfJWnIrky7RmkBvJg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 h1:I3cakv2Uy1vNmmhRQmFptYDxOvBnwCdNwyw63N0RaRU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27/go.mod h1:a1/UpzeyBBerajpnP5nGZa9mGzsBn5cOKxm6NWQsvoI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 h1:5NbbMrIzmUn/TXFqAle6mgrH5m9cOvMLRGL7pnG8tRE= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21/go.mod h1:+Gxn8jYn5k9ebfHEqlhrMirFjSW0v0C9fI+KN5vk2kE= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 h1:KeTxcGdNnQudb46oOl4d90f2I33DF/c6q3RnZAmvQdQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28/go.mod h1:yRZVr/iT0AqyHeep00SZ4YfBAKojXz08w3XMBscdi0c= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 h1:5C6XgTViSb0bunmU57b3CT+MhxULqHH2721FVA+/kDM= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21/go.mod h1:lRToEJsn+DRA9lW4O9L9+/3hjTkUzlzyzHqn8MTds5k= -github.com/aws/aws-sdk-go-v2/service/sqs v1.20.0 h1:tQoMg8i4nFAB70cJ4wiAYEiZRYo2P6uDmU2D6ys/igo= -github.com/aws/aws-sdk-go-v2/service/sqs v1.20.0/go.mod h1:jQhN5f4p3PALMNlUtfb/0wGIFlV7vGtJlPDVfxfNfPY= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.0 h1:/2gzjhQowRLarkkBOGPXSRnb8sQ2RVsjdG1C/UliK/c= -github.com/aws/aws-sdk-go-v2/service/sso v1.12.0/go.mod h1:wo/B7uUm/7zw/dWhBJ4FXuw1sySU5lyIhVg1Bu2yL9A= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.0 h1:Jfly6mRxk2ZOSlbCvZfKNS7TukSx1mIzhSsqZ/IGSZI= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.0/go.mod h1:TZSH7xLO7+phDtViY/KUp9WGCJMQkLJ/VpgkTFd5gh8= -github.com/aws/aws-sdk-go-v2/service/sts v1.18.0 h1:kOO++CYo50RcTFISESluhWEi5Prhg+gaSs4whWabiZU= -github.com/aws/aws-sdk-go-v2/service/sts v1.18.0/go.mod h1:+lGbb3+1ugwKrNTWcf2RT05Xmp543B06zDFTwiTLp7I= -github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= -github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= +github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= +github.com/aws/aws-sdk-go-v2/config v1.25.12 h1:mF4cMuNh/2G+d19nWnm1vJ/ak0qK6SbqF0KtSX9pxu0= +github.com/aws/aws-sdk-go-v2/config v1.25.12/go.mod h1:lOvvqtZP9p29GIjOTuA/76HiVk0c/s8qRcFRq2+E2uc= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1 h1:uR9lXYjdPX0xY+NhvaJ4dD8rpSRz5VY81ccIIoNG+lw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.1/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= +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.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= +github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= +github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= From b8aeb781a6f5f495bf8e6b421daa0b2427876baf Mon Sep 17 00:00:00 2001 From: Kerwood Date: Thu, 1 Feb 2024 17:27:30 +0100 Subject: [PATCH 237/269] fix: removed pkce code challange check for WebUI (#16730) Signed-off-by: Patrick Kerwood --- ui/src/app/login/components/utils.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ui/src/app/login/components/utils.ts b/ui/src/app/login/components/utils.ts index 90453ced77d4a..6c715077cc9cc 100644 --- a/ui/src/app/login/components/utils.ts +++ b/ui/src/app/login/components/utils.ts @@ -74,10 +74,6 @@ export const pkceLogin = async (oidcConfig: AuthSettings['oidcConfig'], redirect throw new PKCELoginError('No Authorization Server endpoint found'); } - if (!authorizationServer?.code_challenge_methods_supported?.includes('S256')) { - throw new PKCELoginError('Authorization Server does not support S256 code challenge method'); - } - const codeVerifier = generateRandomCodeVerifier(); const codeChallange = await calculatePKCECodeChallenge(codeVerifier); From fa31c2323ad319eae5a93dba4c70b3e24726d1a3 Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Thu, 1 Feb 2024 13:39:20 -0500 Subject: [PATCH 238/269] chore(ci): bump k3s versions to latest patches (#17060) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- .github/workflows/ci-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index a08299a223a6b..c86bfb3b3a673 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -362,7 +362,7 @@ jobs: strategy: fail-fast: false matrix: - k3s-version: [v1.29.0, v1.28.2, v1.27.6, v1.26.9, v1.25.14] + k3s-version: [v1.29.1, v1.28.6, v1.27.10, v1.26.13, v1.25.16] needs: - build-go env: From dc1ccea568d2ed1da77c04422676b5e7c8617e04 Mon Sep 17 00:00:00 2001 From: Leonardo Luz Almeida Date: Fri, 2 Feb 2024 11:56:48 -0500 Subject: [PATCH 239/269] feat: add prometheus metrics around proxy extension requests (#17012) * feat: add prometheus metrics around proxy extension requests Signed-off-by: Leonardo Luz Almeida * update go.mod Signed-off-by: Leonardo Luz Almeida * fix metrics bugs Signed-off-by: Leonardo Luz Almeida * fix unit-test Signed-off-by: Leonardo Luz Almeida * Add unit suffix in the duration metric Signed-off-by: Leonardo Luz Almeida * update doc Signed-off-by: Leonardo Luz Almeida --------- Signed-off-by: Leonardo Luz Almeida --- docs/operator-manual/metrics.md | 2 + go.mod | 2 +- server/extension/extension.go | 47 +++++++++++++++++-- server/extension/extension_test.go | 44 +++++++++++++++-- .../mocks/ExtensionMetricsRegistry.go | 38 +++++++++++++++ server/metrics/metrics.go | 37 +++++++++++++-- server/server.go | 35 ++++++++++---- 7 files changed, 180 insertions(+), 25 deletions(-) create mode 100644 server/extension/mocks/ExtensionMetricsRegistry.go diff --git a/docs/operator-manual/metrics.md b/docs/operator-manual/metrics.md index cfd2a8a8093ac..634684a430045 100644 --- a/docs/operator-manual/metrics.md +++ b/docs/operator-manual/metrics.md @@ -70,6 +70,8 @@ Scraped at the `argocd-server-metrics:8083/metrics` endpoint. | `argocd_redis_request_total` | counter | Number of Kubernetes requests executed during application reconciliation. | | `grpc_server_handled_total` | counter | Total number of RPCs completed on the server, regardless of success or failure. | | `grpc_server_msg_sent_total` | counter | Total number of gRPC stream messages sent by the server. | +| `argocd_proxy_extension_request_total` | counter | Number of requests sent to the configured proxy extensions. | +| `argocd_proxy_extension_request_duration_seconds` | histogram | Request duration in seconds between the Argo CD API server and the proxy extension backend. | ## Repo Server Metrics Metrics about the Repo Server. diff --git a/go.mod b/go.mod index f306c51c1722b..297829e95754e 100644 --- a/go.mod +++ b/go.mod @@ -26,6 +26,7 @@ require ( github.com/cyphar/filepath-securejoin v0.2.4 github.com/dustin/go-humanize v1.0.1 github.com/evanphx/json-patch v5.9.0+incompatible + github.com/felixge/httpsnoop v1.0.3 github.com/fsnotify/fsnotify v1.6.0 github.com/gfleury/go-bitbucket-v1 v0.0.0-20220301131131-8e7ed04b843e github.com/go-git/go-git/v5 v5.11.0 @@ -179,7 +180,6 @@ require ( github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fatih/camelcase v1.0.0 // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect github.com/fvbommel/sortorder v1.0.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect diff --git a/server/extension/extension.go b/server/extension/extension.go index aca924620756c..9f8edcd6184fc 100644 --- a/server/extension/extension.go +++ b/server/extension/extension.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/felixge/httpsnoop" log "github.com/sirupsen/logrus" "gopkg.in/yaml.v3" @@ -300,6 +301,19 @@ type Manager struct { project ProjectGetter rbac RbacEnforcer registry ExtensionRegistry + metricsReg ExtensionMetricsRegistry +} + +// ExtensionMetricsRegistry exposes operations to update http metrics in the Argo CD +// API server. +type ExtensionMetricsRegistry interface { + // IncExtensionRequestCounter will increase the request counter for the given + // extension with the given status. + IncExtensionRequestCounter(extension string, status int) + // ObserveExtensionRequestDuration will register the request roundtrip duration + // between Argo CD API Server and the extension backend service for the given + // extension. + ObserveExtensionRequestDuration(extension string, duration time.Duration) } // NewManager will initialize a new manager. @@ -423,7 +437,8 @@ func validateConfigs(configs *ExtensionConfigs) error { } // NewProxy will instantiate a new reverse proxy based on the provided -// targetURL and config. +// targetURL and config. It will remove sensitive information from the +// incoming request such as the Authorization and Cookie headers. func NewProxy(targetURL string, headers []Header, config ProxyConfig) (*httputil.ReverseProxy, error) { url, err := url.Parse(targetURL) if err != nil { @@ -484,6 +499,10 @@ func (m *Manager) RegisterExtensions() error { if err != nil { return fmt.Errorf("error getting settings: %s", err) } + if settings.ExtensionConfig == "" { + m.log.Infof("No extensions configured.") + return nil + } err = m.UpdateExtensionRegistry(settings) if err != nil { return fmt.Errorf("error updating extension registry: %s", err) @@ -683,13 +702,26 @@ func (m *Manager) CallExtension() func(http.ResponseWriter, *http.Request) { prepareRequest(r, extName, app) m.log.Debugf("proxing request for extension %q", extName) - proxy.ServeHTTP(w, r) + // httpsnoop package is used to properly wrap the responseWriter + // and avoid optional intefaces issue: + // https://github.com/felixge/httpsnoop#why-this-package-exists + // CaptureMetrics will call the proxy and return the metrics from it. + metrics := httpsnoop.CaptureMetrics(proxy, w, r) + + go registerMetrics(extName, metrics, m.metricsReg) } } -// prepareRequest is reponsible for preparing and cleaning the given -// request, removing sensitive information before forwarding it to the -// proxy extension. +func registerMetrics(extName string, metrics httpsnoop.Metrics, extensionMetricsRegistry ExtensionMetricsRegistry) { + if extensionMetricsRegistry != nil { + extensionMetricsRegistry.IncExtensionRequestCounter(extName, metrics.Code) + extensionMetricsRegistry.ObserveExtensionRequestDuration(extName, metrics.Duration) + } +} + +// prepareRequest is reponsible for cleaning the incoming request URL removing +// the Argo CD extension API section from it. It will set the cluster destination name +// and cluster destination server in the headers as it is defined in the given app. func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application) { r.URL.Path = strings.TrimPrefix(r.URL.Path, fmt.Sprintf("%s/%s", URLPrefix, extName)) if app.Spec.Destination.Name != "" { @@ -699,3 +731,8 @@ func prepareRequest(r *http.Request, extName string, app *v1alpha1.Application) r.Header.Set(HeaderArgoCDTargetClusterURL, app.Spec.Destination.Server) } } + +// AddMetricsRegistry will associate the given metricsReg in the Manager. +func (m *Manager) AddMetricsRegistry(metricsReg ExtensionMetricsRegistry) { + m.metricsReg = metricsReg +} diff --git a/server/extension/extension_test.go b/server/extension/extension_test.go index 273779d59ca29..ff287dde80424 100644 --- a/server/extension/extension_test.go +++ b/server/extension/extension_test.go @@ -8,6 +8,7 @@ import ( "net/http" "net/http/httptest" "strings" + "sync" "testing" "github.com/sirupsen/logrus/hooks/test" @@ -188,10 +189,6 @@ func TestRegisterExtensions(t *testing.T) { configYaml string } cases := []testCase{ - { - name: "no config", - configYaml: "", - }, { name: "no name", configYaml: getExtensionConfigNoName(), @@ -234,7 +231,7 @@ func TestRegisterExtensions(t *testing.T) { err := f.manager.RegisterExtensions() // then - assert.Error(t, err) + assert.Error(t, err, fmt.Sprintf("expected error in test %s but got nil", tc.name)) }) } }) @@ -247,6 +244,7 @@ func TestCallExtension(t *testing.T) { settingsGetterMock *mocks.SettingsGetter rbacMock *mocks.RbacEnforcer projMock *mocks.ProjectGetter + metricsMock *mocks.ExtensionMetricsRegistry manager *extension.Manager } defaultProjectName := "project-name" @@ -256,10 +254,12 @@ func TestCallExtension(t *testing.T) { settMock := &mocks.SettingsGetter{} rbacMock := &mocks.RbacEnforcer{} projMock := &mocks.ProjectGetter{} + metricsMock := &mocks.ExtensionMetricsRegistry{} logger, _ := test.NewNullLogger() logEntry := logger.WithContext(context.Background()) m := extension.NewManager(logEntry, settMock, appMock, projMock, rbacMock) + m.AddMetricsRegistry(metricsMock) mux := http.NewServeMux() extHandler := http.HandlerFunc(m.CallExtension()) @@ -271,6 +271,7 @@ func TestCallExtension(t *testing.T) { settingsGetterMock: settMock, rbacMock: rbacMock, projMock: projMock, + metricsMock: metricsMock, manager: m, } } @@ -328,6 +329,11 @@ func TestCallExtension(t *testing.T) { f.projMock.On("Get", prj.GetName()).Return(prj, nil) } + withMetrics := func(f *fixture) { + f.metricsMock.On("IncExtensionRequestCounter", mock.Anything, mock.Anything) + f.metricsMock.On("ObserveExtensionRequestDuration", mock.Anything, mock.Anything) + } + withRbac := func(f *fixture, allowApp, allowExt bool) { var appAccessError error var extAccessError error @@ -406,6 +412,18 @@ func TestCallExtension(t *testing.T) { proj := getProjectWithDestinations("project-name", nil, []string{clusterURL}) f.appGetterMock.On("Get", mock.Anything, mock.Anything).Return(app, nil) withProject(proj, f) + var wg sync.WaitGroup + wg.Add(2) + f.metricsMock. + On("IncExtensionRequestCounter", mock.Anything, mock.Anything). + Run(func(args mock.Arguments) { + wg.Done() + }) + f.metricsMock. + On("ObserveExtensionRequestDuration", mock.Anything, mock.Anything). + Run(func(args mock.Arguments) { + wg.Done() + }) // when resp, err := http.DefaultClient.Do(r) @@ -420,6 +438,13 @@ func TestCallExtension(t *testing.T) { assert.Equal(t, backendResponse, actual) assert.Equal(t, clusterURL, resp.Header.Get(extension.HeaderArgoCDTargetClusterURL)) assert.Equal(t, "Bearer some-bearer-token", resp.Header.Get("Authorization")) + + // waitgroup is necessary to make sure assertions aren't executed before + // the goroutine initiated by extension.CallExtension concludes which would + // lead to flaky test. + wg.Wait() + f.metricsMock.AssertCalled(t, "IncExtensionRequestCounter", backendEndpoint, http.StatusOK) + f.metricsMock.AssertCalled(t, "ObserveExtensionRequestDuration", backendEndpoint, mock.Anything) }) t.Run("proxy will return 404 if extension endpoint not registered", func(t *testing.T) { // given @@ -427,6 +452,7 @@ func TestCallExtension(t *testing.T) { f := setup() withExtensionConfig(getExtensionConfigString(), f) withRbac(f, true, true) + withMetrics(f) cluster1Name := "cluster1" f.appGetterMock.On("Get", "namespace", "app-name").Return(getApp(cluster1Name, "", defaultProjectName), nil) withProject(getProjectWithDestinations("project-name", []string{cluster1Name}, []string{"some-url"}), f) @@ -466,6 +492,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, true, true) withExtensionConfig(getExtensionConfigWith2Backends(extName, beSrv1.URL, cluster1Name, beSrv2.URL, cluster2URL), f) withProject(getProjectWithDestinations("project-name", []string{cluster1Name}, []string{cluster2URL}), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() @@ -511,6 +538,7 @@ func TestCallExtension(t *testing.T) { extName := "some-extension" withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -533,6 +561,7 @@ func TestCallExtension(t *testing.T) { extName := "some-extension" withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -556,6 +585,7 @@ func TestCallExtension(t *testing.T) { noCluster := []string{} withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -580,6 +610,7 @@ func TestCallExtension(t *testing.T) { extName := "some-extension" withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -604,6 +635,7 @@ func TestCallExtension(t *testing.T) { differentProject := "differentProject" withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/%s/", ts.URL, extName)) @@ -634,6 +666,7 @@ func TestCallExtension(t *testing.T) { withRbac(f, true, true) withExtensionConfig(getExtensionConfigWith2Backends(extName, "url1", "clusterName", "url2", "clusterURL"), f) withProject(getProjectWithDestinations("project-name", nil, []string{"srv1", destinationServer}), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() @@ -666,6 +699,7 @@ func TestCallExtension(t *testing.T) { differentProject := "differentProject" withRbac(f, allowApp, allowExtension) withExtensionConfig(getExtensionConfig(extName, "http://fake"), f) + withMetrics(f) ts := startTestServer(t, f) defer ts.Close() r := newExtensionRequest(t, "Get", fmt.Sprintf("%s/extensions/", ts.URL)) diff --git a/server/extension/mocks/ExtensionMetricsRegistry.go b/server/extension/mocks/ExtensionMetricsRegistry.go new file mode 100644 index 0000000000000..78e583929f74d --- /dev/null +++ b/server/extension/mocks/ExtensionMetricsRegistry.go @@ -0,0 +1,38 @@ +// Code generated by mockery v2.38.0. DO NOT EDIT. + +package mocks + +import ( + time "time" + + mock "github.com/stretchr/testify/mock" +) + +// ExtensionMetricsRegistry is an autogenerated mock type for the ExtensionMetricsRegistry type +type ExtensionMetricsRegistry struct { + mock.Mock +} + +// IncExtensionRequestCounter provides a mock function with given fields: _a0, status +func (_m *ExtensionMetricsRegistry) IncExtensionRequestCounter(_a0 string, status int) { + _m.Called(_a0, status) +} + +// ObserveExtensionRequestDuration provides a mock function with given fields: _a0, duration +func (_m *ExtensionMetricsRegistry) ObserveExtensionRequestDuration(_a0 string, duration time.Duration) { + _m.Called(_a0, duration) +} + +// NewExtensionMetricsRegistry creates a new instance of ExtensionMetricsRegistry. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewExtensionMetricsRegistry(t interface { + mock.TestingT + Cleanup(func()) +}) *ExtensionMetricsRegistry { + mock := &ExtensionMetricsRegistry{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/server/metrics/metrics.go b/server/metrics/metrics.go index 40698e742b093..4afac9da26c02 100644 --- a/server/metrics/metrics.go +++ b/server/metrics/metrics.go @@ -14,8 +14,10 @@ import ( type MetricsServer struct { *http.Server - redisRequestCounter *prometheus.CounterVec - redisRequestHistogram *prometheus.HistogramVec + redisRequestCounter *prometheus.CounterVec + redisRequestHistogram *prometheus.HistogramVec + extensionRequestCounter *prometheus.CounterVec + extensionRequestDuration *prometheus.HistogramVec } var ( @@ -34,6 +36,21 @@ var ( }, []string{"initiator"}, ) + extensionRequestCounter = prometheus.NewCounterVec( + prometheus.CounterOpts{ + Name: "argocd_proxy_extension_request_total", + Help: "Number of requests sent to configured proxy extensions.", + }, + []string{"extension", "status"}, + ) + extensionRequestDuration = prometheus.NewHistogramVec( + prometheus.HistogramOpts{ + Name: "argocd_proxy_extension_request_duration_seconds", + Help: "Request duration in seconds between the Argo CD API server and the extension backend.", + Buckets: []float64{0.1, 0.25, .5, 1, 2, 5, 10}, + }, + []string{"extension"}, + ) ) // NewMetricsServer returns a new prometheus server which collects api server metrics @@ -48,14 +65,18 @@ func NewMetricsServer(host string, port int) *MetricsServer { registry.MustRegister(redisRequestCounter) registry.MustRegister(redisRequestHistogram) + registry.MustRegister(extensionRequestCounter) + registry.MustRegister(extensionRequestDuration) return &MetricsServer{ Server: &http.Server{ Addr: fmt.Sprintf("%s:%d", host, port), Handler: mux, }, - redisRequestCounter: redisRequestCounter, - redisRequestHistogram: redisRequestHistogram, + redisRequestCounter: redisRequestCounter, + redisRequestHistogram: redisRequestHistogram, + extensionRequestCounter: extensionRequestCounter, + extensionRequestDuration: extensionRequestDuration, } } @@ -67,3 +88,11 @@ func (m *MetricsServer) IncRedisRequest(failed bool) { func (m *MetricsServer) ObserveRedisRequestDuration(duration time.Duration) { m.redisRequestHistogram.WithLabelValues("argocd-server").Observe(duration.Seconds()) } + +func (m *MetricsServer) IncExtensionRequestCounter(extension string, status int) { + m.extensionRequestCounter.WithLabelValues(extension, strconv.Itoa(status)).Inc() +} + +func (m *MetricsServer) ObserveExtensionRequestDuration(extension string, duration time.Duration) { + m.extensionRequestDuration.WithLabelValues(extension).Observe(duration.Seconds()) +} diff --git a/server/server.go b/server/server.go index 8f6aafc689e94..e42e6f59a49a3 100644 --- a/server/server.go +++ b/server/server.go @@ -223,6 +223,18 @@ type ArgoCDServerOpts struct { EnableProxyExtension bool } +// HTTPMetricsRegistry exposes operations to update http metrics in the Argo CD +// API server. +type HTTPMetricsRegistry interface { + // IncExtensionRequestCounter will increase the request counter for the given + // extension with the given status. + IncExtensionRequestCounter(extension string, status int) + // ObserveExtensionRequestDuration will register the request roundtrip duration + // between Argo CD API Server and the extension backend service for the given + // extension. + ObserveExtensionRequestDuration(extension string, duration time.Duration) +} + // initializeDefaultProject creates the default project if it does not already exist func initializeDefaultProject(opts ArgoCDServerOpts) error { defaultProj := &v1alpha1.AppProject{ @@ -484,6 +496,12 @@ func (a *ArgoCDServer) Init(ctx context.Context) { // golang/protobuf). func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { a.userStateStorage.Init(ctx) + + metricsServ := metrics.NewMetricsServer(a.MetricsHost, a.MetricsPort) + if a.RedisClient != nil { + cacheutil.CollectMetrics(a.RedisClient, metricsServ) + } + svcSet := newArgoCDServiceSet(a) a.serviceSet = svcSet grpcS, appResourceTreeFn := a.newGRPCServer() @@ -492,9 +510,9 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { var httpsS *http.Server if a.useTLS() { httpS = newRedirectServer(a.ListenPort, a.RootPath) - httpsS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn) + httpsS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) } else { - httpS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn) + httpS = a.newHTTPServer(ctx, a.ListenPort, grpcWebS, appResourceTreeFn, listeners.GatewayConn, metricsServ) } if a.RootPath != "" { httpS.Handler = withRootPath(httpS.Handler, a) @@ -508,11 +526,6 @@ func (a *ArgoCDServer) Run(ctx context.Context, listeners *Listeners) { httpsS.Handler = &bug21955Workaround{handler: httpsS.Handler} } - metricsServ := metrics.NewMetricsServer(a.MetricsHost, a.MetricsPort) - if a.RedisClient != nil { - cacheutil.CollectMetrics(a.RedisClient, metricsServ) - } - // CMux is used to support servicing gRPC and HTTP1.1+JSON on the same port tcpm := cmux.New(listeners.Main) var tlsm cmux.CMux @@ -960,7 +973,7 @@ func compressHandler(handler http.Handler) http.Handler { // newHTTPServer returns the HTTP server to serve HTTP/HTTPS requests. This is implemented // using grpc-gateway as a proxy to the gRPC server. -func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn) *http.Server { +func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandler http.Handler, appResourceTreeFn application.AppResourceTreeFn, conn *grpc.ClientConn, metricsReg HTTPMetricsRegistry) *http.Server { endpoint := fmt.Sprintf("localhost:%d", port) mux := http.NewServeMux() httpS := http.Server{ @@ -1009,7 +1022,7 @@ func (a *ArgoCDServer) newHTTPServer(ctx context.Context, port int, grpcWebHandl // API server won't panic if extensions fail to register. In // this case an error log will be sent and no extension route // will be added in mux. - registerExtensions(mux, a) + registerExtensions(mux, a, metricsReg) } mustRegisterGWHandler(versionpkg.RegisterVersionServiceHandler, ctx, gwmux, conn) @@ -1079,13 +1092,15 @@ func enforceContentTypes(handler http.Handler, types []string) http.Handler { // registerExtensions will try to register all configured extensions // in the given mux. If any error is returned while registering // extensions handlers, no route will be added in the given mux. -func registerExtensions(mux *http.ServeMux, a *ArgoCDServer) { +func registerExtensions(mux *http.ServeMux, a *ArgoCDServer, metricsReg HTTPMetricsRegistry) { a.log.Info("Registering extensions...") extHandler := http.HandlerFunc(a.extensionManager.CallExtension()) authMiddleware := a.sessionMgr.AuthMiddlewareFunc(a.DisableAuth) // auth middleware ensures that requests to all extensions are authenticated first mux.Handle(fmt.Sprintf("%s/", extension.URLPrefix), authMiddleware(extHandler)) + a.extensionManager.AddMetricsRegistry(metricsReg) + err := a.extensionManager.RegisterExtensions() if err != nil { a.log.Errorf("Error registering extensions: %s", err) From 55713b3474b0591394ad3e1d6abde452db035d9f Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Fri, 2 Feb 2024 15:03:12 -0500 Subject: [PATCH 240/269] fix(ci): correct helm checksum path (#17081) Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- ...390x.tar.gz.sha2564 => helm-v3.14.0-linux-s390x.tar.gz.sha256} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename hack/installers/checksums/{helm-v3.14.0-linux-s390x.tar.gz.sha2564 => helm-v3.14.0-linux-s390x.tar.gz.sha256} (100%) diff --git a/hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 b/hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha256 similarity index 100% rename from hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha2564 rename to hack/installers/checksums/helm-v3.14.0-linux-s390x.tar.gz.sha256 From 3fda27e8d94a34f284c65f464de0e9ca9db4cfb6 Mon Sep 17 00:00:00 2001 From: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:09:35 -0500 Subject: [PATCH 241/269] fix(controller): fix application controller deployment crashing (#16984) * fix application controller deployment crashing and update manifests Signed-off-by: ishitasequeira * remove environment variable ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION Signed-off-by: ishitasequeira * fix auto-generated docs Signed-off-by: ishitasequeira --------- Signed-off-by: ishitasequeira --- .../commands/argocd_application_controller.go | 2 +- docs/operator-manual/dynamic-cluster-distribution.md | 10 ++-------- .../argocd-application-controller-deployment.yaml | 2 -- .../argocd-application-controller-service.yaml | 4 ++-- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 8004340250611..0ff9fa33c8254 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -266,7 +266,7 @@ func getClusterSharding(kubeClient *kubernetes.Clientset, settingsMgr *settings. // If we still see conflicts after the retries, wait for next iteration of heartbeat process. for i := 0; i <= common.AppControllerHeartbeatUpdateRetryCount; i++ { shardNumber, err = sharding.GetOrUpdateShardFromConfigMap(kubeClient, settingsMgr, replicasCount, shardNumber) - if !kubeerrors.IsConflict(err) { + if err != nil && !kubeerrors.IsConflict(err) { err = fmt.Errorf("unable to get shard due to error updating the sharding config map: %s", err) break } diff --git a/docs/operator-manual/dynamic-cluster-distribution.md b/docs/operator-manual/dynamic-cluster-distribution.md index a32258c3f2f0a..9d5d2104a1795 100644 --- a/docs/operator-manual/dynamic-cluster-distribution.md +++ b/docs/operator-manual/dynamic-cluster-distribution.md @@ -17,16 +17,10 @@ which does not require a restart of the application controller pods. ## Enabling Dynamic Distribution of Clusters -This feature is disabled by default while it is in alpha. To enable it, you must set the environment `ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION` to true when running the Application Controller. - -In order to utilize the feature, the manifests `manifests/ha/base/controller-deployment/` can be applied as a Kustomize -overlay. This overlay sets the StatefulSet replicas to `0` and deploys the application controller as a Deployment. The -dynamic distribution code automatically kicks in when the controller is deployed as a Deployment. +This feature is disabled by default while it is in alpha. In order to utilize the feature, the manifests `manifests/ha/base/controller-deployment/` can be applied as a Kustomize overlay. This overlay sets the StatefulSet replicas to `0` and deploys the application controller as a Deployment. Also, you must set the environment `ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION` to true when running the Application Controller as a deployment. !!! important - The use of a Deployment instead of a StatefulSet is an implementation detail which may change in future versions of - this feature. Therefore, the directory name of the Kustomize overlay may change as well. Monitor the release notes - to avoid issues. + The use of a Deployment instead of a StatefulSet is an implementation detail which may change in future versions of this feature. Therefore, the directory name of the Kustomize overlay may change as well. Monitor the release notes to avoid issues. Note the introduction of new environment variable `ARGOCD_CONTROLLER_HEARTBEAT_TIME`. The environment variable is explained in [working of Dynamic Distribution Heartbeat Process](#working-of-dynamic-distribution) diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml index bcaf2d4bb5894..68dd75de2f47f 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-deployment.yaml @@ -20,8 +20,6 @@ spec: - args: - /usr/local/bin/argocd-application-controller env: - - name: ARGOCD_CONTROLLER_REPLICAS - value: "1" - name: ARGOCD_RECONCILIATION_TIMEOUT valueFrom: configMapKeyRef: diff --git a/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml b/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml index f66c8055247f3..a769e75468483 100644 --- a/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml +++ b/manifests/base/application-controller-deployment/argocd-application-controller-service.yaml @@ -14,7 +14,7 @@ spec: targetPort: 8082 - name: metrics protocol: TCP - port: 8082 - targetPort: 8082 + port: 8084 + targetPort: 8084 selector: app.kubernetes.io/name: argocd-application-controller \ No newline at end of file From 5246429cad256b171479dfdfdb70c0d23cd1b90f Mon Sep 17 00:00:00 2001 From: Bardia Heydari Date: Mon, 5 Feb 2024 21:42:20 +0000 Subject: [PATCH 242/269] chore: improve error logs (#10592) (#17089) Signed-off-by: Bardia Heydari --- reposerver/gpgwatcher.go | 4 ++-- reposerver/server.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reposerver/gpgwatcher.go b/reposerver/gpgwatcher.go index 9c2c9be790813..5b43d6a24ac76 100644 --- a/reposerver/gpgwatcher.go +++ b/reposerver/gpgwatcher.go @@ -19,7 +19,7 @@ func StartGPGWatcher(sourcePath string) error { forceSync := false watcher, err := fsnotify.NewWatcher() if err != nil { - return err + return fmt.Errorf("failed to create fsnotify Watcher: %w", err) } defer func(watcher *fsnotify.Watcher) { if err = watcher.Close(); err != nil { @@ -83,7 +83,7 @@ func StartGPGWatcher(sourcePath string) error { err = watcher.Add(sourcePath) if err != nil { - return err + return fmt.Errorf("failed to add a new source to the watcher: %w", err) } <-done return fmt.Errorf("Abnormal termination of GPG watcher, refusing to continue.") diff --git a/reposerver/server.go b/reposerver/server.go index 007b7136e41ed..e1d611801c3ec 100644 --- a/reposerver/server.go +++ b/reposerver/server.go @@ -102,7 +102,7 @@ func NewServer(metricsServer *metrics.MetricsServer, cache *reposervercache.Cach } repoService := repository.NewService(metricsServer, cache, initConstants, argo.NewResourceTracking(), gitCredsStore, filepath.Join(os.TempDir(), "_argocd-repo")) if err := repoService.Init(); err != nil { - return nil, err + return nil, fmt.Errorf("failed to initialize the repo service: %w", err) } return &ArgoCDRepoServer{ From b1c6dc57427ac54f53fa0985edc68caf8d565a8d Mon Sep 17 00:00:00 2001 From: Gustavo Esser Date: Mon, 5 Feb 2024 22:26:17 -0300 Subject: [PATCH 243/269] DOC: add Fly Security and Telavita in USERS.md (#17076) Signed-off-by: Gustavo Esser --- USERS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/USERS.md b/USERS.md index cdf4406b7f296..3f164796d099f 100644 --- a/USERS.md +++ b/USERS.md @@ -94,6 +94,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Fave](https://myfave.com) 1. [Flexport](https://www.flexport.com/) 1. [Flip](https://flip.id) +1. [Fly Security](https://www.flysecurity.com.br/) 1. [Fonoa](https://www.fonoa.com/) 1. [Fortra](https://www.fortra.com) 1. [freee](https://corp.freee.co.jp/en/company/) @@ -283,6 +284,7 @@ Currently, the following organizations are **officially** using Argo CD: 1. [Tamkeen Technologies](https://tamkeentech.sa/) 1. [Techcombank](https://www.techcombank.com.vn/trang-chu) 1. [Technacy](https://www.technacy.it/) +1. [Telavita](https://www.telavita.com.br/) 1. [Tesla](https://tesla.com/) 1. [The Scale Factory](https://www.scalefactory.com/) 1. [ThousandEyes](https://www.thousandeyes.com/) From 2082a21121b945e67f85aa91a968f333b49f4b0a Mon Sep 17 00:00:00 2001 From: Linghao Su Date: Tue, 6 Feb 2024 09:56:58 +0800 Subject: [PATCH 244/269] fix(ui): prevent app name too long hide open icon (#16983) * fix(ui): prevent app name too long hide open icon Signed-off-by: linghaoSu * fix(ui): fix app resource list lint Signed-off-by: linghaoSu --------- Signed-off-by: linghaoSu --- .../application-resource-list.scss | 13 +++++++++++++ .../application-resource-list.tsx | 5 +++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 ui/src/app/applications/components/application-details/application-resource-list.scss diff --git a/ui/src/app/applications/components/application-details/application-resource-list.scss b/ui/src/app/applications/components/application-details/application-resource-list.scss new file mode 100644 index 0000000000000..9bc4b17bfe7ed --- /dev/null +++ b/ui/src/app/applications/components/application-details/application-resource-list.scss @@ -0,0 +1,13 @@ +.application-details__item { + display: flex; + + .application-details__item_text { + overflow: hidden; + text-overflow: ellipsis; + } + + .application-details__external_link { + flex: 0; + min-width: 13px; + } +} diff --git a/ui/src/app/applications/components/application-details/application-resource-list.tsx b/ui/src/app/applications/components/application-details/application-resource-list.tsx index c5519fc4b6ff9..d1e01adb52c04 100644 --- a/ui/src/app/applications/components/application-details/application-resource-list.tsx +++ b/ui/src/app/applications/components/application-details/application-resource-list.tsx @@ -10,6 +10,7 @@ import * as _ from 'lodash'; import Moment from 'react-moment'; import {format} from 'date-fns'; import {ResourceNode, ResourceRef} from '../../../shared/models'; +import './application-resource-list.scss'; export const ApplicationResourceList = ({ resources, @@ -89,8 +90,8 @@ export const ApplicationResourceList = ({
    {ResourceLabel({kind: res.kind})}
    -
    - {res.name} +
    + {res.name} {res.kind === 'Application' && ( {ctx => ( From 769836e6ea92ea4796bc44e4862fc6cd37f01eec Mon Sep 17 00:00:00 2001 From: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:56:39 -0500 Subject: [PATCH 245/269] fix: log all token verification failures (#16625) * fix: log all token verification failures Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> * better Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --------- Signed-off-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- util/oidc/provider.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/util/oidc/provider.go b/util/oidc/provider.go index fcb1a95b60f4f..d75bcf97efecd 100644 --- a/util/oidc/provider.go +++ b/util/oidc/provider.go @@ -73,6 +73,18 @@ func (p *providerImpl) newGoOIDCProvider() (*gooidc.Provider, error) { return prov, nil } +type tokenVerificationError struct { + errorsByAudience map[string]error +} + +func (t tokenVerificationError) Error() string { + var errorStrings []string + for aud, err := range t.errorsByAudience { + errorStrings = append(errorStrings, fmt.Sprintf("error for aud %q: %v", aud, err)) + } + return fmt.Sprintf("token verification failed for all audiences: %s", strings.Join(errorStrings, ", ")) +} + func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDSettings) (*gooidc.IDToken, error) { // According to the JWT spec, the aud claim is optional. The spec also says (emphasis mine): // @@ -104,6 +116,7 @@ func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDS if len(allowedAudiences) == 0 { return nil, errors.New("token has an audience claim, but no allowed audiences are configured") } + tokenVerificationErrors := make(map[string]error) // Token must be verified for at least one allowed audience for _, aud := range allowedAudiences { idToken, err = p.verify(aud, tokenString, false) @@ -117,6 +130,13 @@ func (p *providerImpl) Verify(tokenString string, argoSettings *settings.ArgoCDS if err == nil { break } + // We store the error for each audience so that we can return a more detailed error message to the user. + // If this gets merged, we'll be able to detect failures unrelated to audiences and short-circuit this loop + // to avoid logging irrelevant warnings: https://github.com/coreos/go-oidc/pull/406 + tokenVerificationErrors[aud] = err + } + if len(tokenVerificationErrors) > 0 { + err = tokenVerificationError{errorsByAudience: tokenVerificationErrors} } } From 5100726fd61617a0001a27233cfe8ac4354bdbed Mon Sep 17 00:00:00 2001 From: Thomas Decaux Date: Mon, 5 Feb 2024 22:01:04 -0500 Subject: [PATCH 246/269] feat: add health-checks for eck elastic beat (#16563) * feat: add health-checks for eck elastic beat Signed-off-by: ebuildy * fix tests Signed-off-by: ebuildy --------- Signed-off-by: ebuildy --- .../beat.k8s.elastic.co/Beat/health.lua | 31 +++++++++++++++++++ .../beat.k8s.elastic.co/Beat/health_test.yaml | 29 +++++++++++++++++ .../Beat/testdata/invalid.yaml | 12 +++++++ .../Beat/testdata/progressing.yaml | 11 +++++++ .../Beat/testdata/ready_green.yaml | 13 ++++++++ .../Beat/testdata/ready_red.yaml | 10 ++++++ .../Beat/testdata/ready_yellow.yaml | 11 +++++++ .../testdata/ready_yellow_single_node.yaml | 10 ++++++ .../Beat/testdata/unknown.yaml | 8 +++++ 9 files changed, 135 insertions(+) create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/health.lua create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/health_test.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/invalid.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/progressing.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_green.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_red.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow_single_node.yaml create mode 100644 resource_customizations/beat.k8s.elastic.co/Beat/testdata/unknown.yaml diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/health.lua b/resource_customizations/beat.k8s.elastic.co/Beat/health.lua new file mode 100644 index 0000000000000..c7639dbbd94f0 --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/health.lua @@ -0,0 +1,31 @@ +local hs = {} + +if obj.status ~= nil and (obj.status.health ~= nil or obj.status.expectedNodes ~= nil) then + if obj.status.health == "red" then + hs.status = "Degraded" + hs.message = "Elastic Beat status is Red" + return hs + elseif obj.status.health == "green" then + hs.status = "Healthy" + hs.message = "Elastic Beat status is Green" + return hs + elseif obj.status.health == "yellow" then + if obj.status.availableNodes ~= nil and obj.status.expectedNodes ~= nil then + hs.status = "Progressing" + hs.message = "Elastic Beat status is deploying, there is " .. obj.status.availableNodes .. " instance(s) on " .. obj.status.expectedNodes .. " expected" + return hs + else + hs.status = "Progressing" + hs.message = "Elastic Beat phase is progressing" + return hs + end + elseif obj.status.health == nil then + hs.status = "Progressing" + hs.message = "Elastic Beat phase is progressing" + return hs + end +end + +hs.status = "Unknown" +hs.message = "Elastic Beat status is unknown. Ensure your ArgoCD is current and then check for/file a bug report: https://github.com/argoproj/argo-cd/issues" +return hs diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/health_test.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/health_test.yaml new file mode 100644 index 0000000000000..fb44e998ffaf1 --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/health_test.yaml @@ -0,0 +1,29 @@ +tests: +- healthStatus: + status: Healthy + message: "Elastic Beat status is Green" + inputPath: testdata/ready_green.yaml +- healthStatus: + status: Progressing + message: "Elastic Beat phase is progressing" + inputPath: testdata/ready_yellow_single_node.yaml +- healthStatus: + status: Progressing + message: "Elastic Beat status is deploying, there is 1 instance(s) on 2 expected" + inputPath: testdata/ready_yellow.yaml +- healthStatus: + status: Progressing + message: "Elastic Beat phase is progressing" + inputPath: testdata/progressing.yaml +- healthStatus: + status: Degraded + message: "Elastic Beat status is Red" + inputPath: testdata/ready_red.yaml +- healthStatus: + status: Unknown + message: "Elastic Beat status is unknown. Ensure your ArgoCD is current and then check for/file a bug report: https://github.com/argoproj/argo-cd/issues" + inputPath: testdata/unknown.yaml +- healthStatus: + status: Unknown + message: "Elastic Beat status is unknown. Ensure your ArgoCD is current and then check for/file a bug report: https://github.com/argoproj/argo-cd/issues" + inputPath: testdata/invalid.yaml diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/invalid.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/invalid.yaml new file mode 100644 index 0000000000000..3eca183165a5c --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/invalid.yaml @@ -0,0 +1,12 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: + expectedNodes: 1 + health: invalid + observedGeneration: 1 + version: 8.8.1 diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/progressing.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/progressing.yaml new file mode 100644 index 0000000000000..b007ad72ae3fe --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/progressing.yaml @@ -0,0 +1,11 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: + expectedNodes: 1 + observedGeneration: 1 + version: 8.8.1 diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_green.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_green.yaml new file mode 100644 index 0000000000000..3f3c1866793d8 --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_green.yaml @@ -0,0 +1,13 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: + expectedNodes: 1 + availableNodes: 1 + health: green + observedGeneration: 1 + version: 8.8.1 diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_red.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_red.yaml new file mode 100644 index 0000000000000..fc2433c8076a8 --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_red.yaml @@ -0,0 +1,10 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: + expectedNodes: 1 + health: red diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow.yaml new file mode 100644 index 0000000000000..831ee281ef02d --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow.yaml @@ -0,0 +1,11 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: + availableNodes: 1 + expectedNodes: 2 + health: yellow diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow_single_node.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow_single_node.yaml new file mode 100644 index 0000000000000..d652b5a55d0ff --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/ready_yellow_single_node.yaml @@ -0,0 +1,10 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: + expectedNodes: 1 + health: yellow diff --git a/resource_customizations/beat.k8s.elastic.co/Beat/testdata/unknown.yaml b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/unknown.yaml new file mode 100644 index 0000000000000..dbcca36c9e691 --- /dev/null +++ b/resource_customizations/beat.k8s.elastic.co/Beat/testdata/unknown.yaml @@ -0,0 +1,8 @@ +apiVersion: beat.k8s.elastic.co/v1beta1 +kind: Beat +metadata: + name: quickstart +spec: + version: 8.8.8 + type: metricbeat +status: {} From 555f6f42d27cccfe6f91c859d3019a8d9d882b8d Mon Sep 17 00:00:00 2001 From: Anand Francis Joseph Date: Tue, 6 Feb 2024 20:48:00 +0530 Subject: [PATCH 247/269] docs(proposal): decoupling app sync from control plane user w/ impersonation (#14255) * Proposal for decoupling application sync from control plane user using impersonation Signed-off-by: Anand Francis Joseph * Moved the proposal document to the right directory Signed-off-by: Anand Francis Joseph * Update docs/decouple-application-sync-user-using-impersonation Co-authored-by: Blake Pettersson Signed-off-by: Anand Francis Joseph * Update docs/decouple-application-sync-user-using-impersonation Co-authored-by: Blake Pettersson Signed-off-by: Anand Francis Joseph * Update docs/decouple-application-sync-user-using-impersonation Co-authored-by: Blake Pettersson Signed-off-by: Anand Francis Joseph * Modified the proposal to have control in AppProjects alone instead of Application and AppProject Signed-off-by: Anand Francis Joseph * Removed proposal placed in wrong directory and corrected examples Signed-off-by: Anand Francis Joseph * Update docs/proposals/decouple-application-sync-user-using-impersonation Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Anand Francis Joseph * Update docs/proposals/decouple-application-sync-user-using-impersonation Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> Signed-off-by: Anand Francis Joseph * Addressed review comments Signed-off-by: Anand Francis Joseph * Additional corrections Signed-off-by: anandf * Fixed alternative proposals section to include only AppProject based approach Signed-off-by: anandf * Added information on impersonation and added related links Signed-off-by: anandf * Added examples for remote cluster destination with the required RBAC access Signed-off-by: anandf * Fixed clusterrole and clusterrolebinding creation commands Signed-off-by: anandf * Addressed review comments from Akram Signed-off-by: anandf * Corrected RBAC to include serviceaccounts that can be impersonated as swell Signed-off-by: anandf * Address few more review comments from Ishita, Akram Signed-off-by: anandf * Fixed a typo and updated the last updated date field Signed-off-by: anandf * Added information of the sync hook behaviour and also corrected the namespace to match that of destination Signed-off-by: Anand Francis Joseph * Changed proposal to meet the latest api design using destinationServiceAccounts Signed-off-by: Anand Francis Joseph * Fixed proposal document to use destinationServiceAccounts struct Signed-off-by: Anand Francis Joseph * Renamed proposal file to have .md extension Signed-off-by: anandf * Using glob pattern instead of regex, and corrected the order of precedence when multiple matches are available Signed-off-by: anandf --------- Signed-off-by: Anand Francis Joseph Signed-off-by: Anand Francis Joseph Signed-off-by: anandf Co-authored-by: Blake Pettersson Co-authored-by: Michael Crenshaw <350466+crenshaw-dev@users.noreply.github.com> --- ...plication-sync-user-using-impersonation.md | 592 ++++++++++++++++++ 1 file changed, 592 insertions(+) create mode 100644 docs/proposals/decouple-application-sync-user-using-impersonation.md diff --git a/docs/proposals/decouple-application-sync-user-using-impersonation.md b/docs/proposals/decouple-application-sync-user-using-impersonation.md new file mode 100644 index 0000000000000..e7e459a7059c0 --- /dev/null +++ b/docs/proposals/decouple-application-sync-user-using-impersonation.md @@ -0,0 +1,592 @@ +--- +title: Decouple Control plane and Application Sync privileges +authors: + - "@anandf" +sponsors: + - Red Hat +reviewers: + - "@blakepettersson" + - "@crenshaw-dev" + - "@jannfis" +approvers: + - "@alexmt" + - "@crenshaw-dev" + - "@jannfis" + +creation-date: 2023-06-23 +last-updated: 2024-02-06 +--- + +# Decouple Application Sync using Impersonation + +Application syncs in Argo CD have the same privileges as the Argo CD control plane. As a consequence, in a multi-tenant setup, the Argo CD control plane privileges needs to match the tenant that needs the highest privileges. As an example, if an Argo CD instance has 10 Applications and only one of them requires admin privileges, then the Argo CD control plane must have admin privileges in order to be able to sync that one Application. Argo CD provides a multi-tenancy model to restrict what each Application can do using `AppProjects`, even though the control plane has higher privileges, however that creates a large attack surface since if Argo CD is compromised, attackers would have cluster-admin access to the cluster. + +The goal of this proposal is to perform the Application sync as a different user using impersonation and use the service account provided in the cluster config purely for control plane operations. + +### What is Impersonation + +Impersonation is a feature in Kubernetes and enabled in the `kubectl` CLI client, using which, a user can act as another user through impersonation headers. For example, an admin could use this feature to debug an authorization policy by temporarily impersonating another user and seeing if a request was denied. + +Impersonation requests first authenticate as the requesting user, then switch to the impersonated user info. + +``` +kubectl --as ... +kubectl --as --as-group ... +``` + +## Open Questions [optional] + +- Should the restrictions imposed as part of the `AppProjects` be honored if the impersonation feature is enabled ? +>Yes, other restrictions implemented by `AppProject` related to whitelisting/blacklisting resources must continue to be honoured. +- Can an Application refer to a service account with elevated privileges like say `cluster-admin`, `admin`, and service accounts used for running the ArgoCD controllers itself ? +>Yes, this is possible as long as the ArgoCD admin user explicitly allows it through the `AppProject` configuration. +- Among the destinations configured in the `AppProject`, if there are multiple matches for a given destination, which destination option should be used ? +>If there are more than one matching destination, either with a glob pattern match or an exact match, then we use the first valid match to determine the service account to be used for the sync operation. +- Can the kubernetes audit trail events capture the impersonation. +>Yes, kubernetes audit trail events capture both the actual user and the impersonating user details and hence its possible to track who executed the commands and as which user permissions using the audit trails. +- Would the Sync hooks be using the impersonation service account. +>Yes, if the impersonation feature is enabled and customers use Sync hooks, then impersonation service account would be used for executing the hook jobs as well. +- If application resources have hardcoded namespaces in the git repository, would different service accounts be used for each resource during the sync operation ? +>The service account to be used for impersonation is determined on a per Application level rather than on per resource level. The value specified in `Application.spec.destination.namespace` would be used to determine the service account to be used for the sync operation of all resources present in the `Application`. + +## Summary + +In a multi team/multi tenant environment, an application team is typically granted access to a namespace to self-manage their Applications in a declarative way. Current implementation of ArgoCD requires the ArgoCD Administrator to create an `AppProject` with access settings configured to replicate the RBAC resources that are configured for each team. This approach requires duplication of effort and also requires syncing the access between both to maintain the security posture. It would be desirable for users to use the existing RBAC rules without having to revert to Argo CD API to create and manage these Applications. One namespace per team, or even one namespace per application is what we are looking to address as part of this proposal. + +## Motivation + +This proposal would allow ArgoCD administrators to manage the cluster permissions using kubernetes native RBAC implementation rather than using complex configurations in `AppProjects` to restrict access to individual applications. By decoupling the privileges required for application sync from the privileges required for ArgoCD control plane operations, the security requirement of providing least privileges can be achieved there by improving the security posture of ArgoCD. For implementing multi team/tenant use cases, this decoupling would be greatly beneficial. + +### Assumptions + +- Namespaces are pre-populated with one or more `ServiceAccounts` that define the permissions for each `AppProject`. +- Many users prefer to control access to kubernetes resources through kubernetes RBAC constructs instead of Argo specific constructs. +- Each tenant is generally given access to a specific namespace along with a service account, role or cluster role and role binding to control access to that namespace. +- `Applications` created by a tenant manage namespaced resources. +- An `AppProject` can either be mapped to a single tenant or multiple related tenants and the respective destinations that needs to be managed via the `AppProject`, needs to be configured. + + +### Goals +- Applications may only impersonate ServiceAccounts that live in the same namespace as the destination namespace configured in the application.If the service account is created in a different namespace, then the user can provide the service account name in the format `:` . ServiceAccount to be used for syncing each application is determined by the target destination configured in the `AppProject` associated with the `Application`. +- If impersonation feature is enabled, and no service account name is provided in the associated `AppProject`, then the default service account of the destination namespace of the `Application` should be used. +- Access restrictions implemented through properties in AppProject (if done) must have the existing behavior. From a security standpoint, any restrictions that were available before switching to a service account based approach should continue to exist even when the impersonation feature is enabled. + +### Non-Goals + +None + +## Proposal + +As part of this proposal, it would be possible for an ArgoCD Admin to specify a service account name in `AppProjects` CR for a single or a group of destinations. A destination is uniquely identified by a target cluster and a namespace combined. + +When applications gets synced, based on its destination (target cluster and namespace combination), the `defaultServiceAccount` configured in the `AppProject` will be selected and used for impersonation when executing the kubectl commands for the sync operation. + +We would be introducing a new element `destinationServiceAccounts` in `AppProject.spec`. This element is used for the sole purpose of specifying the impersonation configuration. The `defaultServiceAccount` configured for the `AppProject` would be used for the sync operation for a particular destination cluster and namespace. If impersonation feature is enabled and no specific service account is provided in the `AppProject` CR, then the `default` service account in the destination namespace would be used for impersonation. + +``` +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - * + destinationServiceAccounts: + - server: https://kubernetes.default.svc + namespace: guestbook + defaultServiceAccount: guestbook-deployer + - server: https://kubernetes.default.svc + namespace: guestbook-dev + defaultServiceAccount: guestbook-dev-deployer + - server: https://kubernetes.default.svc + namespace: guestbook-stage + defaultServiceAccount: guestbook-stage-deployer +``` + +### Structure of DestinationServiceAccount: +|Parameter| Type | Required/Optional| Description| +| ------ | ------ | ------- | -------- | +| server | string | Required | Server specifies the URL of the target cluster's Kubernetes control plane API. Glob patterns are supported. | +| namespace | string | Required | Namespace specifies the target namespace for the application's resources. Glob patterns are supported. | +| defaultServiceAccount | string | Required| DefaultServiceAccount specifies the service account to be impersonated when performing the `Application` sync operation.| + +**Note:** Only server URL for the target cluster is supported and target cluster name is not supported. + +### Future enhancements + +In a future release, we plan to support overriding of service accounts at the application level. In that case, we would be adding an element called `allowedServiceAccounts` to `AppProject.spec.destinationServiceAccounts[*]` + +### Use cases + +#### Use case 1: + +As a user, I would like to use kubernetes security constructs to restrict user access for application sync +So that, I can provide granular permissions based on the principle of least privilege required for syncing an application. + +#### Use case 2: + +As a user, I would like to configure a common service account for all applications associated to an AppProject +So that, I can use a generic convention of naming service accounts and avoid associating the service account per application. + +### Design considerations + +- Extending the `destinations` field under `AppProjects` was an option that was considered. But since the intent of it was to restrict the destinations that an associated `Application` can use, it was not used. Also the destination fields allowed negation operator (`!`) which would complicate the service account matching logic. The decision to create a new struct under `AppProject.Spec` for specifying the service account for each destination was considered a better alternative. + +- The field name `defaultServiceAccount` was chosen instead of `serviceAccount` as we wanted to support overriding of the service account at an `Application` at a later point in time and wanted to reserve the name `serviceAccount` for future extension. + +- Not supporting all impersonation options at the moment to keep the initial design to a minimum. Based on the need and feedback, support to impersonate users or groups can be added in future. + +### Implementation Details/Notes/Constraints + +#### Component : GitOps Engine + +- Fix GitOps Engine code to honor Impersonate configuration set in the Application sync context for all kubectl commands that are being executed. + +#### Component: ArgoCD API + +- Create a new struct type `DestinationServiceAccount` having fields `namespace`, `server` and `defaultServiceAccount` +- Create a new field `DestinationServiceAccounts` under a `AppProject.Spec` that takes in a list of `DestinationServiceAccount` objects. +- Add Documentation for newly introduced struct and its fields for `DestinationServiceAccount` and `DestinationServiceAccounts` under `AppProject.Spec` + +#### Component: ArgoCD Application Controller + +- Provide a configuration in `argocd-cm` which can be modified to enable the Impersonation feature. Set `applicationcontroller.enable.impersonation: true` in the Argo CD ConfigMap. Default value of `applicationcontroller.enable.impersonation` would be `false` and user has to explicitly override it to use this feature. +- Provide an option to override the Impersonation feature using environment variables. +Set `ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true` in the Application controller environment variables. Default value of the environment variable must be `false` and user has to explicitly set it to `true` to use this feature. +- Provide an option to enable this feature using a command line flag `--enable-impersonation`. This new argument option needs to be added to the Application controller args. +- Fix Application Controller `sync.go` to set the Impersonate configuration from the AppProject CR to the `SyncContext` Object (rawConfig and restConfig field, need to understand which config is used for the actual sync and if both configs need to be impersonated.) + +#### Component: ArgoCD UI + +- Provide option to create `DestinationServiceAccount` with fields `namespace`, `server` and `defaultServiceAccount`. +- Provide option to add multiple `DestinationServiceAccounts` to an `AppProject` created/updated via the web console. +- Update the User Guide documentation on how to use these newly added fields from the web console. + +#### Component: ArgoCD CLI + +- Provide option to create `DestinationServiceAccount` with fields `namespace`, `server` and `defaultServiceAccount`. +- Provide option to add multiple `DestinationServiceAccounts` to an `AppProject` created/updated via the web console. +- Update the User Guide and other documentation where the CLI option usages are explained. + +#### Component: Documentation + +- Add note that this is a Beta feature in the documentation. +- Add a separate section for this feature under user-guide section. +- Update the ArgoCD CLI command reference documentation. +- Update the ArgoCD UI command reference documentation. + +### Detailed examples + +#### Example 1: Service account for application sync specified at the AppProject level for all namespaces + +In this specific scenario, service account name `generic-deployer` will get used for the application sync as the namespace `guestbook` matches the glob pattern `*`. + +- Install ArgoCD in the `argocd` namespace. +``` +kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd +``` + +- Enable the impersonation feature in ArgoCD. +``` +kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +``` + +- Create a namespace called `guestbook` and a service account called `guestbook-deployer`. +``` +kubectl create namespace guestbook +kubectl create serviceaccount guestbook-deployer +``` + +- Create Role and RoleBindings and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. +``` +kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service +kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role +``` + +- Create the `Application` in the `argocd` namespace and the required `AppProject` as below +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook + namespace: argocd +spec: + project: my-project + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + destination: + server: https://kubernetes.default.svc + namespace: guestbook +--- +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - namespace: * + server: https://kubernetes.default.svc + destinationServiceAccounts: + - namespace: * + server: https://kubernetes.default.svc + defaultServiceAccount: generic-deployer +``` + +#### Example 2: Service account for application sync specified at the AppProject level for specific namespaces + +In this specific scenario, service account name `guestbook-deployer` will get used for the application sync as the namespace `guestbook` matches the target namespace `guestbook`. + +- Install ArgoCD in the `argocd` namespace. +``` +kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd +``` + +- Enable the impersonation feature in ArgoCD. +``` +kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +``` + +- Create a namespace called `guestbook` and a service account called `guestbook-deployer`. +``` +kubectl create namespace guestbook +kubectl create serviceaccount guestbook-deployer +``` +- Create Role and RoleBindings and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. +``` +kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service +kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role +``` + +In this specific scenario, service account name `guestbook-deployer` will get used as it matches to the specific namespace `guestbook`. +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook + namespace: argocd +spec: + project: my-project + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + destination: + server: https://kubernetes.default.svc + namespace: guestbook +--- +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - namespace: guestbook + server: https://kubernetes.default.svc + - namespace: guestbook-ui + server: https://kubernetes.default.svc + destinationServiceAccounts: + - namespace: guestbook + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-deployer + - namespace: guestbook-ui + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-ui-deployer +``` + +#### Example 3: Remote destination with cluster-admin access and using different service account for the sync operation + +**Note**: In this example, we are relying on the default service account `argocd-manager` with `cluster-admin` privileges which gets created when adding a remote cluster destination using the ArgoCD CLI. + +- Install ArgoCD in the `argocd` namespace. +``` +kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd +``` + +- Enable the impersonation feature in ArgoCD. +``` +kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +``` + +- Add the remote cluster as a destination to argocd +``` +argocd cluster add remote-cluster --name remote-cluster +``` +**Note:** The above command would create a service account named `argocd-manager` in `kube-system` namespace and `ClusterRole` named `argocd-manager-role` with full cluster admin access and a `ClusterRoleBinding` named `argocd-manager-role-binding` mapping the `argocd-manager-role` to the service account `remote-cluster` + +- In the remote cluster, create a namespace called `guestbook` and a service account called `guestbook-deployer`. +``` +kubectl ctx remote-cluster +kubectl create namespace guestbook +kubectl create serviceaccount guestbook-deployer +``` + +- In the remote cluster, create `Role` and `RoleBindings` and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. + +``` +kubectl ctx remote-cluster +kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service +kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role +``` + +- Create the `Application` and `AppProject` for the `guestbook` application. +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook + namespace: argocd +spec: + project: my-project + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + destination: + server: https://kubernetes.default.svc + namespace: guestbook +--- +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - namespace: guestbook + server: https://kubernetes.default.svc + serviceAccountName: guestbook-deployer + destinationServiceAccounts: + - namespace: guestbook + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-deployer +``` + +#### Example 4: Remote destination with a custom service account for the sync operation + +**Note**: In this example, we are relying on a non default service account `guestbook` created in the target cluster and namespace for the sync operation. This use case is for handling scenarios where the remote cluster is managed by a different administrator and providing a service account with `cluster-admin` level access is not feasible. + +- Install ArgoCD in the `argocd` namespace. +``` +kubectl apply -f https://raw.githubusercontent.com/argoproj/argo-cd/master/manifests/install.yaml -n argocd +``` + +- Enable the impersonation feature in ArgoCD. +``` +kubectl set env statefulset/argocd-application-controller ARGOCD_APPLICATION_CONTROLLER_ENABLE_IMPERSONATION=true +``` + +- In the remote cluster, create a service account called `argocd-admin` +``` +kubectl ctx remote-cluster +kubectl create serviceaccount argocd-admin +kubectl create clusterrole argocd-admin-role --verb=impersonate --resource="users,groups,serviceaccounts" +kubectl create clusterrole argocd-admin-role-access-review --verb=create --resource="selfsubjectaccessreviews" +kubectl create clusterrolebinding argocd-admin-role-binding --serviceaccount argocd-admin --clusterrole argocd-admin-role +kubectl create clusterrolebinding argocd-admin-access-review-role-binding --serviceaccount argocd-admin --clusterrole argocd-admin-role +``` + +- In the remote cluster, create a namespace called `guestbook` and a service account called `guestbook-deployer`. +``` +kubectl ctx remote-cluster +kubectl create namespace guestbook +kubectl create serviceaccount guestbook-deployer +``` + +- In the remote cluster, create `Role` and `RoleBindings` and configure RBAC access for creating `Service` and `Deployment` objects in namespace `guestbook` for service account `guestbook-deployer`. +``` +kubectl create role guestbook-deployer-role --verb get,list,update,delete --resource pods,deployment,service +kubectl create rolebinding guestbook-deployer-rb --serviceaccount guestbook-deployer --role guestbook-deployer-role +``` + +In this specific scenario, service account name `guestbook-deployer` will get used as it matches to the specific namespace `guestbook`. +``` +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: guestbook + namespace: argocd +spec: + project: my-project + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + destination: + server: https://kubernetes.default.svc + namespace: guestbook +--- +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - namespace: guestbook + server: https://kubernetes.default.svc + - namespace: guestbook-ui + server: https://kubernetes.default.svc + destinationServiceAccounts: + - namespace: guestbook + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-deployer + - namespace: guestbook-ui + server: https://kubernetes.default.svc + defaultServiceAccount: guestbook-ui-deployer +``` + +### Special cases + +#### Specifying service account in a different namespace + +By default, the service account would be looked up in the Application's destination namespace configured through `Application.Spec.Destination.Namespace` field. If the service account is in a different namespace, then users can provide the namespace of the service account explicitly in the format : +eg: +``` + ... + destinationServiceAccounts: + - server: https://kubernetes.default.svc + namespace: * + defaultServiceAccount: mynamespace:guestbook-deployer + ... +``` + +#### Multiple matches of destinations + +If there are multiple matches for a given destination, the first valid match in the list of `destinationServiceAccounts` would be used. + +eg: +Lets assume that the `AppProject` has the below `destinationServiceAccounts` configured. +``` + ... + destinationServiceAccounts: + - server: https://kubernetes.default.svc + namespace: guestbook-prod + defaultServiceAccount: guestbook-prod-deployer + - server: https://kubernetes.default.svc + namespace: guestbook-* + defaultServiceAccount: guestbook-generic-deployer + - server: https://kubernetes.default.svc + namespace: * + defaultServiceAccount: generic-deployer + ... +``` +- If the application destination namespace is `myns`, then the service account `generic-deployer` would be used as the first valid match is the glob pattern `*` and there are no other valid matches in the list. +- If the application destination namespace is `guestbook-dev` or `guestbook-stage`, then both glob patterns `*` and `guestbook-*` are valid matches, however `guestbook-*` pattern appears first and hence, the service account `guestbook-generic-deployer` would be used for the impersonation. +- If the application destination namespace is `guestbook-prod`, then there are three candidates, however the first valid match in the list is the one with service account `guestbook-prod-deployer` and that would be used for the impersonation. + +#### Application resources referring to multiple namespaces +If application resources have hardcoded namespaces in the git repository, would different service accounts be used for each resource during the sync operation ? + +The service account to be used for impersonation is determined on a per Application level rather than on per resource level. The value specified in `Application.spec.destination.namespace` would be used to determine the service account to be used for the sync operation of all resources present in the `Application`. + +### Security Considerations + +* How does this proposal impact the security aspects of Argo CD workloads ? +* Are there any unresolved follow-ups that need to be done to make the enhancement more robust ? + +### Risks and Mitigations + +#### Privilege Escalation + +There could be an issue of privilege escalation, if we allow users to impersonate without restrictions. This is mitigated by only allowing admin users to configure service account used for the sync operation at the `AppProject` level. + +Instead of allowing users to impersonate all possible users, administrators can restrict the users a particular service account can impersonate using the `resourceNames` field in the RBAC spec. + + +### Upgrade / Downgrade Strategy + +If applicable, how will the component be upgraded and downgraded? Make sure this is in the test +plan. + +Consider the following in developing an upgrade/downgrade strategy for this enhancement: + +- What changes (in invocations, configurations, API use, etc.) is an existing cluster required to + make on upgrade in order to keep previous behavior? +- What changes (in invocations, configurations, API use, etc.) is an existing cluster required to + make on upgrade in order to make use of the enhancement? + +- This feature would be implemented on an `opt-in` based on a feature flag and disabled by default. +- The new struct being added to `AppProject.Spec` would be introduced as an optional field and would be enabled only if the feature is enabled explicitly by a feature flag. If new property is used in the CR, but the feature flag is not enabled, then a warning message would be displayed during reconciliation of such CRs. + + +## Drawbacks + +- When using this feature, there is an overhead in creating namespaces, service accounts and the required RBAC policies and mapping the service accounts with the corresponding `AppProject` configuration. + +## Alternatives + +### Option 1 +Allow all options available in the `ImpersonationConfig` available to the user through the `AppProject` CRs. + +``` +apiVersion: argoproj.io/v1alpha1 +kind: AppProject +metadata: + name: my-project + namespace: argocd +spec: + description: Example Project + # Allow manifests to deploy from any Git repos + sourceRepos: + - '*' + destinations: + - namespace: * + server: https://kubernetes.default.svc + namespace: guestbook + impersonate: + user: system:serviceaccount:dev_ns:admin + uid: 1234 + groups: + - admin + - view + - edit +``` + +### Related issue + +https://github.com/argoproj/argo-cd/issues/7689 + + +### Related links + +https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation + +### Prior art + +https://github.com/argoproj/argo-cd/pull/3377 +https://github.com/argoproj/argo-cd/pull/7651 \ No newline at end of file From 228eda5e1ec2a18037693b4ef08f24e71d35d8cb Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Tue, 6 Feb 2024 16:26:38 +0100 Subject: [PATCH 248/269] chore(ci): run ci checks conditionally (#16982) * chore(ci): run ci checks conditionally This should prevent docs changes from having the need to run e2e tests etc, and prevent backend changes from needing to run ui tests, and vice versa. This is similar to previous attempts (see #16706 and #13507), with the difference here that we add the if checks on each _step_ rather than each _job_ - the reason being that most of these jobs are required, and if we skip whole jobs any PR which does this will be left hanging indefinitely, so Github forces us to do this on a step level instead. Signed-off-by: Blake Pettersson * chore(ci): run ci checks conditionally Try conditional jobs, according to https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks Signed-off-by: Blake Pettersson * chore(ci): add composite test-e2e action This is a workaround for the e2e tests which do not run yet report `pending` when they are actually skipped. Signed-off-by: Blake Pettersson --------- Signed-off-by: Blake Pettersson Co-authored-by: Remington Breeze Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> --- .github/workflows/ci-build.yaml | 49 ++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index c86bfb3b3a673..1267a628e42c8 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -23,8 +23,25 @@ permissions: contents: read jobs: + changes: + runs-on: ubuntu-latest + outputs: + backend: ${{ steps.filter.outputs.backend }} + frontend: ${{ steps.filter.outputs.frontend }} + steps: + - uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 + - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2 + id: filter + with: + filters: | + backend: + - '!(ui/**)' + - '!(**/*.md)' + frontend: + - 'ui/**' check-go: name: Ensure Go modules synchronicity + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -43,6 +60,7 @@ jobs: build-go: name: Build & cache Go code + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -67,6 +85,7 @@ jobs: contents: read # for actions/checkout to fetch code pull-requests: read # for golangci/golangci-lint-action to fetch pull requests name: Lint Go code + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -83,6 +102,7 @@ jobs: test-go: name: Run unit tests for Go packages + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 needs: - build-go @@ -150,6 +170,7 @@ jobs: test-go-race: name: Run unit tests with -race for Go packages + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 needs: - build-go @@ -212,6 +233,7 @@ jobs: codegen: name: Check changes to generated code + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -260,6 +282,7 @@ jobs: build-ui: name: Build, test & lint UI code + if: ${{ needs.changes.outputs.frontend == 'true' }} runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -292,6 +315,7 @@ jobs: analyze: name: Process & analyze test artifacts + if: ${{ needs.changes.outputs.backend == 'true' || needs.changes.outputs.frontend == 'true' }} runs-on: ubuntu-22.04 needs: - test-go @@ -315,7 +339,7 @@ jobs: - name: Create test-results directory run: | mkdir -p test-results - - name: Get code coverage artifiact + - name: Get code coverage artifact uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: code-coverage @@ -358,6 +382,7 @@ jobs: test-e2e: name: Run end-to-end tests + if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 strategy: fail-fast: false @@ -462,3 +487,25 @@ jobs: name: e2e-server-k8s${{ matrix.k3s-version }}.log path: /tmp/e2e-server.log if: ${{ failure() }} + + # workaround for status checks -- check this one job instead of each individual E2E job in the matrix + # this allows us to skip the entire matrix when it doesn't need to run while still having accurate status checks + # see: + # https://github.com/argoproj/argo-workflows/pull/12006 + # https://github.com/orgs/community/discussions/9141#discussioncomment-2296809 + # https://github.com/orgs/community/discussions/26822#discussioncomment-3305794 + test-e2e-composite-result: + name: E2E Tests - Composite result + if: ${{ always() }} + needs: + - test-e2e + runs-on: ubuntu-22.04 + steps: + - run: | + result="${{ needs.test-e2e.result }}" + # mark as successful even if skipped + if [[ $result == "success" || $result == "skipped" ]]; then + exit 0 + else + exit 1 + fi From 0b22a1198a8b8c68c0e8a037fcbc431ab685175b Mon Sep 17 00:00:00 2001 From: Eshwar Hebbur Shivakumar Date: Tue, 6 Feb 2024 10:27:05 -0500 Subject: [PATCH 249/269] fix(ui): Change path to "root" when path is root directory (#14949) * change path to display root Signed-off-by: Eshwar Hebbur Shivakumar * Fix inequality typo Signed-off-by: Eshwar Hebbur Shivakumar * Fix lint issues Signed-off-by: Eshwar Hebbur Shivakumar --------- Signed-off-by: Eshwar Hebbur Shivakumar --- .../application-summary/application-summary.tsx | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ui/src/app/applications/components/application-summary/application-summary.tsx b/ui/src/app/applications/components/application-summary/application-summary.tsx index 37e6cc62ff0e9..4f372ef8f55c0 100644 --- a/ui/src/app/applications/components/application-summary/application-summary.tsx +++ b/ui/src/app/applications/components/application-summary/application-summary.tsx @@ -37,6 +37,16 @@ function swap(array: any[], a: number, b: number) { return array; } +function processPath(path: string) { + if (path !== null && path !== undefined) { + if (path === '.') { + return '(root)'; + } + return path; + } + return ''; +} + export interface ApplicationSummaryProps { app: models.Application; updateApp: (app: models.Application, query: {validate?: boolean}) => Promise; @@ -239,7 +249,7 @@ export const ApplicationSummary = (props: ApplicationSummaryProps) => { title: 'PATH', view: ( - {source.path ?? ''} + {processPath(source.path)} ), edit: (formApi: FormApi) => From ca27c41bc25fae889ccec6a8cb3a17720f0ad262 Mon Sep 17 00:00:00 2001 From: Adam Huganir Date: Tue, 6 Feb 2024 11:54:11 -0500 Subject: [PATCH 250/269] typo `registires` -> `registries` (#17099) Signed-off-by: Adam Huganir --- docs/proposals/native-oci-support.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/proposals/native-oci-support.md b/docs/proposals/native-oci-support.md index 64918fde8904e..7ec0053729c2e 100644 --- a/docs/proposals/native-oci-support.md +++ b/docs/proposals/native-oci-support.md @@ -126,10 +126,10 @@ Consider the following in developing an upgrade/downgrade strategy for this enha ## Drawbacks -* Sourcing content from an OCI registry may be perceived to be against GitOps principles as content is not sourced from a Git repository. This concern could be mitigated by attaching additional details related to the content (such as original Git source [URL, revision]). Though it should be noted that the GitOps principles only require a source of truth to be visioned and immutable which OCI registires support. +* Sourcing content from an OCI registry may be perceived to be against GitOps principles as content is not sourced from a Git repository. This concern could be mitigated by attaching additional details related to the content (such as original Git source [URL, revision]). Though it should be noted that the GitOps principles only require a source of truth to be visioned and immutable which OCI registries support. ## Alternatives ### Config Management Plugin -Content stored within OCI artifacts could be sourced using a Config Management Plugin which would not require changes to the core capabilities provided by Argo CD. However, this would be hacky and not represent itself within the Argo CD UI. \ No newline at end of file +Content stored within OCI artifacts could be sourced using a Config Management Plugin which would not require changes to the core capabilities provided by Argo CD. However, this would be hacky and not represent itself within the Argo CD UI. From c4a9df6570316b4ab0f0b8b9810ad3930b0c4bf4 Mon Sep 17 00:00:00 2001 From: Tal Yitzhak Date: Tue, 6 Feb 2024 20:34:54 +0200 Subject: [PATCH 251/269] Updated otelgrpc to remediate CVE found by JFrog Xray (#17084) Signed-off-by: Tal Yitzhak Co-authored-by: Tal Yitzhak Co-authored-by: Blake Pettersson --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 297829e95754e..ced6fb496ea6f 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/whilp/git-urls v1.0.0 github.com/xanzy/go-gitlab v0.91.1 github.com/yuin/gopher-lua v1.1.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 go.opentelemetry.io/otel/sdk v1.21.0 diff --git a/go.sum b/go.sum index 8ab6ead977d19..619cc97b724c0 100644 --- a/go.sum +++ b/go.sum @@ -1746,8 +1746,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 h1:PzIubN4/sjByhDRHLviCjJuweBXWFZWhghjg7cS28+M= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M= go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= From 4bf4629231f2f74e4f07b8de1c5992c75c8006b7 Mon Sep 17 00:00:00 2001 From: Petr Studeny Date: Tue, 6 Feb 2024 21:01:13 +0100 Subject: [PATCH 252/269] docs(webhook): use real cm name instead of placeholder (#17002) The document says I should registed configMap named argocd-notifications-cm but then uses placeholder in examples. Signed-off-by: Petr Studeny --- .../notifications/services/webhook.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/operator-manual/notifications/services/webhook.md b/docs/operator-manual/notifications/services/webhook.md index 965098402236f..4b8ca38a685ad 100755 --- a/docs/operator-manual/notifications/services/webhook.md +++ b/docs/operator-manual/notifications/services/webhook.md @@ -31,7 +31,7 @@ Use the following steps to configure webhook: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webhook.: | url: https:/// @@ -50,7 +50,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: template.github-commit-status: | webhook: @@ -82,7 +82,7 @@ metadata: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webhook.github: | url: https://api.github.com @@ -97,7 +97,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webhook.github: | url: https://api.github.com @@ -128,7 +128,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webhook.jenkins: | url: http:///job//build?token= @@ -145,7 +145,7 @@ type: Opaque apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webhook.form: | url: https://form.example.com @@ -166,7 +166,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webhook.slack_webhook: | url: https://hooks.slack.com/services/xxxxx From af20dae498ad942664f966671239d25e4b752b6f Mon Sep 17 00:00:00 2001 From: jcourteau Date: Tue, 6 Feb 2024 12:33:12 -0800 Subject: [PATCH 253/269] docs: Update Okta OIDC SSO docs (#13811) * Update the Okta SSO docs * fill out the OIDC section with step-by-step instructions on using Okta with custom authorization servers * adjust outdated docs about updating the docs Signed-off-by: Jonas Courteau * Add the Okta version that these docs are written against Signed-off-by: Jonas Courteau --------- Signed-off-by: Jonas Courteau Signed-off-by: Dan Garfield Co-authored-by: Dan Garfield --- docs/assets/api-management.png | Bin 14376 -> 0 bytes docs/assets/groups-claim.png | Bin 82650 -> 0 bytes docs/assets/groups-scope.png | Bin 59680 -> 0 bytes docs/assets/okta-app.png | Bin 0 -> 260259 bytes docs/assets/okta-auth-policy.png | Bin 0 -> 85431 bytes docs/assets/okta-auth-rule.png | Bin 0 -> 229782 bytes docs/assets/okta-create-oidc-app.png | Bin 0 -> 360829 bytes docs/assets/okta-groups-claim.png | Bin 0 -> 144958 bytes docs/assets/okta-groups-scope.png | Bin 0 -> 187202 bytes docs/developer-guide/site.md | 10 +-- docs/operator-manual/user-management/okta.md | 85 ++++++++++++++----- 11 files changed, 68 insertions(+), 27 deletions(-) delete mode 100644 docs/assets/api-management.png delete mode 100644 docs/assets/groups-claim.png delete mode 100644 docs/assets/groups-scope.png create mode 100644 docs/assets/okta-app.png create mode 100644 docs/assets/okta-auth-policy.png create mode 100644 docs/assets/okta-auth-rule.png create mode 100644 docs/assets/okta-create-oidc-app.png create mode 100644 docs/assets/okta-groups-claim.png create mode 100644 docs/assets/okta-groups-scope.png diff --git a/docs/assets/api-management.png b/docs/assets/api-management.png deleted file mode 100644 index ae066f0a6a87d38e9812264ed0d5775eb75312fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14376 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 diff --git a/docs/assets/groups-claim.png b/docs/assets/groups-claim.png deleted file mode 100644 index d27e03b661f825436a937ff75d90ae1f546f1fad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 82650 zcmdqIbzfCm_dZNX3j#`)BCwI}4(Zr*cWy$u8$?7zS~lGv-67H~o0cx=?(Wdv;@tN+ z-d{bR=LJ0cwOMn`8gtAsu5pdALX;Gw9-Oz6jvJb zlm_WZ!?V&w9VHxiiJ=EL4>WVSbsi}*FnoAej8XX>v}5v8O>O=Gx$#Al=fMEK`;V&@ z-izD3Tjy{6b#O{U-~dX*IC#pKbjGmLi>$A-&qo{r;SdjBV-^Pp#!%x9b#w&6KXblW zSX)7alRt1D$n(9sx%v5`(k9~l1GvW#4s5!ez2cXcm6F;B#$0guV($&yJ!_1T_#ed) zJVSdn%RNv~CBQe(!ybmr&NUo8kJ^X$nwCAWT@9|ALtL@XIOmyPcN(hh(X@b2JHp#J zZ9N*2r5My?h`G7^3EtcAk3W}b&+LU_sD%>y)zH38uu*wXq)A7$>0S97z<$Q{V;<>Y zBAP|lwZHD(N{Z&+k^6@Jkwuu7!zRLWm*|FQ{R5)OdII&aLW(KZD6O;;7Zry`gsO)h zW=Oh?AOyUCT>2v2xpIqOlJn!Nc5yH zM{%1$%hEDGNSj+Gee{H7_7byN#`;X92hE+c5ubl%-#FPg+&U4GIQlp{MM|;YnM@ec zMEP9~S1t;Nsba(IQtmV>1=KTbvl^HpOu|&x!C`K6Ns36Zi18*m7}@0Y!}8?)CY!+z zyIZ1-RY>$fjcRsW;Snx`!Ci}04E>f|8WV$X;ESEzjl*X9T1!gZI@jOUs<8?sOd%)dh>p&rZd}oB( zh-|t@mGG7l6-Aly#U})-m)B8rW{A8m_oJ8}V@imkDd9rVkDjtt6VD($5tUG)Q$rgU z6&AC|lpAu*NAW^^C_**Fzljm{rl(w>7@njxt{e{>9Jpxd!J2~39O%3x;K8qlpxFjn zqPfKN!E468=qOuqd@K^J^Z{fGRFC&1$}CnUVJ{Y+6`7ShM7G(m34cm>&HwI=GAzMFj|CGfK=Y)E zG$xX+OU;y+Rg>j{RV*P=i$Md&`n_u>vJqan)s*^_?G)k^vJFWM3jcdD*pkBw9@P{Q zCQMi-WaZfL#u4U7;OOokR;%cNYk*-Nc+o+-e03RqX>!YY`{0)Bmc{QQrPvT{?W1;7 zn|9fDtacnx`Xzkh_bf6{YGT~E_rskW%g82Z6=@zpmv1lA#Gh?NrO4nsC$|zTc|=Jc>G{5I+~O*E5GNq{Z{YSZf`%ecn2Mzj|5SiM*D!_%*E zI<)FEKG<5HHq_S)@xl?pE7PK6TJxw2>XJmYF+|P?AJ~-NOaULEdFeh zV3WJcHEmis2{G(lTE$%TS(|e5bP8T$>U*f7tfpVc9V;;>E-2b0O7;=fOVZ1}I=YIn zrr7P?7fIJmH$~U^qF4!}%2PH}_FjcU$qZx;+E)_DxfD4H{rC=7KP0C9Jzc%G%Xe4UY4xe-sm9Lu zmf#5OCjXZ6*~OOowjv=RaVL=tt0k9*RlZF(OFw5ZyN`)D>oJRtxf;af8=>{CS&E%c z>tzj^jfs6bCmnko1U;EA;TVjaaGqe?pE7W1u5RA6ZsuI?8R40F^*Sg^qWr65sCg)N zoL5{(Tmu6?V~g&zE<}s0!pnxyg3PjMxPJUPH9X{DUvB?;8spcAZ*Hl!p?kXgs{9di zFB^os3w__;;orF3*keUti3WQG<46g@p2M7A2DF}e4tcf;lPRo&27@~(-+2Aq936Vx zc-M~eit4QEcUULmF)#@n@JY2nNNKE{4vHywp4eF2>HxyfwVB zM#HzPPFGI34Kxfy%OuOt>2`*^3xo?Q3l@HSeg%H6ex^Upe-zz* zM__?}3EzO=MMR8=pB=}Fze!k2Q%?1s^zjol;!}aC=URlb#0bGi?{={~aSJJWv2C#s zjl;_4j1@Z`cEkt$#0>~XjRb{y;8>B>@l~>aApXp;tu+R-EZZa-jx-H3>15rj7^w&~ zu{Nb$_F4Y0e7(ZBGTFHRR+3+&u719ZYl>Hd2P3#ybRRWj12AqePiRiz}yF7eA>u^NA0| z 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%0Dcc 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%0Ac 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½Vxq8NUB}6I+!EicH!S59ugg=&jD=ALSeAftrzwQ9X8HoS+24)3S-Zp9-Tj|fl!eIL+rf?Wq zoR)sMZ+|Vl#7n7^*bHu=lVF=qIq*3J{%4aJ&(lHy(tT>76p&y>1&|A3L=K*+fXerD z%2Ti}E*BNUQenLcZLn9uCo6Q6{0?s)f}v5++Ew`M@J~t>32^?XU`53E{al|G_**2n z_1yjQKwf(n3rocE%NiiH7A-9xnc*?ob(getp!RbDVw5aaffeH!_ucL)0FF+AOcyKX zX-7@|a}ZWBp>%f`MHC77+oE6x~{-0)JVNciI?C-;(B6(!b7s41Qe) zCGJ!Kd~cGgS8yI-XzOF3V)xl~`R*Zr=LSIZ607qCIAcFR!?=3yP_o;I7&Bmo+Zb!x z#8vgOJQ>T0vijh%{fH9iRiJREDuDUC7hK+9|6~30PJmWscd2^U&lO=JWza&bSpi{k zaB&(KDkS!w1ak)l>A|oVD%r>I2n-v8?*3Vlk zX8;UNJg_P>0YSIXw~0}+#P7r5X>eB%C-W`ND7@5ZeL}m4FWyw*YymJ5z0Se-h)m=g zMNvxp?JZ*NFb=l&E3~IeiBBH;;_#I4SWlqkJR0cc0y zStP=11{}ch*rw;90CkMo^@6gFTUDKGAGCm&D47rm1p)BJHU4QBDoC`j0P$aCLI8qd zyLODAMKZaPY)6DGqs1mdd_}Se$g7v8Jd%K93<__`nx~%vJc5xIm;;iu-)fm(xU{o~ zlyza?!3mV`Ib=6p!fwOg7(Dbz0&`XlKuXmFaMv4Xi5QfMCmDKf#jeM3R#*;WvRimV z-`#R}x&Q9+pf~1JBZdF_=s%>?5S8}}$Jh$h--@LHx)KO@GeOoMfbqn=C&0w=9XJNF z-6{*;EhX55g@JTB0rvW+^=hr#943C@!pm@R7ha^2Uc5snb}JX=`5x;vv0k9p*P+~= z2S{1y8k7nWh8@U*y0x?|r-wQ$;(-GCNi4>}j{dzlc)cVhIGAC5a{je040y-FAPwUi zxc2O=RELW7$F#6ILa3a^(h(C3S{1-eLfiG?NAvmf9{0a@E5a=~KX)C~miL$QF|*av zWFUk*nc+n*0hSyW3t)L%n;{B+%Lyj63m;^bzFnm;;Fp_IhP4ofY`>YDo}HVCxCktg0_BDA`Ey459HX+2d(6 z+v0jMo8UUHgi>2jvB?a+pU!+wLP4{o9pAYsG?SxD%^S7^_Lqu!k5ec=Oa<<;to@@_ z|M6)ErPE3bBbteo$$x(h6E_=(@T18gdZPdg@gU}GxV>h+)imeh$Wzy8o9aqJ_({E8wJR|fgefdO;j#jfu?umJ>hoZn}$JX zS)U?qNK8492wQwL0XVtyhXPXZ6WEkV>$b@4J*)`TYW<3F2bdrW*t=*XcrcJdJDJPDYqLcmJeU}A>^WN?VSYT&=t?9YLM67)L2zFy(oTr;)4fh+h{rsv*7 zwsylcfuwF5k6oYzkdbs&Sq1zQ~NK?^?kntp|*C)eW5`~w9ZGZJDW5UOk z+iTk206C)MeYMStThP!B1Cw$`;_g4bxE8TAy|3Q&Z?ek~D|qaDgam;SX%X_Ae;30J z=oy~C@v1}89tEx~`lw54_f`y+uReL`J&b~=z}UbzTS1@S7;R_>%O!C@0KRnTj0*>) zk@_{UmL2{`fYCY*$?)E`{pWxiy4iby0eo=>Uv}r_jl>3UsrcXYUJW2ko#F8GVpB_U zPl<6Utv3*GSb?8{>4)p}PU1-lgG_*U80XAY$8>EVD;BL+lu}GeD?ylL1H=htXr1E0#s0e!>;90BVARqo8F47+% zzV&zY*_nx7`Ag*vz3KRApMqy1!;N<`;;iKZcpa9R886~O{o9WA)l?9>M{PLys54&< zx61-yr^4svHCtmjq_^bV`KYPo!a0ODdqx5dkIm%Kka_18_!NG`)9Gt8(jtqnym0Fi zLwo1K$H=m{9UQ~)P`~H#s-19`v?KKgh1MfFNhxfZo!|9QB~)xaKrLGMRjFS>sy9jr zda*ebVDs)Q;3DI69AP3rjYBQe6Af$-lieO2j)2ncIc12|eFSb4dJ_rFZLgRLASmP4 zD*!MM;*Har7k-xGY2VO~!fUGJ3wblHm6Xk1E%CezXW=YCY!UA3KW-CFo%m^Eg}(L> zP}8;Nu`m99t>DN@a@d}P|47!}vLe0HY{)Crg;D+bCCm=#b6$g|j+{>0_2z+Kd6t*7 zA2*`^sNB52fv)0Hj}+UVI`8iXl5&9M4X$_;&HA&zox2fHB`jmYv~O#6@kX+(ed$$^ z%=(|bo<96J3pb&rNk_@g63Utogx)sV>95UlWu&k0jSC{)57k5J!K()Svl@jDET)qa zqzj3liWrn$JL&~UKR@Yxe^D?;=<(i4f0aQa(qXRp+ztul1lt{TS^j`LU24$p(Zb0t zZ)8C}dazSzpPzgUCX!OF2X$};Wc`-A*Y@i};N!1Mf2f8Oq^Nk;Ym>61W)(kRF!U8# z@oH9Mbk~=$A_dU_biX4MOy*=@+k_5WbQ`L3kG|f!`>QA5L}D(ih}?!QJMeQq>{6=p zYZIwqvRf7CfeoBUWxEer#h?9s(!k?8GNK)!6n^<{CDXuMtaOzZF-5fhm8m=c{`1uy z#r=!_DB=I#GrF;e?0p5i4B1Sbl-gOgiFA@(H30aHb%vSF~-El zk33HHm|#hQe=oIWsB9Nh+WDnv&jvx(*uZTH_o+joCaD~8xzn&%P4y6&8 zF{IMM%aFnNr^owiv7fOkR9Q9K^#UayaIkQ}O}TBRYSOM9fDyh1`Qbi<5oZ5vLNI%z ztWjU4T}<_DNgDd6pqiZkolMFFG-k~S#Pm&$l^P9xP627h0z04RtUIEaR_*=2oq?u+ z?Lt}jnBJ%aRJUC+)$bP|)7mN&I&T)O&Z^n-X%U7rtT3DMY(utMZQ>i~v#jw%&Puvd zgancYGG7W?>VA)jfdIfC!k$LJWqZV$O0~%)g;MIPcis;wU<&+GS6~o;x&lKz8#KZy zNLnx&ud{h-YoK*1;*yY_hm5}vVO|A<=i_qBg~m_}VA+n*4wakyTwu0IzR+Hu1kiw|YJrL_$ZnoUe^VgnBe)Yef#Ui4o% zxNBfPbyj*p9uH-ZT7x?s+ve|3T?=QYI80H`0BrI(sj_&Ir$F!V!KKO0@YN1P&qKM+ znmipPz*$Y9hV*H7>Ycqczy+#UtEbAu&-n4ZC+MG-Wq>SpHrXN*qA*Y$rhtKeYEGYS z1k~`%6TgIn2_VqWsMRM6fH)OES2M!|%TZ3FzZd}JeE*#1D*Igo*HnYp{oPt>S`a6 zGlQVU2lN$I6VsqLw|dj*(GVN7)0ZuK)gSjT7T^p0F#*r69+m=-(WC0`0+fBG0<+JrJO;WQ zDAKwNA=D-b9I3xyQ4>V~8=E{lzvcdp5Ty1FBbtM*GSkF?=m9kz18*_27fP6^DffB= zcNNUKy%9dI)cNVP#9Y#&{D!ai1f78_)W^WZ66@@w!_TbstRx#1#Op9RJO!c5LQoFC zfM+{pavEd|($<|7y@_tp1q6@-7bP_`#jtxE56!6XrJTz#GRI)XdLH}gIcbK`aVnNO zK0BycxE&-x=tNkTvlIIIUv>bfEBVo@Tq-TqZHYKNsY$VSZA2u|5$@LhRelDm-abfQ z-kYt5e>`7*vN85OUFeZXOYB4Z0$MG)WvG{f($JIV@z#N$tKe8n=U$JHKDCZf*qtO=LI$Q_xec+uio@ridVG%y z-AhDj3L$KIt8p6UeBDTbHI^@l(J_E%T?*K(* zEzQHOftUPWVbopLO_FkVzYw#6dF?h6)E%L34G=xFIq3Qp?Kz?5<7HX9Yl>5uI?Hc? zqw^lJIhQAeTpa7jL=8~<;b37$BWvlV@fo;5TEw;JOTB`-q3Lh1CsoFz;6z>VTy0EP zO*JYM8MO^_2&@aZsvl+;h-Mcs+qn7;87m4*3qdGqi;2kzf=7>9X*?~l!>6pyMq@G0 z5eluJ994f8*=Y+9oM)$=hZF=llF<4A*+&zyZpswk z(Xv8-svI<2!5ahHncj``r=?b4O2HXQpN#}2(l=8MP6nX-DK+7e=WxrF7 z@tVZJrKomCjuZ;*HLs6~VGRY2SylA3&@?L32a_laNLI539^Qn$PMt3+ZAwBPtz%3q zyjxC5tgOkDe(AK1#*9C*u;nv{XR;i0Gi62jo%Nol7#}hU`eFEEL>-cIK`DOyXYtA3 zi5*Zuq>f>Z6P8DK--STt(q(>p7UWMA1O@D53}Fvs;i37(^%Jbff#R2$v5+NSP!F4Q z;}md`6^3$r?CKiNFA9HDxV=%j>M`gs2xTONhmCY1?Wgb;wHbEB>z&YKdf6Bu0 z_0S?;>z+S?pYx4xncp2Ic&H0AI#9h*YpIl6N8SDsu8OGU-NfT%VKvW$X~t5rB>>3s&?N-WpSuLkO)`Lc)hDXAc3UzIe+UTP7L_tX>BBgL3nWWY9${ix z6CL*5Vg_t_z^eIQObsW&+gMK7hmq~+{Jo`V+S$Fl8fFy1`40a_2H$gU=;aT>HA| zp~%FT;ozW4g{+l7mo`K}9HZU#1!U9N8s^hc_w$ui^7fRwFj~__`8+>Zo>buO*{X?f z3Z6s$p00X3v~xzpd>6+3Qz0-4CXTc|yK*S&=_&FaYWwRz+YiXa{}UedqwROza^L(a zd&{;Z{Wblft}9pwZwZhD(YdA<_);xw5gb=xH#z-r&P#ebeNw%s9Yd~XincSnA?Gd9 z-TtJA94SSk^K9O|s7mfMf5Yi3t7O^jQ2XznNHmuJX{ta{Ut#*IFmQ4HWXD8K>09#Gri$;K z0OeM7KUIg+D&U7f{CSJrvFtxDCyE>#@;p0otXyM(vXmDxv&SKld->z^^W&|9%+ZeF-xRI|ASP-@k_bBCQ@ht?zB|MHe?dUUk)g$K+nfg&`a z>?N@Sz@JIw5=bC${+#X(h3DiF@!pYC$X|mR0M=~=4LelC^r=q(rH=5z7x^{$_T|x! z7mhMIaukZ!M7D#J$3WfxK#tS+23!T{LHrGqRuGc%{sku;8{cb{1l2GNua%VZCEkzP zmZ}RkexFOxP6E;Ne!GWCzB)moUPRecvTQK3POYO<%q@V@nJ#F zd%7Yr#B>w@nE~f6G^WqzmeUCa;$t0!!v@Ht@&tTNCfQg1f6g2s zpizT{f{X!WzCi*vn55nXEdC+_OL0a>V50o%F(5fM1u}B2v5ivDB}2qjA6D%0c4e_g zcSW-&DC-V@muNSvbj;6Cqk!S ztgt!201Vm56;VMK2erfs=pR9sBVOO3Jma#q)dJv$2`4adU2k^kP@!`yikXCQ2MzHhcZCNGCKuo~R3)Z8fbcd!0mCFhp%E zLf(%0otWY=r~w5|7{#}rJ7SpEJM}N@YP^7jW;f+lZz69mRCz+VLgW(}thWQM*~!2M z1OfHu1bpg~^6YiS+jZmp{f3&lw*Erk<#_-Y`*g;lGi+lJipa6~cM=PrRaHC?o%<|>S11N?`OjiH5qnNdasFId6`h;#GSvek?L6%@OpOvN1cl?;R|*K(Jhk zp*V=oqV$&yXB4#A3)_7OAQ%oN{;zK{5j=5#@yuD)q}5fbsvkaZJ7$*?1UYe4U`~Yp zmj1;~Y$=}&`u*tVp564hE}g1r12AiiU9j>|RSMyeW#S!3`s7*9lnxW3ujC}z1p}7P z5c+ETPo)>90N*auat6NsYH%V4dB%;SQaJ9uDd`h(2dz_p;G1UnMY&loZm=wq9)z+) zaqhBv9m~r+>z5=&Y4NXWOmdkE%3k(~CgPlU!MGSmM4o#7&CFMI7X$?2nZWcWTi+y| zoh^$zNxj(1QCyGWM7{Fo+;vF)f9$;U<0#Z`C3F#E1Q@U=tQMxyx z0@Bjbpdj6whK&kHO6R7eySv}D;Z~pLy#Mp@oDb)`-~4U7Vy$bfxyGDx%rU{-%~4AU z;+W&0=$}p#%SmJAXLVZ!f;J_rhsf?3QFnbadMk^o#@nN2` zG$Lb!R9Z_x_CDPQ!2L0>2d(6v7u)`Az#twWGrYSCH3%C9MGRMNz+ zK%49PGM&whzH)35o6_F>qC@zu{zXqr7-$iMS_LFUd{3r9gb{s|H~j@t22V`qbU|Rl zEiB3V{Ky%I%iJ(9xy}Y(lg$(!AE2z>G;g!DAx)A{&Pn zabzr;e5k0*_|);okBif;i``?!c8w*aJe_GOMNAal3UO^tXs*69P76~}YVDn;xiML@#)82d+6^p=&;V9tm=Xs!Q zT`c|{3L>;`*38Bp_L+;vs>M}KzsMC#M-8~!7X0y+?e8=5SnM@B$FW!#496S~<=9VM zrV}Yud9wD>+bVuF5oBJcHajZ=@abgH^jLg{lpWU!T|T3S#-spIihP0Fq{k2CAO#FP zU0*FnYNE)Hu~i!&sGNM03w1f-Yr0hA_rXwQrc6~SY3+_h&tPPH3brRb%5%Eo4Z6Qg zz1B<0Q0f3uUKDgDZ?VRs?P-24PN*cMKkJXdA+Ztai6c>dwtPOcjGn()x%4IB4T>4y z2TaAKo~VwRISOZ$=N`7*$!G2}Vw}0cg(6LgN!E0VKvB(eHNii8R7F*q* zNkAC1Nd%ufwx^KN9Pf)%G}K*r5^p6|(HN*pZam0sxK;L0*A$f3id3bE-F$+RrH;ZY zB#Q5;Td3*1^eobq+*o_n^In;zzpEvaA9Q)3LXA` zSq=`gj00!RQ){N4!th!4oP>3u{H#F2DU1V-Dp_b{e#UJJ9JnJ45YTao52&a9^=1&5gkuv+8_*lDb~xWtqDx2{RJnQ&&b znEu4Cnx{^+6K2opuhnosW=Me<0v?LCKy-!uo#y{EQ16H+PDP7fH{ z?(}@;!0-X3xdPTn-KcuGY}+JFRl&V48ai5RXnOY9&N@n z;8E|RNm^mbYUzyZ4>K3g+kziHIsJ`lquyTAmTwaY=fA|VsoCh}Wli61Q{IP8ztCof zjaxR1?PI27S^2&pz(kmSx?x`i5wplKaJ=Oo6^tNKUM|Gn%Y?pkYuCnj#B&_^)Z#A+ zBSNv}X%$6}%fag|S;(V{VVU1Q9G0)1W82@dp)F4IpDQJ^XqQskZxKmVMMt(Y-EF7j zy{2;8q-}9X))DPX=V;a!=LY6 ziV9<3MiFs}D5U)!m2fJt59iaK{lFi8Prd&D>&s!l>K(7(TcZ9s6aV~G7#9Hez-!c` ze}M3BZvprcG{BcQKYm9l^1u5MitoTZsb9bM`-2q!zRWq&m#7y^llb$~-|Gpez&+6( zeEKtUf3MFHLi!Sg3R$>+48mUrMjYIe0p-2nc0sZLTZABR~h3976|?)qZ|_(twO*C4fGbt??776p7r?hrxyvY)l4Ph z>=x7fwW!2jx9foFUIWf%P%W$i%K@0J900ZUY;S_@ylh&lPwJ zAD6j+5(FQBMAo2JXm%^8>4qmmj9hYF1^56SX_-Y(sD|O6&nfH;KJ+5CK(8or%?S75 zcgK-{ofu70(BW#^v*JABfQ=BE{78@W_AbPwIAlnRzQvrc4T%?35Qb)!<|fS* z@V)#GT_9;>0Jxp8URy!>cc6@t6u`MySzTRyx)2%~n%V){EwNhzu9Ut}w3Lppy1KeT zTrpqFQm(ePeLw4+KhpvBA_3_ct)%3lR1kRrv>K(5!f7Ad3!I)lCno5cJeIs+(aC7|M+KF^jLWY%mz z&JC*vDGLUihyG;uA|p3`~}M1wIe@?=e|e=rQpay^;H1Vy}AEU-FmbD79poiKR!{N&LAO7F?H-OrB}YyiG51F2v5^LY@lECxBv5u{kyD1iHGKoQ`TM%*^YH;n?6 zgo&gz*#OR2nHUyNqo;TXfh=&bLdJnlNtJ}(O!pB z{-c>fXG^L5hx--vkSgQM;tpAt|C`d*Ei37u$aSJ|5=3Nq_fb2K)4vsV6k^Htm_yjOTFq6*{` z#Jn<2d)f#XZO_5;ZkoKUlv+xy&3GSfFJ=cp%CC>VYPc(+M0GRhc*~{!L|0)9q(H0? zSn2#AP|tU=?ow|B`fy{c5!38N65Kl`ykDlv9Zl({%4b>5raBSPIJ_bV_$j?yQ;sm#^BMJ_^4fPk&Jr<5W8RWU1Wn* zWb5HP%gtzt+vJWP#z7!tir%;`xV*f)h*t!f-_hN84h~>gm)E+3fIYG~CDM5j2*g$( z8`WBS;Oj%T1IbKww^Xz?A7}!C;KqQD4Asa;Ri)ILLTZOF_3r?9ikbV|lU6!0vwXpP z&aXpz@_6vo{`)ay)~s>m@)pT(q>oEe8R?xqtXX0##h}gfz?1OZa;|!`a+WC&j z_D%{$fN2X85Hm9dp6xUhej$I)Ai9lIPuqJ>iNGL0BQK%X(l&fpIWrJFU5|)0s^84ZNa*kz z_8Yus7^F7d0Vjp@xLChWuwyw8d#lHdxH@q-K*MbuB4&+$jxE$k$gkzFv-bv1!+6Cc zEDYzwT+H1rq~lUsOUe@#SMNS;qU+{06O}OYtnB>-WH~Sme9OhneSJG~H={9?Uz-yK zswqoePYtLq*IC3-%{T1Mxt&B$mGOgbVk`86_n?q+(V}oavqY{4Y)uR!Sm<;Ld;c@# z8H1-ImtW^V_j34f7964WiG{vXZcX1T$;q&oqN1}6N2N(->C+Abmj95e?KzV{x=v3H zUcPh{7-+*j1tZtv-zX(28?a!ab>3a<3w?peKDh+~1DF<@wX7FE@vk$1BgXaId%P1|EwFmJ#6l1~w?ENbqnu3jL__Vl?85xsc;|n{j=(LoY z=-y}6Fg)?ShzN;V!Y>X&{Su5%V6@^)LjBI<)XSrxyM6T*d-|WJP=Bw{4{_I+I3S-z zaW40~R`~03RKx=yJGoVnqJS4k)W}SP_0;NEzzO$5}sd1EzUsvm6vxTo;x!|Ir zY!Wfm=LY(-SP320pMz=1$8)$B0U9zce;+hVVn8)f(9-7_W;n6&7f8PDx1u`jvjk|d6xj^LJwF9DGj;imyyJFNiew6q&MLOXF?yLq3s z9G*_>6}b4meO`9+nMC0IRz}MFBAlm;{OM8Mg;|UIcbI)&}s($4olDO2`7P~9-AiC`KVL&<*pe><(rCd(fU3weL;MjoQVOwDf)LXOg;>C$P zEv@Q^bf>^0K>3oEe*0<#k6|t%*d(Y*K(IX0_9)1Uqf)NTRYOo)i10m#r<2CMrmJI8 z%R|GTn0?1P@<@Pk*QTDX;+#EIDo*;)2`7U96V6FzMWW@Kie7iYY!l9~>)v_>`343k0RSllN% z8Ba28Hn6Wz($kbzF1V} z*_J!^vU;~_`G~!L7uM=d^w8_*y9oZFG!r|_WC66VD+WRatqUl0+Y&fF6+?s0e~t;b=vopTpgQs$(LBOY^&h)08@M-`2K? zevQ7P2?_d-Ppe~r+wP_zNaiaMGx6*eN{EQC|Fh*G5yubdl!saR>^*VVyiB4(w*xQp zC_cw@$c)R0KSDKBxRjA&*j~BH%J&MKr=p`v8u;{nLg$O2`|U$@zd}768T4C$Ji7D0 zdt=uy?iTzHzoL?c0&na8T=V~%IS?j8`|S}i$o|ur$ioH5WWaS{W|m~WL}3IEAHVt~ zj7%iRC2|+1-Va9}VkJ1jY2m(jkjn$Dy9718L!-(*11PUe02i;jNsSQ?;SeTm3O3yf-r>ui94VPjmE^GwMU&g4!pP#H1qZVwVGnz zLTkxZG!z!O*J2{t)h8DGmtz6l=mrNtmJ5@?7&&MHss|>1$=UaiH=F~R$Itf(T5tRh z(TN;9VF4}GF@jr{8|LS;Ur#TRUt<5%v}{**=2R&?9*aqPduzB8-+#0?0VwNIJbd>j z)S!tD-dP%h=L*mWKLf1sn@rWK4WnTdxNmRA&B?EKt;twect|~u9p9Qp!6%C%?P+?0 z{~Hho;{4MtC0-Q4c=`GqeAn|khFuT{uG;())nzLVtr3bRuK$F#W))dxjGUzG|K9nE z9w>R;SzeTiH?HPN7|a#5iG=$4WX{Df4?%;y?C_hu*TfvE|Hf1}9$Z&5=lCa6$>j3? zXJMn{*OH0}d?-BI>*4E1`TaJgNIPn}VSu=OIT3_3ICQ(m><e;S7$&9Pf&hR`9Pqc3git5>P{j1QK|jkoY> z7DBaGcf+79ohSQ4YeJK5l9C(SC)TAFA1=NOzouO`NYcw&#gP7cAwG9FZQ*EDGT8_nS$QO<1beiZyc28(}$L;Ot=L9 zbl+-H)GL8Eow|(MN7kKu@LG!=DP0S^a7jyY+~u<#DKW`jd)Ww2@4OrUSg{-wAX>+v zm!fnv)miu`x$5+HS_T+SUt48q#@;PTI6r+}vzoauy3lnVV^h=6xqnvZ-IRQ~U{r2z z;*XT7!5_He(dRJwL?^kp!Y-vO`4vNuO(7m@H3zy)bomD*!a87U5CV|bkO1FpE1{>X2Qx< z95C*ZM9CuPys%LklCM+JDAT68NWfHH1z1&bc6ThH63Amn~o zdD7`ppO~BUWV`V$TiYC`H4xYw=`mokcUo_yjf1PtyZ$z%uZ2y}issTGI<16PIM+wm zR$@{hTYoQ?F8pGjtgwRIWxSMLFPGL>M-Stc+pPE0(SqpMytd6KetlDU-&@FZG*79R z&LRHX1{9fHUze|V1T8$nhTUF=_YJ1-4|JYS-EtnKvKaIr{>a_tV@iiZ zw<8izbbROT&&@KZXf9oHi_H@|?=I?F3Q;#^Is+oknp`7LA z1+nInc_IZi?W39t{V)N;gqP#__j%US!-mhgYOU+*X9~GI=4JNJO6wyc+s}e#OAoQR zSCgFQ_CTS4-3mgf`65>LJX2fEhDWKYZU>Wa;cuQI>oEw45#EyBzuLlMsMU_1&$z`t z)g-M8{VH-9CKRgwdhWiFRQ}jyz6rY?YKpUYXuFgMc@PV2Y*E@Dyn$7W3E#Qvv6Mj~ za?WQ4{f6Z|RAck&7gs|0)DP$9woT33V^oPd#2uwp1=VAb{=3*?PBr5$&G`mQE&2s# zy011oHq*EcqIsOZRV`?!o2hd*8^sDtl9p$r4-B!(=BCU(FW_vG2qPhDi}c>^zq?)D zyz~8Uq&oT`I8`DXTd(5j@$s+Kp1q64suKD}esnR@Vq|^XS%a{uwe2DZKR5zgP&Y-d79Haly=UiW*tWUCA74zBGL3$G1d*=q3VEa5=C(7Ec}roZNvkhZ%nt>TmT2cFAAM>v%S-Mp7A@-#Zk)_eV*u8Wg6 zuaoaG_VrwlVG8&LYt3S9HxlR&fT@EjiuIcy5_z>(y62hH+~b^|wJurY$74h?wbT8gGZ;-~TX=wYJr)>5skd)6>Qv~p(?;KCw)e8GL4H5H z3o4jsgBzQ|=>qUpN_22_tk8Lt2L$`{5&avnvKS0NC0AK8vGJ@;<5iA4a97O;9 zOr%Y@k4)S?7wX0MbKM^nrVR3pl*i?aep~gwsq3F2z$`fI(&YdB>GzAm2*7*&Kl89G zYM<*jZoMex2>c5ot{&^d0q}co7S5I9{QFfd4;f)yd~m=Fjf>6wImVF?^vWDb0y+Rq z2!_FbUm=6TP@Yt&;VC2hDI6zD1>AZWW|XCNhVzS7O~^|`?)TNNg*nk5W98A=w7n5t z0`nNv8BFkBce;8||3?t%B6Ydeba{OIeK>ON6nTAe7&)q|tECIc8UNh(>i@j(xi%`3 zb1jbAQW~s?(l2xBpEk>-jpI8UHh+B^oS3jJaZ`M_^sDeW%9ay?*d(!+NjFhJpgfZI z@(dETLGwK56dGpf;x}aihlq*~5gXv;CXg2`IXfc+pGQ42M6y?bh@u9&Jccxi63rCQ zp+NwVcWXdh<;=O>B${f6zF1Y}xYYZY{^gijp5{&t0|&BuFo@=t0&eU(sfqZ32dF5y z=uw}9-}kAB<6X->9!;F8f-a*t#N{0NYFC z7^tPk9e=8q4gn14-QCZ}@@;q{=Zy0%Rp~4!SL~ep$0Qj}_%#A~AID=knzkRpdC(RS z-6(Gj8vHn)zf~*y^a$gw01j%w$S=-;XvOCtJu;7T1O9|cXTp}J+5)(B*15;VrL^0E zvEW|qh@=+el$xWXJQX_oC>ICMU@5^`(V9q3_%<7#uTJSaz&-mVpUY(B=j!}(iuPJ* zF(!6EhJ5$HA|g`qG?#wPP?eR!upUtSMv!7oFMWT22)s2=H%YTC-lk5`ws}7@3rIEP z9w$K~tZdpp=4!k~&i85M$`ivaiBPIT6Ix$naK62D7X$mXDav#0Kg&c|9}QNxS~PdV zp6QI&LE6y*^4)vY(tZ)R)Pz+i1H_ska9DTS9TKl%A6+smWy>r!fN8)=1@AUi8z-x( zW{&ppD<@g4X*JGrHjAJn!;4IgIBw>jYX&7o6>VEZhUJA{-_P+g|Fq@0Yn~=Zg>`8@ zO7Ocqp5>xGE~7~m{0d{e&M4uz@}aO+5}~#B%fLSKNPxdwoHJ!|rgxQF*7j)|Q!b-8 zmsK(#2_>VyF!7ZTxRGj`FZbFXYIPu#kAyXfGAM#cSh*bbgx@B|$p+??mN|a~;;bSH zlo`t=w_DW>fe0u6&Opj5G#D>1E&0%!-O%60%2M{h(HhhF1i7*WMV(B;Z4e0*&Q`(- zoW1Td4K^f!**nxfd!2#FXMG$Cfs$=qY}J%jn6#YB&MyGf*YB50@8wVQ$XGjnM9W_{ z8ePD4B$i4DfWCQ?Ugl3#s$Xnu6}id`zE{@72sdkY`o{K#m%u}}-O#3?@2JPTdMj4d zL=tj+RElcIyl7x#2dS?xt-fG%M~%{$8iJo`44Ck`+nJ9<9qLE(TYR~$5NI}P zgv?FLjUf-~)1opp&h-7gB{^8{-jc4Ch<-+{^1}=9AYx4qkCWv`MB(}~&5rSMP|kn| zT??ZM*yAp4lGxpv`+z{ID1f4RGBUUf{`5eR55>K>=|sYxBb?h|DAjPZl15RHoKUi(;n=xyvPP2vGzedy$g~!WhgAe`Nz`jh}6Q{;| zC-XBE!;w3B#RBx!#v3F5+#UrblKU-W?D>ejY-cw+{r=C|Ga-QWF@!8cM`qLB;28jB zlQZDjB9L5y6Trl<1uUmL_kkHZ#Q{tfTz74*f(Y%HjYj&Ya zgtZnp56|XX52tczmzOj^cW23+7nr(6R9~L4)l66UuT{r|`8%-r-MMETyRoCcU+O(+ zR#CSd>}BNNu*PB)hOK|?)M&!`q>X0CMJ31nBygK0ZG$6V$fGWP9~5SqBMSys$tDl| zKu1QZC?U&!20p-?dHY6eFHXoCuItz%z7IM#B0vd%4d5}rfQA_(Y!wJ{m4}96A*o(# zpmwzA?$fcyjdIESJg^xcYgP_AO0@nVz#zM-BRg!*|4cALHl0Nh@ zc@*YX49wyq_u9Rs zJytv>Sk@#+bv{Rnx!RIF>NlbIGc2(@=`Pu@sSEr#& PWw<}wXjKOEdhw#Ea5Bm5 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 diff --git a/docs/assets/groups-scope.png b/docs/assets/groups-scope.png deleted file mode 100644 index 45557b51ead7f69512a3908424bc419ef2691201..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59680 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 E0mHsFDgXcg diff --git a/docs/assets/okta-app.png b/docs/assets/okta-app.png new file mode 100644 index 0000000000000000000000000000000000000000..bfc4570826b0a25f30128f6b84e54a10c9d74f2c GIT binary patch literal 260259 zcmeFZcQjmU`#wHeghWXMA!@AP|9^tdu$k zgi8zpU9r7-1=w?ux$O@E;X`aBB~|4lCFxY1oh)taEkGdIu=qq=RSiAzfGzJe`bt=+uCSCfQT(){WLD2>FnUAOwaOfnX8S(esvSm8j2VZ7`2yTHe zR6$97UAMS`g3d7Rx-85rO*w#+qWBf_%+5{@FCI7>8sEnSG2fn(a=g!kHMbDjymW~a`N3V|;R7~4Vx-pOSihl?!TX+Tcm09cM-_wcdOcUs^AMi1LssFk?{fn90 z{7UX?nZB2NVq7mGx#3?KJ9;A$hQ2L%di0-2$)3K^bBr?CMFfPd~^@mq=kRvd5Zs`S$A;>APXU_JBcoIJ&q_nkW_Q{cea2O^t%PoT3Fs>(@s+;+A znhzh~F-kzCNi(}uhx08paSQK&v3Nth0@0!0vRJGI$FWhN2Tx=^3al=z4zKpD;=78} zlTN*94y2J#`PlNj^R`w5=QoVDFH&YPoUD)DeBe@KTgG0#yG&+@y-OJWb?_5fSE!hX z?@G#Bqp+!nsUU~e^tJ=Dkh0jvRLXc(5iVbF=0&)zc23^57bXbUT7 z2e&&v=ia`%O~3svE-o%1u1PcWmWeG?vu@}{L65qmI<4H!J%$(|mdJbe9q5PO_rKqK zKONm=E>g}akdXRxTEdaegih?fe{`N~ihM;*-Jo3#Ypy{qZjMPevAL_o2QCGR9rJGU z$S%V~PkM#u;aG5@MNdfrG){!YTgFX2@~#y<`MpH?8od&=&9{>ugq4j|rZv)8P3Zi^ z&tIKB!g)H7SF7hv<1>T{J}=m?&| zv&*d4DxsCxl@paJ*M`U*k^dmG*ZpNG%0eN~ZnWmL)K$wkRK z$VbHubW3;BceBPFJ}}Yr%aqW1sX3Q_tAI+Yt`xtBvLLvyL{sGBc(!0cUdb}_zUBnf z?Fs6Qpwg6TF%F{Nzpi;HMm)Z*yMuGh~5O~j;(H@?XmJ+Q}*|J}saUTnt zFZ3#OU!P4ssxoZ+I_e%u9i@!Iqb5iLrTL`YPdll{HVSrpyU9M~ICbcS_EPh@vp>G~ zZI5(c5ABIoLK6{mUSYq|Lr_TINco(ABG@L_`}#?QDZ`!YTiNp2$Zwy@pqw)vQ7TYym~WyZRII+UBcr-!pcU5ANiVj&=9gzSC+LX0T_qFmx?a-u2cp&Eul5}mII$+ z6G$d(THqhKrvzG$tyZ3pE0I?#RP~VPIOvqvL6OYx=%jApcAquN&HK(ma|hE?t-kRm z0z`2kH8SsIN+FF_udUv!m~pU`nwQ=$#dEr|6+gY=^GMWBbi#M@(~vHeHkRF&k$(4h zr$pK=j^5HQTVXBlTRK}9K!iUCMsNIhq{^>KJW7WBO81G-D;gXmE(g&$FZP|ARO%Ev zJVSSR#43d%Zj#X=ZXd8uviaB@1ziog`cld&N73BSTypV*IVwLUzty^8Rcm16d7Rl1 zC#tM=v~zTPwCihnxH~&dSVb6XL_?F5zg&L|t3rHY9)}1u2MH`vEFnNHRNh+gsF(1$ zP6ZQ*UYJ%G36*<4d%sHwYfYR`zsr3559!#{82OlQF=;XG_o5)RIdQp-vkkkfN2Th% z>W8__D%a$T6iyOo;-_N*VX~c%S)$2v@ahu^IC}ID96V%X__&Ee4`=FpBo>(p`(AS; znpaz?yWGHA*^r_H^;BnSisvtJHME>`A4%Y)@lPT%9Z(XKlA-yXDdz zTK%tvRsOt{f-k`bq#C9@ZGO6$$9=P=&1W_P1z)way@rQY^RUuvI@fB8|tDa6Sjrh3n@YO3D- zj$4Z91PaAIfmB$O-;ob?$KJ4J%S|MUZ=RxP*_BTMk2M>$8_gR9EuAl+8o+K&6K8dI zbLX{l4J;JmZHMy;54~%>uN>5GI!r^VOFd>F8OLHXQ(H|fRr;m%8=wR6gFp!Hd)_Hr z3fw!k@pj>MEkk(gSCEp(2FeXeN=mIeHGHi~^Lg8nFGJ9T-c*iGd^XcF5_T-2n317T z!Y7P#i4!tsk#00*RCb~z-i_Q?TPU?@z@ZGMJ5TOMjTEo!h7Zt2IMTc24UwaZ8*^O2$-7=as zT#tuHLs*$gxk{>yDw+`EW^k8z{*)Qzz43!;-hiIZ$9HJ>*{95> z8r@ibXkVa0C)~H%rzjeGnuOdq&Zdh_#ttDg#lE4Qx_hz*YGY=@9m6em&ZoJog*?1E z&GJ{|Mq_c?Qs-9u&CjEQP87P8HWVx}2y?CyagYkL0by)OFQWQWP|E za$tXE?)2P(-NWI>w zoB{#@9FMp-xVYGWGuT`_9bKP!usOOg{H)|Z^+;K`m^s_LaJ6xAq`R#5*>fkbtH|BE zmlyiu@8^A5c-Z{+N{%kSKNj$S9G6EpIN2X@{82YhRQPhQpsJ0Bg}t7XjRVkTz%@iU z`FOa5e=G1mhyHuXKNZ#eQ_;td9{;)MpAP-KsFsU`v!s&)a8Xy$|905#h5vl;_kzM4 zm(TvEw)ol5zwHHDS`=TH%o@jbtY)s)bDrsGGY-d>B%9VR-$QYCPIy(9)i^YSxNxbS(a(RPv8s>%f z!kEo+n3Gm|HSS5qWwvMZKDgMQNN++l!Rijvy|)Bbrd@mwko&F&#@?u^5zj4`j1h3N zJ2ZZ-a_lt$1~#!c=vQBlFe$DQA5+l=l@mpJ%s=er=Gpx>tDBnIQkZyxMBt@-u=!0abh|4RpQvM z-=6+^gMS@>|F+;iPKbZU;6Kc%|3A%QI!mnfAY7uZbP;d!krE^4`F6az)198BZr0Mc zJ5Iff8@m6h4D?{Cdpq} z;^$Iyd6?~OAw)eoCQ9#bFi3YV_qDVu7&f7U)N3}g)yo%+wh?nui`WV5XKKbCbBr(o zGWOI30p;%2a*LiNxQbY8fkw-_!*capd3ku=yBvu(-V0EYa3=Xgb|(Levl{sRa$kyk zkv2@QW8)tO_2q#%vd|>Zb~wj3`4GZV#jBO2O3%O>VRGsUo=eBOI61|Ki zl~!HuvNB?EdW6^IHFLbX5_^7j(%r{D6IYC^V_w6YyGndZven*`$-*(_*Wi#`iyo^!*;3k9f{T6L6{}ZEc41<$;&+Edz$4RJ zH}xiQ_e|DREWTwezapaY%me4k4Z8kh-U&syajuVMb~~iT7+W*Fe#7+OGnUrkm{mrCfm7d> zK#dj5n1X8&t3rC7S*4EV9^WAAEGB*o8*wD4%PcRO>6b(HIp$TqKl-zLK#;Z#FGh#{m(rs zGz)f2Ki}CL-6rMcg1!{5YnZKoNy{a&mo|hKpRK`L5*j`6OfXHq7+&6xYG#)6V&@Hr zmEg{cgAI!QGJgmdNp8^{=Op}<&44d4(ZsJygRCUT8YgsaodfmDQJsmOGX^TN8yUfp zzKJL`QJMD0wv*k0YCuZ3Y=^8>re2qftf`Z;>EDItDJ23=-!t9huZtX8(@Y{|)sA*v z>h_XuuDf%-l*m@@cQ&@B;j-M=nrx{t@%@Im9isTXQG;6w?{NvQM#=QU_y(ChofQX^|T)QOiU7xQQGl^pr6+(GAbqqy;>8Y8SiX7518@eBEtWG?q6#w$cVc z+p7a+%S}_8HZAh;-CWkH{whf)v!yNPF*{4FUBG<18zri5U^`q$k4|5hh%sxh?9(5s zc4!!0EHP@xv4V-FFE@aZ5B18;Uv|GGWqpun`J=qMX~sG&)^w& zRS49Nxi-X#i44fZWA4pP00sTVw05zsO&+R2tzlEI0SdY7O!2+nj1p`mQxCIJEzRNA-bLq4{@W z)e#k+^JDUPBT2P812)DEZpXuvtkz1urwio($nf};Wq8CohN%lA&o(P%a zyKhZ1j2OCrzgulI-><7~l@_R<*xy2~FuHHv$#q_`J=fT#vHQU1i`HB@Wr!N$!q^jB zsdZV29L!gfTsayoGjpDBnEnJ_?p@1zvb480BeXv$gw~@G_6T6&amx?`ug5i_ZLKK8 z{9ZMTR%D2HyRFT%M3Fua+mUr(x;4B~>4w5DD!I~nY46L-Iy_7EX@$>R6?S(IBS>V? zFqdCh$N^HI3+CNt`l2D}UI>PPPtSbU#;YnI56gmR{S7Up1*Yz{V)C8nQw!+UI0j({ z2{x28N8aK8MrpLlz8eAt%sUCe{G`T5EO$|-BwiBihi##3jRlSi#1wY8J? zKT+cjyq4CmJ-Ld&N+o5(YFFsW6_m z1;4X6KYf$#wl6LN8!pi3d2NYvlK>x!oezhl>|H#l%)IMn*p<&{z3*1;)1E7yA6$9n zTwql(buQ!{-3vnBVZ%9cv1xGN8gp}!L?ZJMqplCyE3$oQ1a{y7=j|G4&wt_kg?#I`+H+YL?p@6%cSRA@zI`yH<~&`=;fq zMi_WxtWc}S_H5&9yCZ|kYma=p8bZE$2A~y&44<6>icE9@Ja|*H#8B=nX#-rbNkmkuOF*U z`_|N~Jh-^p1~sVZY9kui!L|Zyb4)P7oyQ}`ZGtCKEq=be%*EVr9b1q6#n?W~FNsPi z2)(&f-*^6tMgTq_8IP#UTdqXKi!?OpjOEtR(4I8aH(;R*eXbLZCN1$W468TvAh66!)JS8I-wixht*uR8@&)`O#b< zI{$2=;|`Q@5S4*FwrI_h9NyK3O}m;q^d(1Kc|8Dtvr5F`(4kK&4tXa49#=dw>if-L z=~fra;%vyF0;D3Wu+;~NfcB2352FmWe?^BB+>5@CB}LG|bI--8CxML%?rP~m-t`LS zS|4-av-I-Ugquw@jU=aOqQ3gTR?Nm|8N6=wjX<%S6}ju<6Q)oHuCQp-}0)xMaMutUomg{wenhu(*5 zqKZoMI>R}d7jLbtcJkUKcq5#z%LL@}kG5O{G@cza;FWw`ac!^4X5eaY-&)q=;7+af zDpE@EtCqH}cVtyaWS4clm2*)s1wcgZL9X*P+t@pF{TX5k0AQJORcV_!+4BF)otrNP zU`z>@;X+zQg@lL7LiO-$8I=l}RaF4og&MY;$EN?Nc^1tQTH`e1h*;XNgR1CPZ-{gy z#~{|Qg?=>&_%0^_01n5J9}JwaTlJxh9UD0l8)WY*r`k(YxLvmTBz9~NKZd%klCH!^b@GP`1#bQx+YAC97Z+Jb#oOEx#6 zs06;fj^a*RP?hL=OS;9K{e4=6Cm#SIIe@b>sV}tiIWXw{!wF`CYWsK-zp>{^nf12A zwkyr`6~HPnKsPY`g_Ld_#b(^t?uFpC>c_u*Y&o*sf^I8&F}~h3=p1m{UfuxZa&l0b zJdm{j9vOe2nQw}D)OwH!K!Wkto>77wXvO_8G=JK>CPc7`{}2{$gs5@y_q;d@JjmQH zWH4q0*6X}9HtW2r&5U&I2b#*VBPR%TV+Wo16Ec`3INmddKa_KhA3k{D3F|vG3(h!;uLST5rlFmAeewwCav&lGY zA*38KDby4oxfuf2-il4YYNrvI=7I+yc3eKZ4{GY|Y>i5F_7BLnyGiz7@r)ux)VFZe zTJ!MWbeE%Zs9;9$X)A)ssP;vf9_)u4MEO(N^RI8^vZYl%sBSk0yf0~8*9iWFUoddv za{c|lY0_O(>b7&W@rML!18FGEX^aI#rMY?_DkU9ZnLSSBK_It|1v zG{Arw$+Wc{&iJc1)-jf*av{mq<61?$56V;w7*xQ?aKM?GVS!WoI#Oz*M{e(HqGtkw zXOvR-5)#-_7>|mBj1(yT%3%GaL0+3&jsXC#$IH+Zpgd~;cZ)~E&5vm%%{^VC1a7xE zzTe=oF+ElfF4A-Q1a0Un_SZG3cSG67EAb=GM9%hH(sws)9*Z!&qEh_u;|)bp{D|NJ z5mG+>fz7MWDp)1*55;{J-tjNRsz`g3T&q$^G;|KL8p>`_dHJ$#DTFr9d;EZQRTBzE z@)4sT-td5xR$ST_dHN0`o1}+pq1d66=IdVJ3^I|`h?rvi{a#rK*gGR!L9Q|Y*p=KY zlkQ);DmeAUrU;e01bW%~;k|m6)Js&J)ip-()9nt6ol&!Wkr77M@71VlI~x@$9R?Pg zlb&3by}C(!Y;&-5zVFRv3Ohp@eG3lZB)_sP)R(qpeKq$jX;Ejj!-NPvuz+&Wn_{Wx z`QV;^l0w#DwJ-JPe6XQGda_@vL3o|Fzmj`*O9=c30bBG;vjH5&wOXDs(92F@>ayXU zI%S9lK$)oZzf^aVK*cunq4zW5o`#b(gy)#Fh+1mulUlvj`?OEcCV;seC3YTXm2Shx zs-0@&T?zoNo#T}ZPc-SqZ1c$jTp!B~wWPVqVQ&cV_>;Aq>Xob17*gjMVWtek{wFB+ z0{#8W0AhiUoEksI?Wh4%Cf%xx6GtuN){8yaQ@k&=PlV0$nW)-fyfSi4F{oAbpC^m> zEu2B~fc!20AG1Wl8jR!jO?)`z-;#4!(q8dR;uNS-?G@7VxH7jOvRa%08{( z!L$GtV8p?nw3U|DPMmOLovmXZ`ovxa+MaNNqzo8BQ>(#ynI*aT+1Jh{64(rK9VXn= zq2pMVuBNAwBnq?uFP5X#1fPtg5XKM17k69<@1SF=VVGd=&x4Y?YmipjA5JHj7isSqWrP^aXCHzIKC~2uzlrdYj*} z7Z@ArRq6g{1*3%*KV}b?zTI&ef@9dx-FL^HpKA-reK98lET-xS+;~}ZHffHJ7KqZCnRvwwYaE+2OO4?+D(=7q?^|?FqTJdvg44+49~j94AkP|+)|E;d69Xi3J@Sfozlq;*-7VJTGl~}`ZKA)hZ&Jo| zeOE%!h)egJfYL*Tee9l~V5xfUNip%(#rf8S`BHa$`sXhtD}MX9p$i=>bn)8kw(XQIgD?Fdd0e-1UrwmNnA(9T=x(p zD#DI$_$ikgPaJ70XciS$8aIbZO<>q*Mrq}$C*~#}pEv;iEJ_kt1vtTjxe78}N!$?o zvGS*auB#h(hN$lKWFdD)5P6_GC*3d?+(K>IwFlOA$_`6I9Xq;U1`%djc*vg>Ij`n4o;ra ze)PrK^cm`2k@bgcjWp#HzNtC{EuC%jK)#wrl9+#{22)(xdxj7pj3@*VZ!uuVhv5dZTCei{I`6Asw@pDjRLjwGJJ0iDtB4iMifMBa zmEoKS@u6$r*Css)Fl@!lH5;D5AVILLLKKaYm+k8wgrg?bh-quCud&J5)(ODvCet18 zy2l5c9iU9O7#^hJ8lBp%Mt-p;B15WrhOqFK)h zcx_z~8`QJx&uM=#!PTG8_2Guva=C8`SMZr4KW0ik;-;qHwI7wS+?!?Q9!GLR-inD2 zkz6uJc!lZlT1DDI`!~l20wjY756NtG$>js`Q6&H`q+jVFIPgLqX{#z|*(+POmM84B zY7bb+y3ZS{Uao>)EhSP)F!V|c^*pz~CSn!>Msn!erBenhSp0VAcSN;15;%gC8Y7Cr z7pJ>eg>Tvrj;{0VT?oOrgO{Il`~y687Uh6dgC3y6yg#jL>)GOjIyE0hCS5s<^*D(i z4I>i0ZT=1);f3A+#w@c&o=@zk1>$(ZiQ_KTl}083=f$f9qVc~7JJUI1asr;;#7vD- z2Cr7`l~>*e8+Z@07*Z&Cz0{L=Z0_k8z8_X39}^h>sofb=wd#!K4m9&&0NnE;Tj@7d z(ZC`?{KCm!mwZOHP!(WP{oI~}lPTrCT#$YO@wr~5;%0Dw+!%A| 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

    v)q##M≫gwMV+-A*5ADULf=#ME6S00_m<;}6 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

    E?+P9ym|ccEV)py{-d>;=Ts8N+_Lx@wU8JdS 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 Q1O7ZxR8uIGGx7g_02|rQ1ONa4 literal 0 HcmV?d00001 diff --git a/docs/assets/okta-auth-policy.png b/docs/assets/okta-auth-policy.png new file mode 100644 index 0000000000000000000000000000000000000000..dbf99a88ed6e3cfe22708af63f6befa06d170f64 GIT binary patch literal 85431 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 LDHO{+2>gEl!89X`!O0vSyhYj)tbj5Q!?`- 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%0AxC_scxWE6#{bNQQyg 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%0DE2kP(qbSnXvmW4nM>C`)4NImm@ys{1{3JR#i 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

    aly*&Cn?#_uN}{$vcv6miP9Ymc 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�(^ZCz9mBq<;W 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%0A&~5PT~7 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 z

    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 literal 0 HcmV?d00001 diff --git a/docs/developer-guide/site.md b/docs/developer-guide/site.md index af32753a323e2..efd6aece9aedb 100644 --- a/docs/developer-guide/site.md +++ b/docs/developer-guide/site.md @@ -7,20 +7,14 @@ The website is built using `mkdocs` and `mkdocs-material`. To test: ```bash +make build-docs make serve-docs ``` - Once running, you can view your locally built documentation at [http://0.0.0.0:8000/](http://0.0.0.0:8000/). -## Deploying - -```bash -make publish-docs -``` - ## Analytics !!! tip Don't forget to disable your ad-blocker when testing. -We collect [Google Analytics](https://analytics.google.com/analytics/web/#/report-home/a105170809w198079555p192782995). \ No newline at end of file +We collect [Google Analytics](https://analytics.google.com/analytics/web/#/report-home/a105170809w198079555p192782995). diff --git a/docs/operator-manual/user-management/okta.md b/docs/operator-manual/user-management/okta.md index 09d7099d19954..308254759de6e 100644 --- a/docs/operator-manual/user-management/okta.md +++ b/docs/operator-manual/user-management/okta.md @@ -118,34 +118,81 @@ data: ## OIDC (without Dex) -!!! warning "Do you want groups for RBAC later?" - If you want `groups` scope returned from Okta you need to unfortunately contact support to enable [API Access Management with Okta](https://developer.okta.com/docs/concepts/api-access-management/) or [_just use SAML above!_](#saml-with-dex) +!!! warning "Okta groups for RBAC" + If you want `groups` scope returned from Okta, you will need to enable [API Access Management with Okta](https://developer.okta.com/docs/concepts/api-access-management/). This addon is free, and automatically enabled, on Okta developer edition. However, it's an optional add-on for production environments, with an additional associated cost. - Next you may need the API Access Management feature, which the support team can enable for your OktaPreview domain for testing, to enable "custom scopes" and a separate endpoint to use instead of the "public" `/oauth2/v1/authorize` API Access Management endpoint. This might be a paid feature if you want OIDC unfortunately. The free alternative I found was SAML. + You may alternately add a "groups" scope and claim to the default authorization server, and then filter the claim in the Okta application configuration. It's not clear if this requires the Authorization Server add-on. + + If this is not an option for you, use the [SAML (with Dex)](#saml-with-dex) option above instead. + +!!! note + These instructions and screenshots are of Okta version 2023.05.2 E. You can find the current version in the Okta website footer. + +First, create the OIDC integration: + +1. On the `Okta Admin` page, navigate to the Okta Applications at `Applications > Applications.` +1. Choose `Create App Integration`, and choose `OIDC`, and then `Web Application` in the resulting dialogues. + ![Okta OIDC app dialogue](../../assets/okta-create-oidc-app.png) +1. Update the following: + 1. `App Integration name` and `Logo` - set these to suit your needs; they'll be displayed in the Okta catalogue. + 1. `Sign-in redirect URLs`: Add `https://argocd.example.com/auth/callback`; replacing `argocd.example.com` with your ArgoCD web interface URL. Also add `http://localhost:8085/auth/callback` if you would like to be able to login with the CLI. + 1. `Sign-out redirect URIs`: Add `https://argocd.example.com`; substituting the correct domain name as above. + 1. Either assign groups, or choose to skip this step for now. + 1. Leave the rest of the options as-is, and save the integration. + ![Okta app settings](../../assets/okta-app.png) +1. Copy the `Client ID` and the `Client Secret` from the newly created app; you will need these later. + +Next, create a custom Authorization server: 1. On the `Okta Admin` page, navigate to the Okta API Management at `Security > API`. - ![Okta API Management](../../assets/api-management.png) -1. Choose your `default` authorization server. -1. Click `Scopes > Add Scope` - 1. Add a scope called `groups`. - ![Groups Scope](../../assets/groups-scope.png) -1. Click `Claims > Add Claim.` - 1. Add a claim called `groups` - 1. Choose the matching options you need, one example is: - * e.g. to match groups starting with `argocd-` you'd return an `ID Token` using your scope name from step 3 (e.g. `groups`) where the groups name `matches` the `regex` `argocd-.*` - ![Groups Claim](../../assets/groups-claim.png) -1. Edit the `argocd-cm` and configure the `data.oidc.config` section: +1. Click `Add Authorization Server`, and assign it a name and a description. The `Audience` should match your ArgoCD URL - `https://argocd.example.com` +1. Click `Scopes > Add Scope`: + 1. Add a scope called `groups`. Leave the rest of the options as default. + ![Groups Scope](../../assets/okta-groups-scope.png) +1. Click `Claims > Add Claim`: + 1. Add a claim called `groups`. + 1. Adjust the `Include in token type` to `ID Token`, `Always`. + 1. Adjust the `Value type` to `Groups`. + 1. Add a filter that will match the Okta groups you want passed on to ArgoCD; for example `Regex: argocd-.*`. + 1. Set `Include in` to `groups` (the scope you created above). + ![Groups Claim](../../assets/okta-groups-claim.png) +1. Click on `Access Policies` > `Add Policy.` This policy will restrict how this authorization server is used. + 1. Add a name and description. + 1. Assign the policy to the client (application integration) you created above. The field should auto-complete as you type. + 1. Create the policy. + ![Auth Policy](../../assets/okta-auth-policy.png) +1. Add a rule to the policy: + 1. Add a name; `default` is a reasonable name for this rule. + 1. Fine-tune the settings to suit your organization's security posture. Some ideas: + 1. uncheck all the grant types except the Authorization Code. + 1. Adjust the token lifetime to govern how long a session can last. + 1. Restrict refresh token lifetime, or completely disable it. + ![Default rule](../../assets/okta-auth-rule.png) +1. Finally, click `Back to Authorization Servers`, and copy the `Issuer URI`. You will need this later. + +If you haven't yet created Okta groups, and assigned them to the application integration, you should do that now: + +1. Go to `Directory > Groups` +1. For each group you wish to add: + 1. Click `Add Group`, and choose a meaningful name. It should match the regex or pattern you added to your custom `group` claim. + 1. Click on the group (refresh the page if the new group didn't show up in the list). + 1. Assign Okta users to the group. + 1. Click on `Applications` and assign the OIDC application integration you created to this group. + 1. Repeat as needed. + +Finally, configure ArgoCD itself. Edit the `argocd-cm` configmap: ```yaml +url: https://argocd.example.com oidc.config: | name: Okta - issuer: https://yourorganization.oktapreview.com - clientID: 0oaltaqg3oAIf2NOa0h3 - clientSecret: ZXF_CfUc-rtwNfzFecGquzdeJ_MxM4sGc8pDT2Tg6t + # this is the authorization server URI + issuer: https://example.okta.com/oauth2/aus9abcdefgABCDEFGd7 + clientID: 0oa9abcdefgh123AB5d7 + clientSecret: ABCDEFG1234567890abcdefg requestedScopes: ["openid", "profile", "email", "groups"] requestedIDTokenClaims: {"groups": {"essential": true}} ``` - - +You may want to store the `clientSecret` in a Kubernetes secret; see [how to deal with SSO secrets](./index.md/#sensitive-data-and-sso-client-secrets ) for more details. From b93874e7414a53e4a6689cd9c529c5f103a98b39 Mon Sep 17 00:00:00 2001 From: borisssmidtCET <134265736+borisssmidtCET@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:56:30 +0100 Subject: [PATCH 254/269] Add a description for using contour httpproxy CRD (#14614) Which allows you to reuse the same hostname. Co-authored-by: Boris Smidt Co-authored-by: pasha-codefresh --- docs/operator-manual/ingress.md | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/docs/operator-manual/ingress.md b/docs/operator-manual/ingress.md index 5ea947345d507..aad2208c21873 100644 --- a/docs/operator-manual/ingress.md +++ b/docs/operator-manual/ingress.md @@ -166,6 +166,43 @@ The argocd-server Service needs to be annotated with `projectcontour.io/upstream The API server should then be run with TLS disabled. Edit the `argocd-server` deployment to add the `--insecure` flag to the argocd-server command, or simply set `server.insecure: "true"` in the `argocd-cmd-params-cm` ConfigMap [as described here](server-commands/additional-configuration-method.md). +Contour httpproxy CRD: + +Using a contour httpproxy CRD allows you to use the same hostname for the GRPC and REST api. + +```yaml +apiVersion: projectcontour.io/v1 +kind: HTTPProxy +metadata: + name: argocd-server + namespace: argocd +spec: + ingressClassName: contour + virtualhost: + fqdn: path.to.argocd.io + tls: + secretName: wildcard-tls + routes: + - conditions: + - prefix: / + - header: + name: Content-Type + contains: application/grpc + services: + - name: argocd-server + port: 80 + protocol: h2c # allows for unencrypted http2 connections + timeoutPolicy: + response: 1h + idle: 600s + idleConnection: 600s + - conditions: + - prefix: / + services: + - name: argocd-server + port: 80 +``` + ## [kubernetes/ingress-nginx](https://github.com/kubernetes/ingress-nginx) ### Option 1: SSL-Passthrough From d494d3a3311050f36a7ebaa9d816d560a3f73a31 Mon Sep 17 00:00:00 2001 From: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> Date: Wed, 7 Feb 2024 05:26:14 +0530 Subject: [PATCH 255/269] fix: ci failures (#17107) Signed-off-by: Soumya Ghosh Dastidar --- .github/workflows/ci-build.yaml | 63 ++++++++++++------- .../notifications/services/alertmanager.md | 8 +-- .../notifications/services/awssqs.md | 23 +++++-- .../notifications/services/email.md | 6 +- .../notifications/services/github.md | 3 +- .../notifications/services/googlechat.md | 2 +- .../notifications/services/grafana.md | 2 +- .../notifications/services/mattermost.md | 2 +- .../notifications/services/newrelic.md | 2 +- .../notifications/services/opsgenie.md | 5 +- .../notifications/services/pagerduty.md | 4 +- .../notifications/services/pagerduty_v2.md | 4 +- .../notifications/services/pushover.md | 4 +- .../notifications/services/rocketchat.md | 2 +- .../notifications/services/slack.md | 3 +- .../notifications/services/teams.md | 2 +- .../notifications/services/telegram.md | 4 +- .../notifications/services/webex.md | 2 +- go.mod | 4 +- go.sum | 8 +-- 20 files changed, 92 insertions(+), 61 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 1267a628e42c8..e01964e1e6a60 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -1,5 +1,5 @@ name: Integration tests -on: +on: push: branches: - 'master' @@ -43,6 +43,8 @@ jobs: name: Ensure Go modules synchronicity if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 + needs: + - changes steps: - name: Checkout code uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 @@ -62,6 +64,8 @@ jobs: name: Build & cache Go code if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 + needs: + - changes steps: - name: Checkout code uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 @@ -87,6 +91,8 @@ jobs: name: Lint Go code if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 + needs: + - changes steps: - name: Checkout code uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 @@ -106,9 +112,10 @@ jobs: runs-on: ubuntu-22.04 needs: - build-go + - changes env: GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} + GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} steps: - name: Create checkout directory run: mkdir -p ~/go/src/github.com/argoproj @@ -174,9 +181,10 @@ jobs: runs-on: ubuntu-22.04 needs: - build-go + - changes env: GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} + GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} steps: - name: Create checkout directory run: mkdir -p ~/go/src/github.com/argoproj @@ -235,6 +243,8 @@ jobs: name: Check changes to generated code if: ${{ needs.changes.outputs.backend == 'true' }} runs-on: ubuntu-22.04 + needs: + - changes steps: - name: Checkout code uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 @@ -284,6 +294,8 @@ jobs: name: Build, test & lint UI code if: ${{ needs.changes.outputs.frontend == 'true' }} runs-on: ubuntu-22.04 + needs: + - changes steps: - name: Checkout code uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 @@ -320,6 +332,7 @@ jobs: needs: - test-go - build-ui + - changes env: sonar_secret: ${{ secrets.SONAR_TOKEN }} steps: @@ -360,24 +373,24 @@ jobs: SCANNER_PATH: /tmp/cache/scanner OS: linux run: | - # We do not use the provided action, because it does contain an old - # version of the scanner, and also takes time to build. - set -e - mkdir -p ${SCANNER_PATH} - export SONAR_USER_HOME=${SCANNER_PATH}/.sonar - if [[ ! -x "${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/bin/sonar-scanner" ]]; then - curl -Ol https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SCANNER_VERSION}-${OS}.zip - unzip -qq -o sonar-scanner-cli-${SCANNER_VERSION}-${OS}.zip -d ${SCANNER_PATH} - fi - - chmod +x ${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/bin/sonar-scanner - chmod +x ${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/jre/bin/java - - # Explicitly set NODE_MODULES - export NODE_MODULES=${PWD}/ui/node_modules - export NODE_PATH=${PWD}/ui/node_modules - - ${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/bin/sonar-scanner + # We do not use the provided action, because it does contain an old + # version of the scanner, and also takes time to build. + set -e + mkdir -p ${SCANNER_PATH} + export SONAR_USER_HOME=${SCANNER_PATH}/.sonar + if [[ ! -x "${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/bin/sonar-scanner" ]]; then + curl -Ol https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SCANNER_VERSION}-${OS}.zip + unzip -qq -o sonar-scanner-cli-${SCANNER_VERSION}-${OS}.zip -d ${SCANNER_PATH} + fi + + chmod +x ${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/bin/sonar-scanner + chmod +x ${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/jre/bin/java + + # Explicitly set NODE_MODULES + export NODE_MODULES=${PWD}/ui/node_modules + export NODE_PATH=${PWD}/ui/node_modules + + ${SCANNER_PATH}/sonar-scanner-${SCANNER_VERSION}-${OS}/bin/sonar-scanner if: env.sonar_secret != '' test-e2e: @@ -388,8 +401,9 @@ jobs: fail-fast: false matrix: k3s-version: [v1.29.1, v1.28.6, v1.27.10, v1.26.13, v1.25.16] - needs: + needs: - build-go + - changes env: GOPATH: /home/runner/go ARGOCD_FAKE_IN_CLUSTER: "true" @@ -402,7 +416,7 @@ jobs: ARGOCD_APPLICATION_NAMESPACES: "argocd-e2e-external,argocd-e2e-external-2" ARGOCD_SERVER: "127.0.0.1:8088" GITHUB_TOKEN: ${{ secrets.E2E_TEST_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} + GITLAB_TOKEN: ${{ secrets.E2E_TEST_GITLAB_TOKEN }} steps: - name: Checkout code uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0 @@ -499,6 +513,7 @@ jobs: if: ${{ always() }} needs: - test-e2e + - changes runs-on: ubuntu-22.04 steps: - run: | @@ -508,4 +523,4 @@ jobs: exit 0 else exit 1 - fi + fi \ No newline at end of file diff --git a/docs/operator-manual/notifications/services/alertmanager.md b/docs/operator-manual/notifications/services/alertmanager.md index e0f9d7e4e7889..033a76a29ea65 100755 --- a/docs/operator-manual/notifications/services/alertmanager.md +++ b/docs/operator-manual/notifications/services/alertmanager.md @@ -43,7 +43,7 @@ You should turn off "send_resolved" or you will receive unnecessary recovery not apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.alertmanager: | targets: @@ -58,7 +58,7 @@ If your alertmanager has changed the default api, you can customize "apiPath". apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.alertmanager: | targets: @@ -89,7 +89,7 @@ stringData: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.alertmanager: | targets: @@ -110,7 +110,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.alertmanager: | targets: diff --git a/docs/operator-manual/notifications/services/awssqs.md b/docs/operator-manual/notifications/services/awssqs.md index 6b744f4744b93..5331533826348 100755 --- a/docs/operator-manual/notifications/services/awssqs.md +++ b/docs/operator-manual/notifications/services/awssqs.md @@ -1,8 +1,8 @@ -# AWS SQS +# AWS SQS ## Parameters -This notification service is capable of sending simple messages to AWS SQS queue. +This notification service is capable of sending simple messages to AWS SQS queue. * `queue` - name of the queue you are intending to send messages to. Can be overridden with target destination annotation. * `region` - region of the sqs queue can be provided via env variable AWS_DEFAULT_REGION @@ -30,7 +30,7 @@ metadata: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.awssqs: | region: "us-east-2" @@ -63,7 +63,7 @@ stringData: ### Minimal configuration using AWS Env variables -Ensure following list of environment variables are injected via OIDC, or other method. And assuming SQS is local to the account. +Ensure the following list of environment variables are injected via OIDC, or another method. And assuming SQS is local to the account. You may skip usage of secret for sensitive data and omit other parameters. (Setting parameters via ConfigMap takes precedent.) Variables: @@ -89,7 +89,7 @@ metadata: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.awssqs: | queue: "myqueue" @@ -104,3 +104,16 @@ data: - oncePer: obj.metadata.annotations["generation"] ``` + +## FIFO SQS Queues + +FIFO queues require a [MessageGroupId](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html#SQS-SendMessage-request-MessageGroupId) to be sent along with every message, every message with a matching MessageGroupId will be processed one by one in order. + +To send to a FIFO SQS Queue you must include a `messageGroupId` in the template such as in the example below: + +```yaml +template.deployment-ready: | + message: | + Deployment {{.obj.metadata.name}} is ready! + messageGroupId: {{.obj.metadata.name}}-deployment +``` diff --git a/docs/operator-manual/notifications/services/email.md b/docs/operator-manual/notifications/services/email.md index b81ab6cde8b4c..7fd3f0e22379c 100755 --- a/docs/operator-manual/notifications/services/email.md +++ b/docs/operator-manual/notifications/services/email.md @@ -20,7 +20,7 @@ The following snippet contains sample Gmail service configuration: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.email.gmail: | username: $email-username @@ -36,7 +36,7 @@ Without authentication: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.email.example: | host: smtp.example.com @@ -52,7 +52,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: template.app-sync-succeeded: | email: diff --git a/docs/operator-manual/notifications/services/github.md b/docs/operator-manual/notifications/services/github.md index be76ab150d1a1..1fa1a985d2682 100755 --- a/docs/operator-manual/notifications/services/github.md +++ b/docs/operator-manual/notifications/services/github.md @@ -24,7 +24,7 @@ in `argocd-notifications-cm` ConfigMap apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.github: | appID: @@ -76,6 +76,7 @@ template.app-deployed: | logURL: "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true" requiredContexts: [] autoMerge: true + transientEnvironment: false pullRequestComment: content: | Application {{.app.metadata.name}} is now running new version of deployments manifests. diff --git a/docs/operator-manual/notifications/services/googlechat.md b/docs/operator-manual/notifications/services/googlechat.md index 885ce685a4511..821c23023e863 100755 --- a/docs/operator-manual/notifications/services/googlechat.md +++ b/docs/operator-manual/notifications/services/googlechat.md @@ -19,7 +19,7 @@ The Google Chat notification service send message notifications to a google chat apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.googlechat: | webhooks: diff --git a/docs/operator-manual/notifications/services/grafana.md b/docs/operator-manual/notifications/services/grafana.md index a36672d0fa423..1f3e77701f044 100755 --- a/docs/operator-manual/notifications/services/grafana.md +++ b/docs/operator-manual/notifications/services/grafana.md @@ -21,7 +21,7 @@ Available parameters : apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.grafana: | apiUrl: https://grafana.example.com/api diff --git a/docs/operator-manual/notifications/services/mattermost.md b/docs/operator-manual/notifications/services/mattermost.md index 98e0d0fd7b82f..d1f187e955b9c 100755 --- a/docs/operator-manual/notifications/services/mattermost.md +++ b/docs/operator-manual/notifications/services/mattermost.md @@ -19,7 +19,7 @@ in `argocd-notifications-cm` ConfigMap apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.mattermost: | apiURL: diff --git a/docs/operator-manual/notifications/services/newrelic.md b/docs/operator-manual/notifications/services/newrelic.md index d98288a846422..b0c7e340c9b28 100755 --- a/docs/operator-manual/notifications/services/newrelic.md +++ b/docs/operator-manual/notifications/services/newrelic.md @@ -14,7 +14,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.newrelic: | apiURL: diff --git a/docs/operator-manual/notifications/services/opsgenie.md b/docs/operator-manual/notifications/services/opsgenie.md index c590a4ac979b6..e92ee99756ab8 100755 --- a/docs/operator-manual/notifications/services/opsgenie.md +++ b/docs/operator-manual/notifications/services/opsgenie.md @@ -13,13 +13,14 @@ To be able to send notifications with argocd-notifications you have to create an 9. Make sure the checkboxes for "Create and Update Access" and "enable" are selected, disable the other checkboxes to remove unnecessary permissions 10. Click "Safe Integration" at the bottom 11. Check your browser for the correct server apiURL. If it is "app.opsgenie.com" then use the US/international api url `api.opsgenie.com` in the next step, otherwise use `api.eu.opsgenie.com` (European API). -12. You are finished with configuring opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret. +12. You are finished with configuring Opsgenie. Now you need to configure argocd-notifications. Use the apiUrl, the team name and the apiKey to configure the Opsgenie integration in the `argocd-notifications-secret` secret. + ```yaml apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.opsgenie: | apiUrl: diff --git a/docs/operator-manual/notifications/services/pagerduty.md b/docs/operator-manual/notifications/services/pagerduty.md index 3b507e7fdba58..c6e1e41dac81d 100755 --- a/docs/operator-manual/notifications/services/pagerduty.md +++ b/docs/operator-manual/notifications/services/pagerduty.md @@ -26,7 +26,7 @@ stringData: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.pagerduty: | token: $pagerdutyToken @@ -41,7 +41,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: template.rollout-aborted: | message: Rollout {{.rollout.metadata.name}} is aborted. diff --git a/docs/operator-manual/notifications/services/pagerduty_v2.md b/docs/operator-manual/notifications/services/pagerduty_v2.md index 01eee28fc0c9b..549cdc937b150 100755 --- a/docs/operator-manual/notifications/services/pagerduty_v2.md +++ b/docs/operator-manual/notifications/services/pagerduty_v2.md @@ -28,7 +28,7 @@ stringData: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.pagerdutyv2: | serviceKeys: @@ -43,7 +43,7 @@ data: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: template.rollout-aborted: | message: Rollout {{.rollout.metadata.name}} is aborted. diff --git a/docs/operator-manual/notifications/services/pushover.md b/docs/operator-manual/notifications/services/pushover.md index 37cb20b277dcc..a09b3660f9233 100755 --- a/docs/operator-manual/notifications/services/pushover.md +++ b/docs/operator-manual/notifications/services/pushover.md @@ -1,13 +1,13 @@ # Pushover 1. Create an app at [pushover.net](https://pushover.net/apps/build). -2. Store the API key in `` Secret and define the secret name in `` ConfigMap: +2. Store the API key in `` Secret and define the secret name in `argocd-notifications-cm` ConfigMap: ```yaml apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.pushover: | token: $pushover-token diff --git a/docs/operator-manual/notifications/services/rocketchat.md b/docs/operator-manual/notifications/services/rocketchat.md index f1157050139d0..20aaa405c80d0 100755 --- a/docs/operator-manual/notifications/services/rocketchat.md +++ b/docs/operator-manual/notifications/services/rocketchat.md @@ -43,7 +43,7 @@ stringData: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.rocketchat: | email: $rocketchat-email diff --git a/docs/operator-manual/notifications/services/slack.md b/docs/operator-manual/notifications/services/slack.md index 0f3fdf1739210..41bdddd7617c4 100755 --- a/docs/operator-manual/notifications/services/slack.md +++ b/docs/operator-manual/notifications/services/slack.md @@ -15,6 +15,7 @@ The Slack notification service configuration includes following settings: | `signingSecret` | False | `string` | | `8f742231b10e8888abcd99yyyzzz85a5` | | `token` | **True** | `string` | The app's OAuth access token. | `xoxb-1234567890-1234567890123-5n38u5ed63fgzqlvuyxvxcx6` | | `username` | False | `string` | The app username. | `argocd` | +| `disableUnfurl` | False | `bool` | Disable slack unfurling links in messages | `true` | ## Configuration @@ -48,7 +49,7 @@ The Slack notification service configuration includes following settings: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.slack: | token: $slack-token diff --git a/docs/operator-manual/notifications/services/teams.md b/docs/operator-manual/notifications/services/teams.md index 8b8c6b819c795..0e44456d4de19 100755 --- a/docs/operator-manual/notifications/services/teams.md +++ b/docs/operator-manual/notifications/services/teams.md @@ -18,7 +18,7 @@ The Teams notification service send message notifications using Teams bot and re apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.teams: | recipientUrls: diff --git a/docs/operator-manual/notifications/services/telegram.md b/docs/operator-manual/notifications/services/telegram.md index 953c2a9fca0bf..8612a09d1ca84 100755 --- a/docs/operator-manual/notifications/services/telegram.md +++ b/docs/operator-manual/notifications/services/telegram.md @@ -2,13 +2,13 @@ 1. Get an API token using [@Botfather](https://t.me/Botfather). 2. Store token in `` Secret and configure telegram integration -in `` ConfigMap: +in `argocd-notifications-cm` ConfigMap: ```yaml apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.telegram: | token: $telegram-token diff --git a/docs/operator-manual/notifications/services/webex.md b/docs/operator-manual/notifications/services/webex.md index 440ed1ddc738f..eba4c5e11b8dc 100755 --- a/docs/operator-manual/notifications/services/webex.md +++ b/docs/operator-manual/notifications/services/webex.md @@ -24,7 +24,7 @@ The Webex Teams notification service configuration includes following settings: apiVersion: v1 kind: ConfigMap metadata: - name: + name: argocd-notifications-cm data: service.webex: | token: $webex-token diff --git a/go.mod b/go.mod index ced6fb496ea6f..cb024e3183404 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/alicebob/miniredis/v2 v2.30.4 github.com/antonmedv/expr v1.15.2 github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 - github.com/argoproj/notifications-engine v0.4.1-0.20240126143042-84b9f7913604 + github.com/argoproj/notifications-engine v0.4.1-0.20240206192038-2daee6022f41 github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 github.com/aws/aws-sdk-go v1.50.8 github.com/bmatcuk/doublestar/v4 v4.6.0 @@ -78,7 +78,7 @@ require ( github.com/whilp/git-urls v1.0.0 github.com/xanzy/go-gitlab v0.91.1 github.com/yuin/gopher-lua v1.1.0 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 go.opentelemetry.io/otel/sdk v1.21.0 diff --git a/go.sum b/go.sum index 619cc97b724c0..2d33e5a248cce 100644 --- a/go.sum +++ b/go.sum @@ -696,8 +696,8 @@ github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2 github.com/appscode/go v0.0.0-20191119085241-0887d8ec2ecc/go.mod h1:OawnOmAL4ZX3YaPdN+8HTNwBveT1jMsqP74moa9XUbE= github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757 h1:5fKAhTQcTBom0vin56cz/UTPx2GMuvdb+lJRAUOPbHA= github.com/argoproj/gitops-engine v0.7.1-0.20240124052710-5fd9f449e757/go.mod h1:gWE8uROi7hIkWGNAVM+8FWkMfo0vZ03SLx/aFw/DBzg= -github.com/argoproj/notifications-engine v0.4.1-0.20240126143042-84b9f7913604 h1:pMfBao6Vm1Ax0xGIp9BWEia2nKkccHwV0dTEdrsFOpo= -github.com/argoproj/notifications-engine v0.4.1-0.20240126143042-84b9f7913604/go.mod h1:TsyusmXQWIL0ST7YMRG/ered7WlWDmbmnPpXnS2LJmM= +github.com/argoproj/notifications-engine v0.4.1-0.20240206192038-2daee6022f41 h1:PQE8LbcbRHdtnQzeEWwVU2QHXACKOA30yS3No5HSoTQ= +github.com/argoproj/notifications-engine v0.4.1-0.20240206192038-2daee6022f41/go.mod h1:TsyusmXQWIL0ST7YMRG/ered7WlWDmbmnPpXnS2LJmM= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1 h1:qsHwwOJ21K2Ao0xPju1sNuqphyMnMYkyB3ZLoLtxWpo= github.com/argoproj/pkg v0.13.7-0.20230626144333-d56162821bd1/go.mod h1:CZHlkyAD1/+FbEn6cB2DQTj48IoLGvEYsWEvtzP3238= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -1746,8 +1746,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 h1:PzIubN4/sjByhDRHLviCjJuweBXWFZWhghjg7cS28+M= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0/go.mod h1:Ct6zzQEuGK3WpJs2n4dn+wfJYzd/+hNnxMRTWjGn30M= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0 h1:ZOLJc06r4CB42laIXg/7udr0pbZyuAihN10A/XuiQRY= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.42.0/go.mod h1:5z+/ZWJQKXa9YT34fQNx5K8Hd1EoIhvtUygUQPqEOgQ= go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= From 8ac7b6da38e961c21e489e53da49ebd5ee4e1da5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:53:43 +0200 Subject: [PATCH 256/269] chore(deps): bump library/golang from 1.21.3 to 1.22.0 in /test/remote (#17111) Bumps library/golang from 1.21.3 to 1.22.0. --- updated-dependencies: - dependency-name: library/golang 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> --- test/remote/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/remote/Dockerfile b/test/remote/Dockerfile index 8d03d1321d25b..886a855f92597 100644 --- a/test/remote/Dockerfile +++ b/test/remote/Dockerfile @@ -1,6 +1,6 @@ ARG BASE_IMAGE=docker.io/library/ubuntu:22.04 -FROM docker.io/library/golang:1.21.3@sha256:02d7116222536a5cf0fcf631f90b507758b669648e0f20186d2dc94a9b419a9b AS go +FROM docker.io/library/golang:1.22.0@sha256:094e47ef90125eb49dfbc67d3480b56ee82ea9b05f50b750b5e85fab9606c2de AS go RUN go install github.com/mattn/goreman@latest && \ go install github.com/kisielk/godepgraph@latest From b23e71f578881427cdd01775c473f99a4e8e33c3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:54:46 +0200 Subject: [PATCH 257/269] chore(deps-dev): bump yarn from 1.22.10 to 1.22.13 in /ui-test (#17092) Bumps [yarn](https://github.com/yarnpkg/yarn) from 1.22.10 to 1.22.13. - [Release notes](https://github.com/yarnpkg/yarn/releases) - [Changelog](https://github.com/yarnpkg/yarn/blob/master/CHANGELOG.md) - [Commits](https://github.com/yarnpkg/yarn/compare/1.22.10...v1.22.13) --- updated-dependencies: - dependency-name: yarn dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: pasha-codefresh --- ui-test/package.json | 2 +- ui-test/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui-test/package.json b/ui-test/package.json index 1875e31b6fd62..fd34ca2edab4a 100644 --- a/ui-test/package.json +++ b/ui-test/package.json @@ -27,6 +27,6 @@ "tslint-config-prettier": "^1.18.0", "tslint-plugin-prettier": "^2.0.1", "typescript": "^4.0.3", - "yarn": "^1.22.10" + "yarn": "^1.22.13" } } diff --git a/ui-test/yarn.lock b/ui-test/yarn.lock index c9cf7265fffe0..6765cbf79d61b 100644 --- a/ui-test/yarn.lock +++ b/ui-test/yarn.lock @@ -1510,10 +1510,10 @@ yargs@13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" -yarn@^1.22.10: - version "1.22.10" - resolved "https://registry.npmjs.org/yarn/-/yarn-1.22.10.tgz" - integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA== +yarn@^1.22.13: + version "1.22.13" + resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.13.tgz#8789ef23b630fe99b819b044f4b7b93ab1bc1b8f" + integrity sha512-G8qG4t7Ef5cLVpzbM3HWWsow4hpfeSCfKtMnjfERmp9V5qSCOKz0uGAIQCM/x3gWfCzH8Bvb4hl3ZfhG/XD1Jg== yauzl@^2.10.0: version "2.10.0" From 7ce342fb88579b560abf9e66ff20bc91f9d7048e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:55:20 +0200 Subject: [PATCH 258/269] chore(deps): bump library/redis from 7.0.11 to 7.2.4 in /test/container (#16806) Bumps library/redis from 7.0.11 to 7.2.4. --- updated-dependencies: - dependency-name: library/redis 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> Co-authored-by: pasha-codefresh --- test/container/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/container/Dockerfile b/test/container/Dockerfile index c86fbb1f387b1..7de89a2cf613e 100644 --- a/test/container/Dockerfile +++ b/test/container/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/redis:7.0.11@sha256:f50031a49f41e493087fb95f96fdb3523bb25dcf6a3f0b07c588ad3cdbe1d0aa as redis +FROM docker.io/library/redis:7.2.4@sha256:cc8b0b85fe6917a401334fd285f9a8d66fae231abcf13aadfd02975bf3924a47 as redis # There are libraries we will want to copy from here in the final stage of the # build, but the COPY directive does not have a way to determine system From 98d5a2bf869eef7995cb842c298b08b1f92d4c91 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 14:11:05 +0200 Subject: [PATCH 259/269] chore(deps-dev): bump yarn from 1.22.10 to 1.22.21 in /ui (#17096) Bumps [yarn](https://github.com/yarnpkg/yarn) from 1.22.10 to 1.22.21. - [Release notes](https://github.com/yarnpkg/yarn/releases) - [Changelog](https://github.com/yarnpkg/yarn/blob/master/CHANGELOG.md) - [Commits](https://github.com/yarnpkg/yarn/compare/1.22.10...v1.22.21) --- updated-dependencies: - dependency-name: yarn dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Blake Pettersson Co-authored-by: pasha-codefresh --- ui/package.json | 2 +- ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ui/package.json b/ui/package.json index d290c93be08cb..e5979d7ec5bc7 100644 --- a/ui/package.json +++ b/ui/package.json @@ -120,6 +120,6 @@ "webpack": "^5.84.1", "webpack-cli": "^4.9.2", "webpack-dev-server": "^4.7.4", - "yarn": "^1.22.10" + "yarn": "^1.22.21" } } diff --git a/ui/yarn.lock b/ui/yarn.lock index 346e47b078610..a3a25d70166a8 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -9941,10 +9941,10 @@ yargs@^17.0.1: y18n "^5.0.5" yargs-parser "^20.2.2" -yarn@^1.22.10: - version "1.22.10" - resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c" - integrity sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA== +yarn@^1.22.21: + version "1.22.21" + resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.21.tgz#1959a18351b811cdeedbd484a8f86c3cc3bbaf72" + integrity sha512-ynXaJsADJ9JiZ84zU25XkPGOvVMmZ5b7tmTSpKURYwgELdjucAOydqIOrOfTxVYcNXe91xvLZwcRh68SR3liCg== yn@3.1.1: version "3.1.1" From 93a668ac091db3cf077969ab5572729b535fe400 Mon Sep 17 00:00:00 2001 From: Sorav Kumar Sharma Date: Wed, 7 Feb 2024 18:32:07 +0530 Subject: [PATCH 260/269] fix the typo (#17116) --- controller/sync.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/sync.go b/controller/sync.go index 2d21bf1cb1190..34c12bdb5da3c 100644 --- a/controller/sync.go +++ b/controller/sync.go @@ -103,7 +103,7 @@ func (m *appStateManager) SyncAppState(app *v1alpha1.Application, state *v1alpha if syncOp.SyncOptions.HasOption("FailOnSharedResource=true") && hasSharedResource { state.Phase = common.OperationFailed - state.Message = fmt.Sprintf("Shared resouce found: %s", sharedResourceMessage) + state.Message = fmt.Sprintf("Shared resource found: %s", sharedResourceMessage) return } From 3c9a2fbc59236b21a00cfca571fcf0fae59ad265 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:06:57 +0200 Subject: [PATCH 261/269] chore(deps): bump library/node from 20.6.1 to 21.6.1 (#17053) Bumps library/node from 20.6.1 to 21.6.1. --- updated-dependencies: - dependency-name: library/node 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> Co-authored-by: pasha-codefresh --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 461a42305f3ae..511fa7cceef96 100644 --- a/Dockerfile +++ b/Dockerfile @@ -83,7 +83,7 @@ WORKDIR /home/argocd #################################################################################################### # Argo CD UI stage #################################################################################################### -FROM --platform=$BUILDPLATFORM docker.io/library/node:20.6.1@sha256:14bd39208dbc0eb171cbfb26ccb9ac09fa1b2eba04ccd528ab5d12983fd9ee24 AS argocd-ui +FROM --platform=$BUILDPLATFORM docker.io/library/node:21.6.1@sha256:abc4a25c8b5a2b460f3144aabfc8941ecd7e4fb721e0b14b635e70394c1899fb AS argocd-ui WORKDIR /src COPY ["ui/package.json", "ui/yarn.lock", "./"] From 52ffd7df4dd2c08b3dcf75dafd71ba194148f0f0 Mon Sep 17 00:00:00 2001 From: fsl <1171313930@qq.com> Date: Wed, 7 Feb 2024 22:21:00 +0800 Subject: [PATCH 262/269] chore(deps): bump library/node from 20.7.0 to 21.6.1 (#17065) Signed-off-by: fengshunli <1171313930@qq.com> Co-authored-by: pasha-codefresh --- .github/workflows/ci-build.yaml | 2 +- test/container/Dockerfile | 2 +- ui-test/Dockerfile | 2 +- ui/.nvmrc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index e01964e1e6a60..23d542f6385ed 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -302,7 +302,7 @@ jobs: - name: Setup NodeJS uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1 with: - node-version: '20.7.0' + node-version: '21.6.1' - name: Restore node dependency cache id: cache-dependencies uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 diff --git a/test/container/Dockerfile b/test/container/Dockerfile index 7de89a2cf613e..9db9a2b07c33f 100644 --- a/test/container/Dockerfile +++ b/test/container/Dockerfile @@ -6,7 +6,7 @@ FROM docker.io/library/redis:7.2.4@sha256:cc8b0b85fe6917a401334fd285f9a8d66fae23 RUN ln -s /usr/lib/$(uname -m)-linux-gnu /usr/lib/linux-gnu # Please make sure to also check the contained yarn version and update the references below when upgrading this image's version -FROM docker.io/library/node:20.7.0@sha256:f08c20b9f9c55dd47b1841793f0ee480c5395aa165cd02edfd68b068ed64bfb5 as node +FROM docker.io/library/node:21.6.1@sha256:abc4a25c8b5a2b460f3144aabfc8941ecd7e4fb721e0b14b635e70394c1899fb as node FROM docker.io/library/golang:1.21.3@sha256:02d7116222536a5cf0fcf631f90b507758b669648e0f20186d2dc94a9b419a9b as golang diff --git a/ui-test/Dockerfile b/ui-test/Dockerfile index a5a77710eca52..7327aa1b6dcd7 100644 --- a/ui-test/Dockerfile +++ b/ui-test/Dockerfile @@ -1,4 +1,4 @@ -FROM docker.io/library/node:20.7.0@sha256:f08c20b9f9c55dd47b1841793f0ee480c5395aa165cd02edfd68b068ed64bfb5 as node +FROM docker.io/library/node:21.6.1@sha256:abc4a25c8b5a2b460f3144aabfc8941ecd7e4fb721e0b14b635e70394c1899fb as node RUN apt-get update && apt-get install --no-install-recommends -y \ software-properties-common diff --git a/ui/.nvmrc b/ui/.nvmrc index 376d26203e61e..a8d3ff91fa10d 100644 --- a/ui/.nvmrc +++ b/ui/.nvmrc @@ -1 +1 @@ -v20.7.0 +v21.6.1 From f77cf949086f25f80b55862a855fac6c47e96cb3 Mon Sep 17 00:00:00 2001 From: Prune Sebastien THOMAS Date: Wed, 7 Feb 2024 14:00:00 -0500 Subject: [PATCH 263/269] fix(kustomize): set build dir (#15057) #16229 #16652 (#16653) * use repo root, not app path Signed-off-by: Prune correct patch Signed-off-by: Prune * use Getwd to find the root path for diff commands Signed-off-by: Prune * set dot a default for argo app commands Signed-off-by: Prune * revert default values Signed-off-by: Prune * patch diff in TestNamespacedResourceDiffing Signed-off-by: Prune * patching some diff and sync Signed-off-by: Prune * patch remaining diff in error Signed-off-by: Prune --------- Signed-off-by: Prune --- cmd/argocd/commands/app.go | 1 + reposerver/repository/repository.go | 8 ++++---- test/e2e/app_management_ns_test.go | 10 +++++----- test/e2e/app_management_test.go | 4 ++-- util/kustomize/kustomize.go | 6 +++++- util/kustomize/kustomize_test.go | 14 +++++++------- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 8e49fbc0e29e1..f18a4fb34fa32 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -1116,6 +1116,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co defer argoio.Close(conn) cluster, err := clusterIf.Get(ctx, &clusterpkg.ClusterQuery{Name: app.Spec.Destination.Name, Server: app.Spec.Destination.Server}) errors.CheckError(err) + diffOption.local = local diffOption.localRepoRoot = localRepoRoot diffOption.cluster = cluster diff --git a/reposerver/repository/repository.go b/reposerver/repository/repository.go index 41f26b1f434b8..5d11a6438272d 100644 --- a/reposerver/repository/repository.go +++ b/reposerver/repository/repository.go @@ -1389,7 +1389,7 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string, if q.KustomizeOptions != nil { kustomizeBinary = q.KustomizeOptions.BinaryPath } - k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary) + k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary) targetObjs, _, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env) case v1alpha1.ApplicationSourceTypePlugin: pluginName := "" @@ -1976,7 +1976,7 @@ func (s *Service) GetAppDetails(ctx context.Context, q *apiclient.RepoServerAppD return err } case v1alpha1.ApplicationSourceTypeKustomize: - if err := populateKustomizeAppDetails(res, q, opContext.appPath, commitSHA, s.gitCredsStore); err != nil { + if err := populateKustomizeAppDetails(res, q, repoRoot, opContext.appPath, commitSHA, s.gitCredsStore); err != nil { return err } case v1alpha1.ApplicationSourceTypePlugin: @@ -2117,13 +2117,13 @@ func walkHelmValueFilesInPath(root string, valueFiles *[]string) filepath.WalkFu } } -func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apiclient.RepoServerAppDetailsQuery, appPath string, reversion string, credsStore git.CredsStore) error { +func populateKustomizeAppDetails(res *apiclient.RepoAppDetailsResponse, q *apiclient.RepoServerAppDetailsQuery, repoRoot string, appPath string, reversion string, credsStore git.CredsStore) error { res.Kustomize = &apiclient.KustomizeAppSpec{} kustomizeBinary := "" if q.KustomizeOptions != nil { kustomizeBinary = q.KustomizeOptions.BinaryPath } - k := kustomize.NewKustomizeApp(appPath, q.Repo.GetGitCreds(credsStore), q.Repo.Repo, kustomizeBinary) + k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(credsStore), q.Repo.Repo, kustomizeBinary) fakeManifestRequest := apiclient.ManifestRequest{ AppName: q.AppName, Namespace: "", // FIXME: omit it for now diff --git a/test/e2e/app_management_ns_test.go b/test/e2e/app_management_ns_test.go index 3e13131791ab9..32636e2b52c49 100644 --- a/test/e2e/app_management_ns_test.go +++ b/test/e2e/app_management_ns_test.go @@ -748,7 +748,7 @@ func TestNamespacedResourceDiffing(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeOutOfSync)). And(func(app *Application) { - diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local", "testdata/guestbook") + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook") assert.Error(t, err) assert.Contains(t, diffOutput, fmt.Sprintf("===== apps/Deployment %s/guestbook-ui ======", DeploymentNamespace())) }). @@ -761,7 +761,7 @@ func TestNamespacedResourceDiffing(t *testing.T) { Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { - diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local", "testdata/guestbook") + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", "testdata/guestbook") assert.NoError(t, err) assert.Empty(t, diffOutput) }). @@ -897,7 +897,7 @@ func testNSEdgeCasesApplicationResources(t *testing.T, appPath string, statusCod expect. Expect(HealthIs(statusCode)). And(func(app *Application) { - diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local", path.Join("testdata", appPath)) + diffOutput, err := RunCli("app", "diff", ctx.AppQualifiedName(), "--local-repo-root", ".", "--local", path.Join("testdata", appPath)) assert.Empty(t, diffOutput) assert.NoError(t, err) }) @@ -998,7 +998,7 @@ func TestNamespacedLocalManifestSync(t *testing.T) { Given(). LocalPath(guestbookPathLocal). When(). - Sync(). + Sync("--local-repo-root", "."). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { @@ -1066,7 +1066,7 @@ func TestNamespacedLocalSyncDryRunWithASEnabled(t *testing.T) { assert.NoError(t, err) appBefore := app.DeepCopy() - _, err = RunCli("app", "sync", app.QualifiedName(), "--dry-run", "--local", guestbookPathLocal) + _, err = RunCli("app", "sync", app.QualifiedName(), "--dry-run", "--local-repo-root", ".", "--local", guestbookPathLocal) assert.NoError(t, err) appAfter := app.DeepCopy() diff --git a/test/e2e/app_management_test.go b/test/e2e/app_management_test.go index d2902e27c97d8..10b2cf926723c 100644 --- a/test/e2e/app_management_test.go +++ b/test/e2e/app_management_test.go @@ -1324,7 +1324,7 @@ func TestLocalManifestSync(t *testing.T) { Given(). LocalPath(guestbookPathLocal). When(). - Sync(). + Sync("--local-repo-root", "."). Then(). Expect(SyncStatusIs(SyncStatusCodeSynced)). And(func(app *Application) { @@ -1385,7 +1385,7 @@ func TestLocalSyncDryRunWithAutosyncEnabled(t *testing.T) { assert.NoError(t, err) appBefore := app.DeepCopy() - _, err = RunCli("app", "sync", app.Name, "--dry-run", "--local", guestbookPathLocal) + _, err = RunCli("app", "sync", app.Name, "--dry-run", "--local-repo-root", ".", "--local", guestbookPathLocal) assert.NoError(t, err) appAfter := app.DeepCopy() diff --git a/util/kustomize/kustomize.go b/util/kustomize/kustomize.go index f3d2246899d12..d938beeceb578 100644 --- a/util/kustomize/kustomize.go +++ b/util/kustomize/kustomize.go @@ -35,8 +35,9 @@ type Kustomize interface { } // NewKustomizeApp create a new wrapper to run commands on the `kustomize` command-line tool. -func NewKustomizeApp(path string, creds git.Creds, fromRepo string, binaryPath string) Kustomize { +func NewKustomizeApp(repoRoot string, path string, creds git.Creds, fromRepo string, binaryPath string) Kustomize { return &kustomize{ + repoRoot: repoRoot, path: path, creds: creds, repo: fromRepo, @@ -45,6 +46,8 @@ func NewKustomizeApp(path string, creds git.Creds, fromRepo string, binaryPath s } type kustomize struct { + // path to the Git repository root + repoRoot string // path inside the checked out tree path string // creds structure @@ -301,6 +304,7 @@ func (k *kustomize) Build(opts *v1alpha1.ApplicationSourceKustomize, kustomizeOp cmd = exec.Command(k.getBinaryPath(), "build", k.path) } cmd.Env = env + cmd.Dir = k.repoRoot out, err := executil.Run(cmd) if err != nil { return nil, nil, err diff --git a/util/kustomize/kustomize_test.go b/util/kustomize/kustomize_test.go index a6275cf01ae1b..b7a8e319c3295 100644 --- a/util/kustomize/kustomize_test.go +++ b/util/kustomize/kustomize_test.go @@ -40,7 +40,7 @@ func TestKustomizeBuild(t *testing.T) { namePrefix := "namePrefix-" nameSuffix := "-nameSuffix" namespace := "custom-namespace" - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") env := &v1alpha1.Env{ &v1alpha1.EnvEntry{Name: "ARGOCD_APP_NAME", Value: "argo-cd-tests"}, } @@ -123,7 +123,7 @@ func TestKustomizeBuild(t *testing.T) { func TestFailKustomizeBuild(t *testing.T) { appPath, err := testDataDir(t, kustomization1) assert.Nil(t, err) - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") kustomizeSource := v1alpha1.ApplicationSourceKustomize{ Replicas: []v1alpha1.KustomizeReplica{ { @@ -222,7 +222,7 @@ func TestKustomizeBuildForceCommonLabels(t *testing.T) { for _, tc := range testCases { appPath, err := testDataDir(t, tc.TestData) assert.Nil(t, err) - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env) switch tc.ExpectErr { case true: @@ -314,7 +314,7 @@ func TestKustomizeBuildForceCommonAnnotations(t *testing.T) { for _, tc := range testCases { appPath, err := testDataDir(t, tc.TestData) assert.Nil(t, err) - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") objs, _, err := kustomize.Build(&tc.KustomizeSource, nil, tc.Env) switch tc.ExpectErr { case true: @@ -334,7 +334,7 @@ func TestKustomizeCustomVersion(t *testing.T) { kustomizePath, err := testDataDir(t, kustomization4) assert.Nil(t, err) envOutputFile := kustomizePath + "/env_output" - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", kustomizePath+"/kustomize.special") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", kustomizePath+"/kustomize.special") kustomizeSource := v1alpha1.ApplicationSourceKustomize{ Version: "special", } @@ -356,7 +356,7 @@ func TestKustomizeCustomVersion(t *testing.T) { func TestKustomizeBuildComponents(t *testing.T) { appPath, err := testDataDir(t, kustomization6) assert.Nil(t, err) - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") kustomizeSource := v1alpha1.ApplicationSourceKustomize{ Components: []string{"./components"}, @@ -377,7 +377,7 @@ func TestKustomizeBuildComponents(t *testing.T) { func TestKustomizeBuildPatches(t *testing.T) { appPath, err := testDataDir(t, kustomization5) assert.Nil(t, err) - kustomize := NewKustomizeApp(appPath, git.NopCreds{}, "", "") + kustomize := NewKustomizeApp(appPath, appPath, git.NopCreds{}, "", "") kustomizeSource := v1alpha1.ApplicationSourceKustomize{ Patches: []v1alpha1.KustomizePatch{ From 7e80f1e8e59da2701c87e97b6bda4c64345a90e2 Mon Sep 17 00:00:00 2001 From: Blake Pettersson Date: Wed, 7 Feb 2024 13:43:50 -1000 Subject: [PATCH 264/269] chore(ci): tweak backend filters (#17134) The existing backend filters get triggered even on frontend-only or docs-only changes, which should not be the case. The reason for this seems to be the fact that each filter line is ORed rather than ANDed. To remedy this, we put all the filters on the same line. I tried the filter out in a REPL (https://runkit.com/blakepettersson/65c3daba99653f0008c74eda). This is a filter using picomatch (the same library `dorny/paths-filter` uses). Signed-off-by: Blake Pettersson --- .github/workflows/ci-build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 23d542f6385ed..36859a2e60bc1 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -33,10 +33,10 @@ jobs: - uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2 id: filter with: + # Any file which is not under docs/, ui/ or is not a markdown file is counted as a backend file filters: | backend: - - '!(ui/**)' - - '!(**/*.md)' + - '!(ui/**|docs/**|**.md|**/*.md)' frontend: - 'ui/**' check-go: From d7da05f3aaff0697de814c5e9d1df4d4a7b408ca Mon Sep 17 00:00:00 2001 From: Alexandre Gaudreault Date: Thu, 8 Feb 2024 21:09:17 -0500 Subject: [PATCH 265/269] docs: fix error in toolchain setup (#17154) Signed-off-by: Alexandre Gaudreault --- docs/developer-guide/toolchain-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer-guide/toolchain-guide.md b/docs/developer-guide/toolchain-guide.md index 42ca7fac87404..335180438dac6 100644 --- a/docs/developer-guide/toolchain-guide.md +++ b/docs/developer-guide/toolchain-guide.md @@ -304,7 +304,7 @@ For installing the tools required to build and test Argo CD on your local system You can change the target location by setting the `BIN` environment before running the installer scripts. For example, you can install the binaries into `~/go/bin` (which should then be the first component in your `PATH` environment, i.e. `export PATH=~/go/bin:$PATH`): ```shell -make BIN=~/go/bin install-tools-local +BIN=~/go/bin make install-tools-local ``` Additionally, you have to install at least the following tools via your OS's package manager (this list might not be always up-to-date): From bb1c1ed44d3c802329c5437f3904852dc3ea98de Mon Sep 17 00:00:00 2001 From: AS <11219262+ashutosh16@users.noreply.github.com> Date: Fri, 9 Feb 2024 06:37:04 -0800 Subject: [PATCH 266/269] chore(dex): 2.37.0 to 2.38.0 (#17157) Signed-off-by: asingh51 Co-authored-by: asingh51 --- .github/workflows/ci-build.yaml | 2 +- manifests/base/dex/argocd-dex-server-deployment.yaml | 2 +- manifests/ha/install.yaml | 2 +- manifests/ha/namespace-install.yaml | 2 +- manifests/install.yaml | 2 +- manifests/namespace-install.yaml | 2 +- test/container/Procfile | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index 36859a2e60bc1..c8a522fbf7198 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -466,7 +466,7 @@ jobs: git config --global user.email "john.doe@example.com" - name: Pull Docker image required for tests run: | - docker pull ghcr.io/dexidp/dex:v2.37.0 + docker pull ghcr.io/dexidp/dex:v2.38.0 docker pull argoproj/argo-cd-ci-builder:v1.0.0 docker pull redis:7.0.14-alpine - name: Create target directory for binaries in the build-process diff --git a/manifests/base/dex/argocd-dex-server-deployment.yaml b/manifests/base/dex/argocd-dex-server-deployment.yaml index 8d3b37d177913..7ff5985f44a90 100644 --- a/manifests/base/dex/argocd-dex-server-deployment.yaml +++ b/manifests/base/dex/argocd-dex-server-deployment.yaml @@ -37,7 +37,7 @@ spec: type: RuntimeDefault containers: - name: dex - image: ghcr.io/dexidp/dex:v2.37.0 + image: ghcr.io/dexidp/dex:v2.38.0 imagePullPolicy: Always command: [/shared/argocd-dex, rundex] env: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index a092e4d205efd..83fc7a0f1c864 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -22496,7 +22496,7 @@ spec: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.37.0 + image: ghcr.io/dexidp/dex:v2.38.0 imagePullPolicy: Always name: dex ports: diff --git a/manifests/ha/namespace-install.yaml b/manifests/ha/namespace-install.yaml index 2c1def5603cc8..044a061bf0cb1 100644 --- a/manifests/ha/namespace-install.yaml +++ b/manifests/ha/namespace-install.yaml @@ -1762,7 +1762,7 @@ spec: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.37.0 + image: ghcr.io/dexidp/dex:v2.38.0 imagePullPolicy: Always name: dex ports: diff --git a/manifests/install.yaml b/manifests/install.yaml index 40331559f3959..6f9c88dbb9d57 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -21591,7 +21591,7 @@ spec: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.37.0 + image: ghcr.io/dexidp/dex:v2.38.0 imagePullPolicy: Always name: dex ports: diff --git a/manifests/namespace-install.yaml b/manifests/namespace-install.yaml index d9cc590df7861..cb58228423c11 100644 --- a/manifests/namespace-install.yaml +++ b/manifests/namespace-install.yaml @@ -857,7 +857,7 @@ spec: key: dexserver.disable.tls name: argocd-cmd-params-cm optional: true - image: ghcr.io/dexidp/dex:v2.37.0 + image: ghcr.io/dexidp/dex:v2.38.0 imagePullPolicy: Always name: dex ports: diff --git a/test/container/Procfile b/test/container/Procfile index ef5100e71bab3..3ec9add44d5a7 100644 --- a/test/container/Procfile +++ b/test/container/Procfile @@ -1,6 +1,6 @@ controller: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_TLS_DATA_PATH=${ARGOCD_TLS_DATA_PATH:-/tmp/argocd-local/tls} ARGOCD_SSH_DATA_PATH=${ARGOCD_SSH_DATA_PATH:-/tmp/argocd-local/ssh} ARGOCD_BINARY_NAME=argocd-application-controller $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''}" api-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_BINARY_NAME=argocd-server $COMMAND --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --disable-auth=${ARGOCD_E2E_DISABLE_AUTH:-'true'} --insecure --dex-server http://localhost:${ARGOCD_E2E_DEX_PORT:-5556} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081} --port ${ARGOCD_E2E_APISERVER_PORT:-8080} --application-namespaces=${ARGOCD_APPLICATION_NAMESPACES:-''} " -dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.37.0 serve /dex.yaml" +dex: sh -c "test $ARGOCD_IN_CI = true && exit 0; ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/cmd gendexcfg -o `pwd`/dist/dex.yaml && docker run --rm -p ${ARGOCD_E2E_DEX_PORT:-5556}:${ARGOCD_E2E_DEX_PORT:-5556} -v `pwd`/dist/dex.yaml:/dex.yaml ghcr.io/dexidp/dex:v2.38.0 serve /dex.yaml" redis: sh -c "/usr/local/bin/redis-server --save "" --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}" repo-server: [ "$BIN_MODE" = 'true' ] && COMMAND=./dist/argocd || COMMAND='go run ./cmd/main.go' && sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-./test/cmp} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} ARGOCD_BINARY_NAME=argocd-repo-server $COMMAND --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}" ui: sh -c "test $ARGOCD_IN_CI = true && exit 0; cd ui && ARGOCD_E2E_YARN_HOST=0.0.0.0 ${ARGOCD_E2E_YARN_CMD:-yarn} start" From adceae9ec81ddbec68dd6fc621a5714d3a4212fe Mon Sep 17 00:00:00 2001 From: shlomi tubul <33376277+shlomitubul@users.noreply.github.com> Date: Sun, 11 Feb 2024 07:48:15 +0200 Subject: [PATCH 267/269] feat: Add support for passing Redis Sentinel username(ACL) and password (#17168) * Add support for passing Sentinel username and password Signed-off-by: ShlomiTubul * fix align with var naming Signed-off-by: ShlomiTubul * fix align with var naming Signed-off-by: ShlomiTubul --------- Signed-off-by: ShlomiTubul Co-authored-by: ShlomiTubul --- util/cache/cache.go | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/util/cache/cache.go b/util/cache/cache.go index d34fba5d38f7b..b632824e9c96b 100644 --- a/util/cache/cache.go +++ b/util/cache/cache.go @@ -27,6 +27,10 @@ const ( envRedisRetryCount = "REDIS_RETRY_COUNT" // defaultRedisRetryCount holds default number of retries defaultRedisRetryCount = 3 + // envRedisSentinelPassword is an env variable name which stores redis sentinel password + envRedisSentinelPassword = "REDIS_SENTINEL_PASSWORD" + // envRedisSentinelUsername is an env variable name which stores redis sentinel username + envRedisSentinelUsername = "REDIS_SENTINEL_USERNAME" ) const ( @@ -57,21 +61,23 @@ func buildRedisClient(redisAddress, password, username string, redisDB, maxRetri return client } -func buildFailoverRedisClient(sentinelMaster, password, username string, redisDB, maxRetries int, tlsConfig *tls.Config, sentinelAddresses []string) *redis.Client { +func buildFailoverRedisClient(sentinelMaster, sentinelUsername, sentinelPassword, password, username string, redisDB, maxRetries int, tlsConfig *tls.Config, sentinelAddresses []string) *redis.Client { opts := &redis.FailoverOptions{ - MasterName: sentinelMaster, - SentinelAddrs: sentinelAddresses, - DB: redisDB, - Password: password, - MaxRetries: maxRetries, - TLSConfig: tlsConfig, - Username: username, + MasterName: sentinelMaster, + SentinelAddrs: sentinelAddresses, + DB: redisDB, + Password: password, + MaxRetries: maxRetries, + TLSConfig: tlsConfig, + Username: username, + SentinelUsername: sentinelUsername, + SentinelPassword: sentinelPassword, } client := redis.NewFailoverClient(opts) client.AddHook(redis.Hook(NewArgoRedisHook(func() { - *client = *buildFailoverRedisClient(sentinelMaster, password, username, redisDB, maxRetries, tlsConfig, sentinelAddresses) + *client = *buildFailoverRedisClient(sentinelMaster, sentinelUsername, sentinelPassword, password, username, redisDB, maxRetries, tlsConfig, sentinelAddresses) }))) return client @@ -199,6 +205,8 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...Options) func() (*Cache, err } password := os.Getenv(envRedisPassword) username := os.Getenv(envRedisUsername) + sentinelUsername := os.Getenv(envRedisSentinelUsername) + sentinelPassword := os.Getenv(envRedisSentinelPassword) if opt.FlagPrefix != "" { if val := os.Getenv(opt.getEnvPrefix() + envRedisUsername); val != "" { username = val @@ -206,14 +214,21 @@ func AddCacheFlagsToCmd(cmd *cobra.Command, opts ...Options) func() (*Cache, err if val := os.Getenv(opt.getEnvPrefix() + envRedisPassword); val != "" { password = val } + if val := os.Getenv(opt.getEnvPrefix() + envRedisSentinelUsername); val != "" { + sentinelUsername = val + } + if val := os.Getenv(opt.getEnvPrefix() + envRedisSentinelPassword); val != "" { + sentinelPassword = val + } } + maxRetries := env.ParseNumFromEnv(envRedisRetryCount, defaultRedisRetryCount, 0, math.MaxInt32) compression, err := CompressionTypeFromString(compressionStr) if err != nil { return nil, err } if len(sentinelAddresses) > 0 { - client := buildFailoverRedisClient(sentinelMaster, password, username, redisDB, maxRetries, tlsConfig, sentinelAddresses) + client := buildFailoverRedisClient(sentinelMaster, sentinelUsername, sentinelPassword, password, username, redisDB, maxRetries, tlsConfig, sentinelAddresses) opt.callOnClientCreated(client) return NewCache(NewRedisCache(client, defaultCacheExpiration, compression)), nil } From 4458d5fa80f452d2abf5bec997ad4466581c2c5e Mon Sep 17 00:00:00 2001 From: Soumya Ghosh Dastidar <44349253+gdsoumya@users.noreply.github.com> Date: Mon, 12 Feb 2024 00:02:17 +0530 Subject: [PATCH 268/269] fix: stop initializing deployment informer if dynamic sharding is disabled (#17097) * fix: stop initializing deployment informer if dynamic sharding is disabled Signed-off-by: Soumya Ghosh Dastidar * feat: updated sharding cache getter func Signed-off-by: Soumya Ghosh Dastidar --------- Signed-off-by: Soumya Ghosh Dastidar --- .../commands/argocd_application_controller.go | 38 +++++--- controller/appcontroller.go | 97 +++++++++++-------- controller/appcontroller_test.go | 1 + 3 files changed, 82 insertions(+), 54 deletions(-) diff --git a/cmd/argocd-application-controller/commands/argocd_application_controller.go b/cmd/argocd-application-controller/commands/argocd_application_controller.go index 0ff9fa33c8254..c38a2113e2b34 100644 --- a/cmd/argocd-application-controller/commands/argocd_application_controller.go +++ b/cmd/argocd-application-controller/commands/argocd_application_controller.go @@ -147,7 +147,8 @@ func NewCommand() *cobra.Command { appController.InvalidateProjectsCache() })) kubectl := kubeutil.NewKubectl() - clusterSharding := getClusterSharding(kubeClient, settingsMgr, shardingAlgorithm, enableDynamicClusterDistribution) + clusterSharding, err := getClusterSharding(kubeClient, settingsMgr, shardingAlgorithm, enableDynamicClusterDistribution) + errors.CheckError(err) appController, err = controller.NewApplicationController( namespace, settingsMgr, @@ -170,6 +171,7 @@ func NewCommand() *cobra.Command { applicationNamespaces, &workqueueRateLimit, serverSideDiff, + enableDynamicClusterDistribution, ) errors.CheckError(err) cacheutil.CollectMetrics(redisClient, appController.GetMetricsServer()) @@ -238,21 +240,29 @@ func NewCommand() *cobra.Command { return &command } -func getClusterSharding(kubeClient *kubernetes.Clientset, settingsMgr *settings.SettingsManager, shardingAlgorithm string, enableDynamicClusterDistribution bool) sharding.ClusterShardingCache { - var replicasCount int +func getClusterSharding(kubeClient *kubernetes.Clientset, settingsMgr *settings.SettingsManager, shardingAlgorithm string, enableDynamicClusterDistribution bool) (sharding.ClusterShardingCache, error) { + var ( + replicasCount int + ) // StatefulSet mode and Deployment mode uses different default values for shard number. defaultShardNumberValue := 0 - applicationControllerName := env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName) - appControllerDeployment, err := kubeClient.AppsV1().Deployments(settingsMgr.GetNamespace()).Get(context.Background(), applicationControllerName, metav1.GetOptions{}) - // if the application controller deployment was not found, the Get() call returns an empty Deployment object. So, set the variable to nil explicitly - if err != nil && kubeerrors.IsNotFound(err) { - appControllerDeployment = nil - } + if enableDynamicClusterDistribution { + applicationControllerName := env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName) + appControllerDeployment, err := kubeClient.AppsV1().Deployments(settingsMgr.GetNamespace()).Get(context.Background(), applicationControllerName, metav1.GetOptions{}) + + // if app controller deployment is not found when dynamic cluster distribution is enabled error out + if err != nil { + return nil, fmt.Errorf("(dymanic cluster distribution) failed to get app controller deployment: %v", err) + } + + if appControllerDeployment != nil && appControllerDeployment.Spec.Replicas != nil { + replicasCount = int(*appControllerDeployment.Spec.Replicas) + defaultShardNumberValue = -1 + } else { + return nil, fmt.Errorf("(dymanic cluster distribution) failed to get app controller deployment replica count") + } - if enableDynamicClusterDistribution && appControllerDeployment != nil && appControllerDeployment.Spec.Replicas != nil { - replicasCount = int(*appControllerDeployment.Spec.Replicas) - defaultShardNumberValue = -1 } else { replicasCount = env.ParseNumFromEnv(common.EnvControllerReplicas, 0, 0, math.MaxInt32) } @@ -260,7 +270,7 @@ func getClusterSharding(kubeClient *kubernetes.Clientset, settingsMgr *settings. if replicasCount > 1 { // check for shard mapping using configmap if application-controller is a deployment // else use existing logic to infer shard from pod name if application-controller is a statefulset - if enableDynamicClusterDistribution && appControllerDeployment != nil { + if enableDynamicClusterDistribution { var err error // retry 3 times if we find a conflict while updating shard mapping configMap. // If we still see conflicts after the retries, wait for next iteration of heartbeat process. @@ -288,5 +298,5 @@ func getClusterSharding(kubeClient *kubernetes.Clientset, settingsMgr *settings. log.Info("Processing all cluster shards") } db := db.NewDB(settingsMgr.GetNamespace(), settingsMgr, kubeClient) - return sharding.NewClusterSharding(db, shardNumber, replicasCount, shardingAlgorithm) + return sharding.NewClusterSharding(db, shardNumber, replicasCount, shardingAlgorithm), nil } diff --git a/controller/appcontroller.go b/controller/appcontroller.go index e6dee507caa2e..f038b770c29c4 100644 --- a/controller/appcontroller.go +++ b/controller/appcontroller.go @@ -113,7 +113,6 @@ type ApplicationController struct { appInformer cache.SharedIndexInformer appLister applisters.ApplicationLister projInformer cache.SharedIndexInformer - deploymentInformer informerv1.DeploymentInformer appStateManager AppStateManager stateCache statecache.LiveStateCache statusRefreshTimeout time.Duration @@ -130,6 +129,10 @@ type ApplicationController struct { clusterSharding sharding.ClusterShardingCache projByNameCache sync.Map applicationNamespaces []string + + // dynamicClusterDistributionEnabled if disabled deploymentInformer is never initialized + dynamicClusterDistributionEnabled bool + deploymentInformer informerv1.DeploymentInformer } // NewApplicationController creates new instance of ApplicationController. @@ -155,6 +158,7 @@ func NewApplicationController( applicationNamespaces []string, rateLimiterConfig *ratelimiter.AppControllerRateLimiterConfig, serverSideDiff bool, + dynamicClusterDistributionEnabled bool, ) (*ApplicationController, error) { log.Infof("appResyncPeriod=%v, appHardResyncPeriod=%v, appResyncJitter=%v", appResyncPeriod, appHardResyncPeriod, appResyncJitter) db := db.NewDB(namespace, settingsMgr, kubeClientset) @@ -163,28 +167,29 @@ func NewApplicationController( log.Info("Using default workqueue rate limiter config") } ctrl := ApplicationController{ - cache: argoCache, - namespace: namespace, - kubeClientset: kubeClientset, - kubectl: kubectl, - applicationClientset: applicationClientset, - repoClientset: repoClientset, - appRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_reconciliation_queue"), - appOperationQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_operation_processing_queue"), - projectRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "project_reconciliation_queue"), - appComparisonTypeRefreshQueue: workqueue.NewRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig)), - db: db, - statusRefreshTimeout: appResyncPeriod, - statusHardRefreshTimeout: appHardResyncPeriod, - statusRefreshJitter: appResyncJitter, - refreshRequestedApps: make(map[string]CompareWith), - refreshRequestedAppsMutex: &sync.Mutex{}, - auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController), - settingsMgr: settingsMgr, - selfHealTimeout: selfHealTimeout, - clusterSharding: clusterSharding, - projByNameCache: sync.Map{}, - applicationNamespaces: applicationNamespaces, + cache: argoCache, + namespace: namespace, + kubeClientset: kubeClientset, + kubectl: kubectl, + applicationClientset: applicationClientset, + repoClientset: repoClientset, + appRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_reconciliation_queue"), + appOperationQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "app_operation_processing_queue"), + projectRefreshQueue: workqueue.NewNamedRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig), "project_reconciliation_queue"), + appComparisonTypeRefreshQueue: workqueue.NewRateLimitingQueue(ratelimiter.NewCustomAppControllerRateLimiter(rateLimiterConfig)), + db: db, + statusRefreshTimeout: appResyncPeriod, + statusHardRefreshTimeout: appHardResyncPeriod, + statusRefreshJitter: appResyncJitter, + refreshRequestedApps: make(map[string]CompareWith), + refreshRequestedAppsMutex: &sync.Mutex{}, + auditLogger: argo.NewAuditLogger(namespace, kubeClientset, common.ApplicationController), + settingsMgr: settingsMgr, + selfHealTimeout: selfHealTimeout, + clusterSharding: clusterSharding, + projByNameCache: sync.Map{}, + applicationNamespaces: applicationNamespaces, + dynamicClusterDistributionEnabled: dynamicClusterDistributionEnabled, } if kubectlParallelismLimit > 0 { ctrl.kubectlSemaphore = semaphore.NewWeighted(kubectlParallelismLimit) @@ -227,25 +232,33 @@ func NewApplicationController( } factory := informers.NewSharedInformerFactoryWithOptions(ctrl.kubeClientset, defaultDeploymentInformerResyncDuration, informers.WithNamespace(settingsMgr.GetNamespace())) - deploymentInformer := factory.Apps().V1().Deployments() + + var deploymentInformer informerv1.DeploymentInformer + + // only initialize deployment informer if dynamic distribution is enabled + if dynamicClusterDistributionEnabled { + deploymentInformer = factory.Apps().V1().Deployments() + } readinessHealthCheck := func(r *http.Request) error { - applicationControllerName := env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName) - appControllerDeployment, err := deploymentInformer.Lister().Deployments(settingsMgr.GetNamespace()).Get(applicationControllerName) - if err != nil { - if kubeerrors.IsNotFound(err) { - appControllerDeployment = nil - } else { - return fmt.Errorf("error retrieving Application Controller Deployment: %s", err) - } - } - if appControllerDeployment != nil { - if appControllerDeployment.Spec.Replicas != nil && int(*appControllerDeployment.Spec.Replicas) <= 0 { - return fmt.Errorf("application controller deployment replicas is not set or is less than 0, replicas: %d", appControllerDeployment.Spec.Replicas) + if dynamicClusterDistributionEnabled { + applicationControllerName := env.StringFromEnv(common.EnvAppControllerName, common.DefaultApplicationControllerName) + appControllerDeployment, err := deploymentInformer.Lister().Deployments(settingsMgr.GetNamespace()).Get(applicationControllerName) + if err != nil { + if kubeerrors.IsNotFound(err) { + appControllerDeployment = nil + } else { + return fmt.Errorf("error retrieving Application Controller Deployment: %s", err) + } } - shard := env.ParseNumFromEnv(common.EnvControllerShard, -1, -math.MaxInt32, math.MaxInt32) - if _, err := sharding.GetOrUpdateShardFromConfigMap(kubeClientset.(*kubernetes.Clientset), settingsMgr, int(*appControllerDeployment.Spec.Replicas), shard); err != nil { - return fmt.Errorf("error while updating the heartbeat for to the Shard Mapping ConfigMap: %s", err) + if appControllerDeployment != nil { + if appControllerDeployment.Spec.Replicas != nil && int(*appControllerDeployment.Spec.Replicas) <= 0 { + return fmt.Errorf("application controller deployment replicas is not set or is less than 0, replicas: %d", appControllerDeployment.Spec.Replicas) + } + shard := env.ParseNumFromEnv(common.EnvControllerShard, -1, -math.MaxInt32, math.MaxInt32) + if _, err := sharding.GetOrUpdateShardFromConfigMap(kubeClientset.(*kubernetes.Clientset), settingsMgr, int(*appControllerDeployment.Spec.Replicas), shard); err != nil { + return fmt.Errorf("error while updating the heartbeat for to the Shard Mapping ConfigMap: %s", err) + } } } return nil @@ -773,7 +786,11 @@ func (ctrl *ApplicationController) Run(ctx context.Context, statusProcessors int go ctrl.appInformer.Run(ctx.Done()) go ctrl.projInformer.Run(ctx.Done()) - go ctrl.deploymentInformer.Informer().Run(ctx.Done()) + + if ctrl.dynamicClusterDistributionEnabled { + // only start deployment informer if dynamic distribution is enabled + go ctrl.deploymentInformer.Informer().Run(ctx.Done()) + } clusters, err := ctrl.db.ListClusters(ctx) if err != nil { diff --git a/controller/appcontroller_test.go b/controller/appcontroller_test.go index 4162a9983e941..33a29bc5ca3f8 100644 --- a/controller/appcontroller_test.go +++ b/controller/appcontroller_test.go @@ -157,6 +157,7 @@ func newFakeController(data *fakeData, repoErr error) *ApplicationController { nil, false, + false, ) db := &dbmocks.ArgoDB{} db.On("GetApplicationControllerReplicas").Return(1) From 82433ff1a85a8112f003d6f904eedfc04481dcd9 Mon Sep 17 00:00:00 2001 From: Jan Schumann Date: Mon, 12 Feb 2024 11:34:16 +0100 Subject: [PATCH 269/269] feat: query escape function for notifications (#16343) Signed-off-by: Jan Schumann Co-authored-by: pasha-codefresh --- docs/operator-manual/notifications/functions.md | 10 ++++++++++ util/notification/expression/repo/repo.go | 2 ++ 2 files changed, 12 insertions(+) diff --git a/docs/operator-manual/notifications/functions.md b/docs/operator-manual/notifications/functions.md index 3d614e4e53a55..c50d122024b76 100644 --- a/docs/operator-manual/notifications/functions.md +++ b/docs/operator-manual/notifications/functions.md @@ -48,6 +48,16 @@ Transforms given GIT URL into HTTPs format. Returns repository URL full name `(/)`. Currently supports only Github, GitLab and Bitbucket. +
    +**`repo.QueryEscape(s string) string`** + +QueryEscape escapes the string, so it can be safely placed inside a URL + +Example: +``` +/projects/{{ call .repo.QueryEscape (call .repo.FullNameByRepoURL .app.status.RepoURL) }}/merge_requests +``` +
    **`repo.GetCommitMetadata(sha string) CommitMetadata`** diff --git a/util/notification/expression/repo/repo.go b/util/notification/expression/repo/repo.go index 060060cbccd68..110c278cb486b 100644 --- a/util/notification/expression/repo/repo.go +++ b/util/notification/expression/repo/repo.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "errors" + "net/url" "regexp" "strings" @@ -90,6 +91,7 @@ func NewExprs(argocdService service.Service, app *unstructured.Unstructured) map return map[string]interface{}{ "RepoURLToHTTPS": repoURLToHTTPS, "FullNameByRepoURL": FullNameByRepoURL, + "QueryEscape": url.QueryEscape, "GetCommitMetadata": func(commitSHA string) interface{} { meta, err := getCommitMetadata(commitSHA, app, argocdService) if err != nil {

    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 D#fBI6 literal 0 HcmV?d00001 diff --git a/docs/assets/okta-create-oidc-app.png b/docs/assets/okta-create-oidc-app.png new file mode 100644 index 0000000000000000000000000000000000000000..cf0b75b0e4a21f6196799a5097b52261f876e627 GIT binary patch literal 360829 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