Compare commits

...

23 Commits

Author SHA1 Message Date
argo-bot
987f6659b8 Bump version to 2.2.3 2022-01-18 17:45:46 +00:00
argo-bot
e099a6a851 Bump version to 2.2.3 2022-01-18 17:45:31 +00:00
Alexander Matyushentsev
afbd59ba63 refactor: introduce 'byClusterName' secret index to speedup cluster server URL lookup (#8133)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-01-17 19:25:00 -08:00
pasha-codefresh
b1e3a07d92 fix: application exist panic when execute api call (#8188)
fix: application exist panic when execute api call (#8188)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2022-01-15 09:05:19 +01:00
Ishita Sequeira
c3144c0059 fix: route health check stuck in 'Progressing' (#8170)
Signed-off-by: ishitasequeira <isequeir@redhat.com>
2022-01-14 09:03:39 +00:00
jannfis
33547f149b chore: Update to Redis 6.2.4 (#8157) (#8158)
Signed-off-by: jannfis <jann@mistrust.net>
2022-01-12 13:45:56 -08:00
Alexander Matyushentsev
06dc9aa836 docs: update roadmap document with v2.2 release changes (#8089)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2022-01-05 09:21:41 -08:00
argo-bot
03b17e0233 Bump version to 2.2.2 2022-01-01 06:18:52 +00:00
argo-bot
d5909f7168 Bump version to 2.2.2 2022-01-01 06:18:35 +00:00
pasha-codefresh
7d0d665747 fix: issue with project scoped resources (#8048)
fix: issue with project scoped resources (#8048)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-30 09:12:45 -08:00
Michael Crenshaw
834a102c09 chore: escape proj in regex (#7985)
* chore: escape proj in regex

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: test normal cases

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>

* chore: typo

Signed-off-by: Michael Crenshaw <michael@crenshaw.dev>
2021-12-30 09:12:40 -08:00
plakyda-codefresh
4bcd8cf733 fix: Default value for retry validation #8055 (#8064)
fix: Default value for retry validation #8055 (#8064)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-12-30 09:04:56 -08:00
pasha-codefresh
a069c602dc fix: sync window panel is crashed if resource name not contain letters (#8053)
fix: sync window panel is crashed if resource name not contain letters (#8053)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-29 11:08:52 -08:00
Alexander Matyushentsev
e309ceebac fix: upgrade github.com/argoproj/gitops-engine to v0.5.2
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-22 13:45:57 -08:00
plakyda-codefresh
4a7f0bbfd8 fix: retry disabled text (#8004)
fix: retry disabled text (#8004)

Signed-off-by: viktorplakida <plakyda1@gmail.com>
2021-12-22 11:40:30 -08:00
Niklas Steiner
28a54bf2a2 fix: Opening app details shows UI error on some apps (#8016) (#8019)
Signed-off-by: Niklas Steiner <niklas@sbg.at>
2021-12-22 11:17:50 -08:00
Alexander Matyushentsev
e209426a7e fix: correctly handle project field during partial cluster update (#7994)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-21 11:10:39 -08:00
May Zhang
06a95f86ce fix: Cluster API does not support updating labels and annotations (#7901)
Signed-off-by: May Zhang <may_zhang@intuit.com>
2021-12-21 11:10:32 -08:00
argo-bot
122ecefc3a Bump version to 2.2.1 2021-12-17 01:23:50 +00:00
argo-bot
004d73ce92 Bump version to 2.2.1 2021-12-17 01:23:35 +00:00
Alexander Matyushentsev
81e1a58328 fix: resource details page crashes when resource is not deployed and hide managed fields is selected (#7971)
Signed-off-by: Alexander Matyushentsev <AMatyushentsev@gmail.com>
2021-12-16 17:21:54 -08:00
pasha-codefresh
84f949ff17 fix: issue with headless installation (#7958)
fix: issue with headless installation (#7958)

Signed-off-by: pashavictorovich <pavel@codefresh.io>
2021-12-16 10:20:06 -08:00
jomenxiao
a7e7f32a0f fix nil point (#7905)
Signed-off-by: jomenxiao <jomenxiao@gmail.com>
2021-12-16 08:24:54 -08:00
40 changed files with 438 additions and 160 deletions

View File

@@ -400,7 +400,7 @@ jobs:
run: |
docker pull quay.io/dexidp/dex:v2.25.0
docker pull argoproj/argo-cd-ci-builder:v1.0.0
docker pull redis:6.2.4-alpine
docker pull redis:6.2.6-alpine
- name: Create target directory for binaries in the build-process
run: |
mkdir -p dist

View File

@@ -1,7 +1,7 @@
controller: 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 go run ./cmd/main.go --loglevel debug --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379} --repo-server localhost:${ARGOCD_E2E_REPOSERVER_PORT:-8081}"
api-server: 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 go run ./cmd/main.go --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} "
dex: sh -c "ARGOCD_BINARY_NAME=argocd-dex go run github.com/argoproj/argo-cd/v2/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.30.0 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} redis:6.2.4-alpine --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi"
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} redis:6.2.6-alpine --save '' --appendonly no --port ${ARGOCD_E2E_REDIS_PORT:-6379}; fi"
repo-server: sh -c "FORCE_LOG_COLORS=1 ARGOCD_FAKE_IN_CLUSTER=true ARGOCD_GNUPGHOME=${ARGOCD_GNUPGHOME:-/tmp/argocd-local/gpg/keys} ARGOCD_PLUGINSOCKFILEPATH=${ARGOCD_PLUGINSOCKFILEPATH:-/tmp/argo-e2e/app/config/plugin} ARGOCD_GPG_DATA_PATH=${ARGOCD_GPG_DATA_PATH:-/tmp/argocd-local/gpg/source} 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-repo-server ARGOCD_GPG_ENABLED=${ARGOCD_GPG_ENABLED:-false} go run ./cmd/main.go --loglevel debug --port ${ARGOCD_E2E_REPOSERVER_PORT:-8081} --redis localhost:${ARGOCD_E2E_REDIS_PORT:-6379}"
ui: sh -c 'cd ui && ${ARGOCD_E2E_YARN_CMD:-yarn} start'
git-server: test/fixture/testrepos/start-git.sh

View File

@@ -1 +1 @@
2.2.0
2.2.3

View File

@@ -27,6 +27,8 @@ import (
"github.com/argoproj/argo-cd/v2/util/cli"
"github.com/argoproj/argo-cd/v2/util/io"
"github.com/argoproj/argo-cd/v2/util/localconfig"
flag "github.com/spf13/pflag"
)
func testAPI(clientOpts *argoapi.ClientOptions) error {
@@ -43,6 +45,13 @@ func testAPI(clientOpts *argoapi.ClientOptions) error {
return err
}
func retrieveContextIfChanged(contextFlag *flag.Flag) string {
if contextFlag != nil && contextFlag.Changed {
return contextFlag.Value.String()
}
return ""
}
// InitCommand allows executing command in a headless mode: on the fly starts Argo CD API server and
// changes provided client options to use started API server port
func InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *int) *cobra.Command {
@@ -108,10 +117,7 @@ func InitCommand(cmd *cobra.Command, clientOpts *argoapi.ClientOptions, port *in
return err
}
var context string
if cmd.Flag("context").Changed {
context = cmd.Flag("context").Value.String()
}
context := retrieveContextIfChanged(cmd.Flag("context"))
mr, err := miniredis.Run()
if err != nil {

View File

@@ -0,0 +1,80 @@
package headless
import (
"testing"
flag "github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)
type StringFlag struct {
// The exact value provided on the flag
value string
}
func (f StringFlag) String() string {
return f.value
}
func (f *StringFlag) Set(value string) error {
f.value = value
return nil
}
func (f *StringFlag) Type() string {
return "string"
}
func Test_FlagContextNotChanged(t *testing.T) {
res := retrieveContextIfChanged(&flag.Flag{
Name: "",
Shorthand: "",
Usage: "",
Value: &StringFlag{value: "test"},
DefValue: "",
Changed: false,
NoOptDefVal: "",
Deprecated: "",
Hidden: false,
ShorthandDeprecated: "",
Annotations: nil,
})
assert.Equal(t, "", res)
}
func Test_FlagContextChanged(t *testing.T) {
res := retrieveContextIfChanged(&flag.Flag{
Name: "",
Shorthand: "",
Usage: "",
Value: &StringFlag{value: "test"},
DefValue: "",
Changed: true,
NoOptDefVal: "",
Deprecated: "",
Hidden: false,
ShorthandDeprecated: "",
Annotations: nil,
})
assert.Equal(t, "test", res)
}
func Test_FlagContextNil(t *testing.T) {
res := retrieveContextIfChanged(&flag.Flag{
Name: "",
Shorthand: "",
Usage: "",
Value: nil,
DefValue: "",
Changed: false,
NoOptDefVal: "",
Deprecated: "",
Hidden: false,
ShorthandDeprecated: "",
Annotations: nil,
})
assert.Equal(t, "", res)
}

View File

@@ -1102,7 +1102,7 @@ func (ctrl *ApplicationController) processRequestedAppOperation(app *appv1.Appli
}
ctrl.setOperationState(app, state)
if state.Phase.Completed() && !app.Operation.Sync.DryRun {
if state.Phase.Completed() && (app.Operation.Sync != nil && !app.Operation.Sync.DryRun) {
// if we just completed an operation, force a refresh so that UI will report up-to-date
// sync/health information
if _, err := cache.MetaNamespaceKeyFunc(app); err == nil {

View File

@@ -1,26 +1,26 @@
# Roadmap
- [Roadmap](#roadmap)
- [v2.2](#v22)
- [Config Management Tools Integrations (proposal)](#config-management-tools-integrations-proposal)
- [Argo CD Extensions (proposal)](#argo-cd-extensions-proposal)
- [Project scoped repository and clusters (proposal)](#project-scoped-repository-and-clusters-proposal)
- [v2.3 and beyond](#v23-and-beyond)
- [Input Forms UI Refresh](#input-forms-ui-refresh)
- [Merge ApplicationSet controller into Argo CD](#merge-applicationset-controller-into-argo-cd)
- [v2.3](#v23)
- [Merge Argo CD Notifications into Argo CD](#merge-argo-cd-notifications-into-argo-cd)
- [Merge Argo CD Image Updater into Argo CD](#merge-argo-cd-image-updater-into-argo-cd)
- [Compact Resources Tree](#compact-resources-tree)
- [Input Forms UI Refresh](#input-forms-ui-refresh)
- [Compact resources tree](#compact-resources-tree)
- [Maintain difference in cluster and git values for specific fields](#maintain-difference-in-cluster-and-git-values-for-specific-fields)
- [Web Shell](#web-shell)
- [Helm values from external repo](#helm-values-from-external-repo)
- [v2.4 and beyond](#v24-and-beyond)
- [Merge ApplicationSet controller into Argo CD](#merge-applicationset-controller-into-argo-cd)
- [Merge Argo CD Image Updater into Argo CD](#merge-argo-cd-image-updater-into-argo-cd)
- [Config Management Tools Integrations UI/CLI](#config-management-tools-integrations-uicli)
- [Allow specifying parent/child relationships in config](#allow-specifying-parentchild-relationships-in-config)
- [Dependencies between applications](#dependencies-between-applications)
- [Maintain difference in cluster and git values for specific fields](#maintain-difference-in-cluster-and-git-values-for-specific-fields)
- [Multi-tenancy improvements](#multi-tenancy-improvements)
- [GitOps Engine Enhancements](#gitops-engine-enhancements)
- [Completed](#completed)
- [✅ Core Argo CD (proposal)](#core-argo-cd-aka-gitops-agent-proposal)
- [✅ Config Management Tools Integrations (proposal)](#-config-management-tools-integrations-proposal)
- [✅ Argo CD Extensions (proposal)](#-argo-cd-extensions-proposal)
- [✅ Project scoped repository and clusters (proposal)](#-project-scoped-repository-and-clusters-proposal)
- [✅ Core Argo CD (proposal)](#-core-argo-cd-proposal)
- [✅ Core Functionality Bug Fixes](#-core-functionality-bug-fixes)
- [✅ Performance](#-performance)
- [✅ ApplicationSet](#-applicationset)
@@ -30,50 +30,24 @@
- [✅ Automated Registry Monitoring](#-automated-registry-monitoring)
- [✅ Projects Enhancements](#-projects-enhancements)
## v2.2
### Config Management Tools Integrations ([proposal](https://github.com/argoproj/argo-cd/pull/5927))
The community likes the first class support of Helm, Kustomize and keeps requesting support for more tools.
Argo CD provides a mechanism to integrate with any config management tool. We need to investigate why
it is not enough and implement missing features.
### Argo CD Extensions ([proposal](https://github.com/argoproj/argo-cd/pull/6240))
Argo CD supports customizing handling of Kubernetes resources via diffing customizations,
health checks, and custom actions. The Argo CD Extensions proposal takes it to next
level and allows to deliver the resource customizations along with custom visualization in Argo CD
via Git repository.
### Project scoped repository and clusters ([proposal](https://github.com/argoproj/argo-cd/blob/master/docs/proposals/project-repos-and-clusters.md))
The feature streamlines the process of adding repositories and clusters to the project and makes it self-service.
Instead of asking an administrator to change Argo CD settings end users can perform the change independently.
## v2.3 and beyond
### Input Forms UI Refresh
Improved design of the input forms in Argo CD Web UI: https://www.figma.com/file/IIlsFqqmM5UhqMVul9fQNq/Argo-CD?node-id=0%3A1
### Merge ApplicationSet controller into Argo CD
The ApplicationSet functionality is available in Argo CD out-of-the-box ([#7351](https://github.com/argoproj/argo-cd/issues/7351)).
The Argo CD UI/CLI/API allows to manage ApplicationSet resources same as Argo CD Applications ([#7352](https://github.com/argoproj/argo-cd/issues/7352)).
## v2.3
### Merge Argo CD Notifications into Argo CD
The [Argo CD Notifications](https://github.com/argoproj-labs/argocd-notifications) should be merged into Argo CD and available out-of-the-box: [#7350](https://github.com/argoproj/argo-cd/issues/7350)
### Merge Argo CD Image Updater into Argo CD
### Input Forms UI Refresh
The [Argo CD Image Updater](https://github.com/argoproj-labs/argocd-image-updater) should be merged into Argo CD and available out-of-the-box: [#7385](https://github.com/argoproj/argo-cd/issues/7385)
Improved design of the input forms in Argo CD Web UI: https://www.figma.com/file/IIlsFqqmM5UhqMVul9fQNq/Argo-CD?node-id=0%3A1
### Compact resources tree
An ability to collaps leaf resources tree to improve visualization of very large applications: [#7349](https://github.com/argoproj/argo-cd/issues/7349)
### Maintain difference in cluster and git values for specific fields
The feature allows to avoid updating fields excluded from diffing ([#2913](https://github.com/argoproj/argo-cd/issues/2913)).
### Web Shell
Exec into the Kubernetes Pod right from Argo CD Web UI! [#4351](https://github.com/argoproj/argo-cd/issues/4351)
@@ -82,6 +56,21 @@ Exec into the Kubernetes Pod right from Argo CD Web UI! [#4351](https://github.c
The feature allows combining of-the-shelf Helm chart and value file in Git repository ([#2789](https://github.com/argoproj/argo-cd/issues/2789))
## v2.4 and beyond
### Merge ApplicationSet controller into Argo CD
The ApplicationSet functionality is available in Argo CD out-of-the-box ([#7351](https://github.com/argoproj/argo-cd/issues/7351)).
The Argo CD UI/CLI/API allows to manage ApplicationSet resources same as Argo CD Applications ([#7352](https://github.com/argoproj/argo-cd/issues/7352)).
### Merge Argo CD Image Updater into Argo CD
The [Argo CD Image Updater](https://github.com/argoproj-labs/argocd-image-updater) should be merged into Argo CD and available out-of-the-box: [#7385](https://github.com/argoproj/argo-cd/issues/7385)
### Config Management Tools Integrations UI/CLI
The continuation of the Config Management Tools of [proposal](https://github.com/argoproj/argo-cd/pull/5927). The Argo CD UI/CLI
@@ -96,9 +85,6 @@ visualize custom resources that don't have owner references.
The feature allows specifying dependencies between applications that allow orchestrating synchronization of multiple applications. [#3517](https://github.com/argoproj/argo-cd/issues/3517)
### Maintain difference in cluster and git values for specific fields
The feature allows to avoid updating fields excluded from diffing ([#2913](https://github.com/argoproj/argo-cd/issues/2913)).
### Multi-tenancy improvements
@@ -119,6 +105,25 @@ A lot of Argo CD features are still not available in GitOps engine. The followin
## Completed
### ✅ Config Management Tools Integrations ([proposal](https://github.com/argoproj/argo-cd/pull/5927))
The community likes the first class support of Helm, Kustomize and keeps requesting support for more tools.
Argo CD provides a mechanism to integrate with any config management tool. We need to investigate why
it is not enough and implement missing features.
### ✅ Argo CD Extensions ([proposal](https://github.com/argoproj/argo-cd/pull/6240))
Argo CD supports customizing handling of Kubernetes resources via diffing customizations,
health checks, and custom actions. The Argo CD Extensions proposal takes it to next
level and allows to deliver the resource customizations along with custom visualization in Argo CD
via Git repository.
### ✅ Project scoped repository and clusters ([proposal](https://github.com/argoproj/argo-cd/blob/master/docs/proposals/project-repos-and-clusters.md))
The feature streamlines the process of adding repositories and clusters to the project and makes it self-service.
Instead of asking an administrator to change Argo CD settings end users can perform the change independently.
### ✅ Core Argo CD ([proposal](https://github.com/argoproj/argo-cd/pull/6385))
Core Argo CD allows to installation and use of lightweight Argo CD that includes only the backend without exposing the API or UI.

2
go.mod
View File

@@ -8,7 +8,7 @@ require (
github.com/TomOnTime/utfutil v0.0.0-20180511104225-09c41003ee1d
github.com/alicebob/miniredis v2.5.0+incompatible
github.com/alicebob/miniredis/v2 v2.14.2
github.com/argoproj/gitops-engine v0.5.1
github.com/argoproj/gitops-engine v0.5.2
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0
github.com/bombsimon/logrusr v1.0.0
github.com/bradleyfalzon/ghinstallation/v2 v2.0.2

4
go.sum
View File

@@ -103,8 +103,8 @@ github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYU
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
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/argoproj/gitops-engine v0.5.1 h1:kIPvoYFRvDA+3Tz2aEjwRBVGIgcuZ+HIzuHcRmvxo54=
github.com/argoproj/gitops-engine v0.5.1/go.mod h1:K2RYpGXh11VdFwDksS23SyFTOJaPcsF+MVJ/FHlqEOE=
github.com/argoproj/gitops-engine v0.5.2 h1:UQ2ajVyUPCSgFyqidzlTXddh/Xf6cE3I0s9uu92BoJg=
github.com/argoproj/gitops-engine v0.5.2/go.mod h1:K2RYpGXh11VdFwDksS23SyFTOJaPcsF+MVJ/FHlqEOE=
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0 h1:Cfp7rO/HpVxnwlRqJe0jHiBbZ77ZgXhB6HWlYD02Xdc=
github.com/argoproj/pkg v0.11.1-0.20211203175135-36c59d8fafe0/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=

View File

@@ -5,7 +5,7 @@ kind: Kustomization
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.2.0
newTag: v2.2.3
resources:
- ./application-controller
- ./dex

View File

@@ -21,7 +21,7 @@ spec:
serviceAccountName: argocd-redis
containers:
- name: redis
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: Always
args:
- "--save"

View File

@@ -2890,7 +2890,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -3018,7 +3018,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -3067,7 +3067,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -3232,7 +3232,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -11,4 +11,4 @@ resources:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.2.0
newTag: v2.2.3

View File

@@ -11,7 +11,7 @@ patchesStrategicMerge:
images:
- name: quay.io/argoproj/argocd
newName: quay.io/argoproj/argocd
newTag: v2.2.0
newTag: v2.2.3
resources:
- ../../base/application-controller
- ../../base/dex

View File

@@ -878,7 +878,7 @@ spec:
automountServiceAccountToken: false
initContainers:
- name: config-init
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
resources:
{}
@@ -906,7 +906,7 @@ spec:
containers:
- name: redis
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
command:
- redis-server
@@ -947,7 +947,7 @@ spec:
lifecycle:
{}
- name: sentinel
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
command:
- redis-sentinel

View File

@@ -15,6 +15,6 @@ redis-ha:
client: 6m
checkInterval: 3s
image:
tag: 6.2.4-alpine
tag: 6.2.6-alpine
sentinel:
bind: "0.0.0.0"

View File

@@ -3709,7 +3709,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -3926,7 +3926,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -3975,7 +3975,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -4202,7 +4202,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -4398,7 +4398,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -4480,7 +4480,7 @@ spec:
- /data/conf/redis.conf
command:
- redis-server
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -4518,7 +4518,7 @@ spec:
- /data/conf/sentinel.conf
command:
- redis-sentinel
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -4564,7 +4564,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
name: config-init
volumeMounts:

View File

@@ -1068,7 +1068,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -1285,7 +1285,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -1334,7 +1334,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -1561,7 +1561,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1757,7 +1757,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1839,7 +1839,7 @@ spec:
- /data/conf/redis.conf
command:
- redis-server
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -1877,7 +1877,7 @@ spec:
- /data/conf/sentinel.conf
command:
- redis-sentinel
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
lifecycle: {}
livenessProbe:
@@ -1923,7 +1923,7 @@ spec:
value: 40000915ab58c3fa8fd888fb8b24711944e6cbb4
- name: SENTINEL_ID_2
value: 2bbec7894d954a8af3bb54d13eaec53cb024e2ca
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: IfNotPresent
name: config-init
volumeMounts:

View File

@@ -3079,7 +3079,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -3132,7 +3132,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -3260,7 +3260,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -3309,7 +3309,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -3532,7 +3532,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -3722,7 +3722,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -438,7 +438,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /shared/argocd-dex
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
name: copyutil
volumeMounts:
@@ -491,7 +491,7 @@ spec:
- ""
- --appendonly
- "no"
image: redis:6.2.4-alpine
image: redis:6.2.6-alpine
imagePullPolicy: Always
name: redis
ports:
@@ -619,7 +619,7 @@ spec:
value: /helm-working-dir
- name: HELM_DATA_HOME
value: /helm-working-dir
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
failureThreshold: 3
@@ -668,7 +668,7 @@ spec:
- -n
- /usr/local/bin/argocd
- /var/run/argocd/argocd-cmp-server
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
name: copyutil
volumeMounts:
- mountPath: /var/run/argocd
@@ -891,7 +891,7 @@ spec:
key: server.http.cookie.maxnumber
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:
@@ -1081,7 +1081,7 @@ spec:
key: controller.default.cache.expiration
name: argocd-cmd-params-cm
optional: true
image: quay.io/argoproj/argocd:v2.2.0
image: quay.io/argoproj/argocd:v2.2.3
imagePullPolicy: Always
livenessProbe:
httpGet:

View File

@@ -1569,8 +1569,8 @@ func validatePolicy(proj string, role string, policy string) error {
}
// resource
resource := strings.Trim(policyComponents[2], " ")
if resource != "applications" {
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', not '%s'", policy, resource)
if resource != "applications" && resource != "repositories" && resource != "clusters" {
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': project resource must be: 'applications', 'repositories' or 'clusters', not '%s'", policy, resource)
}
// action
action := strings.Trim(policyComponents[3], " ")
@@ -1579,7 +1579,7 @@ func validatePolicy(proj string, role string, policy string) error {
}
// object
object := strings.Trim(policyComponents[4], " ")
objectRegexp, err := regexp.Compile(fmt.Sprintf(`^%s/[*\w-.]+$`, proj))
objectRegexp, err := regexp.Compile(fmt.Sprintf(`^%s/[*\w-.]+$`, regexp.QuoteMeta(proj)))
if err != nil || !objectRegexp.MatchString(object) {
return status.Errorf(codes.InvalidArgument, "invalid policy rule '%s': object must be of form '%s/*' or '%s/<APPNAME>', not '%s'", policy, proj, proj, object)
}

View File

@@ -2561,3 +2561,22 @@ func TestOrphanedResourcesMonitorSettings_IsWarn(t *testing.T) {
settings.Warn = pointer.BoolPtr(true)
assert.True(t, settings.IsWarn())
}
func Test_validatePolicy_projIsNotRegex(t *testing.T) {
// Make sure the "." in "some.project" isn't treated as the regex wildcard.
err := validatePolicy("some.project", "org-admin", "p, proj:some.project:org-admin, applications, *, some-project/*, allow")
assert.Error(t, err)
err = validatePolicy("some.project", "org-admin", "p, proj:some.project:org-admin, applications, *, some.project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, applications, *, some-project/*, allow")
assert.NoError(t, err)
}
func Test_validatePolicy_ValidResource(t *testing.T) {
err := validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, repositories, *, some-project/*, allow")
assert.NoError(t, err)
err = validatePolicy("some-project", "org-admin", "p, proj:some-project:org-admin, clusters, *, some-project/*, allow")
assert.NoError(t, err)
}

View File

@@ -2,10 +2,10 @@ health_status = {}
if obj.status ~= nil then
if obj.status.ingress ~= nil then
numIngressRules = 0
numTrue = 0
numFalse = 0
for _, ingressRules in pairs(obj.status.ingress) do
numIngressRules = numIngressRules + 1
numTrue = 0
numFalse = 0
if obj.status.ingress ~= nil then
for _, condition in pairs(ingressRules.conditions) do
if condition.type == "Admitted" and condition.status == "True" then

View File

@@ -213,7 +213,7 @@ func (s *Server) Create(ctx context.Context, q *application.ApplicationCreateReq
return existing, nil
}
if q.Upsert == nil || !*q.Upsert {
return nil, status.Errorf(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("application", existing.Spec, a.Spec))
return nil, status.Errorf(codes.InvalidArgument, "existing application spec is different, use upsert flag to force update")
}
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceApplications, rbacpolicy.ActionUpdate, appRBACName(a)); err != nil {
return nil, err

View File

@@ -3,20 +3,20 @@ package cluster
import (
"time"
"github.com/argoproj/argo-cd/v2/util/argo"
"github.com/argoproj/gitops-engine/pkg/utils/kube"
log "github.com/sirupsen/logrus"
"golang.org/x/net/context"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/kubernetes"
"github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
appv1 "github.com/argoproj/argo-cd/v2/pkg/apis/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/clusterauth"
"github.com/argoproj/argo-cd/v2/util/db"
"github.com/argoproj/argo-cd/v2/util/rbac"
@@ -181,6 +181,15 @@ var clusterFieldsByPath = map[string]func(updated *appv1.Cluster, existing *appv
"clusterResources": func(updated *appv1.Cluster, existing *appv1.Cluster) {
updated.ClusterResources = existing.ClusterResources
},
"labels": func(updated *appv1.Cluster, existing *appv1.Cluster) {
updated.Labels = existing.Labels
},
"annotations": func(updated *appv1.Cluster, existing *appv1.Cluster) {
updated.Annotations = existing.Annotations
},
"project": func(updated *appv1.Cluster, existing *appv1.Cluster) {
updated.Project = existing.Project
},
}
// Update updates a cluster
@@ -197,9 +206,12 @@ func (s *Server) Update(ctx context.Context, q *cluster.ClusterUpdateRequest) (*
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionUpdate, createRBACObject(c.Project, q.Cluster.Server)); err != nil {
return nil, err
}
// verify that user can do update inside project where cluster will be located
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionUpdate, createRBACObject(q.Cluster.Project, q.Cluster.Server)); err != nil {
return nil, err
if len(q.UpdatedFields) == 0 || sets.NewString(q.UpdatedFields...).Has("project") {
// verify that user can do update inside project where cluster will be located
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceClusters, rbacpolicy.ActionUpdate, createRBACObject(q.Cluster.Project, q.Cluster.Server)); err != nil {
return nil, err
}
}
if len(q.UpdatedFields) != 0 {

View File

@@ -109,4 +109,52 @@ func TestUpdateCluster_FieldsPathSet(t *testing.T) {
assert.Equal(t, updated.Name, "minikube")
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
assert.Equal(t, *updated.Shard, int64(1))
labelEnv := map[string]string{
"env": "qa",
}
_, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{
Cluster: &v1alpha1.Cluster{
Server: "https://127.0.0.1",
Labels: labelEnv,
},
UpdatedFields: []string{"labels"},
})
require.NoError(t, err)
assert.Equal(t, updated.Name, "minikube")
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
assert.Equal(t, updated.Labels, labelEnv)
annotationEnv := map[string]string{
"env": "qa",
}
_, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{
Cluster: &v1alpha1.Cluster{
Server: "https://127.0.0.1",
Annotations: annotationEnv,
},
UpdatedFields: []string{"annotations"},
})
require.NoError(t, err)
assert.Equal(t, updated.Name, "minikube")
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
assert.Equal(t, updated.Annotations, annotationEnv)
_, err = server.Update(context.Background(), &clusterapi.ClusterUpdateRequest{
Cluster: &v1alpha1.Cluster{
Server: "https://127.0.0.1",
Project: "new-project",
},
UpdatedFields: []string{"project"},
})
require.NoError(t, err)
assert.Equal(t, updated.Name, "minikube")
assert.Equal(t, updated.Namespaces, []string{"default", "kube-system"})
assert.Equal(t, updated.Project, "new-project")
}

View File

@@ -167,8 +167,8 @@ func (p *RBACPolicyEnforcer) getProjectFromRequest(rvals ...interface{}) *v1alph
if res, ok := rvals[1].(string); ok {
if obj, ok := rvals[3].(string); ok {
switch res {
case ResourceApplications:
if objSplit := strings.Split(obj, "/"); len(objSplit) == 2 {
case ResourceApplications, ResourceRepositories, ResourceClusters:
if objSplit := strings.Split(obj, "/"); len(objSplit) >= 2 {
return getProjectByName(objSplit[0])
}
case ResourceProjects:

View File

@@ -149,3 +149,13 @@ func TestGetScopes_CustomScopes(t *testing.T) {
scopes := rbacEnforcer.GetScopes()
assert.Equal(t, scopes, customScopes)
}
func Test_getProjectFromRequest(t *testing.T) {
fp := newFakeProj()
projLister := test.NewFakeProjLister(fp)
rbacEnforcer := NewRBACPolicyEnforcer(nil, projLister)
project := rbacEnforcer.getProjectFromRequest("", "repositories", "create", fp.Name+"/https://github.com/argoproj/argocd-example-apps")
assert.Equal(t, project.Name, fp.Name)
}

View File

@@ -1,4 +1,4 @@
FROM redis:6.2.4 as redis
FROM redis:6.2.6-alpine as redis
FROM node:12.18.4 as node

View File

@@ -97,7 +97,7 @@ export const ApplicationNodeInfo = (props: {
<DataLoader load={() => services.viewPreferences.getPreferences()}>
{pref => {
const live = deepMerge(props.live, {}) as any;
if (live && pref.appDetails.hideManagedFields) {
if (live?.metadata?.managedFields && pref.appDetails.hideManagedFields) {
delete live.metadata.managedFields;
}
return (

View File

@@ -27,11 +27,11 @@ const retryOptions: Array<(formApi: FormApi) => React.ReactNode> = [
];
const defaultInitialValues = {
limit: '',
limit: 2,
backoff: {
duration: '',
maxDuration: '',
factor: ''
duration: '5s',
maxDuration: '3m0s',
factor: 2
}
};

View File

@@ -17,10 +17,10 @@ const retryOptionsView: Array<(initData: models.RetryStrategy) => React.ReactNod
initData => buildRetryOptionView('Limit', initData?.limit),
initData => buildRetryOptionView('Duration', initData?.backoff?.duration),
initData => buildRetryOptionView('Max Duration', initData?.backoff?.maxDuration),
initData => buildRetryOptionView('Factor', initData?.backoff.factor)
initData => buildRetryOptionView('Factor', initData?.backoff?.factor)
];
export const ApplicationRetryView = ({initValues}: {initValues?: models.RetryStrategy}) => {
const result = !initValues ? 'Retry not installed' : retryOptionsView.map((render, i) => render(initValues));
const result = !initValues ? 'Retry disabled' : retryOptionsView.map((render, i) => render(initValues));
return <div className='application-retry-option-view-list'>{result}</div>;
};

View File

@@ -176,8 +176,10 @@ export const ApplicationSyncPanel = ({application, selectedResource, hide}: {app
let contentEnd = resKey.substr(-Math.floor(resKey.length / 2));
// We want the ellipsis to be in the middle of our text, so we use RTL layout to put it there.
// Unfortunately, strong LTR characters get jumbled around, so make sure that the last character isn't strong.
const indexOfFirstLetter = /[a-z]/i.exec(contentEnd).index;
contentEnd = contentEnd.slice(indexOfFirstLetter);
const firstLetter = /[a-z]/i.exec(contentEnd);
if (firstLetter) {
contentEnd = contentEnd.slice(firstLetter.index);
}
const isLongLabel = resKey.length > 68;
return (
<div key={resKey} className='application-sync-panel__resource'>

View File

@@ -607,16 +607,10 @@ func GetPermittedRepos(proj *argoappv1.AppProject, repos []*argoappv1.Repository
}
func getDestinationServer(ctx context.Context, db db.ArgoDB, clusterName string) (string, error) {
clusterList, err := db.ListClusters(ctx)
servers, err := db.GetClusterServersByName(ctx, clusterName)
if err != nil {
return "", err
}
var servers []string
for _, c := range clusterList.Items {
if c.Name == clusterName {
servers = append(servers, c.Server)
}
}
if len(servers) > 1 {
return "", fmt.Errorf("there are %d clusters with the same name: %v", len(servers), servers)
} else if len(servers) == 0 {

View File

@@ -680,14 +680,7 @@ func TestValidateDestination(t *testing.T) {
}
db := &dbmocks.ArgoDB{}
db.On("ListClusters", context.Background()).Return(&argoappv1.ClusterList{
Items: []argoappv1.Cluster{
{
Name: "minikube",
Server: "https://127.0.0.1:6443",
},
},
}, nil)
db.On("GetClusterServersByName", context.Background(), "minikube").Return([]string{"https://127.0.0.1:6443"}, nil)
appCond := ValidateDestination(context.Background(), &dest, db)
assert.Nil(t, appCond)
@@ -707,13 +700,13 @@ func TestValidateDestination(t *testing.T) {
assert.False(t, dest.IsServerInferred())
})
t.Run("List clusters fails", func(t *testing.T) {
t.Run("GetClusterServersByName fails", func(t *testing.T) {
dest := argoappv1.ApplicationDestination{
Name: "minikube",
}
db := &dbmocks.ArgoDB{}
db.On("ListClusters", context.Background()).Return(nil, fmt.Errorf("an error occurred"))
db.On("GetClusterServersByName", context.Background(), mock.Anything).Return(nil, fmt.Errorf("an error occurred"))
err := ValidateDestination(context.Background(), &dest, db)
assert.Equal(t, "unable to find destination server: an error occurred", err.Error())
@@ -726,14 +719,7 @@ func TestValidateDestination(t *testing.T) {
}
db := &dbmocks.ArgoDB{}
db.On("ListClusters", context.Background()).Return(&argoappv1.ClusterList{
Items: []argoappv1.Cluster{
{
Name: "dind",
Server: "https://127.0.0.1:6443",
},
},
}, nil)
db.On("GetClusterServersByName", context.Background(), "minikube").Return(nil, nil)
err := ValidateDestination(context.Background(), &dest, db)
assert.Equal(t, "unable to find destination server: there are no clusters with this name: minikube", err.Error())
@@ -746,18 +732,7 @@ func TestValidateDestination(t *testing.T) {
}
db := &dbmocks.ArgoDB{}
db.On("ListClusters", context.Background()).Return(&argoappv1.ClusterList{
Items: []argoappv1.Cluster{
{
Name: "dind",
Server: "https://127.0.0.1:2443",
},
{
Name: "dind",
Server: "https://127.0.0.1:8443",
},
},
}, nil)
db.On("GetClusterServersByName", context.Background(), "dind").Return([]string{"https://127.0.0.1:2443", "https://127.0.0.1:8443"}, nil)
err := ValidateDestination(context.Background(), &dest, db)
assert.Equal(t, "unable to find destination server: there are 2 clusters with the same name: [https://127.0.0.1:2443 https://127.0.0.1:8443]", err.Error())

View File

@@ -232,6 +232,34 @@ func (db *db) GetProjectClusters(ctx context.Context, project string) ([]*appv1.
return res, nil
}
func (db *db) GetClusterServersByName(ctx context.Context, name string) ([]string, error) {
informer, err := db.settingsMgr.GetSecretsInformer()
if err != nil {
return nil, err
}
// if local cluster name is not overridden and specified name is local cluster name, return local cluster server
localClusterSecrets, err := informer.GetIndexer().ByIndex(settings.ByClusterURLIndexer, appv1.KubernetesInternalAPIServerAddr)
if err != nil {
return nil, err
}
if len(localClusterSecrets) == 0 && db.getLocalCluster().Name == name {
return []string{appv1.KubernetesInternalAPIServerAddr}, nil
}
secrets, err := informer.GetIndexer().ByIndex(settings.ByClusterNameIndexer, name)
if err != nil {
return nil, err
}
var res []string
for i := range secrets {
s := secrets[i].(*apiv1.Secret)
res = append(res, strings.TrimRight(string(s.Data["server"]), "/"))
}
return res, nil
}
// UpdateCluster updates a cluster
func (db *db) UpdateCluster(ctx context.Context, c *appv1.Cluster) (*appv1.Cluster, error) {
clusterSecret, err := db.getClusterSecret(c.Server)

View File

@@ -27,8 +27,10 @@ type ArgoDB interface {
handleAddEvent func(cluster *appv1.Cluster),
handleModEvent func(oldCluster *appv1.Cluster, newCluster *appv1.Cluster),
handleDeleteEvent func(clusterServer string)) error
// GetCluster get returns a cluster by given server url
// GetCluster returns a cluster by given server url
GetCluster(ctx context.Context, server string) (*appv1.Cluster, error)
// GetClusterServersByName returns a cluster server urls by given cluster name
GetClusterServersByName(ctx context.Context, name string) ([]string, error)
// GetProjectClusters return project scoped clusters by given project name
GetProjectClusters(ctx context.Context, project string) ([]*appv1.Cluster, error)
// UpdateCluster updates a cluster

View File

@@ -693,3 +693,59 @@ func TestHelmRepositorySecretsTrim(t *testing.T) {
assert.Equal(t, tt.expectedSecret, tt.retrievedSecret)
}
}
func TestGetClusterServersByName(t *testing.T) {
clientset := getClientset(nil, &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster-secret",
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Annotations: map[string]string{
common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
},
},
Data: map[string][]byte{
"name": []byte("my-cluster-name"),
"server": []byte("https://my-cluster-server"),
"config": []byte("{}"),
},
})
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
servers, err := db.GetClusterServersByName(context.Background(), "my-cluster-name")
assert.NoError(t, err)
assert.ElementsMatch(t, []string{"https://my-cluster-server"}, servers)
}
func TestGetClusterServersByName_InClusterNotConfigured(t *testing.T) {
clientset := getClientset(nil)
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster")
assert.NoError(t, err)
assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers)
}
func TestGetClusterServersByName_InClusterConfigured(t *testing.T) {
clientset := getClientset(nil, &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster-secret",
Namespace: testNamespace,
Labels: map[string]string{
common.LabelKeySecretType: common.LabelValueSecretTypeCluster,
},
Annotations: map[string]string{
common.AnnotationKeyManagedBy: common.AnnotationValueManagedByArgoCD,
},
},
Data: map[string][]byte{
"name": []byte("in-cluster-renamed"),
"server": []byte(v1alpha1.KubernetesInternalAPIServerAddr),
"config": []byte("{}"),
},
})
db := NewDB(testNamespace, settings.NewSettingsManager(context.Background(), clientset, testNamespace), clientset)
servers, err := db.GetClusterServersByName(context.Background(), "in-cluster-renamed")
assert.NoError(t, err)
assert.ElementsMatch(t, []string{v1alpha1.KubernetesInternalAPIServerAddr}, servers)
}

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
// Code generated by mockery v1.0.0. DO NOT EDIT.
package mocks
@@ -242,6 +242,29 @@ func (_m *ArgoDB) GetCluster(ctx context.Context, server string) (*v1alpha1.Clus
return r0, r1
}
// GetClusterServersByName provides a mock function with given fields: ctx, name
func (_m *ArgoDB) GetClusterServersByName(ctx context.Context, name string) ([]string, error) {
ret := _m.Called(ctx, name)
var r0 []string
if rf, ok := ret.Get(0).(func(context.Context, string) []string); ok {
r0 = rf(ctx, name)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]string)
}
}
var r1 error
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, name)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetProjectClusters provides a mock function with given fields: ctx, project
func (_m *ArgoDB) GetProjectClusters(ctx context.Context, project string) ([]*v1alpha1.Cluster, error) {
ret := _m.Called(ctx, project)

View File

@@ -163,6 +163,23 @@ var (
}
return nil, nil
}
ByClusterNameIndexer = "byClusterName"
byClusterNameIndexerFunc = func(obj interface{}) ([]string, error) {
s, ok := obj.(*apiv1.Secret)
if !ok {
return nil, nil
}
if s.Labels == nil || s.Labels[common.LabelKeySecretType] != common.LabelValueSecretTypeCluster {
return nil, nil
}
if s.Data == nil {
return nil, nil
}
if name, ok := s.Data["name"]; ok {
return []string{string(name)}, nil
}
return nil, nil
}
ByProjectClusterIndexer = "byProjectCluster"
ByProjectRepoIndexer = "byProjectRepo"
byProjectIndexerFunc = func(secretType string) func(obj interface{}) ([]string, error) {
@@ -1044,6 +1061,7 @@ func (mgr *SettingsManager) initialize(ctx context.Context) error {
indexers := cache.Indexers{
cache.NamespaceIndex: cache.MetaNamespaceIndexFunc,
ByClusterURLIndexer: byClusterURLIndexerFunc,
ByClusterNameIndexer: byClusterNameIndexerFunc,
ByProjectClusterIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeCluster),
ByProjectRepoIndexer: byProjectIndexerFunc(common.LabelValueSecretTypeRepository),
}