feat: add backup and restore commands to kubectl-documentdb plugin - #449
feat: add backup and restore commands to kubectl-documentdb plugin#449WentingWu666666 wants to merge 2 commits into
Conversation
The kubectl plugin could inspect and promote clusters but had no coverage for the backup lifecycle, so operators had to hand-write Backup, ScheduledBackup, and recovery-bootstrapped DocumentDB manifests. Add: - `backup create` - creates a Backup for a DocumentDB, with an optional `--retention-days` override and `--wait` that polls until the backup reaches a terminal phase (exiting non-zero on failed/skipped). - `backup list` - lists backups with phase, owning schedule, start and stop times, expiry, and the captured schema version, filterable by `--documentdb`, `--scheduled-backup`, and `--status`. - `backup schedule create|list` - manages ScheduledBackup resources. The cron expression is validated client-side with the same `cron.ParseStandard` call the operator uses, so accept/reject semantics match exactly. - `restore` - creates a *new* DocumentDB that bootstraps from an existing backup. The source cluster's spec is cloned as unstructured data so unknown fields survive, `spec.clusterReplication` is dropped because a restored cluster starts standalone, and `spec.bootstrap.recovery.backup` is injected. `--dry-run` prints the manifest instead of creating it and `--source-documentdb` supplies a template when the original cluster is gone. The GVR helpers shared by these commands move into cmd/gvr.go, and the hand-rolled fake dynamic client used by the tests gains Create, a label-selector-aware List, and per-Kind object keying so multiple resource types can coexist in one fake. Closes documentdb#139 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Wenting Wu <wentingwu@microsoft.com>
There was a problem hiding this comment.
Pull request overview
Adds backup lifecycle coverage to the kubectl documentdb plugin so operators can create/list backups and schedules, and restore a backup into a new DocumentDB without hand-authoring CR manifests. This fits into the repo’s day-two ops tooling by extending the existing plugin commands (status/events/promote) with backup/restore workflows.
Changes:
- Introduces
backup create|list,backup schedule create|list, andrestorecommands (including--wait/--dry-runflows). - Refactors shared GroupVersionResource construction into
cmd/gvr.goand updates existing commands to use it. - Enhances the fake dynamic client to support Create and label-selector-aware List to enable broader unit test coverage; updates docs and changelog accordingly.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| documentdb-kubectl-plugin/kubectl-plugin.md | Documents new backup/restore commands and flags for the plugin guide copy in the plugin module. |
| docs/operator-public-documentation/preview/kubectl-plugin.md | Mirrors the plugin guide updates in public operator documentation. |
| documentdb-kubectl-plugin/go.mod | Promotes existing indirect deps to direct deps to support new command implementation. |
| documentdb-kubectl-plugin/cmd/root.go | Registers new backup and restore commands with the root CLI. |
| documentdb-kubectl-plugin/cmd/backup.go | Implements backup create/list and scheduled backup create/list commands plus shared helpers. |
| documentdb-kubectl-plugin/cmd/restore.go | Implements restore command that clones a source DocumentDB spec and injects bootstrap.recovery.backup. |
| documentdb-kubectl-plugin/cmd/gvr.go | Centralizes GVR helpers for DocumentDB/Backup/ScheduledBackup resources. |
| documentdb-kubectl-plugin/cmd/status.go | Switches DocumentDB GVR construction to the shared helper. |
| documentdb-kubectl-plugin/cmd/promote.go | Switches DocumentDB GVR construction to the shared helper. |
| documentdb-kubectl-plugin/cmd/fake_dynamic_test.go | Extends fake dynamic client to support Create, label selector List, and kind-scoped object keying. |
| documentdb-kubectl-plugin/cmd/backup_test.go | Adds unit tests for backup and scheduled-backup commands, filtering, and --wait paths. |
| documentdb-kubectl-plugin/cmd/restore_test.go | Adds unit tests for restore validation, spec cloning, dry-run, already-exists, and wait behavior. |
| CHANGELOG.md | Adds an Unreleased entry describing the new kubectl backup/restore functionality and links to docs. |
Suppressed comments (1)
documentdb-kubectl-plugin/cmd/backup.go:487
- The validation allows
--retention-daysto be 0 (meaning "use the cluster default"), but this error message claims the value must be > 0. This is misleading for users who pass 0 explicitly.
if o.retentionDays < 0 {
return fmt.Errorf("--retention-days must be greater than zero, got %d", o.retentionDays)
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if o.retentionDays < 0 { | ||
| return fmt.Errorf("--retention-days must be greater than zero, got %d", o.retentionDays) | ||
| } |
The kubectl-documentdb plugin is a separate Go module that falls outside the path filters of test-unit.yml, so its tests were never executed in CI -- govulncheck was the only job that looked at the module at all. Add a workflow that runs gofmt, build, vet and the race-enabled unit tests for it, filtered on the plugin directory plus operator/src/api (which the plugin consumes through a replace directive). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Wenting Wu <wentingwu@microsoft.com>
|
🤖 Auto-triaged by documentdb-triage-tool. Applied: Reasoningcomponent from path globs (kubectl-plugin, docs, test, ci, dependencies); effort from diff stats (2146+24 LOC, 14 files); LLM: Adds five new backup/restore commands to the kubectl plugin, involving cross-cutting refactors of GVR helpers, test infrastructure, and new manifest generation logic — a substantial cross-file feature addition. If a label is wrong, remove it manually and ping |
Closes #139
What
The
kubectl documentdbplugin could inspect (status,events) and fail over (promote) clusters, but had no coverage for the backup lifecycle. Operators had to hand-writeBackup,ScheduledBackup, and recovery-bootstrappedDocumentDBmanifests.This adds five commands:
backup createBackupfor a DocumentDB, with--retention-daysand an optional--waitbackup listbackup schedule createScheduledBackupwith client-side cron validationbackup schedule listrestoreNotable design points
restorenever overwrites. It always creates a newDocumentDB. The source cluster's spec is cloned as unstructured data so unknown/future fields survive the round-trip,spec.clusterReplicationis dropped (a restored cluster starts standalone), andspec.bootstrap.recovery.backupis injected.--dry-runprints the manifest instead of creating it, and--source-documentdbsupplies a spec template for the DR case where the original cluster is gone.backup schedule createvalidates with the samecron.ParseStandardcall the ScheduledBackup controller uses, so anything the plugin accepts the operator accepts.--waitreusespreview.BackupStatus.IsDone()so the plugin and operator stay in lockstep as phases evolve. Askippedbackup (standby cluster) exits non-zero under--wait.scheduledbackuplabel the operator already sets, sobackup list --scheduled-backup <name>works without extra API fields.backup create/backup schedule createverify the target DocumentDB exists first, rather than leaving an orphaned resource the operator can only reject on reconcile.Refactors
cmd/gvr.go;status.goandpromote.gonow use them.Create, a label-selector-awareList, and per-Kindobject keying (it previously keyed onnamespace/nameonly, which collides once more than one resource type is in play).CI
While validating this I found the
documentdb-kubectl-pluginmodule has no test execution in CI at all —test-unit.ymlis path-filtered tooperator/src/**, so govulncheck was the only job that ever looked at the module. The plugin's pre-existing tests (and the ~24 added here) never ran on a PR.This adds
.github/workflows/test-kubectl-plugin.yml, which runsgofmt,go build,go vet, and race-enabledgo testfor the module. It is filtered ondocumentdb-kubectl-plugin/**plusoperator/src/api/**(the plugin consumesapi/previewthrough areplacedirective, so API changes can break it). It is a separate workflow rather than new paths ontest-unit.ymlso plugin-only PRs do not needlessly spin up the operator and Helm jobs. Happy to fold it intotest-unit.ymlinstead if maintainers prefer.Dependencies
go.modpromotes four already-present indirect deps to direct (cloudnative-pg,robfig/cron,sigs.k8s.io/yaml).go.sumis unchanged — no new modules, no supply-chain delta.Testing
cmd/backup_test.goandcmd/restore_test.gocovering flag validation, spec cloning, the phase guard, dry-run, already-exists, status filtering, and both--waitpaths.gofmt -l,go build ./...,go vet ./...,go test -race -count=1 ./...all clean.--helpoutput and error paths (missing required flags, invalid cron).backup list/backup schedule listread-only against a live AKS cluster.Backup,ScheduledBackup, and the restore-shapedDocumentDBwithbootstrap.recoveryand noclusterReplication) against the real CRDs and validating webhook viakubectl apply --dry-run=server. All three accepted; nothing persisted.Docs
Both copies of
kubectl-plugin.md(documentdb-kubectl-plugin/anddocs/operator-public-documentation/preview/) are updated and remain byte-identical.CHANGELOG.mdgets an[Unreleased]entry.Open questions for reviewers
restorebe top-level (as here) or nested asbackup restore?--wait, askippedbackup currently exits non-zero. Would you prefer a warning + exit 0?