feat: Add on-conflict flag to influx-cli - #582
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an --on-conflict option to influx restore so users can control how bucket name conflicts are handled during restore operations.
Changes:
- Adds
--on-conflictflag wiring to theinflux restorecommand andrestore.Params. - Introduces conflict-option parsing/serialization in the restore client and forwards the choice to the restore bucket-metadata API.
- Extends the generated restore API request builder to include an
onConflictquery parameter.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| cmd/influx/restore.go | Adds the --on-conflict CLI flag and validates the provided value. |
| clients/restore/restore.go | Defines conflict options, plumbs them into restore flows, and sends onConflict on restore bucket-metadata requests. |
| api/api_restore.gen.go | Adds an optional onConflict query param to the generated PostRestoreBucketMetadata request. |
Files not reviewed (1)
- api/api_restore.gen.go: Generated file
Suppressed comments (1)
clients/restore/restore.go:373
restoreBucketLegacyacceptsonConflictbut currently never uses it. As a result,--on-conflict=skip|replacewill have no effect against legacy (v2.0.x) servers, and restores will still fail on bucket name conflicts (or behave as the legacy API default). The legacy path should implement the same conflict behavior (skip/replace/error), e.g., by checking for an existing bucket by org+name and then either short-circuiting (skip) or deleting/recreating (replace).
func (c Client) restoreBucketLegacy(ctx context.Context, bkt br.ManifestBucketEntry, onConflict ConflictOption) (map[int64]int64, error) {
log.Printf("INFO: Restoring bucket %q as %q using legacy APIs\n", bkt.BucketID, bkt.BucketName)
// Legacy APIs require creating the bucket as a separate call.
rps := make([]api.RetentionRule, len(bkt.RetentionPolicies))
for i, rp := range bkt.RetentionPolicies {
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- api/api_restore.gen.go: Generated file
Suppressed comments (2)
clients/restore/restore.go:320
- Validation happens only after
restoreOrghas already run. For callers that useClient.Restoredirectly, an invalid value can therefore create an organization before failing, and it is never rejected at all when no bucket matches. Parseparams.OnConflictonce before entering the bucket loop, then reuse the parsed option here.
onConflict, err := ToConflictOption(params.OnConflict)
if err != nil {
return err
clients/restore/restore.go:371
- This legacy implementation never uses
onConflict. SincepartialRestoreroutes v2.0.x servers here,--on-conflict skipand--on-conflict replacestill attemptPostBucketsand fail when the bucket exists, silently violating the requested behavior. Implement the corresponding existing-bucket handling here, or explicitly reject unsupported modes before any restore side effects.
func (c Client) restoreBucketLegacy(ctx context.Context, bkt br.ManifestBucketEntry, onConflict ConflictOption) (map[int64]int64, error) {
…ta/influx-cli into db/27578/restore-conflict
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Files not reviewed (1)
- api/api_restore.gen.go: Generated file
Suppressed comments (2)
clients/restore/restore.go:321
- Validation occurs only after a manifest bucket matches and after
restoreOrgmay create an organization. Consequently, programmatic callers can receive success for an invalid option when no bucket matches, or mutate server state before receiving the validation error. Parseparams.OnConflictonce at the start ofpartialRestore, before the loop and any API calls, and reuse the parsed value.
onConflict, err := ToConflictOption(params.OnConflict)
if err != nil {
return err
}
clients/restore/restore.go:371
onConflictis never used in the legacy implementation, so against the supported v2.0.x server path bothskipandreplacestill callPostBucketsand fail when the bucket already exists. Implement the three conflict modes for this path (or reject unsupported modes explicitly) instead of silently ignoring the flag.
func (c Client) restoreBucketLegacy(ctx context.Context, bkt br.ManifestBucketEntry, onConflict ConflictOption) (map[int64]int64, error) {
| }, | ||
| &cli.StringFlag{ | ||
| Name: "on-conflict", | ||
| Usage: "How to handle conflicting buckets -- i.e. buckets that already exist. Valid inputs: 'skip', 'replace', or 'error'.", |
There was a problem hiding this comment.
I think we should state what the default is when the option is omitted. I thought maybe the CLI library would include this by default, but I just tried it and it does not.
Allows for user to indicate what to do during restore when there are buckets that are the same name as the ones being restored.