From edd7b6711736a790ebac032a28fad1214733e63a Mon Sep 17 00:00:00 2001 From: ABBOUD Moncef Date: Mon, 18 Nov 2024 15:23:49 -0600 Subject: [PATCH] feat(app): Add optional 'name' to Source object (#20470) Signed-off-by: cef Co-authored-by: Alexandre Gaudreault --- assets/swagger.json | 4 + cmd/argocd/commands/app.go | 190 ++++++++++++++++-- cmd/util/app.go | 4 + .../argocd_admin_app_generate-spec.md | 1 + docs/user-guide/commands/argocd_app.md | 2 +- .../commands/argocd_app_add-source.md | 3 +- docs/user-guide/commands/argocd_app_create.md | 1 + docs/user-guide/commands/argocd_app_diff.md | 1 + docs/user-guide/commands/argocd_app_get.md | 4 + .../commands/argocd_app_manifests.md | 4 + .../commands/argocd_app_remove-source.md | 6 +- docs/user-guide/commands/argocd_app_set.md | 4 + docs/user-guide/commands/argocd_app_sync.md | 4 +- docs/user-guide/commands/argocd_app_unset.md | 3 + manifests/core-install.yaml | 146 ++++++++++++++ manifests/crds/application-crd.yaml | 50 +++++ manifests/crds/applicationset-crd.yaml | 96 +++++++++ manifests/ha/install.yaml | 146 ++++++++++++++ manifests/install.yaml | 146 ++++++++++++++ pkg/apis/application/v1alpha1/generated.proto | 3 + pkg/apis/application/v1alpha1/types.go | 2 + server/application/application.go | 12 ++ test/e2e/app_multiple_sources_test.go | 128 ++++++++++++ .../application-parameters.tsx | 8 +- .../application-parameters/source-panel.tsx | 6 + ui/src/app/shared/models.ts | 2 + 26 files changed, 958 insertions(+), 18 deletions(-) diff --git a/assets/swagger.json b/assets/swagger.json index bd25c617636a33..6b0e8e69cede19 100644 --- a/assets/swagger.json +++ b/assets/swagger.json @@ -6529,6 +6529,10 @@ "kustomize": { "$ref": "#/definitions/v1alpha1ApplicationSourceKustomize" }, + "name": { + "description": "Name is used to refer to a source and is displayed in the UI. It is used in multi-source Applications.", + "type": "string" + }, "path": { "description": "Path is a directory path within the Git repository, and is only valid for applications sourced from Git.", "type": "string" diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index c48382e23feded..6f517cde2920ec 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -317,6 +317,17 @@ func printHeader(acdClient argocdclient.Client, app *argoappv1.Application, ctx } } +// getSourceNameToPositionMap returns a map of source name to position +func getSourceNameToPositionMap(app *argoappv1.Application) map[string]int64 { + sourceNameToPosition := make(map[string]int64) + for i, s := range app.Spec.Sources { + if s.Name != "" { + sourceNameToPosition[s.Name] = int64(i + 1) + } + } + return sourceNameToPosition +} + // NewApplicationGetCommand returns a new instance of an `argocd app get` command func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( @@ -327,6 +338,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com showOperation bool appNamespace string sourcePosition int + sourceName string ) command := &cobra.Command{ Use: "get APPNAME", @@ -350,6 +362,9 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Show application parameters and overrides for a source at position 1 under spec.sources of app my-app argocd app get my-app --show-params --source-position 1 + # Show application parameters and overrides for a source named "test" + argocd app get my-app --show-params --source-name test + # Refresh application data when retrieving argocd app get my-app --refresh @@ -382,6 +397,19 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com }) errors.CheckError(err) + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + // check for source position if --show-params is set if app.Spec.HasMultipleSources() && showParams { if sourcePosition <= 0 { @@ -437,6 +465,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com command.Flags().BoolVar(&hardRefresh, "hard-refresh", false, "Refresh application data as well as target manifests cache") command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only get application from namespace") command.Flags().IntVar(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") + command.Flags().StringVar(&sourceName, "source-name", "", "Name of the source from the list of sources of the app.") return command } @@ -766,6 +795,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com appOpts cmdutil.AppOptions appNamespace string sourcePosition int + sourceName string ) command := &cobra.Command{ Use: "set APPNAME", @@ -780,6 +810,9 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com # Set and override application parameters for a source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app set my-app --source-position 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Set and override application parameters for a source named "test" under spec.sources of app my-app. + argocd app set my-app --source-name test --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 `), @@ -798,6 +831,20 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) + sourceName = appOpts.SourceName + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + if app.Spec.HasMultipleSources() { if sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) @@ -861,6 +908,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 sourcePosition int + var sourceName string appOpts := cmdutil.AppOptions{} opts := unsetOpts{} var appNamespace string @@ -876,6 +924,9 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C # Unset kustomize override suffix for source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app unset my-app --source-position 1 --namesuffix + # Unset kustomize override suffix for source named "test" under spec.sources of app my-app. + argocd app unset my-app --source-name test --namesuffix + # Unset parameter override argocd app unset my-app -p COMPONENT=PARAM`, @@ -893,6 +944,20 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) errors.CheckError(err) + sourceName = appOpts.SourceName + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + if app.Spec.HasMultipleSources() { if sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Source position should be specified and must be greater than 0 for applications with multiple sources")) @@ -1161,6 +1226,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co appNamespace string revisions []string sourcePositions []int64 + sourceNames []string ignoreNormalizerOpts normalizers.IgnoreNormalizerOpts ) shortDesc := "Perform a diff against the target and live state." @@ -1176,8 +1242,16 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co os.Exit(2) } - if len(revisions) != len(sourcePositions) { - errors.CheckError(fmt.Errorf("While using revisions and source-positions, length of values for both flags should be same.")) + if len(sourceNames) > 0 && len(sourcePositions) > 0 { + errors.CheckError(fmt.Errorf("Only one of source-positions and source-names can be specified.")) + } + + if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-positions, length of values for both flags should be same.")) + } + + if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-names, length of values for both flags should be same.")) } clientset := headless.NewClientOrDie(clientOpts, c) @@ -1191,6 +1265,18 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) errors.CheckError(err) + if len(sourceNames) > 0 { + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + resources, err := appIf.ManagedResources(ctx, &application.ResourcesQuery{ApplicationName: &appName, AppNamespace: &appNs}) errors.CheckError(err) conn, settingsIf := clientset.NewSettingsClientOrDie() @@ -1271,6 +1357,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only render the difference in namespace") command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions") command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.") + command.Flags().StringArrayVar(&sourceNames, "source-names", []string{}, "List of source names. Default is an empty array.") command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout") return command } @@ -1835,6 +1922,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co revision string revisions []string sourcePositions []int64 + sourceNames []string resources []string labels []string selector string @@ -1878,7 +1966,8 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)' # Sync a multi-source application for specific revision of specific sources - argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-names my-chart --revisions 0.0.2 --source-names my-values # Sync a specific resource # Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME @@ -1903,10 +1992,22 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co log.Fatal("Cannot use --revisions and --source-positions options when 0 or more than 1 application names are passed as argument(s)") } - if len(revisions) != len(sourcePositions) { + if len(args) != 1 && (len(revisions) > 0 || len(sourceNames) > 0) { + log.Fatal("Cannot use --revisions and --source-names options when 0 or more than 1 application names are passed as argument(s)") + } + + if len(sourceNames) > 0 && len(sourcePositions) > 0 { + log.Fatal("Only one of source-positions and source-names can be specified.") + } + + if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { log.Fatal("While using --revisions and --source-positions, length of values for both flags should be same.") } + if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { + log.Fatal("While using --revisions and --source-names, length of values for both flags should be same.") + } + for _, pos := range sourcePositions { if pos <= 0 { log.Fatal("source-position cannot be less than or equal to 0, Counting starts at 1") @@ -1920,6 +2021,22 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co selectedLabels, err := label.Parse(labels) errors.CheckError(err) + if len(args) == 1 && len(sourceNames) > 0 { + appName, _ := argo.ParseFromQualifiedName(args[0], appNamespace) + app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName}) + errors.CheckError(err) + + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + appNames := args if selector != "" || len(projects) > 0 { list, err := appIf.List(ctx, &application.ApplicationQuery{ @@ -2178,6 +2295,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().DurationVar(&ignoreNormalizerOpts.JQExecutionTimeout, "ignore-normalizer-jq-execution-timeout", normalizers.DefaultJQExecutionTimeout, "Set ignore normalizer JQ execution timeout") command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for source position in source-positions") command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.") + command.Flags().StringArrayVar(&sourceNames, "source-names", []string{}, "List of source names. Default is an empty array.") return command } @@ -2818,6 +2936,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob revision string revisions []string sourcePositions []int64 + sourceNames []string local string localRepoRoot string ) @@ -2831,6 +2950,9 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob # Get manifests for an application at a specific revision argocd app manifests my-app --revision 0.0.1 + # Get manifests for a multi-source application at specific revisions for specific sources + argocd app manifests my-app --revisions 0.0.1 --source-names src-base --revisions 0.0.2 --source-names src-values + # Get manifests for a multi-source application at specific revisions for specific sources argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 `), @@ -2842,8 +2964,16 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob os.Exit(1) } - if len(revisions) != len(sourcePositions) { - errors.CheckError(fmt.Errorf("While using revisions and source-positions, length of values for both flags should be same.")) + if len(sourceNames) > 0 && len(sourcePositions) > 0 { + errors.CheckError(fmt.Errorf("Only one of source-positions and source-names can be specified.")) + } + + if len(sourcePositions) > 0 && len(revisions) != len(sourcePositions) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-positions, length of values for both flags should be same.")) + } + + if len(sourceNames) > 0 && len(revisions) != len(sourceNames) { + errors.CheckError(fmt.Errorf("While using --revisions and --source-names, length of values for both flags should be same.")) } for _, pos := range sourcePositions { @@ -2857,6 +2987,24 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob conn, appIf := clientset.NewApplicationClientOrDie() defer argoio.Close(conn) + app, err := appIf.Get(context.Background(), &application.ApplicationQuery{ + Name: &appName, + AppNamespace: &appNs, + }) + errors.CheckError(err) + + if len(sourceNames) > 0 { + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatalf("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + resources, err := appIf.ManagedResources(ctx, &application.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, @@ -2867,9 +3015,6 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob switch source { case "git": if local != "" { - app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName}) - errors.CheckError(err) - settingsConn, settingsIf := clientset.NewSettingsClientOrDie() defer argoio.Close(settingsConn) argoSettings, err := settingsIf.Get(context.Background(), &settings.SettingsQuery{}) @@ -2938,6 +3083,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob command.Flags().StringVar(&revision, "revision", "", "Show manifests at a specific revision") command.Flags().StringArrayVar(&revisions, "revisions", []string{}, "Show manifests at specific revisions for the source at position in source-positions") command.Flags().Int64SliceVar(&sourcePositions, "source-positions", []int64{}, "List of source positions. Default is empty array. Counting start at 1.") + command.Flags().StringArrayVar(&sourceNames, "source-names", []string{}, "List of source names. Default is an empty array.") command.Flags().StringVar(&local, "local", "", "If set, show locally-generated manifests. Value is the absolute path to app manifests within the manifest repo. Example: '/home/username/apps/env/app-1'.") command.Flags().StringVar(&localRepoRoot, "local-repo-root", ".", "Path to the local repository root. Used together with --local allows setting the repository root. Example: '/home/username/apps'.") return command @@ -3086,7 +3232,7 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob Use: "add-source APPNAME", Short: "Adds a source to the list of sources in the application", Example: ` # Append a source to the list of sources in the application - argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook`, + argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --source-name guestbook`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() if len(args) != 1 { @@ -3144,13 +3290,17 @@ func NewApplicationAddSourceCommand(clientOpts *argocdclient.ClientOptions) *cob func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( sourcePosition int + sourceName string appNamespace string ) command := &cobra.Command{ Use: "remove-source APPNAME", - Short: "Remove a source from multiple sources application. Counting starts with 1. Default value is -1.", + Short: "Remove a source from multiple sources application.", Example: ` # Remove the source at position 1 from application's sources. Counting starts at 1. - argocd app remove-source myapplication --source-position 1`, + argocd app remove-source myapplication --source-position 1 + + # Remove the source named "test" from application's sources. + argocd app remove-source myapplication --source-name test`, Run: func(c *cobra.Command, args []string) { ctx := c.Context() @@ -3159,7 +3309,7 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * os.Exit(1) } - if sourcePosition <= 0 { + if sourceName == "" && sourcePosition <= 0 { errors.CheckError(fmt.Errorf("Value of source-position must be greater than 0")) } @@ -3176,6 +3326,19 @@ func NewApplicationRemoveSourceCommand(clientOpts *argocdclient.ClientOptions) * }) errors.CheckError(err) + if sourceName != "" && sourcePosition != -1 { + errors.CheckError(fmt.Errorf("Only one of source-position and source-name can be specified.")) + } + + if sourceName != "" { + sourceNameToPosition := getSourceNameToPositionMap(app) + if pos, ok := sourceNameToPosition[sourceName]; !ok { + log.Fatalf("Unknown source name '%s'", sourceName) + } else { + sourcePosition = int(pos) + } + } + if !app.Spec.HasMultipleSources() { errors.CheckError(fmt.Errorf("Application does not have multiple sources configured")) } @@ -3208,6 +3371,7 @@ 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(&sourcePosition, "source-position", -1, "Position of the source from the list of sources of the app. Counting starts at 1.") + command.Flags().StringVar(&sourceName, "source-name", "", "Name of the source from the list of sources of the app.") return command } diff --git a/cmd/util/app.go b/cmd/util/app.go index 7b5745c1882dcf..c7e84eaa59c7f7 100644 --- a/cmd/util/app.go +++ b/cmd/util/app.go @@ -90,6 +90,7 @@ type AppOptions struct { retryBackoffMaxDuration time.Duration retryBackoffFactor int64 ref string + SourceName string } // SetAutoMaxProcs sets the GOMAXPROCS value based on the binary name. @@ -166,6 +167,7 @@ func AddAppFlags(command *cobra.Command, opts *AppOptions) { command.Flags().DurationVar(&opts.retryBackoffMaxDuration, "sync-retry-backoff-max-duration", argoappv1.DefaultSyncRetryMaxDuration, "Max sync retry backoff duration. Input needs to be a duration (e.g. 2m, 1h)") command.Flags().Int64Var(&opts.retryBackoffFactor, "sync-retry-backoff-factor", argoappv1.DefaultSyncRetryFactor, "Factor multiplies the base duration after each failed sync retry") command.Flags().StringVar(&opts.ref, "ref", "", "Ref is reference to another source within sources field") + command.Flags().StringVar(&opts.SourceName, "source-name", "", "Name of the source from the list of sources of the app.") } func SetAppSpecOptions(flags *pflag.FlagSet, spec *argoappv1.ApplicationSpec, appOpts *AppOptions, sourcePosition int) int { @@ -759,6 +761,8 @@ func ConstructSource(source *argoappv1.ApplicationSource, appOpts AppOptions, fl setPluginOptEnvs(source, appOpts.pluginEnvs) case "ref": source.Ref = appOpts.ref + case "source-name": + source.Name = appOpts.SourceName } }) return source, visited diff --git a/docs/user-guide/commands/argocd_admin_app_generate-spec.md b/docs/user-guide/commands/argocd_admin_app_generate-spec.md index 439e605177a42c..63b756a76f7ecb 100644 --- a/docs/user-guide/commands/argocd_admin_app_generate-spec.md +++ b/docs/user-guide/commands/argocd_admin_app_generate-spec.md @@ -94,6 +94,7 @@ argocd admin app generate-spec 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-name string Name of the source from the list of sources of the app. --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.md b/docs/user-guide/commands/argocd_app.md index b66326093ae6e8..2ff8e6cf830ff6 100644 --- a/docs/user-guide/commands/argocd_app.md +++ b/docs/user-guide/commands/argocd_app.md @@ -94,7 +94,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. Counting starts with 1. Default value is -1. +* [argocd app remove-source](argocd_app_remove-source.md) - Remove a source from multiple sources application. * [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_add-source.md b/docs/user-guide/commands/argocd_app_add-source.md index 5ec1180668e72f..8ea0f9d0d7e7df 100644 --- a/docs/user-guide/commands/argocd_app_add-source.md +++ b/docs/user-guide/commands/argocd_app_add-source.md @@ -12,7 +12,7 @@ argocd app add-source APPNAME [flags] ``` # Append a source to the list of sources in the application - argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook + argocd app add-source guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path guestbook --source-name guestbook ``` ### Options @@ -71,6 +71,7 @@ argocd app add-source 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-name string Name of the source from the list of sources of the app. --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_create.md b/docs/user-guide/commands/argocd_app_create.md index a0e1efb3df9114..504393af349d57 100644 --- a/docs/user-guide/commands/argocd_app_create.md +++ b/docs/user-guide/commands/argocd_app_create.md @@ -94,6 +94,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-name string Name of the source from the list of sources of the app. --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_diff.md b/docs/user-guide/commands/argocd_app_diff.md index 88eba2e7a255fe..743fa6e2b203d6 100644 --- a/docs/user-guide/commands/argocd_app_diff.md +++ b/docs/user-guide/commands/argocd_app_diff.md @@ -31,6 +31,7 @@ argocd app diff APPNAME [flags] --revision string Compare live app to a particular revision --revisions stringArray Show manifests at specific revisions for source position in source-positions --server-side-generate Used with --local, this will send your manifests to the server for diffing + --source-names stringArray List of source names. Default is an empty array. --source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default []) ``` diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index dc436d5b92f18c..667978ee27c850 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -29,6 +29,9 @@ argocd app get APPNAME [flags] # Show application parameters and overrides for a source at position 1 under spec.sources of app my-app argocd app get my-app --show-params --source-position 1 + # Show application parameters and overrides for a source named "test" + argocd app get my-app --show-params --source-name test + # Refresh application data when retrieving argocd app get my-app --refresh @@ -52,6 +55,7 @@ argocd app get APPNAME [flags] --refresh Refresh application data when retrieving --show-operation Show application operation --show-params Show application parameters and overrides + --source-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) ``` diff --git a/docs/user-guide/commands/argocd_app_manifests.md b/docs/user-guide/commands/argocd_app_manifests.md index 2ea32ccc91e8be..e2cbe3bfb8c7a4 100644 --- a/docs/user-guide/commands/argocd_app_manifests.md +++ b/docs/user-guide/commands/argocd_app_manifests.md @@ -17,6 +17,9 @@ argocd app manifests APPNAME [flags] # Get manifests for an application at a specific revision argocd app manifests my-app --revision 0.0.1 + # Get manifests for a multi-source application at specific revisions for specific sources + argocd app manifests my-app --revisions 0.0.1 --source-names src-base --revisions 0.0.2 --source-names src-values + # Get manifests for a multi-source application at specific revisions for specific sources argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 ``` @@ -30,6 +33,7 @@ argocd app manifests APPNAME [flags] --revision string Show manifests at a specific revision --revisions stringArray Show manifests at specific revisions for the source at position in source-positions --source string Source of manifests. One of: live|git (default "git") + --source-names stringArray List of source names. Default is an empty array. --source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default []) ``` diff --git a/docs/user-guide/commands/argocd_app_remove-source.md b/docs/user-guide/commands/argocd_app_remove-source.md index 1835ef38adc0da..2b0aa9ec29841c 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. Counting starts with 1. Default value is -1. +Remove a source from multiple sources application. ``` argocd app remove-source APPNAME [flags] @@ -13,6 +13,9 @@ argocd app remove-source APPNAME [flags] ``` # Remove the source at position 1 from application's sources. Counting starts at 1. argocd app remove-source myapplication --source-position 1 + + # Remove the source named "test" from application's sources. + argocd app remove-source myapplication --source-name test ``` ### Options @@ -20,6 +23,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-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting starts at 1. (default -1) ``` diff --git a/docs/user-guide/commands/argocd_app_set.md b/docs/user-guide/commands/argocd_app_set.md index 39a12d549658bb..b468526675554f 100644 --- a/docs/user-guide/commands/argocd_app_set.md +++ b/docs/user-guide/commands/argocd_app_set.md @@ -20,6 +20,9 @@ argocd app set APPNAME [flags] # Set and override application parameters for a source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app set my-app --source-position 1 --repo https://github.com/argoproj/argocd-example-apps.git + # Set and override application parameters for a source named "test" under spec.sources of app my-app. + argocd app set my-app --source-name test --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 ``` @@ -80,6 +83,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-name string Name of the source from the list of sources of the app. --source-position int Position of the source from the list of sources of the app. Counting 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)) diff --git a/docs/user-guide/commands/argocd_app_sync.md b/docs/user-guide/commands/argocd_app_sync.md index 8cb89b0c97483f..0a59bc82293348 100644 --- a/docs/user-guide/commands/argocd_app_sync.md +++ b/docs/user-guide/commands/argocd_app_sync.md @@ -25,7 +25,8 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] argocd app sync -l 'app.kubernetes.io/instance notin (my-app,other-app)' # Sync a multi-source application for specific revision of specific sources - argocd app manifests my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-positions 1 --revisions 0.0.2 --source-positions 2 + argocd app sync my-app --revisions 0.0.1 --source-names my-chart --revisions 0.0.2 --source-names my-values # Sync a specific resource # Resource should be formatted as GROUP:KIND:NAME. If no GROUP is specified then :KIND:NAME @@ -67,6 +68,7 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] --revisions stringArray Show manifests at specific revisions for source position in source-positions -l, --selector string Sync apps that match this label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints. --server-side Use server-side apply while syncing the application + --source-names stringArray List of source names. Default is an empty array. --source-positions int64Slice List of source positions. Default is empty array. Counting start at 1. (default []) --strategy string Sync strategy (one of: apply|hook) --timeout uint Time out after this many seconds diff --git a/docs/user-guide/commands/argocd_app_unset.md b/docs/user-guide/commands/argocd_app_unset.md index 10b4846341d40c..a4ff76356539cc 100644 --- a/docs/user-guide/commands/argocd_app_unset.md +++ b/docs/user-guide/commands/argocd_app_unset.md @@ -20,6 +20,9 @@ argocd app unset APPNAME parameters [flags] # Unset kustomize override suffix for source at position 1 under spec.sources of app my-app. source-position starts at 1. argocd app unset my-app --source-position 1 --namesuffix + # Unset kustomize override suffix for source named "test" under spec.sources of app my-app. + argocd app unset my-app --source-name test --namesuffix + # Unset parameter override argocd app unset my-app -p COMPONENT=PARAM ``` diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 6287e631f7dfbe..2cd1b46bb204f5 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -464,6 +464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -840,6 +844,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1326,6 +1334,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1692,6 +1704,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2224,6 +2240,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2603,6 +2623,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -3131,6 +3155,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3529,6 +3558,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -4037,6 +4071,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4427,6 +4465,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4961,6 +5003,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5351,6 +5397,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -5789,6 +5839,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6023,6 +6075,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6421,6 +6475,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6655,6 +6711,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7052,6 +7110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7286,6 +7346,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7663,6 +7725,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7897,6 +7961,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8299,6 +8365,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8533,6 +8601,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8931,6 +9001,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9165,6 +9237,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9562,6 +9636,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9796,6 +9872,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10173,6 +10251,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10407,6 +10487,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10792,6 +10874,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11026,6 +11110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11630,6 +11716,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11864,6 +11952,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12463,6 +12553,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12697,6 +12789,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13091,6 +13185,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13325,6 +13421,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13729,6 +13827,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13963,6 +14063,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14361,6 +14463,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14595,6 +14699,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14992,6 +15098,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15226,6 +15334,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15603,6 +15713,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15837,6 +15949,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16222,6 +16336,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16456,6 +16572,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17060,6 +17178,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17294,6 +17414,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17893,6 +18015,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18127,6 +18251,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18525,6 +18651,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18759,6 +18887,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19143,6 +19273,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19377,6 +19509,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19981,6 +20115,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20215,6 +20351,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20814,6 +20952,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21048,6 +21188,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21517,6 +21659,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21751,6 +21895,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: diff --git a/manifests/crds/application-crd.yaml b/manifests/crds/application-crd.yaml index f2fedb577a6399..f3ea94da1bc868 100644 --- a/manifests/crds/application-crd.yaml +++ b/manifests/crds/application-crd.yaml @@ -463,6 +463,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -839,6 +843,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1325,6 +1333,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1691,6 +1703,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2223,6 +2239,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2602,6 +2622,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -3130,6 +3154,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3528,6 +3557,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -4036,6 +4070,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4426,6 +4464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4960,6 +5002,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5350,6 +5396,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index 765f616003d782..34bbd56df02032 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -333,6 +333,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -567,6 +569,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -965,6 +969,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -1199,6 +1205,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -1596,6 +1604,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -1830,6 +1840,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2207,6 +2219,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2441,6 +2455,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -2843,6 +2859,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -3077,6 +3095,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -3475,6 +3495,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -3709,6 +3731,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4106,6 +4130,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4340,6 +4366,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4717,6 +4745,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -4951,6 +4981,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5336,6 +5368,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -5570,6 +5604,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6174,6 +6210,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6408,6 +6446,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7007,6 +7047,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7241,6 +7283,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7635,6 +7679,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7869,6 +7915,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8273,6 +8321,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8507,6 +8557,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8905,6 +8957,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9139,6 +9193,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9536,6 +9592,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9770,6 +9828,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10147,6 +10207,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10381,6 +10443,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10766,6 +10830,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11000,6 +11066,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11604,6 +11672,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11838,6 +11908,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12437,6 +12509,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12671,6 +12745,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13069,6 +13145,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13303,6 +13381,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13687,6 +13767,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13921,6 +14003,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14525,6 +14609,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14759,6 +14845,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15358,6 +15446,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15592,6 +15682,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16061,6 +16153,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16295,6 +16389,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index a0fc002ef73a64..94fbeac70379ad 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -464,6 +464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -840,6 +844,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1326,6 +1334,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1692,6 +1704,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2224,6 +2240,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2603,6 +2623,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -3131,6 +3155,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3529,6 +3558,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -4037,6 +4071,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4427,6 +4465,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4961,6 +5003,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5351,6 +5397,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -5789,6 +5839,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6023,6 +6075,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6421,6 +6475,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6655,6 +6711,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7052,6 +7110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7286,6 +7346,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7663,6 +7725,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7897,6 +7961,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8299,6 +8365,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8533,6 +8601,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8931,6 +9001,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9165,6 +9237,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9562,6 +9636,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9796,6 +9872,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10173,6 +10251,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10407,6 +10487,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10792,6 +10874,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11026,6 +11110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11630,6 +11716,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11864,6 +11952,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12463,6 +12553,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12697,6 +12789,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13091,6 +13185,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13325,6 +13421,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13729,6 +13827,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13963,6 +14063,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14361,6 +14463,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14595,6 +14699,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14992,6 +15098,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15226,6 +15334,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15603,6 +15713,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15837,6 +15949,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16222,6 +16336,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16456,6 +16572,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17060,6 +17178,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17294,6 +17414,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17893,6 +18015,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18127,6 +18251,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18525,6 +18651,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18759,6 +18887,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19143,6 +19273,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19377,6 +19509,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19981,6 +20115,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20215,6 +20351,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20814,6 +20952,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21048,6 +21188,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21517,6 +21659,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21751,6 +21895,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: diff --git a/manifests/install.yaml b/manifests/install.yaml index a5f460c8c2268b..68d774ec687e9b 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -464,6 +464,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -840,6 +844,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1326,6 +1334,10 @@ spec: use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -1692,6 +1704,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2224,6 +2240,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is displayed + in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -2603,6 +2623,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -3131,6 +3155,11 @@ spec: Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -3529,6 +3558,11 @@ spec: of Kustomize to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and + is displayed in the UI. It is used in multi-source + Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications @@ -4037,6 +4071,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -4427,6 +4465,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -4961,6 +5003,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced from Git. @@ -5351,6 +5397,10 @@ spec: to use for rendering manifests type: string type: object + name: + description: Name is used to refer to a source and is + displayed in the UI. It is used in multi-source Applications. + type: string path: description: Path is a directory path within the Git repository, and is only valid for applications sourced @@ -5789,6 +5839,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6023,6 +6075,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6421,6 +6475,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -6655,6 +6711,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7052,6 +7110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7286,6 +7346,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7663,6 +7725,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -7897,6 +7961,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8299,6 +8365,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8533,6 +8601,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -8931,6 +9001,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9165,6 +9237,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9562,6 +9636,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -9796,6 +9872,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10173,6 +10251,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10407,6 +10487,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -10792,6 +10874,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11026,6 +11110,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11630,6 +11716,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -11864,6 +11952,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12463,6 +12553,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -12697,6 +12789,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13091,6 +13185,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13325,6 +13421,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13729,6 +13827,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -13963,6 +14063,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14361,6 +14463,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14595,6 +14699,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -14992,6 +15098,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15226,6 +15334,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15603,6 +15713,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -15837,6 +15949,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16222,6 +16336,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -16456,6 +16572,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17060,6 +17178,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17294,6 +17414,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -17893,6 +18015,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18127,6 +18251,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18525,6 +18651,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -18759,6 +18887,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19143,6 +19273,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19377,6 +19509,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -19981,6 +20115,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20215,6 +20351,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -20814,6 +20952,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21048,6 +21188,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21517,6 +21659,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: @@ -21751,6 +21895,8 @@ spec: version: type: string type: object + name: + type: string path: type: string plugin: diff --git a/pkg/apis/application/v1alpha1/generated.proto b/pkg/apis/application/v1alpha1/generated.proto index 238479ea9cb25e..68b03bfb5a8065 100644 --- a/pkg/apis/application/v1alpha1/generated.proto +++ b/pkg/apis/application/v1alpha1/generated.proto @@ -454,6 +454,9 @@ message ApplicationSource { // Ref is reference to another source within sources field. This field will not be used if used with a `source` tag. optional string ref = 13; + + // Name is used to refer to a source and is displayed in the UI. It is used in multi-source Applications. + optional string name = 14; } // ApplicationSourceDirectory holds options for applications of type plain YAML or Jsonnet diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 5d931e8ff62b90..52aaa79c72ad35 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -191,6 +191,8 @@ type ApplicationSource struct { Chart string `json:"chart,omitempty" protobuf:"bytes,12,opt,name=chart"` // Ref is reference to another source within sources field. This field will not be used if used with a `source` tag. Ref string `json:"ref,omitempty" protobuf:"bytes,13,opt,name=ref"` + // Name is used to refer to a source and is displayed in the UI. It is used in multi-source Applications. + Name string `json:"name,omitempty" protobuf:"bytes,14,opt,name=name"` } // ApplicationSources contains list of required information about the sources of an application diff --git a/server/application/application.go b/server/application/application.go index de961c82ea5f7f..838110c388e1d8 100644 --- a/server/application/application.go +++ b/server/application/application.go @@ -1229,6 +1229,18 @@ func (s *Server) validateAndNormalizeApp(ctx context.Context, app *appv1.Applica if app.GetName() == "" { return fmt.Errorf("resource name may not be empty") } + + // ensure sources names are unique + if app.Spec.HasMultipleSources() { + sourceNames := make(map[string]bool) + for _, source := range app.Spec.Sources { + if len(source.Name) > 0 && sourceNames[source.Name] { + return fmt.Errorf("application %s has duplicate source name: %s", app.Name, source.Name) + } + sourceNames[source.Name] = true + } + } + appNs := s.appNamespaceOrDefault(app.Namespace) currApp, err := s.appclientset.ArgoprojV1alpha1().Applications(appNs).Get(ctx, app.Name, metav1.GetOptions{}) if err != nil { diff --git a/test/e2e/app_multiple_sources_test.go b/test/e2e/app_multiple_sources_test.go index fd5f2d8d5fb696..e3118244e18d0b 100644 --- a/test/e2e/app_multiple_sources_test.go +++ b/test/e2e/app_multiple_sources_test.go @@ -167,3 +167,131 @@ func TestMultiSourceAppWithSourceOverride(t *testing.T) { assert.Contains(t, output, "foo=bar") }) } + +func TestMultiSourceAppWithSourceName(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + Name: "guestbook", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + Name: "dynamic duo", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + assert.Equal(t, sources[i].Name, source.Name) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(app *Application) { + // we remove the first source + output, err := RunCli("app", "remove-source", Name(), "--source-name", sources[0].Name) + require.NoError(t, err) + assert.Contains(t, output, "updated successfully") + }). + Expect(Success("")). + And(func(app *Application) { + assert.Len(t, app.Spec.GetSources(), 1) + // we add a source + output, err := RunCli("app", "add-source", Name(), "--source-name", sources[0].Name, "--repo", RepoURL(RepoURLTypeFile), "--path", guestbookPath) + require.NoError(t, err) + assert.Contains(t, output, "updated successfully") + }). + Expect(Success("")). + Given().Timeout(60). + When().Wait().Then(). + Expect(Success("")). + And(func(app *Application) { + assert.Len(t, app.Spec.GetSources(), 2) + // sources order has been inverted + assert.Equal(t, sources[1].Name, app.Spec.GetSources()[0].Name) + assert.Equal(t, sources[0].Name, app.Spec.GetSources()[1].Name) + statusByName := map[string]SyncStatusCode{} + for _, r := range app.Status.Resources { + statusByName[r.Name] = r.Status + } + // check if the app has 3 resources, guestbook and 2 pods + assert.Len(t, statusByName, 3) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-1"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["pod-2"]) + assert.Equal(t, SyncStatusCodeSynced, statusByName["guestbook-ui"]) + }) +} + +func TestMultiSourceAppSetWithSourceName(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + Name: "guestbook", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + Name: "dynamic duo", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + And(func(app *Application) { + assert.Equal(t, Name(), app.Name) + for i, source := range app.Spec.GetSources() { + assert.Equal(t, sources[i].RepoURL, source.RepoURL) + assert.Equal(t, sources[i].Path, source.Path) + assert.Equal(t, sources[i].Name, source.Name) + } + assert.Equal(t, DeploymentNamespace(), app.Spec.Destination.Namespace) + assert.Equal(t, KubernetesInternalAPIServerAddr, app.Spec.Destination.Server) + }). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(app *Application) { + _, err := RunCli("app", "set", Name(), "--source-name", sources[1].Name, "--path", "deployment") + require.NoError(t, err) + }). + Expect(Success("")). + And(func(app *Application) { + assert.Equal(t, "deployment", app.Spec.GetSources()[1].Path) + }) +} + +func TestMultiSourceApptErrorWhenSourceNameAndSourcePosition(t *testing.T) { + sources := []ApplicationSource{{ + RepoURL: RepoURL(RepoURLTypeFile), + Path: guestbookPath, + Name: "guestbook", + }, { + RepoURL: RepoURL(RepoURLTypeFile), + Path: "two-nice-pods", + Name: "dynamic duo", + }} + ctx := Given(t) + ctx. + Sources(sources). + When(). + CreateMultiSourceAppFromFile(). + Then(). + Expect(Event(EventReasonResourceCreated, "create")). + And(func(app *Application) { + _, err := RunCli("app", "get", Name(), "--source-name", sources[1].Name, "--source-position", "1") + require.Error(t, err) + assert.Contains(t, err.Error(), "Only one of source-position and source-name can be specified.") + }). + And(func(app *Application) { + _, err := RunCli("app", "manifests", Name(), "--revisions", "0.0.2", "--source-names", sources[0].Name, "--revisions", "0.0.2", "--source-positions", "1") + require.Error(t, err) + assert.Contains(t, err.Error(), "Only one of source-positions and source-names can be specified.") + }) +} diff --git a/ui/src/app/applications/components/application-parameters/application-parameters.tsx b/ui/src/app/applications/components/application-parameters/application-parameters.tsx index 3771d32d3cf1a2..aacbfc6b20bfd2 100644 --- a/ui/src/app/applications/components/application-parameters/application-parameters.tsx +++ b/ui/src/app/applications/components/application-parameters/application-parameters.tsx @@ -307,7 +307,7 @@ export const ApplicationParameters = (props: {
-
Source {index + 1 + ': ' + appSource.repoURL}
+
Source {index + 1 + (appSource.name ? ' - ' + appSource.name : '') + ': ' + appSource.repoURL}
{(appSource.path ? 'PATH=' + appSource.path : '') + (appSource.targetRevision ? (appSource.path ? ', ' : '') + 'REVISION=' + appSource.targetRevision : '')}
@@ -586,6 +586,7 @@ function gatherCoreSourceDetails(i: number, attributes: EditablePanelItem[], sou const repoUrlField = 'spec.sources[' + i + '].repoURL'; const sourcesPathField = 'spec.sources[' + i + '].path'; const refField = 'spec.sources[' + i + '].ref'; + const nameField = 'spec.sources[' + i + '].name'; const chartField = 'spec.sources[' + i + '].chart'; const revisionField = 'spec.sources[' + i + '].targetRevision'; // For single source apps using the source field, these fields are shown in the Summary tab. @@ -595,6 +596,11 @@ function gatherCoreSourceDetails(i: number, attributes: EditablePanelItem[], sou view: , edit: (formApi: FormApi) => }); + attributes.push({ + title: 'NAME', + view: {source?.name}, + edit: (formApi: FormApi) => + }); if (isHelm) { attributes.push({ title: 'CHART', diff --git a/ui/src/app/applications/components/application-parameters/source-panel.tsx b/ui/src/app/applications/components/application-parameters/source-panel.tsx index c5d6ca4050291b..0e956670a6c081 100644 --- a/ui/src/app/applications/components/application-parameters/source-panel.tsx +++ b/ui/src/app/applications/components/application-parameters/source-panel.tsx @@ -57,6 +57,7 @@ const DEFAULT_APP: Partial = { path: '', repoURL: '', ref: '', + name: '', targetRevision: 'HEAD' }, sources: [], @@ -204,6 +205,11 @@ export const SourcePanel = (props: {
+
+
+ +
+
{(repoType === 'git' && ( diff --git a/ui/src/app/shared/models.ts b/ui/src/app/shared/models.ts index c9d37184539d3b..7d77bff2aab769 100644 --- a/ui/src/app/shared/models.ts +++ b/ui/src/app/shared/models.ts @@ -210,6 +210,8 @@ export interface ApplicationSource { directory?: ApplicationSourceDirectory; ref?: string; + + name?: string; } export interface ApplicationSourceHelm {