Files
velero/design/cli-dynamic-resource-completion_design.md
893188aa63
Run the E2E test on kind / get-go-version (push) Failing after 58s
Run the E2E test on kind / build (push) Has been skipped
Run the E2E test on kind / setup-test-matrix (push) Successful in 3s
Run the E2E test on kind / run-e2e-test (push) Has been skipped
Main CI / get-go-version (push) Successful in 11s
Main CI / Build (push) Failing after 24s
Add design doc for dynamic CLI resource autocompletion (#9969)
* Add design doc for dynamic CLI resource autocompletion

Proposes adding ValidArgsFunction and RegisterFlagCompletionFunc
to all Velero CLI commands that accept existing resource names,
covering 20 commands and 5 flags across 6 resource types.

Signed-off-by: Joseph <jvaikath@redhat.com>

* Update design doc to reflect implementation details

- Document the shared completeNames helper using apimachinery's
  meta.ExtractList/Accessor instead of six duplicated functions
- Add 3-second timeout, deep-copy, and per-item error resilience details
- Update generics alternative to explain why they were unnecessary
- Add testing section describing unit test coverage

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>

* Add RBAC and bash compatibility notes to design doc

- Note that users without list permission receive empty completions
- Document bash 4.0+ requirement and macOS bash 3.2 workarounds

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>

* Add issue reference to design doc abstract

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>

* Address PR review comments: add debug flag completion and arg deduplication

- Add `debug --backup` and `--restore` to flag completion table (chlins)
- Document deduplication of already-typed args in completeNames (chlins)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>

* Trim design doc to focus on reviewable decisions

Remove implementation mechanics (code snippets, type alias justification,
deep-copy rationale, closure internals) that are verifiable from code.
Drop bash v1-to-v2 migration (v1 already supports ValidArgsFunction).
Fix flag count from 7 to 9 (add schedule create inherited flags).
Add Open Issues section for single-arg commands, comma-separated flag
values, and optional v2 migration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Joseph <jvaikath@redhat.com>

---------

Signed-off-by: Joseph <jvaikath@redhat.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-07-16 10:57:53 -07:00

6.6 KiB

Dynamic Resource Autocompletion for Velero CLI

Abstract

Velero CLI has no dynamic shell completion for resource names (#9782). Tab-completing velero backup describe <TAB> produces no suggestions, even when backups exist on the cluster. This proposal adds dynamic completion for all commands that take Velero resource names as positional arguments or flag values (using cobra's built-in completion callbacks).

Background

Shell completion is a standard UX feature in Kubernetes CLI tooling. Tools like kubectl, oc, and helm all provide dynamic completions that query the cluster to suggest resource names. Velero's velero completion command generates completion scripts, but the CLI does not register any completion callbacks, so tab-completing resource names produces no suggestions. Cobra's completion infrastructure already supports dynamic completion across all shell types (bash, zsh, fish); Velero just needs to register the callbacks.

Goals

  • Add dynamic shell completion for all 20 commands that accept existing Velero resource names as positional arguments.
  • Add dynamic flag completion for 9 flags that reference existing Velero resources.
  • Fail silently when the cluster is unreachable, matching the behavior of kubectl.

Non Goals

  • Completing positional arguments for commands that take new resource names (e.g., velero backup create <new-name>).
  • Completing flags that take non-resource values (e.g., --include-namespaces, --labels).
  • Adding completion for hidden internal commands (data-mover, pod-volume, repo-maintenance).
  • Caching cluster state across tab presses.

High-Level Design

A centralized set of completion functions is added to pkg/cmd/cli/completion_functions.go. Each function takes a client.Factory, returns a closure matching cobra's completion function signature, and lists resources of a specific type from the cluster. Each command constructor wires the appropriate completion function onto its cobra.Command via ValidArgsFunction or RegisterFlagCompletionFunc.

Detailed Design

Completion functions

A new file pkg/cmd/cli/completion_functions.go provides six public functions:

Function Resource listed
CompleteBackupNames(f client.Factory) BackupList
CompleteRestoreNames(f client.Factory) RestoreList
CompleteScheduleNames(f client.Factory) ScheduleList
CompleteBackupStorageLocationNames(f client.Factory) BackupStorageLocationList
CompleteVolumeSnapshotLocationNames(f client.Factory) VolumeSnapshotLocationList
CompleteBackupRepositoryNames(f client.Factory) BackupRepositoryList

All six delegate to a single private completeNames helper that uses meta.ExtractList() and meta.Accessor() to extract names from any ObjectList type.

The completion closure:

  • Lists resources in the configured namespace with a 3-second context timeout.
  • Filters by strings.HasPrefix(name, toComplete).
  • Removes names already present in args to avoid re-suggesting previously typed arguments.
  • Returns cobra.ShellCompDirectiveNoFileComp in all cases (success or failure).
  • Fails silently on any error (client construction, API call, extraction), returning no suggestions.

Commands wired with ValidArgsFunction

Package Commands Completion function
backup get, describe, delete, logs, download CompleteBackupNames
restore get, describe, delete, logs CompleteRestoreNames
schedule get, describe, delete, pause, unpause CompleteScheduleNames
backuplocation get, set, delete CompleteBackupStorageLocationNames
snapshotlocation get, set CompleteVolumeSnapshotLocationNames
repo get CompleteBackupRepositoryNames

Flags wired with RegisterFlagCompletionFunc

Command Flag Completion function
backup create --from-schedule CompleteScheduleNames
backup create --storage-location CompleteBackupStorageLocationNames
backup create --volume-snapshot-locations * CompleteVolumeSnapshotLocationNames
schedule create --storage-location CompleteBackupStorageLocationNames
schedule create --volume-snapshot-locations * CompleteVolumeSnapshotLocationNames
restore create --from-backup CompleteBackupNames
restore create --from-schedule CompleteScheduleNames
debug --backup CompleteBackupNames
debug --restore CompleteRestoreNames

* See Open Issues — comma-separated values.

Alternatives Considered

The approach follows the standard cobra pattern for dynamic completion. No alternative designs were considered.

Security Considerations

Completion functions issue read-only list requests using the user's existing kubeconfig credentials. No new permissions are required beyond what the user already has. Users without list permission receive empty completions, consistent with kubectl's behavior.

Compatibility

Existing command behavior is unaffected. ValidArgsFunction is only invoked during shell completion; it has no effect on normal command execution. Completion respects the --namespace flag and VELERO_NAMESPACE environment variable.

Testing

Unit tests in pkg/cmd/cli/completion_functions_test.go cover:

  • Core logic: Table-driven tests across all six resource types: empty cluster, full match, prefix filtering, no match.
  • Error resilience: Factory errors return nil completions without panicking.
  • Wrapper isolation: Each Complete*Names wrapper returns only its own resource type.

Open Issues

  • Single-argument commands: Commands like backup download and backup logs accept exactly one positional argument, but cobra still calls the completion function after one arg is provided. The completion function should check len(args) and return no suggestions when the maximum arg count is reached. The approach (parameter on the helper vs. per-command wrapper) is TBD.

  • Comma-separated flag values: --volume-snapshot-locations accepts comma-separated values. Completion only works for the first value because toComplete contains the full string including commas. Completing subsequent values would require comma-aware splitting, similar to how kubectl handles this.

  • Bash v1 to v2 migration: The current bash completion generator already supports dynamic completion through cobra's __complete mechanism, so migration to v2 is not required for this feature. A separate migration could be considered for other benefits (cleaner generated scripts, ActiveHelp support) but would require users to regenerate their completion scripts.