From 41dfbde38c2ca9ad2634047f53ad704b2c8a08f4 Mon Sep 17 00:00:00 2001 From: Mangaal <44372157+Mangaal@users.noreply.github.com> Date: Sat, 2 Mar 2024 04:05:31 +0530 Subject: [PATCH] feat: enable users to run commands related to Argo Applications in any namespace (#17360) * enable --app-namespace falg for application get command Signed-off-by: Mangaal * enable --app-namespace falg for application diff command Signed-off-by: Mangaal * enable --app-namespace falg for application wait command Signed-off-by: Mangaal * enable --app-namespace falg for application rollback command Signed-off-by: Mangaal * enable --app-namespace falg for application patch command Signed-off-by: Mangaal * enable --app-namespace falg for application edit command Signed-off-by: Mangaal * enable --app-namespace falg for application history command Signed-off-by: Mangaal * enable --app-namespace falg for application sync command Signed-off-by: Mangaal * enable --app-namespace falg for application delete command Signed-off-by: Mangaal * cli doc generated Signed-off-by: Mangaal --------- Signed-off-by: Mangaal Co-authored-by: Ishita Sequeira <46771830+ishitasequeira@users.noreply.github.com> Signed-off-by: Kevin Lyda --- cmd/argocd/commands/app.go | 70 +++++++++++++------ docs/user-guide/commands/argocd_app_delete.md | 1 + docs/user-guide/commands/argocd_app_diff.md | 1 + docs/user-guide/commands/argocd_app_edit.md | 3 +- docs/user-guide/commands/argocd_app_get.md | 13 ++-- .../user-guide/commands/argocd_app_history.md | 5 +- docs/user-guide/commands/argocd_app_patch.md | 7 +- .../commands/argocd_app_rollback.md | 9 +-- docs/user-guide/commands/argocd_app_sync.md | 1 + docs/user-guide/commands/argocd_app_wait.md | 1 + 10 files changed, 75 insertions(+), 36 deletions(-) diff --git a/cmd/argocd/commands/app.go b/cmd/argocd/commands/app.go index 55a204222fb5c..11762c026b25d 100644 --- a/cmd/argocd/commands/app.go +++ b/cmd/argocd/commands/app.go @@ -318,6 +318,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com output string showParams bool showOperation bool + appNamespace string ) var command = &cobra.Command{ Use: "get APPNAME", @@ -361,7 +362,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com conn, appIf := acdClient.NewApplicationClientOrDie() defer argoio.Close(conn) - appName, appNs := argo.ParseFromQualifiedName(args[0], "") + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, @@ -414,6 +415,7 @@ func NewApplicationGetCommand(clientOpts *argocdclient.ClientOptions) *cobra.Com command.Flags().BoolVar(&showParams, "show-params", false, "Show application parameters and overrides") command.Flags().BoolVar(&refresh, "refresh", false, "Refresh application data when retrieving") 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") return command } @@ -1072,6 +1074,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co localRepoRoot string serverSideGenerate bool localIncludes []string + appNamespace string ) shortDesc := "Perform a diff against the target and live state." var command = &cobra.Command{ @@ -1088,7 +1091,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co clientset := headless.NewClientOrDie(clientOpts, c) conn, appIf := clientset.NewApplicationClientOrDie() defer argoio.Close(conn) - appName, appNs := argo.ParseFromQualifiedName(args[0], "") + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, Refresh: getRefreshType(refresh, hardRefresh), @@ -1152,6 +1155,7 @@ func NewApplicationDiffCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().StringVar(&localRepoRoot, "local-repo-root", "/", "Path to the repository root. Used together with --local allows setting the repository root") command.Flags().BoolVar(&serverSideGenerate, "server-side-generate", false, "Used with --local, this will send your manifests to the server for diffing") command.Flags().StringArrayVar(&localIncludes, "local-include", []string{"*.yaml", "*.yml", "*.json"}, "Used with --server-side-generate, specify patterns of filenames to send. Matching is based on filename and not path.") + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only render the difference in namespace") return command } @@ -1293,6 +1297,7 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. propagationPolicy string selector string wait bool + appNamespace string ) var command = &cobra.Command{ Use: "delete APPNAME", @@ -1335,7 +1340,7 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. } for _, appFullName := range appNames { - appName, appNs := argo.ParseFromQualifiedName(appFullName, "") + appName, appNs := argo.ParseFromQualifiedName(appFullName, appNamespace) appDeleteReq := application.ApplicationDeleteRequest{ Name: &appName, AppNamespace: &appNs, @@ -1387,6 +1392,7 @@ func NewApplicationDeleteCommand(clientOpts *argocdclient.ClientOptions) *cobra. command.Flags().BoolVarP(&noPrompt, "yes", "y", false, "Turn off prompting to confirm cascaded deletion of application resources") command.Flags().StringVarP(&selector, "selector", "l", "", "Delete all apps with matching label. Supports '=', '==', '!=', in, notin, exists & not exists. Matching apps must satisfy all of the specified label constraints.") command.Flags().BoolVar(&wait, "wait", false, "Wait until deletion of the application(s) completes") + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Namespace where the application will be deleted from") return command } @@ -1610,11 +1616,12 @@ func getWatchOpts(watch watchOpts) watchOpts { // NewApplicationWaitCommand returns a new instance of an `argocd app wait` command func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - watch watchOpts - timeout uint - selector string - resources []string - output string + watch watchOpts + timeout uint + selector string + resources []string + output string + appNamespace string ) var command = &cobra.Command{ Use: "wait [APPNAME.. | -l selector]", @@ -1663,6 +1670,10 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } } for _, appName := range appNames { + // Construct QualifiedName + if appNamespace != "" && !strings.Contains(appName, "/") { + appName = appNamespace + "/" + appName + } _, _, err := waitOnApplicationStatus(ctx, acdClient, appName, timeout, watch, selectedResources, output) errors.CheckError(err) } @@ -1677,6 +1688,7 @@ func NewApplicationWaitCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().StringArrayVar(&resources, "resource", []string{}, fmt.Sprintf("Sync only specific resources as GROUP%[1]sKIND%[1]sNAME or %[2]sGROUP%[1]sKIND%[1]sNAME. Fields may be blank and '*' can be used. This option may be specified repeatedly", resourceFieldDelimiter, resourceExcludeIndicator)) command.Flags().BoolVar(&watch.operation, "operation", false, "Wait for pending operations") command.Flags().UintVar(&timeout, "timeout", defaultCheckTimeoutSeconds, "Time out after this many seconds") + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only wait for an application in namespace") command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|tree|tree=detailed") return command } @@ -1734,6 +1746,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co diffChangesConfirm bool projects []string output string + appNamespace string ) var command = &cobra.Command{ Use: "sync [APPNAME... | -l selector | --project project-name]", @@ -1778,7 +1791,10 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co appNames := args if selector != "" || len(projects) > 0 { - list, err := appIf.List(ctx, &application.ApplicationQuery{Selector: pointer.String(selector), Projects: projects}) + list, err := appIf.List(ctx, &application.ApplicationQuery{ + Selector: pointer.String(selector), + AppNamespace: &appNamespace, + Projects: projects}) errors.CheckError(err) // unlike list, we'd want to fail if nothing was found @@ -1799,6 +1815,10 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co } for _, appQualifiedName := range appNames { + // Construct QualifiedName + if appNamespace != "" && !strings.Contains(appQualifiedName, "/") { + appQualifiedName = appNamespace + "/" + appQualifiedName + } appName, appNs := argo.ParseFromQualifiedName(appQualifiedName, "") if len(selectedLabels) > 0 { @@ -2016,6 +2036,7 @@ func NewApplicationSyncCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co command.Flags().BoolVar(&diffChanges, "preview-changes", false, "Preview difference against the target and live state before syncing app and wait for user confirmation") command.Flags().StringArrayVar(&projects, "project", []string{}, "Sync apps that belong to the specified projects. This option may be specified repeatedly.") command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|tree|tree=detailed") + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only sync an application in namespace") return command } @@ -2452,7 +2473,8 @@ func printApplicationHistoryTable(revHistory []argoappv1.RevisionHistory) { // NewApplicationHistoryCommand returns a new instance of an `argocd app history` command func NewApplicationHistoryCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - output string + output string + appNamespace string ) var command = &cobra.Command{ Use: "history APPNAME", @@ -2466,7 +2488,7 @@ func NewApplicationHistoryCommand(clientOpts *argocdclient.ClientOptions) *cobra } conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() defer argoio.Close(conn) - appName, appNs := argo.ParseFromQualifiedName(args[0], "") + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) app, err := appIf.Get(ctx, &application.ApplicationQuery{ Name: &appName, AppNamespace: &appNs, @@ -2480,6 +2502,7 @@ func NewApplicationHistoryCommand(clientOpts *argocdclient.ClientOptions) *cobra } }, } + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only show application deployment history in namespace") command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: wide|id") return command } @@ -2504,9 +2527,10 @@ func findRevisionHistory(application *argoappv1.Application, historyId int64) (* // NewApplicationRollbackCommand returns a new instance of an `argocd app rollback` command func NewApplicationRollbackCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { var ( - prune bool - timeout uint - output string + prune bool + timeout uint + output string + appNamespace string ) var command = &cobra.Command{ Use: "rollback APPNAME [ID]", @@ -2517,7 +2541,7 @@ func NewApplicationRollbackCommand(clientOpts *argocdclient.ClientOptions) *cobr c.HelpFunc()(c, args) os.Exit(1) } - appName, appNs := argo.ParseFromQualifiedName(args[0], "") + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) var err error depID := -1 if len(args) > 1 { @@ -2553,6 +2577,7 @@ func NewApplicationRollbackCommand(clientOpts *argocdclient.ClientOptions) *cobr command.Flags().BoolVar(&prune, "prune", false, "Allow deleting unexpected resources") command.Flags().UintVar(&timeout, "timeout", defaultCheckTimeoutSeconds, "Time out after this many seconds") command.Flags().StringVarP(&output, "output", "o", "wide", "Output format. One of: json|yaml|wide|tree|tree=detailed") + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Rollback application in namespace") return command } @@ -2702,6 +2727,7 @@ func NewApplicationTerminateOpCommand(clientOpts *argocdclient.ClientOptions) *c } func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { + var appNamespace string var command = &cobra.Command{ Use: "edit APPNAME", Short: "Edit application", @@ -2712,7 +2738,7 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co c.HelpFunc()(c, args) os.Exit(1) } - appName, appNs := argo.ParseFromQualifiedName(args[0], "") + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() defer argoio.Close(conn) app, err := appIf.Get(ctx, &application.ApplicationQuery{ @@ -2752,12 +2778,16 @@ func NewApplicationEditCommand(clientOpts *argocdclient.ClientOptions) *cobra.Co }) }, } + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only edit application in namespace") return command } func NewApplicationPatchCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command { - var patch string - var patchType string + var ( + patch string + patchType string + appNamespace string + ) command := cobra.Command{ Use: "patch APPNAME", @@ -2774,7 +2804,7 @@ func NewApplicationPatchCommand(clientOpts *argocdclient.ClientOptions) *cobra.C c.HelpFunc()(c, args) os.Exit(1) } - appName, appNs := argo.ParseFromQualifiedName(args[0], "") + appName, appNs := argo.ParseFromQualifiedName(args[0], appNamespace) conn, appIf := headless.NewClientOrDie(clientOpts, c).NewApplicationClientOrDie() defer argoio.Close(conn) @@ -2792,7 +2822,7 @@ func NewApplicationPatchCommand(clientOpts *argocdclient.ClientOptions) *cobra.C fmt.Println(string(yamlBytes)) }, } - + command.Flags().StringVarP(&appNamespace, "app-namespace", "N", "", "Only patch application in namespace") command.Flags().StringVar(&patch, "patch", "", "Patch body") command.Flags().StringVar(&patchType, "type", "json", "The type of patch being provided; one of [json merge]") return &command diff --git a/docs/user-guide/commands/argocd_app_delete.md b/docs/user-guide/commands/argocd_app_delete.md index aad06f9398ec2..827eeaab4ce7a 100644 --- a/docs/user-guide/commands/argocd_app_delete.md +++ b/docs/user-guide/commands/argocd_app_delete.md @@ -28,6 +28,7 @@ argocd app delete APPNAME [flags] ### Options ``` + -N, --app-namespace string Namespace where the application will be deleted from --cascade Perform a cascaded deletion of all application resources (default true) -h, --help help for delete -p, --propagation-policy string Specify propagation policy for deletion of application's resources. One of: foreground|background (default "foreground") diff --git a/docs/user-guide/commands/argocd_app_diff.md b/docs/user-guide/commands/argocd_app_diff.md index 139584d4fead5..18cc8f4751324 100644 --- a/docs/user-guide/commands/argocd_app_diff.md +++ b/docs/user-guide/commands/argocd_app_diff.md @@ -17,6 +17,7 @@ argocd app diff APPNAME [flags] ### Options ``` + -N, --app-namespace string Only render the difference in namespace --exit-code Return non-zero exit code when there is a diff (default true) --hard-refresh Refresh application data as well as target manifests cache -h, --help help for diff diff --git a/docs/user-guide/commands/argocd_app_edit.md b/docs/user-guide/commands/argocd_app_edit.md index 204e96cb76c0f..e581677b79c12 100644 --- a/docs/user-guide/commands/argocd_app_edit.md +++ b/docs/user-guide/commands/argocd_app_edit.md @@ -11,7 +11,8 @@ argocd app edit APPNAME [flags] ### Options ``` - -h, --help help for edit + -N, --app-namespace string Only edit application in namespace + -h, --help help for edit ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_get.md b/docs/user-guide/commands/argocd_app_get.md index cf766ed9eb0d7..d0bf744054c38 100644 --- a/docs/user-guide/commands/argocd_app_get.md +++ b/docs/user-guide/commands/argocd_app_get.md @@ -42,12 +42,13 @@ argocd app get APPNAME [flags] ### Options ``` - --hard-refresh Refresh application data as well as target manifests cache - -h, --help help for get - -o, --output string Output format. One of: json|yaml|wide|tree (default "wide") - --refresh Refresh application data when retrieving - --show-operation Show application operation - --show-params Show application parameters and overrides + -N, --app-namespace string Only get application from namespace + --hard-refresh Refresh application data as well as target manifests cache + -h, --help help for get + -o, --output string Output format. One of: json|yaml|wide|tree (default "wide") + --refresh Refresh application data when retrieving + --show-operation Show application operation + --show-params Show application parameters and overrides ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_history.md b/docs/user-guide/commands/argocd_app_history.md index 253a1dec64dd5..eefadef01f417 100644 --- a/docs/user-guide/commands/argocd_app_history.md +++ b/docs/user-guide/commands/argocd_app_history.md @@ -11,8 +11,9 @@ argocd app history APPNAME [flags] ### Options ``` - -h, --help help for history - -o, --output string Output format. One of: wide|id (default "wide") + -N, --app-namespace string Only show application deployment history in namespace + -h, --help help for history + -o, --output string Output format. One of: wide|id (default "wide") ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_patch.md b/docs/user-guide/commands/argocd_app_patch.md index 01147f022c755..0c453ea159e64 100644 --- a/docs/user-guide/commands/argocd_app_patch.md +++ b/docs/user-guide/commands/argocd_app_patch.md @@ -21,9 +21,10 @@ argocd app patch APPNAME [flags] ### Options ``` - -h, --help help for patch - --patch string Patch body - --type string The type of patch being provided; one of [json merge] (default "json") + -N, --app-namespace string Only patch application in namespace + -h, --help help for patch + --patch string Patch body + --type string The type of patch being provided; one of [json merge] (default "json") ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_rollback.md b/docs/user-guide/commands/argocd_app_rollback.md index bfcbf89631854..923023e35a2e8 100644 --- a/docs/user-guide/commands/argocd_app_rollback.md +++ b/docs/user-guide/commands/argocd_app_rollback.md @@ -11,10 +11,11 @@ argocd app rollback APPNAME [ID] [flags] ### Options ``` - -h, --help help for rollback - -o, --output string Output format. One of: json|yaml|wide|tree|tree=detailed (default "wide") - --prune Allow deleting unexpected resources - --timeout uint Time out after this many seconds + -N, --app-namespace string Rollback application in namespace + -h, --help help for rollback + -o, --output string Output format. One of: json|yaml|wide|tree|tree=detailed (default "wide") + --prune Allow deleting unexpected resources + --timeout uint Time out after this many seconds ``` ### Options inherited from parent commands diff --git a/docs/user-guide/commands/argocd_app_sync.md b/docs/user-guide/commands/argocd_app_sync.md index 81ce3fd024c5c..a0a8f8459eeaa 100644 --- a/docs/user-guide/commands/argocd_app_sync.md +++ b/docs/user-guide/commands/argocd_app_sync.md @@ -38,6 +38,7 @@ argocd app sync [APPNAME... | -l selector | --project project-name] [flags] ### Options ``` + -N, --app-namespace string Only sync an application in namespace --apply-out-of-sync-only Sync only out-of-sync resources --assumeYes Assume yes as answer for all user queries or prompts --async Do not wait for application to sync before continuing diff --git a/docs/user-guide/commands/argocd_app_wait.md b/docs/user-guide/commands/argocd_app_wait.md index 4543a6cbbcc0b..e2d3886f4d3ab 100644 --- a/docs/user-guide/commands/argocd_app_wait.md +++ b/docs/user-guide/commands/argocd_app_wait.md @@ -38,6 +38,7 @@ argocd app wait [APPNAME.. | -l selector] [flags] ### Options ``` + -N, --app-namespace string Only wait for an application in namespace --degraded Wait for degraded --delete Wait for delete --health Wait for health