diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 4c262a67fddca..6cbbfd10015c4 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -314,6 +314,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 ( @@ -324,6 +335,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com showOperation bool appNamespace string sourcePosition int + sourceName string ) command := &cobra.Command{ Use: "get APPNAME", @@ -347,6 +359,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 @@ -379,6 +394,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.Fatal("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")) @@ -433,6 +461,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 } @@ -762,6 +791,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com appOpts cmdutil.AppOptions appNamespace string sourcePosition int + sourceName string ) command := &cobra.Command{ Use: "set APPNAME", @@ -776,6 +806,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 `), @@ -794,6 +827,19 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) 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.Fatal("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")) @@ -823,6 +869,7 @@ func NewApplicationSetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com cmdutil.AddAppFlags(command, &appOpts) command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Set application parameters in 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 } @@ -857,6 +904,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 @@ -872,6 +920,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`, @@ -889,6 +940,19 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C app, err := appIf.Get(ctx, &application.ApplicationQuery{Name: &appName, AppNamespace: &appNs}) 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.Fatal("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")) @@ -934,6 +998,7 @@ func NewApplicationUnsetCommand(clientOpts *argocdclient.ClientOptions) *cobra.C 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(&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 } @@ -2816,6 +2881,7 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob revision string revisions []string sourcePositions []int64 + sourceNames []string local string localRepoRoot string ) @@ -2829,6 +2895,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 `), @@ -2840,8 +2909,12 @@ 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-position and source-name can be specified.")) + } + + if len(revisions) != len(sourcePositions) || len(revisions) != len(sourceNames) { + errors.CheckError(fmt.Errorf("While using revisions and either source-positions or source-names, length of values for both flags should be same.")) } for _, pos := range sourcePositions { @@ -2855,6 +2928,21 @@ func NewApplicationManifestsCommand(clientOpts *argocdclient.ClientOptions) *cob conn, appIf := clientset.NewApplicationClientOrDie() defer argoio.Close(conn) + app, err := appIf.Get(context.Background(), &application.ApplicationQuery{Name: &appName}) + errors.CheckError(err) + + if len(sourceNames) > 0 { + sourceNameToPosition := getSourceNameToPositionMap(app) + + for _, name := range sourceNames { + if pos, ok := sourceNameToPosition[name]; !ok { + log.Fatal("Unknown source name '%s'", name) + } else { + sourcePositions = append(sourcePositions, pos) + } + } + } + resources, err := appIf.ManagedResources(ctx, &application.ResourcesQuery{ ApplicationName: &appName, AppNamespace: &appNs, @@ -2865,9 +2953,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{}) @@ -2936,6 +3021,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 diff --git a/pkg/apis/application/v1alpha1/types.go b/pkg/apis/application/v1alpha1/types.go index 62b45a27b314a..e9e8dcc7799de 100644 --- a/pkg/apis/application/v1alpha1/types.go +++ b/pkg/apis/application/v1alpha1/types.go @@ -190,6 +190,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. + Name string `json:"name,omitempty" protobuf:"bytes,14,opt,name=name"` } // ApplicationSources contains list of required information about the sources of an application