diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml index b7e345be7abb4..58de56108dcd6 100644 --- a/.github/workflows/ci-build.yaml +++ b/.github/workflows/ci-build.yaml @@ -420,7 +420,7 @@ jobs: # port 8080 which is not visible in netstat -tulpen, but still there # with a HTTP listener. We have API server listening on port 8088 # instead. - make start-e2e-local ARGOCD_BIN_MODE=true 2>&1 | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g" > /tmp/e2e-server.log & + make start-e2e-local 2>&1 | sed -r "s/[[:cntrl:]]\[[0-9]{1,3}m//g" > /tmp/e2e-server.log & count=1 until curl -f http://127.0.0.1:8088/healthz; do sleep 10; diff --git a/Makefile b/Makefile index d026cd936e98c..e0e2ccb7403e4 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ ARGOCD_E2E_TEST_TIMEOUT?=30m ARGOCD_IN_CI?=false ARGOCD_TEST_E2E?=true -ARGOCD_BIN_MODE?=false +ARGOCD_BIN_MODE?=true ARGOCD_LINT_GOGC?=20 diff --git a/Procfile b/Procfile index 4492146517284..c02bb2d8fdeea 100644 --- a/Procfile +++ b/Procfile @@ -9,3 +9,4 @@ 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_ASK_PASS_SOCK=/tmp/applicationset-ask-pass.sock 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" \ No newline at end of file diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index c1012a20bae2c..cdc74fb0dee8c 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -569,16 +569,16 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com // unsetOpts describe what to unset in an Application. type unsetOpts struct { - namePrefix bool - nameSuffix bool - kustomizeVersion bool - kustomizeImages []string - parameters []string - valuesFiles []string - valuesLiteral bool + namePrefix bool + nameSuffix bool + kustomizeVersion bool + kustomizeImages []string + parameters []string + valuesFiles []string + valuesLiteral bool ignoreMissingValueFiles bool - pluginEnvs []string - passCredentials bool + pluginEnvs []string + passCredentials bool } // NewApplicationUnsetCommand returns a new instance of an `argocd app unset` command @@ -1210,35 +1210,44 @@ const ( resourceFieldNameWithNamespaceCount = 2 ) -func parseSelectedResources(resources []string) []*argoappv1.SyncOperationResource { +// resource is GROUP:KIND:NAMESPACE/NAME or GROUP:KIND:NAME +func parseSelectedResources(resources []string) ([]*argoappv1.SyncOperationResource, error) { + // retrieve name and namespace in case if format is GROUP:KIND:NAMESPACE/NAME, otherwise return name and empty namespace + nameRetriever := func(resourceName, resource string) (string, string, error) { + if !strings.Contains(resourceName, resourceFieldNamespaceDelimiter) { + return resourceName, "", nil + } + nameFields := strings.Split(resourceName, resourceFieldNamespaceDelimiter) + if len(nameFields) != resourceFieldNameWithNamespaceCount { + return "", "", fmt.Errorf("Resource with namespace should have GROUP%sKIND%sNAMESPACE%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resourceFieldNamespaceDelimiter, resource) + } + namespace := nameFields[0] + name := nameFields[1] + return name, namespace, nil + } + var selectedResources []*argoappv1.SyncOperationResource - if resources != nil { - selectedResources = []*argoappv1.SyncOperationResource{} - for _, r := range resources { - fields := strings.Split(r, resourceFieldDelimiter) - if len(fields) != resourceFieldCount { - log.Fatalf("Resource should have GROUP%sKIND%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, r) - } - name := fields[2] - namespace := "" - if strings.Contains(fields[2], resourceFieldNamespaceDelimiter) { - nameFields := strings.Split(fields[2], resourceFieldNamespaceDelimiter) - if len(nameFields) != resourceFieldNameWithNamespaceCount { - log.Fatalf("Resource with namespace should have GROUP%sKIND%sNAMESPACE%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resourceFieldNamespaceDelimiter, r) - } - namespace = nameFields[0] - name = nameFields[1] - } - rsrc := argoappv1.SyncOperationResource{ - Group: fields[0], - Kind: fields[1], - Name: name, - Namespace: namespace, - } - selectedResources = append(selectedResources, &rsrc) + if resources == nil { + return selectedResources, nil + } + + for _, resource := range resources { + fields := strings.Split(resource, resourceFieldDelimiter) + if len(fields) != resourceFieldCount { + return nil, fmt.Errorf("Resource should have GROUP%sKIND%sNAME, but instead got: %s", resourceFieldDelimiter, resourceFieldDelimiter, resource) + } + name, namespace, err := nameRetriever(fields[2], resource) + if err != nil { + return nil, err } + selectedResources = append(selectedResources, &argoappv1.SyncOperationResource{ + Group: fields[0], + Kind: fields[1], + Name: name, + Namespace: namespace, + }) } - return selectedResources + return selectedResources, nil } func getWatchOpts(watch watchOpts) watchOpts { @@ -1278,7 +1287,8 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co os.Exit(1) } watch = getWatchOpts(watch) - selectedResources := parseSelectedResources(resources) + selectedResources, err := parseSelectedResources(resources) + errors.CheckError(err) appNames := args acdClient := headless.NewClientOrDie(clientOpts, c) closer, appIf := acdClient.NewApplicationClientOrDie() @@ -1415,7 +1425,8 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } } - selectedResources := parseSelectedResources(resources) + selectedResources, err := parseSelectedResources(resources) + errors.CheckError(err) var localObjsStrings []string diffOption := &DifferenceOption{} @@ -1514,7 +1525,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } } ctx := context.Background() - _, err := appIf.Sync(ctx, &syncReq) + _, err = appIf.Sync(ctx, &syncReq) errors.CheckError(err) if !async { diff --git a/cmd/argocd/commands/app_test.go b/cmd/argocd/commands/app_test.go index 569ec7d5b37e4..8b8b01e221eaf 100644 --- a/cmd/argocd/commands/app_test.go +++ b/cmd/argocd/commands/app_test.go @@ -965,6 +965,45 @@ func Test_unset_nothingToUnset(t *testing.T) { } } +func TestParseSelectedResources(t *testing.T) { + resources := []string{"v1alpha:Application:test", "v1alpha:Application:namespace/test"} + operationResources, err := parseSelectedResources(resources) + assert.NoError(t, err) + assert.Len(t, operationResources, 2) + assert.Equal(t, *operationResources[0], v1alpha1.SyncOperationResource{ + Namespace: "", + Name: "test", + Kind: "Application", + Group: "v1alpha", + }) + assert.Equal(t, *operationResources[1], v1alpha1.SyncOperationResource{ + Namespace: "namespace", + Name: "test", + Kind: "Application", + Group: "v1alpha", + }) +} + +func TestParseSelectedResourcesIncorrect(t *testing.T) { + resources := []string{"v1alpha:test", "v1alpha:Application:namespace/test"} + _, err := parseSelectedResources(resources) + assert.ErrorContains(t, err, "v1alpha:test") +} + +func TestParseSelectedResourcesIncorrectNamespace(t *testing.T) { + resources := []string{"v1alpha:Application:namespace/test/unknown"} + _, err := parseSelectedResources(resources) + assert.ErrorContains(t, err, "v1alpha:Application:namespace/test/unknown") + +} + +func TestParseSelectedResourcesEmptyList(t *testing.T) { + var resources []string + operationResources, err := parseSelectedResources(resources) + assert.NoError(t, err) + assert.Len(t, operationResources, 0) +} + func TestPrintApplicationTableNotWide(t *testing.T) { output, err := captureOutput(func() error { app := &v1alpha1.Application{ diff --git a/test/container/Procfile b/test/container/Procfile index 8c572aa31c981..c0b30152a2190 100644 --- a/test/container/Procfile +++ b/test/container/Procfile @@ -10,4 +10,5 @@ fcgiwrap: sudo sh -c "test $ARGOCD_E2E_TEST = true && (fcgiwrap -s unix:/var/run nginx: sudo sh -c "test $ARGOCD_E2E_TEST = true && nginx -g 'daemon off;' -c $(pwd)/test/fixture/testrepos/nginx.conf" helm-registry: sudo sh -c "registry serve /etc/docker/registry/config.yml" dev-mounter: test "$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_ASK_PASS_SOCK=/tmp/applicationset-ask-pass.sock 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}" \ No newline at end of file +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_ASK_PASS_SOCK=/tmp/applicationset-ask-pass.sock 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: 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 go run ./cmd/main.go --loglevel debug"