From 609f2b91941a4af173904ebe78c1e9ca63964d16 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Wed, 6 Mar 2024 10:37:41 -0500 Subject: [PATCH 01/16] "feat:add cli commands to create/set/unset/edit sources for multi-source app" Signed-off-by: ishitasequeira --- cmd/argocd/commands/admin/app.go | 2 +- cmd/argocd/commands/app.go | 44 ++++++++++++--- cmd/util/app.go | 24 ++++++--- cmd/util/app_test.go | 57 ++++++++++++++++++-- docs/user-guide/commands/argocd_app_set.md | 1 + docs/user-guide/commands/argocd_app_unset.md | 1 + pkg/apis/application/v1alpha1/types.go | 5 +- server/repository/repository_test.go | 4 +- util/notification/expression/repo/repo.go | 2 +- 9 files changed, 116 insertions(+), 24 deletions(-) diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index 096c92f9feb01..1e70fd18c1dd9 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -100,7 +100,7 @@ func NewGenAppSpecCommand() *cobra.Command { argocd admin app generate-spec kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane `, Run: func(c *cobra.Command, args []string) { - apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags()) + apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags(), nil) errors.CheckError(err) if len(apps) > 1 { errors.CheckError(fmt.Errorf("failed to generate spec, more than one application is not supported")) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 25c02db5f291d..e1c14a6654ab2 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -118,6 +118,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. annotations []string setFinalizer bool appNamespace string + source_index int ) var command = &cobra.Command{ Use: "create APPNAME", @@ -142,9 +143,11 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. Run: func(c *cobra.Command, args []string) { ctx := c.Context() + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be greater than 0")) + } argocdClient := headless.NewClientOrDie(clientOpts, c) - - apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags()) + apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags(), &source_index) errors.CheckError(err) for _, app := range apps { @@ -202,6 +205,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. log.Fatal(err) } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace where the application will be created in") + command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") cmdutil.AddAppFlags(command, &appOpts) return command } @@ -730,6 +734,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com var ( appOpts cmdutil.AppOptions appNamespace string + source_index int ) var command = &cobra.Command{ Use: "set APPNAME", @@ -758,6 +763,9 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com c.HelpFunc()(c, args) os.Exit(1) } + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be greater than 0")) + } appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) argocdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := argocdClient.NewApplicationClientOrDie() @@ -765,7 +773,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) - visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts) + visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) if visited == 0 { log.Error("Please set at least one option to update") c.HelpFunc()(c, args) @@ -782,6 +790,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com errors.CheckError(err) }, } + command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") cmdutil.AddAppFlags(command, &appOpts) command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in namespace") return command @@ -816,6 +825,9 @@ func (o *unsetOpts) KustomizeIsZero() bool { // NewApplicationUnsetCommand returns a new instance of an `argocd app unset` command func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { + var ( + source_index int + ) appOpts := cmdutil.AppOptions{} opts := unsetOpts{} var appNamespace string @@ -838,14 +850,21 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C c.HelpFunc()(c, args) os.Exit(1) } + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be greater than 0")) + } appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) - source := app.Spec.GetSource() - updated, nothingToUnset := unset(&source, opts) + if app.Spec.HasMultipleSources() && len(app.Spec.GetSources()) < source_index { + errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) + } + source := app.Spec.GetSourcePtr(&source_index) + + updated, nothingToUnset := unset(source, opts) if nothingToUnset { c.HelpFunc()(c, args) os.Exit(1) @@ -854,7 +873,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C return } - cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts) + cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, Spec: &app.Spec, @@ -877,6 +896,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C command.Flags().StringArrayVar(&opts.kustomizeReplicas, "kustomize-replica", []string{}, "Kustomize replicas name (e.g. --kustomize-replica my-deployment --kustomize-replica my-statefulset)") command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)") command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials") + command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") return command } @@ -2731,7 +2751,10 @@ func NewApplicationTerminateOpCommand(clientOpts *argocdclient.ClientOptions) *c } func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { - var appNamespace string + var ( + appNamespace string + source_index int + ) var command = &cobra.Command{ Use: "edit APPNAME", Short: "Edit application", @@ -2742,6 +2765,10 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co c.HelpFunc()(c, args) os.Exit(1) } + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be greater than 0")) + } + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() defer argoio.Close(conn) @@ -2768,7 +2795,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } var appOpts cmdutil.AppOptions - cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts) + cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &appName, Spec: &updatedSpec, @@ -2783,6 +2810,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }, } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only edit application in namespace") + command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") return command } diff --git a/cmd/util/app.go b/cmd/util/app.go index 9a284b56ce38b..6590b58f7c6a6 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -139,16 +139,25 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().StringVar(&opts.ref, "ref", "", "Ref is reference to another source within sources field") } -func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions) int { +func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, index *int) int { visited := 0 if flags == nil { return visited } - source := spec.GetSourcePtr() + source := spec.GetSourcePtr(index) if source == nil { source = &argoappv1.ApplicationSource{} } source, visited = ConstructSource(source, *appOpts, flags) + if spec.HasMultipleSources() { + if index != nil { + spec.Sources[*index] = *source + } else { + spec.Sources = append(spec.Sources, *source) + } + } else { + spec.Source = source + } flags.Visit(func(f *pflag.Flag) { visited++ @@ -220,7 +229,6 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap log.Fatalf("Invalid sync-retry-limit [%d]", appOpts.retryLimit) } } - spec.Source = source }) if flags.Changed("auto-prune") { if spec.SyncPolicy == nil || spec.SyncPolicy.Automated == nil { @@ -530,7 +538,7 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, Source: &argoappv1.ApplicationSource{}, }, } - SetAppSpecOptions(flags, &app.Spec, &appOpts) + SetAppSpecOptions(flags, &app.Spec, &appOpts, nil) SetParameterOverrides(app, appOpts.Parameters) mergeLabels(app, labels) setAnnotations(app, annotations) @@ -539,7 +547,7 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, }, nil } -func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) { +func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet, source_index *int) ([]*argoappv1.Application, error) { apps := make([]*argoappv1.Application, 0) // read uri err := readAppsFromURI(fileURL, &apps) @@ -557,7 +565,7 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args return nil, fmt.Errorf("app.Name is empty. --name argument can be used to provide app.Name") } - SetAppSpecOptions(flags, &app.Spec, &appOpts) + SetAppSpecOptions(flags, &app.Spec, &appOpts, source_index) SetParameterOverrides(app, appOpts.Parameters) mergeLabels(app, labels) setAnnotations(app, annotations) @@ -565,11 +573,11 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args return apps, nil } -func ConstructApps(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) { +func ConstructApps(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet, source_index *int) ([]*argoappv1.Application, error) { if fileURL == "-" { return constructAppsFromStdin() } else if fileURL != "" { - return constructAppsFromFileUrl(fileURL, appName, labels, annotations, args, appOpts, flags) + return constructAppsFromFileUrl(fileURL, appName, labels, annotations, args, appOpts, flags, source_index) } return constructAppsBaseOnName(appName, labels, annotations, args, appOpts, flags) diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index b5fce9c1e663e..0d2fbcbc74604 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -170,7 +170,16 @@ func (f *appOptionsFixture) SetFlag(key, value string) error { if err != nil { return err } - _ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options) + _ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options, nil) + return err +} + +func (f *appOptionsFixture) SetFlagWithSourceIndex(key, value string, index *int) error { + err := f.command.Flags().Set(key, value) + if err != nil { + return err + } + _ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options, index) return err } @@ -225,6 +234,48 @@ func Test_setAppSpecOptions(t *testing.T) { }) } +func newMultiSourceAppOptionsFixture() *appOptionsFixture { + fixture := &appOptionsFixture{ + spec: &v1alpha1.ApplicationSpec{ + Sources: v1alpha1.ApplicationSources{ + v1alpha1.ApplicationSource{}, + v1alpha1.ApplicationSource{}, + }, + }, + command: &cobra.Command{}, + options: &AppOptions{}, + } + AddAppFlags(fixture.command, fixture.options) + return fixture +} + +func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) { + f := newMultiSourceAppOptionsFixture() + index1 := 0 + index2 := 1 + t.Run("SyncPolicy", func(t *testing.T) { + assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automated", &index1)) + assert.NotNil(t, f.spec.SyncPolicy.Automated) + + f.spec.SyncPolicy = nil + assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automatic", &index1)) + assert.NotNil(t, f.spec.SyncPolicy.Automated) + }) + t.Run("Kustomize", func(t *testing.T) { + assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=2", &index1)) + assert.Equal(t, f.spec.Sources[index1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}}) + assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=4", &index2)) + assert.Equal(t, f.spec.Sources[index2].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(4)}}) + }) + t.Run("Helm", func(t *testing.T) { + assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", &index1)) + assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v3", &index2)) + assert.Equal(t, len(f.spec.GetSources()), 2) + assert.Equal(t, f.spec.GetSources()[index1].Helm.Version, "v2") + assert.Equal(t, f.spec.GetSources()[index2].Helm.Version, "v3") + }) +} + func Test_setAnnotations(t *testing.T) { t.Run("Annotations", func(t *testing.T) { app := v1alpha1.Application{} @@ -326,7 +377,7 @@ func TestConstructAppFromStdin(t *testing.T) { os.Stdin = file - apps, err := ConstructApps("-", "test", []string{}, []string{}, []string{}, AppOptions{}, nil) + apps, err := ConstructApps("-", "test", []string{}, []string{}, []string{}, AppOptions{}, nil, nil) if err := file.Close(); err != nil { log.Fatal(err) @@ -339,7 +390,7 @@ func TestConstructAppFromStdin(t *testing.T) { } func TestConstructBasedOnName(t *testing.T) { - apps, err := ConstructApps("", "test", []string{}, []string{}, []string{}, AppOptions{}, nil) + apps, err := ConstructApps("", "test", []string{}, []string{}, []string{}, AppOptions{}, nil, nil) assert.NoError(t, err) assert.Equal(t, 1, len(apps)) diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 1c6cc40bd5c27..4e8bcdc24d1e9 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -76,6 +76,7 @@ argocd app set APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated + --source-index int Index of the source from the list of sources of the app. Default index is 0. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 34194b02d447c..96e17db4207ab 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -36,6 +36,7 @@ argocd app unset APPNAME parameters [flags] -p, --parameter stringArray Unset a parameter override (e.g. -p guestbook=image) --pass-credentials Unset passCredentials --plugin-env stringArray Unset plugin env variables (e.g --plugin-env name) + --source-index int Index of the source from the list of sources of the app. Default index is 0. --values stringArray Unset one or more Helm values files --values-literal Unset literal Helm values block ``` diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index fc2908c4643dc..d4f054b6285ad 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -230,9 +230,12 @@ func (a *ApplicationSpec) HasMultipleSources() bool { return a.Sources != nil && len(a.Sources) > 0 } -func (a *ApplicationSpec) GetSourcePtr() *ApplicationSource { +func (a *ApplicationSpec) GetSourcePtr(index *int) *ApplicationSource { // if Application has multiple sources, return the first source in sources if a.HasMultipleSources() { + if index != nil { + return &a.Sources[*index] + } return &a.Sources[0] } return a.Source diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index 9c294b5a332b9..95df1f8c7b67c 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -654,7 +654,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ - Source: guestbookApp.Spec.GetSourcePtr(), + Source: guestbookApp.Spec.GetSourcePtr(nil), AppName: "guestbook", AppProject: "default", }) @@ -752,7 +752,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ - Source: guestbookApp.Spec.GetSourcePtr(), + Source: guestbookApp.Spec.GetSourcePtr(nil), AppName: "guestbook", AppProject: "mismatch", }) diff --git a/util/notification/expression/repo/repo.go b/util/notification/expression/repo/repo.go index a782c0b7c1725..d1ee5b2738fa7 100644 --- a/util/notification/expression/repo/repo.go +++ b/util/notification/expression/repo/repo.go @@ -33,7 +33,7 @@ func getApplicationSourceAndName(obj *unstructured.Unstructured) (*v1alpha1.Appl if err != nil { return nil, "", err } - return application.Spec.GetSourcePtr(), application.GetName(), nil + return application.Spec.GetSourcePtr(nil), application.GetName(), nil } func getAppDetails(app *unstructured.Unstructured, argocdService service.Service) (*shared.AppDetail, error) { From 5e416594544eb44b515d37bc6b42ba914ef6c60a Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Wed, 6 Mar 2024 11:35:32 -0500 Subject: [PATCH 02/16] fixed the ci failure Signed-off-by: ishitasequeira --- docs/user-guide/commands/argocd_app_create.md | 1 + docs/user-guide/commands/argocd_app_edit.md | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 00b4949f7993b..b8feaf4b40c4e 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -84,6 +84,7 @@ argocd app create APPNAME [flags] --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion + --source-index int Index of the source from the list of sources of the app. Default index is 0. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index e581677b79c12..a4fa48c5e59ec 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -13,6 +13,7 @@ argocd app edit APPNAME [flags] ``` -N, --app-namespace string Only edit application in namespace -h, --help help for edit + --source-index int Index of the source from the list of sources of the app. Default index is 0. ``` ### Options inherited from parent commands From 74f224711812ec3b888fc491b56279d2a0704b05 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Wed, 6 Mar 2024 21:43:24 -0500 Subject: [PATCH 03/16] update commands Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 33 ++++++++++++++++--- docs/user-guide/commands/argocd_app_create.md | 6 ++++ docs/user-guide/commands/argocd_app_set.md | 3 ++ docs/user-guide/commands/argocd_app_unset.md | 6 +++- 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index e1c14a6654ab2..5010a857c2bb7 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -138,6 +138,12 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. # Create a Kustomize app argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 + # Create a MultiSource app + argocd app create guestbook --file + + # Create a MultiSource app while overriding repo of source at index 1 under spec.sources (Indexes start at 0) + argocd app create guestbook --file --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Create a app using a custom tool: argocd app create kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane`, Run: func(c *cobra.Command, args []string) { @@ -752,6 +758,9 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Set and override application parameters with a parameter file argocd app set my-app --parameter-file path/to/parameter-file.yaml + # Set and override application parameters for a source at index 1 under spec.sources of app my-app (Indexes start at 0) + argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Set application parameters and specify the namespace argocd app set my-app --parameter key1=value1 --parameter key2=value2 --namespace my-namespace `), @@ -810,6 +819,7 @@ type unsetOpts struct { ignoreMissingValueFiles bool pluginEnvs []string passCredentials bool + ref bool } // IsZero returns true when the Application options for kustomize are considered empty @@ -837,9 +847,12 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C Example: ` # Unset kustomize override kustomize image argocd app unset my-app --kustomize-image=alpine - # Unset kustomize override prefix + # Unset kustomize override suffix argocd app unset my-app --namesuffix + # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app (Indexes start at 0) + argocd app unset my-app --source-index 1 --namesuffix + # Unset parameter override argocd app unset my-app -p COMPONENT=PARAM`, @@ -896,14 +909,23 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C command.Flags().StringArrayVar(&opts.kustomizeReplicas, "kustomize-replica", []string{}, "Kustomize replicas name (e.g. --kustomize-replica my-deployment --kustomize-replica my-statefulset)") command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)") command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials") + command.Flags().BoolVar(&opts.ref, "ref", false, "Unset ref on the source") command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") return command } func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, nothingToUnset bool) { + + needToUnsetRef := false + if opts.ref && source.Ref != "" { + source.Ref = "" + updated = true + needToUnsetRef = true + } + if source.Kustomize != nil { if opts.KustomizeIsZero() { - return false, true + return updated, !needToUnsetRef && true } if opts.namePrefix && source.Kustomize.NamePrefix != "" { @@ -953,7 +975,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n } if source.Helm != nil { if len(opts.parameters) == 0 && len(opts.valuesFiles) == 0 && !opts.valuesLiteral && !opts.ignoreMissingValueFiles && !opts.passCredentials { - return false, true + return updated, !needToUnsetRef && true } for _, paramStr := range opts.parameters { helmParams := source.Helm.Parameters @@ -990,9 +1012,10 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n updated = true } } + if source.Plugin != nil { if len(opts.pluginEnvs) == 0 { - return false, true + return false, !needToUnsetRef && true } for _, env := range opts.pluginEnvs { err := source.Plugin.RemoveEnvEntry(env) @@ -1001,7 +1024,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n } } } - return updated, false + return updated, !needToUnsetRef && false } // targetObjects deserializes the list of target states into unstructured objects diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index b8feaf4b40c4e..1133f5bf42d0f 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -26,6 +26,12 @@ argocd app create APPNAME [flags] # Create a Kustomize app argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 + # Create a MultiSource app + argocd app create guestbook --file + + # Create a MultiSource app while overriding repo of source at index 1 under spec.sources (Indexes start at 0) + argocd app create guestbook --file --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Create a app using a custom tool: argocd app create kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane ``` diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 4e8bcdc24d1e9..706d737e25751 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -23,6 +23,9 @@ argocd app set APPNAME [flags] # Set and override application parameters with a parameter file argocd app set my-app --parameter-file path/to/parameter-file.yaml + # Set and override application parameters for a source at index 1 under spec.sources of app my-app (Indexes start at 0) + argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Set application parameters and specify the namespace argocd app set my-app --parameter key1=value1 --parameter key2=value2 --namespace my-namespace ``` diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 96e17db4207ab..ef85e31cfc3ef 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -14,9 +14,12 @@ argocd app unset APPNAME parameters [flags] # Unset kustomize override kustomize image argocd app unset my-app --kustomize-image=alpine - # Unset kustomize override prefix + # Unset kustomize override suffix argocd app unset my-app --namesuffix + # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app (Indexes start at 0) + argocd app unset my-app --source-index 1 --namesuffix + # Unset parameter override argocd app unset my-app -p COMPONENT=PARAM ``` @@ -36,6 +39,7 @@ argocd app unset APPNAME parameters [flags] -p, --parameter stringArray Unset a parameter override (e.g. -p guestbook=image) --pass-credentials Unset passCredentials --plugin-env stringArray Unset plugin env variables (e.g --plugin-env name) + --ref Unset ref on the source --source-index int Index of the source from the list of sources of the app. Default index is 0. --values stringArray Unset one or more Helm values files --values-literal Unset literal Helm values block From 22ffda512363e3bd0d3542cbb92d6581792e7e8d Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Fri, 8 Mar 2024 13:50:15 -0500 Subject: [PATCH 04/16] error out if source-index not specified for multi-source applications Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 45 +++++++++++++++++++++++++------------- cmd/util/app.go | 9 ++++++++ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 5010a857c2bb7..28d6efae13bed 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -211,7 +211,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. log.Fatal(err) } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace where the application will be created in") - command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") cmdutil.AddAppFlags(command, &appOpts) return command } @@ -772,9 +772,6 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com c.HelpFunc()(c, args) os.Exit(1) } - if source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be greater than 0")) - } appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) argocdClient := headless.NewClientOrDie(clientOpts, c) conn, appIf := argocdClient.NewApplicationClientOrDie() @@ -782,6 +779,15 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) + if app.Spec.HasMultipleSources() { + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) + } + if len(app.Spec.GetSources()) < source_index { + errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) + } + } + visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) if visited == 0 { log.Error("Please set at least one option to update") @@ -799,7 +805,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com errors.CheckError(err) }, } - command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") cmdutil.AddAppFlags(command, &appOpts) command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in namespace") return command @@ -863,17 +869,20 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C c.HelpFunc()(c, args) os.Exit(1) } - if source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be greater than 0")) - } + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) - if app.Spec.HasMultipleSources() && len(app.Spec.GetSources()) < source_index { - errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) + if app.Spec.HasMultipleSources() { + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) + } + if len(app.Spec.GetSources()) < source_index { + errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) + } } source := app.Spec.GetSourcePtr(&source_index) @@ -910,7 +919,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)") command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials") command.Flags().BoolVar(&opts.ref, "ref", false, "Unset ref on the source") - command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") return command } @@ -2788,9 +2797,6 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co c.HelpFunc()(c, args) os.Exit(1) } - if source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be greater than 0")) - } appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() @@ -2801,6 +2807,15 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) + if app.Spec.HasMultipleSources() { + if source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) + } + if len(app.Spec.GetSources()) < source_index { + errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) + } + } + appData, err := json.Marshal(app.Spec) errors.CheckError(err) appData, err = yaml.JSONToYAML(appData) @@ -2833,7 +2848,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }, } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only edit application in namespace") - command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") return command } diff --git a/cmd/util/app.go b/cmd/util/app.go index 6590b58f7c6a6..53b2e8e60564a 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -565,6 +565,15 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args return nil, fmt.Errorf("app.Name is empty. --name argument can be used to provide app.Name") } + if source_index != nil && app.Spec.HasMultipleSources() { + if *source_index < 0 { + errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) + } + if len(app.Spec.GetSources()) < *source_index { + errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) + } + } + SetAppSpecOptions(flags, &app.Spec, &appOpts, source_index) SetParameterOverrides(app, appOpts.Parameters) mergeLabels(app, labels) From b0a0f7f6642657a451fe4b930c0b31a24981a3bf Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Fri, 8 Mar 2024 14:18:20 -0500 Subject: [PATCH 05/16] fixed the ci failure Signed-off-by: ishitasequeira --- docs/user-guide/commands/argocd_app_create.md | 2 +- docs/user-guide/commands/argocd_app_edit.md | 2 +- docs/user-guide/commands/argocd_app_set.md | 2 +- docs/user-guide/commands/argocd_app_unset.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 1133f5bf42d0f..eebed6032d611 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -90,7 +90,7 @@ argocd app create APPNAME [flags] --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion - --source-index int Index of the source from the list of sources of the app. Default index is 0. + --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index a4fa48c5e59ec..ce0c94bbcf545 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -13,7 +13,7 @@ argocd app edit APPNAME [flags] ``` -N, --app-namespace string Only edit application in namespace -h, --help help for edit - --source-index int Index of the source from the list of sources of the app. Default index is 0. + --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 706d737e25751..a5e45eb034de4 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -79,7 +79,7 @@ argocd app set APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated - --source-index int Index of the source from the list of sources of the app. Default index is 0. + --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index ef85e31cfc3ef..31c7ee4d834b8 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -40,7 +40,7 @@ argocd app unset APPNAME parameters [flags] --pass-credentials Unset passCredentials --plugin-env stringArray Unset plugin env variables (e.g --plugin-env name) --ref Unset ref on the source - --source-index int Index of the source from the list of sources of the app. Default index is 0. + --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) --values stringArray Unset one or more Helm values files --values-literal Unset literal Helm values block ``` From 1ee6847eae0cc5eebb65fbc9996409e4dd720792 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Fri, 8 Mar 2024 15:28:00 -0500 Subject: [PATCH 06/16] fix tests Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 28d6efae13bed..3da0eec564562 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -149,9 +149,6 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. Run: func(c *cobra.Command, args []string) { ctx := c.Context() - if source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be greater than 0")) - } argocdClient := headless.NewClientOrDie(clientOpts, c) apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags(), &source_index) errors.CheckError(err) From 38d90cba48a08dff85592f57e1c9384bd71babf7 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Sun, 10 Mar 2024 16:01:12 -0400 Subject: [PATCH 07/16] set 0 as default source index for app create Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 2 +- cmd/util/app.go | 9 --------- docs/user-guide/commands/argocd_app_create.md | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 3da0eec564562..0b0026fe352ac 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -208,7 +208,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. log.Fatal(err) } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace where the application will be created in") - command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") cmdutil.AddAppFlags(command, &appOpts) return command } diff --git a/cmd/util/app.go b/cmd/util/app.go index 53b2e8e60564a..6590b58f7c6a6 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -565,15 +565,6 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args return nil, fmt.Errorf("app.Name is empty. --name argument can be used to provide app.Name") } - if source_index != nil && app.Spec.HasMultipleSources() { - if *source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) - } - if len(app.Spec.GetSources()) < *source_index { - errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) - } - } - SetAppSpecOptions(flags, &app.Spec, &appOpts, source_index) SetParameterOverrides(app, appOpts.Parameters) mergeLabels(app, labels) diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index eebed6032d611..1133f5bf42d0f 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -90,7 +90,7 @@ argocd app create APPNAME [flags] --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion - --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) + --source-index int Index of the source from the list of sources of the app. Default index is 0. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) From 78a718e21e37dd9ca33f234a02edf2ddada6fbaf Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Mon, 11 Mar 2024 01:00:05 -0400 Subject: [PATCH 08/16] add index to ParameterOverrides function Signed-off-by: ishitasequeira --- cmd/util/app.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/util/app.go b/cmd/util/app.go index 6590b58f7c6a6..91d6b77e9314c 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -422,11 +422,11 @@ func setJsonnetOptLibs(src *argoappv1.ApplicationSource, libs []string) { // SetParameterOverrides updates an existing or appends a new parameter override in the application // The app is assumed to be a helm app and is expected to be in the form: // param=value -func SetParameterOverrides(app *argoappv1.Application, parameters []string) { +func SetParameterOverrides(app *argoappv1.Application, parameters []string, index *int) { if len(parameters) == 0 { return } - source := app.Spec.GetSource() + source := app.Spec.GetSourcePtr(index) var sourceType argoappv1.ApplicationSourceType if st, _ := source.ExplicitType(); st != nil { sourceType = *st @@ -539,7 +539,7 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, }, } SetAppSpecOptions(flags, &app.Spec, &appOpts, nil) - SetParameterOverrides(app, appOpts.Parameters) + SetParameterOverrides(app, appOpts.Parameters, nil) mergeLabels(app, labels) setAnnotations(app, annotations) return []*argoappv1.Application{ @@ -566,7 +566,7 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args } SetAppSpecOptions(flags, &app.Spec, &appOpts, source_index) - SetParameterOverrides(app, appOpts.Parameters) + SetParameterOverrides(app, appOpts.Parameters, source_index) mergeLabels(app, labels) setAnnotations(app, annotations) } From 75941d107eff1562383cace169a24b2209220edf Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Mon, 11 Mar 2024 17:26:54 -0400 Subject: [PATCH 09/16] do not allow overrides for applications with multiple sources Signed-off-by: ishitasequeira --- cmd/argocd/commands/admin/app.go | 2 +- cmd/argocd/commands/app.go | 30 ++++++++----------- cmd/util/app.go | 13 ++++---- docs/user-guide/commands/argocd_app_create.md | 1 - docs/user-guide/commands/argocd_app_edit.md | 1 - 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/cmd/argocd/commands/admin/app.go b/cmd/argocd/commands/admin/app.go index 1e70fd18c1dd9..096c92f9feb01 100644 --- a/cmd/argocd/commands/admin/app.go +++ b/cmd/argocd/commands/admin/app.go @@ -100,7 +100,7 @@ func NewGenAppSpecCommand() *cobra.Command { argocd admin app generate-spec kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane `, Run: func(c *cobra.Command, args []string) { - apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags(), nil) + apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags()) errors.CheckError(err) if len(apps) > 1 { errors.CheckError(fmt.Errorf("failed to generate spec, more than one application is not supported")) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 0b0026fe352ac..1af6b8e1190ed 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -118,7 +118,6 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. annotations []string setFinalizer bool appNamespace string - source_index int ) var command = &cobra.Command{ Use: "create APPNAME", @@ -150,7 +149,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. ctx := c.Context() argocdClient := headless.NewClientOrDie(clientOpts, c) - apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags(), &source_index) + apps, err := cmdutil.ConstructApps(fileURL, appName, labels, annotations, args, appOpts, c.Flags()) errors.CheckError(err) for _, app := range apps { @@ -208,7 +207,6 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. log.Fatal(err) } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace where the application will be created in") - command.Flags().IntVar(&source_index, "source-index", 0, "Index of the source from the list of sources of the app. Default index is 0.") cmdutil.AddAppFlags(command, &appOpts) return command } @@ -792,7 +790,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com os.Exit(1) } - setParameterOverrides(app, appOpts.Parameters) + setParameterOverrides(app, appOpts.Parameters, &source_index) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, Spec: &app.Spec, @@ -2468,11 +2466,11 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, // setParameterOverrides updates an existing or appends a new parameter override in the application // the app is assumed to be a helm app and is expected to be in the form: // param=value -func setParameterOverrides(app *argoappv1.Application, parameters []string) { +func setParameterOverrides(app *argoappv1.Application, parameters []string, index *int) { if len(parameters) == 0 { return } - source := app.Spec.GetSource() + source := app.Spec.GetSourcePtr(index) var sourceType argoappv1.ApplicationSourceType if st, _ := source.ExplicitType(); st != nil { sourceType = *st @@ -2782,7 +2780,6 @@ func NewApplicationTerminateOpCommand(clientOpts *argocdclient.ClientOptions) *c func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( appNamespace string - source_index int ) var command = &cobra.Command{ Use: "edit APPNAME", @@ -2804,15 +2801,6 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) - if app.Spec.HasMultipleSources() { - if source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) - } - if len(app.Spec.GetSources()) < source_index { - errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) - } - } - appData, err := json.Marshal(app.Spec) errors.CheckError(err) appData, err = yaml.JSONToYAML(appData) @@ -2830,7 +2818,10 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } var appOpts cmdutil.AppOptions - cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) + + if !app.Spec.HasMultipleSources() { + cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, nil) + } _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &appName, Spec: &updatedSpec, @@ -2845,7 +2836,6 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }, } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only edit application in namespace") - command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") return command } @@ -2934,8 +2924,12 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob if len(app.Spec.Sources) > 0 { appSource, _ := cmdutil.ConstructSource(&argoappv1.ApplicationSource{}, appOpts, c.Flags()) + // source_index would be the index at which you append the new source to spec.Sources + source_index := len(app.Spec.GetSources()) app.Spec.Sources = append(app.Spec.Sources, *appSource) + setParameterOverrides(app, appOpts.Parameters, &source_index) + _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, Spec: &app.Spec, diff --git a/cmd/util/app.go b/cmd/util/app.go index 91d6b77e9314c..6c7ebb34152dc 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -547,7 +547,7 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, }, nil } -func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet, source_index *int) ([]*argoappv1.Application, error) { +func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) { apps := make([]*argoappv1.Application, 0) // read uri err := readAppsFromURI(fileURL, &apps) @@ -565,19 +565,22 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args return nil, fmt.Errorf("app.Name is empty. --name argument can be used to provide app.Name") } - SetAppSpecOptions(flags, &app.Spec, &appOpts, source_index) - SetParameterOverrides(app, appOpts.Parameters, source_index) mergeLabels(app, labels) setAnnotations(app, annotations) + + if !app.Spec.HasMultipleSources() { + SetAppSpecOptions(flags, &app.Spec, &appOpts, nil) + SetParameterOverrides(app, appOpts.Parameters, nil) + } } return apps, nil } -func ConstructApps(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet, source_index *int) ([]*argoappv1.Application, error) { +func ConstructApps(fileURL, appName string, labels, annotations, args []string, appOpts AppOptions, flags *pflag.FlagSet) ([]*argoappv1.Application, error) { if fileURL == "-" { return constructAppsFromStdin() } else if fileURL != "" { - return constructAppsFromFileUrl(fileURL, appName, labels, annotations, args, appOpts, flags, source_index) + return constructAppsFromFileUrl(fileURL, appName, labels, annotations, args, appOpts, flags) } return constructAppsBaseOnName(appName, labels, annotations, args, appOpts, flags) diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 1133f5bf42d0f..275b65ce849b7 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -90,7 +90,6 @@ argocd app create APPNAME [flags] --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated --set-finalizer Sets deletion finalizer on the application, application resources will be cascaded on deletion - --source-index int Index of the source from the list of sources of the app. Default index is 0. --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index ce0c94bbcf545..e581677b79c12 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -13,7 +13,6 @@ argocd app edit APPNAME [flags] ``` -N, --app-namespace string Only edit application in namespace -h, --help help for edit - --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) ``` ### Options inherited from parent commands From 17b7d5b7dd9af1eb6c4d221e7559cf95bf2b40a3 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Mon, 11 Mar 2024 17:44:01 -0400 Subject: [PATCH 10/16] update tests Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 1 + cmd/util/app.go | 1 + cmd/util/app_test.go | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 1af6b8e1190ed..96005a8d919ea 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -2820,6 +2820,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co var appOpts cmdutil.AppOptions if !app.Spec.HasMultipleSources() { + // do not allow overrides for applications with multiple sources cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, nil) } _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ diff --git a/cmd/util/app.go b/cmd/util/app.go index 6c7ebb34152dc..b842c6a772d8d 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -569,6 +569,7 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args setAnnotations(app, annotations) if !app.Spec.HasMultipleSources() { + // do not allow overrides for applications with multiple sources SetAppSpecOptions(flags, &app.Spec, &appOpts, nil) SetParameterOverrides(app, appOpts.Parameters, nil) } diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index 0d2fbcbc74604..37941f828ca68 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -377,7 +377,7 @@ func TestConstructAppFromStdin(t *testing.T) { os.Stdin = file - apps, err := ConstructApps("-", "test", []string{}, []string{}, []string{}, AppOptions{}, nil, nil) + apps, err := ConstructApps("-", "test", []string{}, []string{}, []string{}, AppOptions{}, nil) if err := file.Close(); err != nil { log.Fatal(err) @@ -390,7 +390,7 @@ func TestConstructAppFromStdin(t *testing.T) { } func TestConstructBasedOnName(t *testing.T) { - apps, err := ConstructApps("", "test", []string{}, []string{}, []string{}, AppOptions{}, nil, nil) + apps, err := ConstructApps("", "test", []string{}, []string{}, []string{}, AppOptions{}, nil) assert.NoError(t, err) assert.Equal(t, 1, len(apps)) From 1d2cc378f555053f973929c1b725eb75942b859a Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Mon, 11 Mar 2024 19:48:51 -0400 Subject: [PATCH 11/16] remove create with override example Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 3 --- docs/user-guide/commands/argocd_app_create.md | 3 --- 2 files changed, 6 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 96005a8d919ea..c8d75a8828f5c 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -140,9 +140,6 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. # Create a MultiSource app argocd app create guestbook --file - # Create a MultiSource app while overriding repo of source at index 1 under spec.sources (Indexes start at 0) - argocd app create guestbook --file --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git - # Create a app using a custom tool: argocd app create kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane`, Run: func(c *cobra.Command, args []string) { diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 275b65ce849b7..5996a76041c90 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -29,9 +29,6 @@ argocd app create APPNAME [flags] # Create a MultiSource app argocd app create guestbook --file - # Create a MultiSource app while overriding repo of source at index 1 under spec.sources (Indexes start at 0) - argocd app create guestbook --file --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git - # Create a app using a custom tool: argocd app create kasane --repo https://github.com/argoproj/argocd-example-apps.git --path plugins/kasane --dest-namespace default --dest-server https://kubernetes.default.svc --config-management-plugin kasane ``` From d660bdeb9af39986b3061e758bd0c55e643c2338 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Tue, 12 Mar 2024 14:35:24 -0400 Subject: [PATCH 12/16] address comments Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 66 ++++++++++--------- cmd/util/app.go | 18 ++--- cmd/util/app_test.go | 16 ++--- docs/user-guide/commands/argocd_app_create.md | 2 +- .../commands/argocd_app_remove-source.md | 2 +- docs/user-guide/commands/argocd_app_set.md | 2 +- docs/user-guide/commands/argocd_app_unset.md | 2 +- pkg/apis/application/v1alpha1/types.go | 6 +- server/repository/repository_test.go | 4 +- util/notification/expression/repo/repo.go | 2 +- 10 files changed, 61 insertions(+), 59 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index c8d75a8828f5c..baf220da4aad0 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -137,7 +137,7 @@ func NewApplicationCreateCommand(clientOpts *argocdclient.ClientOptions) *cobra. # Create a Kustomize app argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 - # Create a MultiSource app + # Create a MultiSource app while yaml file contains an application with multiple sources argocd app create guestbook --file # Create a app using a custom tool: @@ -732,7 +732,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com var ( appOpts cmdutil.AppOptions appNamespace string - source_index int + sourceIndex int ) var command = &cobra.Command{ Use: "set APPNAME", @@ -772,22 +772,24 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com errors.CheckError(err) if app.Spec.HasMultipleSources() { - if source_index < 0 { + if sourceIndex <= 0 { errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) } - if len(app.Spec.GetSources()) < source_index { + if len(app.Spec.GetSources()) < sourceIndex { errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) } } - visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) + // sourceIndex startes with 1, thus, it needs to be decreased by 1 to find the correct index in the list of sources + sourceIndex = sourceIndex - 1 + visited := cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourceIndex) if visited == 0 { log.Error("Please set at least one option to update") c.HelpFunc()(c, args) os.Exit(1) } - setParameterOverrides(app, appOpts.Parameters, &source_index) + setParameterOverrides(app, appOpts.Parameters, sourceIndex) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, Spec: &app.Spec, @@ -797,7 +799,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com errors.CheckError(err) }, } - command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Default index is -1.") cmdutil.AddAppFlags(command, &appOpts) command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in namespace") return command @@ -834,7 +836,7 @@ func (o *unsetOpts) KustomizeIsZero() bool { // NewApplicationUnsetCommand returns a new instance of an `argocd app unset` command func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - source_index int + sourceIndex int ) appOpts := cmdutil.AppOptions{} opts := unsetOpts{} @@ -869,14 +871,15 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C errors.CheckError(err) if app.Spec.HasMultipleSources() { - if source_index < 0 { - errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) + if sourceIndex <= 0 { + errors.CheckError(fmt.Errorf("Source index should be specified and greater than 0 for applications with multiple sources")) } - if len(app.Spec.GetSources()) < source_index { + if len(app.Spec.GetSources()) < sourceIndex { errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) } } - source := app.Spec.GetSourcePtr(&source_index) + + source := app.Spec.GetSourcePtr(sourceIndex) updated, nothingToUnset := unset(source, opts) if nothingToUnset { @@ -887,7 +890,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C return } - cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, &source_index) + cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, sourceIndex) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, Spec: &app.Spec, @@ -911,12 +914,11 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)") command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials") command.Flags().BoolVar(&opts.ref, "ref", false, "Unset ref on the source") - command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Default index is 0.") + command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Default index is -1.") return command } func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, nothingToUnset bool) { - needToUnsetRef := false if opts.ref && source.Ref != "" { source.Ref = "" @@ -926,7 +928,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n if source.Kustomize != nil { if opts.KustomizeIsZero() { - return updated, !needToUnsetRef && true + return updated, !needToUnsetRef } if opts.namePrefix && source.Kustomize.NamePrefix != "" { @@ -976,7 +978,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n } if source.Helm != nil { if len(opts.parameters) == 0 && len(opts.valuesFiles) == 0 && !opts.valuesLiteral && !opts.ignoreMissingValueFiles && !opts.passCredentials { - return updated, !needToUnsetRef && true + return updated, !needToUnsetRef } for _, paramStr := range opts.parameters { helmParams := source.Helm.Parameters @@ -1016,7 +1018,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n if source.Plugin != nil { if len(opts.pluginEnvs) == 0 { - return false, !needToUnsetRef && true + return false, !needToUnsetRef } for _, env := range opts.pluginEnvs { err := source.Plugin.RemoveEnvEntry(env) @@ -1025,7 +1027,7 @@ func unset(source *argoappv1.ApplicationSource, opts unsetOpts) (updated bool, n } } } - return updated, !needToUnsetRef && false + return updated, false } // targetObjects deserializes the list of target states into unstructured objects @@ -2463,7 +2465,7 @@ func waitOnApplicationStatus(ctx context.Context, acdClient argocdclient.Client, // setParameterOverrides updates an existing or appends a new parameter override in the application // the app is assumed to be a helm app and is expected to be in the form: // param=value -func setParameterOverrides(app *argoappv1.Application, parameters []string, index *int) { +func setParameterOverrides(app *argoappv1.Application, parameters []string, index int) { if len(parameters) == 0 { return } @@ -2816,9 +2818,9 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co var appOpts cmdutil.AppOptions + // do not allow overrides for applications with multiple sources if !app.Spec.HasMultipleSources() { - // do not allow overrides for applications with multiple sources - cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, nil) + cmdutil.SetAppSpecOptions(c.Flags(), &app.Spec, &appOpts, 0) } _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &appName, @@ -2922,11 +2924,11 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob if len(app.Spec.Sources) > 0 { appSource, _ := cmdutil.ConstructSource(&argoappv1.ApplicationSource{}, appOpts, c.Flags()) - // source_index would be the index at which you append the new source to spec.Sources - source_index := len(app.Spec.GetSources()) + // sourceIndex is the index at which new source will be appended to spec.Sources + sourceIndex := len(app.Spec.GetSources()) app.Spec.Sources = append(app.Spec.Sources, *appSource) - setParameterOverrides(app, appOpts.Parameters, &source_index) + setParameterOverrides(app, appOpts.Parameters, sourceIndex) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, @@ -2950,7 +2952,7 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob // NewApplicationRemoveSourceCommand returns a new instance of an `argocd app remove-source` command func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - source_index int + sourceIndex int appNamespace string ) command := &cobra.Command{ @@ -2966,8 +2968,8 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * os.Exit(1) } - if source_index < 0 { - errors.CheckError(fmt.Errorf("Index value of source cannot be less than 0")) + if sourceIndex <= 0 { + errors.CheckError(fmt.Errorf("Index value of source must be greater than 0")) } argocdClient := headless.NewClientOrDie(clientOpts, c) @@ -2991,11 +2993,11 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * errors.CheckError(fmt.Errorf("Cannot remove the only source remaining in the app")) } - if len(app.Spec.GetSources()) <= source_index { - errors.CheckError(fmt.Errorf("Application does not have source at %d\n", source_index)) + if len(app.Spec.GetSources()) < sourceIndex { + errors.CheckError(fmt.Errorf("Application does not have source at %d\n", sourceIndex)) } - app.Spec.Sources = append(app.Spec.Sources[:source_index], app.Spec.Sources[source_index+1:]...) + app.Spec.Sources = append(app.Spec.Sources[:sourceIndex-1], app.Spec.Sources[sourceIndex:]...) _, err = appIf.UpdateSpec(ctx, &application.ApplicationUpdateSpecRequest{ Name: &app.Name, @@ -3008,6 +3010,6 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * }, } command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace of the target application where the source will be appended") - command.Flags().IntVar(&source_index, "source-index", -1, "Index of the source from the list of sources of the app. Index starts from 0.") + command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Index starts from 1.") return command } diff --git a/cmd/util/app.go b/cmd/util/app.go index b842c6a772d8d..5e378a93d8475 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -139,7 +139,7 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().StringVar(&opts.ref, "ref", "", "Ref is reference to another source within sources field") } -func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, index *int) int { +func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, index int) int { visited := 0 if flags == nil { return visited @@ -150,8 +150,8 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap } source, visited = ConstructSource(source, *appOpts, flags) if spec.HasMultipleSources() { - if index != nil { - spec.Sources[*index] = *source + if index > 0 { + spec.Sources[index-1] = *source } else { spec.Sources = append(spec.Sources, *source) } @@ -422,7 +422,7 @@ func setJsonnetOptLibs(src *argoappv1.ApplicationSource, libs []string) { // SetParameterOverrides updates an existing or appends a new parameter override in the application // The app is assumed to be a helm app and is expected to be in the form: // param=value -func SetParameterOverrides(app *argoappv1.Application, parameters []string, index *int) { +func SetParameterOverrides(app *argoappv1.Application, parameters []string, index int) { if len(parameters) == 0 { return } @@ -538,8 +538,8 @@ func constructAppsBaseOnName(appName string, labels, annotations, args []string, Source: &argoappv1.ApplicationSource{}, }, } - SetAppSpecOptions(flags, &app.Spec, &appOpts, nil) - SetParameterOverrides(app, appOpts.Parameters, nil) + SetAppSpecOptions(flags, &app.Spec, &appOpts, 0) + SetParameterOverrides(app, appOpts.Parameters, 0) mergeLabels(app, labels) setAnnotations(app, annotations) return []*argoappv1.Application{ @@ -568,10 +568,10 @@ func constructAppsFromFileUrl(fileURL, appName string, labels, annotations, args mergeLabels(app, labels) setAnnotations(app, annotations) + // do not allow overrides for applications with multiple sources if !app.Spec.HasMultipleSources() { - // do not allow overrides for applications with multiple sources - SetAppSpecOptions(flags, &app.Spec, &appOpts, nil) - SetParameterOverrides(app, appOpts.Parameters, nil) + SetAppSpecOptions(flags, &app.Spec, &appOpts, 0) + SetParameterOverrides(app, appOpts.Parameters, 0) } } return apps, nil diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index 37941f828ca68..e399894e44456 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -170,11 +170,11 @@ func (f *appOptionsFixture) SetFlag(key, value string) error { if err != nil { return err } - _ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options, nil) + _ = SetAppSpecOptions(f.command.Flags(), f.spec, f.options, 0) return err } -func (f *appOptionsFixture) SetFlagWithSourceIndex(key, value string, index *int) error { +func (f *appOptionsFixture) SetFlagWithSourceIndex(key, value string, index int) error { err := f.command.Flags().Set(key, value) if err != nil { return err @@ -254,22 +254,22 @@ func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) { index1 := 0 index2 := 1 t.Run("SyncPolicy", func(t *testing.T) { - assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automated", &index1)) + assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automated", index1)) assert.NotNil(t, f.spec.SyncPolicy.Automated) f.spec.SyncPolicy = nil - assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automatic", &index1)) + assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automatic", index1)) assert.NotNil(t, f.spec.SyncPolicy.Automated) }) t.Run("Kustomize", func(t *testing.T) { - assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=2", &index1)) + assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=2", index1)) assert.Equal(t, f.spec.Sources[index1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}}) - assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=4", &index2)) + assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=4", index2)) assert.Equal(t, f.spec.Sources[index2].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(4)}}) }) t.Run("Helm", func(t *testing.T) { - assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", &index1)) - assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v3", &index2)) + assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", index1)) + assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v3", index2)) assert.Equal(t, len(f.spec.GetSources()), 2) assert.Equal(t, f.spec.GetSources()[index1].Helm.Version, "v2") assert.Equal(t, f.spec.GetSources()[index2].Helm.Version, "v3") diff --git a/docs/user-guide/commands/argocd_app_create.md b/docs/user-guide/commands/argocd_app_create.md index 5996a76041c90..fb147b8e4aa9f 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -26,7 +26,7 @@ argocd app create APPNAME [flags] # Create a Kustomize app argocd app create kustomize-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path kustomize-guestbook --dest-namespace default --dest-server https://kubernetes.default.svc --kustomize-image gcr.io/heptio-images/ks-guestbook-demo:0.1 - # Create a MultiSource app + # Create a MultiSource app while yaml file contains an application with multiple sources argocd app create guestbook --file # Create a app using a custom tool: diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index b7bd0df09823d..ac95618623608 100644 --- a/docs/user-guide/commands/argocd_app_remove-source.md +++ b/docs/user-guide/commands/argocd_app_remove-source.md @@ -20,7 +20,7 @@ argocd app remove-source APPNAME [flags] ``` -N, --app-namespace string Namespace of the target application where the source will be appended -h, --help help for remove-source - --source-index int Index of the source from the list of sources of the app. Index starts from 0. (default -1) + --source-index int Index of the source from the list of sources of the app. Index starts from 1. (default -1) ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index a5e45eb034de4..363b1c5cf4f20 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -79,7 +79,7 @@ argocd app set APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated - --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) + --source-index int Index of the source from the list of sources of the app. Default index is -1. (default -1) --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 31c7ee4d834b8..938ea35c729e5 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -40,7 +40,7 @@ argocd app unset APPNAME parameters [flags] --pass-credentials Unset passCredentials --plugin-env stringArray Unset plugin env variables (e.g --plugin-env name) --ref Unset ref on the source - --source-index int Index of the source from the list of sources of the app. Default index is 0. (default -1) + --source-index int Index of the source from the list of sources of the app. Default index is -1. (default -1) --values stringArray Unset one or more Helm values files --values-literal Unset literal Helm values block ``` diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index d4f054b6285ad..abd2735710e72 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -230,11 +230,11 @@ func (a *ApplicationSpec) HasMultipleSources() bool { return a.Sources != nil && len(a.Sources) > 0 } -func (a *ApplicationSpec) GetSourcePtr(index *int) *ApplicationSource { +func (a *ApplicationSpec) GetSourcePtr(index int) *ApplicationSource { // if Application has multiple sources, return the first source in sources if a.HasMultipleSources() { - if index != nil { - return &a.Sources[*index] + if index > 0 { + return &a.Sources[index-1] } return &a.Sources[0] } diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index 95df1f8c7b67c..55bf7ab7220ac 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -654,7 +654,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ - Source: guestbookApp.Spec.GetSourcePtr(nil), + Source: guestbookApp.Spec.GetSourcePtr(0), AppName: "guestbook", AppProject: "default", }) @@ -752,7 +752,7 @@ func TestRepositoryServerGetAppDetails(t *testing.T) { s := NewServer(&repoServerClientset, db, enforcer, newFixtures().Cache, appLister, projLister, testNamespace, settingsMgr) resp, err := s.GetAppDetails(context.TODO(), &repository.RepoAppDetailsQuery{ - Source: guestbookApp.Spec.GetSourcePtr(nil), + Source: guestbookApp.Spec.GetSourcePtr(0), AppName: "guestbook", AppProject: "mismatch", }) diff --git a/util/notification/expression/repo/repo.go b/util/notification/expression/repo/repo.go index d1ee5b2738fa7..8456774f0869a 100644 --- a/util/notification/expression/repo/repo.go +++ b/util/notification/expression/repo/repo.go @@ -33,7 +33,7 @@ func getApplicationSourceAndName(obj *unstructured.Unstructured) (*v1alpha1.Appl if err != nil { return nil, "", err } - return application.Spec.GetSourcePtr(nil), application.GetName(), nil + return application.Spec.GetSourcePtr(0), application.GetName(), nil } func getAppDetails(app *unstructured.Unstructured, argocdService service.Service) (*shared.AppDetail, error) { From a0be16e96e8b42bae698aff30a6276906a023a22 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Tue, 12 Mar 2024 14:47:58 -0400 Subject: [PATCH 13/16] update tests Signed-off-by: ishitasequeira --- cmd/util/app_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index e399894e44456..eee996f12280e 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -251,8 +251,8 @@ func newMultiSourceAppOptionsFixture() *appOptionsFixture { func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) { f := newMultiSourceAppOptionsFixture() - index1 := 0 - index2 := 1 + index1 := 1 + index2 := 2 t.Run("SyncPolicy", func(t *testing.T) { assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automated", index1)) assert.NotNil(t, f.spec.SyncPolicy.Automated) @@ -263,16 +263,16 @@ func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) { }) t.Run("Kustomize", func(t *testing.T) { assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=2", index1)) - assert.Equal(t, f.spec.Sources[index1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}}) + assert.Equal(t, f.spec.Sources[index1-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}}) assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=4", index2)) - assert.Equal(t, f.spec.Sources[index2].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(4)}}) + assert.Equal(t, f.spec.Sources[index2-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(4)}}) }) t.Run("Helm", func(t *testing.T) { assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", index1)) assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v3", index2)) assert.Equal(t, len(f.spec.GetSources()), 2) - assert.Equal(t, f.spec.GetSources()[index1].Helm.Version, "v2") - assert.Equal(t, f.spec.GetSources()[index2].Helm.Version, "v3") + assert.Equal(t, f.spec.GetSources()[index1-1].Helm.Version, "v2") + assert.Equal(t, f.spec.GetSources()[index2-1].Helm.Version, "v3") }) } From ed5263c369614beb9b721fd4e8d4d5ba1110b149 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Tue, 12 Mar 2024 15:45:22 -0400 Subject: [PATCH 14/16] update examples in docs Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 4 ++-- docs/user-guide/commands/argocd_app_set.md | 2 +- docs/user-guide/commands/argocd_app_unset.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index baf220da4aad0..869a7be6b9aa3 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -750,7 +750,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Set and override application parameters with a parameter file argocd app set my-app --parameter-file path/to/parameter-file.yaml - # Set and override application parameters for a source at index 1 under spec.sources of app my-app (Indexes start at 0) + # Set and override application parameters for a source at index 1 under spec.sources of app my-app argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git # Set application parameters and specify the namespace @@ -850,7 +850,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C # Unset kustomize override suffix argocd app unset my-app --namesuffix - # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app (Indexes start at 0) + # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app argocd app unset my-app --source-index 1 --namesuffix # Unset parameter override diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 363b1c5cf4f20..637a600aa4c24 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -23,7 +23,7 @@ argocd app set APPNAME [flags] # Set and override application parameters with a parameter file argocd app set my-app --parameter-file path/to/parameter-file.yaml - # Set and override application parameters for a source at index 1 under spec.sources of app my-app (Indexes start at 0) + # Set and override application parameters for a source at index 1 under spec.sources of app my-app argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git # Set application parameters and specify the namespace diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 938ea35c729e5..2a6f17b15e35e 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -17,7 +17,7 @@ argocd app unset APPNAME parameters [flags] # Unset kustomize override suffix argocd app unset my-app --namesuffix - # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app (Indexes start at 0) + # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app argocd app unset my-app --source-index 1 --namesuffix # Unset parameter override From 2981def310ed14eb70c358fb1b010c5933839b72 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Tue, 12 Mar 2024 16:16:24 -0400 Subject: [PATCH 15/16] update logs Signed-off-by: ishitasequeira --- 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 869a7be6b9aa3..3267ae6a8b032 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -773,7 +773,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com if app.Spec.HasMultipleSources() { if sourceIndex <= 0 { - errors.CheckError(fmt.Errorf("Source index should be specified and greater than or equal to 0 for applications with multiple sources")) + errors.CheckError(fmt.Errorf("Source index should be specified and greater than 0 for applications with multiple sources")) } if len(app.Spec.GetSources()) < sourceIndex { errors.CheckError(fmt.Errorf("Source index should be less than the number of sources in the application")) From 3520132a8bf2e0cabc570e2957b9b8ec42252e42 Mon Sep 17 00:00:00 2001 From: ishitasequeira Date: Fri, 15 Mar 2024 11:45:50 -0400 Subject: [PATCH 16/16] Add test and update docs Signed-off-by: ishitasequeira --- cmd/argocd/commands/app.go | 12 ++++++------ cmd/util/app.go | 4 +++- cmd/util/app_test.go | 6 ++++++ docs/user-guide/commands/argocd_app.md | 2 +- docs/user-guide/commands/argocd_app_remove-source.md | 4 ++-- docs/user-guide/commands/argocd_app_set.md | 4 ++-- docs/user-guide/commands/argocd_app_unset.md | 4 ++-- 7 files changed, 22 insertions(+), 14 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 3267ae6a8b032..9f2a8295b60a5 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -750,7 +750,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Set and override application parameters with a parameter file argocd app set my-app --parameter-file path/to/parameter-file.yaml - # Set and override application parameters for a source at index 1 under spec.sources of app my-app + # Set and override application parameters for a source at index 1 under spec.sources of app my-app. source-index starts at 1. argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git # Set application parameters and specify the namespace @@ -799,7 +799,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com errors.CheckError(err) }, } - command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Default index is -1.") + command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Index starts at 1.") cmdutil.AddAppFlags(command, &appOpts) command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in namespace") return command @@ -850,7 +850,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C # Unset kustomize override suffix argocd app unset my-app --namesuffix - # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app + # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app. source-index starts at 1. argocd app unset my-app --source-index 1 --namesuffix # Unset parameter override @@ -914,7 +914,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C command.Flags().StringArrayVar(&opts.pluginEnvs, "plugin-env", []string{}, "Unset plugin env variables (e.g --plugin-env name)") command.Flags().BoolVar(&opts.passCredentials, "pass-credentials", false, "Unset passCredentials") command.Flags().BoolVar(&opts.ref, "ref", false, "Unset ref on the source") - command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Default index is -1.") + command.Flags().IntVar(&sourceIndex, "source-index", -1, "Index of the source from the list of sources of the app. Index starts at 1.") return command } @@ -2957,8 +2957,8 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * ) command := &cobra.Command{ Use: "remove-source APPNAME", - Short: "Remove a source from multiple sources application. Index starts with 0.", - Example: ` # Remove the source at index 1 from application's sources + Short: "Remove a source from multiple sources application. Index starts with 1. Default value is -1.", + Example: ` # Remove the source at index 1 from application's sources. Index starts at 1. argocd app remove-source myapplication --source-index 1`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() diff --git a/cmd/util/app.go b/cmd/util/app.go index 5e378a93d8475..b1693689004c4 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -150,7 +150,9 @@ func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, ap } source, visited = ConstructSource(source, *appOpts, flags) if spec.HasMultipleSources() { - if index > 0 { + if index == 0 { + spec.Sources[index] = *source + } else if index > 0 { spec.Sources[index-1] = *source } else { spec.Sources = append(spec.Sources, *source) diff --git a/cmd/util/app_test.go b/cmd/util/app_test.go index eee996f12280e..5e95eeb388634 100644 --- a/cmd/util/app_test.go +++ b/cmd/util/app_test.go @@ -251,6 +251,7 @@ func newMultiSourceAppOptionsFixture() *appOptionsFixture { func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) { f := newMultiSourceAppOptionsFixture() + index := 0 index1 := 1 index2 := 2 t.Run("SyncPolicy", func(t *testing.T) { @@ -261,6 +262,11 @@ func Test_setAppSpecOptionsMultiSourceApp(t *testing.T) { assert.NoError(t, f.SetFlagWithSourceIndex("sync-policy", "automatic", index1)) assert.NotNil(t, f.spec.SyncPolicy.Automated) }) + t.Run("Helm - Index 0", func(t *testing.T) { + assert.NoError(t, f.SetFlagWithSourceIndex("helm-version", "v2", index)) + assert.Equal(t, len(f.spec.GetSources()), 2) + assert.Equal(t, f.spec.GetSources()[index].Helm.Version, "v2") + }) t.Run("Kustomize", func(t *testing.T) { assert.NoError(t, f.SetFlagWithSourceIndex("kustomize-replica", "my-deployment=2", index1)) assert.Equal(t, f.spec.Sources[index1-1].Kustomize.Replicas, v1alpha1.KustomizeReplicas{{Name: "my-deployment", Count: intstr.FromInt(2)}}) diff --git a/docs/user-guide/commands/argocd_app.md b/docs/user-guide/commands/argocd_app.md index ff8fe0d4a01b6..a5878502ce5c7 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -91,7 +91,7 @@ argocd app [flags] * [argocd app manifests](argocd_app_manifests.md) - Print manifests of an application * [argocd app patch](argocd_app_patch.md) - Patch application * [argocd app patch-resource](argocd_app_patch-resource.md) - Patch resource in an application -* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. Index starts with 0. +* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. Index starts with 1. Default value is -1. * [argocd app resources](argocd_app_resources.md) - List resource of application * [argocd app rollback](argocd_app_rollback.md) - Rollback application to a previous deployed version by History ID, omitted will Rollback to the previous version * [argocd app set](argocd_app_set.md) - Set application parameters diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index ac95618623608..b9f29d8c6eb45 100644 --- a/docs/user-guide/commands/argocd_app_remove-source.md +++ b/docs/user-guide/commands/argocd_app_remove-source.md @@ -2,7 +2,7 @@ ## argocd app remove-source -Remove a source from multiple sources application. Index starts with 0. +Remove a source from multiple sources application. Index starts with 1. Default value is -1. ``` argocd app remove-source APPNAME [flags] @@ -11,7 +11,7 @@ argocd app remove-source APPNAME [flags] ### Examples ``` - # Remove the source at index 1 from application's sources + # Remove the source at index 1 from application's sources. Index starts at 1. argocd app remove-source myapplication --source-index 1 ``` diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 637a600aa4c24..97288ad775345 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -23,7 +23,7 @@ argocd app set APPNAME [flags] # Set and override application parameters with a parameter file argocd app set my-app --parameter-file path/to/parameter-file.yaml - # Set and override application parameters for a source at index 1 under spec.sources of app my-app + # Set and override application parameters for a source at index 1 under spec.sources of app my-app. source-index starts at 1. argocd app set my-app --source-index 1 --repo https://github.com/argoproj/argocd-example-apps.git # Set application parameters and specify the namespace @@ -79,7 +79,7 @@ argocd app set APPNAME [flags] --revision string The tracking source branch, tag, commit or Helm chart version the application will sync to --revision-history-limit int How many items to keep in revision history (default 10) --self-heal Set self healing when sync is automated - --source-index int Index of the source from the list of sources of the app. Default index is -1. (default -1) + --source-index int Index of the source from the list of sources of the app. Index starts at 1. (default -1) --sync-option Prune=false Add or remove a sync option, e.g add Prune=false. Remove using `!` prefix, e.g. `!Prune=false` --sync-policy string Set the sync policy (one of: manual (aliases of manual: none), automated (aliases of automated: auto, automatic)) --sync-retry-backoff-duration duration Sync retry backoff base duration. Input needs to be a duration (e.g. 2m, 1h) (default 5s) diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 2a6f17b15e35e..0c3bf25d7fa91 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -17,7 +17,7 @@ argocd app unset APPNAME parameters [flags] # Unset kustomize override suffix argocd app unset my-app --namesuffix - # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app + # Unset kustomize override suffix for source at index 1 under spec.sources of app my-app. source-index starts at 1. argocd app unset my-app --source-index 1 --namesuffix # Unset parameter override @@ -40,7 +40,7 @@ argocd app unset APPNAME parameters [flags] --pass-credentials Unset passCredentials --plugin-env stringArray Unset plugin env variables (e.g --plugin-env name) --ref Unset ref on the source - --source-index int Index of the source from the list of sources of the app. Default index is -1. (default -1) + --source-index int Index of the source from the list of sources of the app. Index starts at 1. (default -1) --values stringArray Unset one or more Helm values files --values-literal Unset literal Helm values block ```