Add dynamic disk CLI support: disks --dynamic and delete-disk --dynamic#728
Conversation
Implements five new CLI commands and extends bosh disks: Phase 1 (TNZ-99509 - provide/detach/delete): bosh provide-disk DISK-NAME INSTANCE-GROUP/ID --disk-pool POOL --size MB bosh detach-dynamic-disk DISK-NAME bosh delete-dynamic-disk DISK-NAME Phase 2 (TNZ-109499 - create/attach standalone + list): bosh create-dynamic-disk DISK-NAME --disk-pool POOL --size MB bosh attach-dynamic-disk DISK-NAME INSTANCE-GROUP/ID bosh disks --dynamic Director interface extended with ProvideDynamicDisk, DetachDynamicDisk, DeleteDynamicDisk, DynamicDisks, CreateDynamicDisk, AttachDynamicDisk. DynamicDisk interface added with counterfeiter fake generated. 947 cmd package tests, 0 failures. [TNZ-99509] [TNZ-109499] Co-authored-by: Cursor <cursoragent@cursor.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
💤 Files with no reviewable changes (1)
WalkthroughAdds dynamic disk lifecycle contracts and HTTP client support, including listing and deletion operations. The disks command gains 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds new BOSH CLI support for managing “dynamic disks” via the Director API, including create/provide/attach/detach/delete operations and a bosh disks --dynamic listing mode.
Changes:
- Extended the
Directorinterface with dynamic disk methods and added aDynamicDiskmodel interface. - Implemented Director HTTP client calls for dynamic disk endpoints and regenerated Counterfeiter fakes.
- Added new CLI commands + options and updated
bosh disksto support--dynamic, with command-level tests.
Reviewed changes
Copilot reviewed 16 out of 18 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| director/interfaces.go | Adds DynamicDisk interface and new Director methods for dynamic disk operations. |
| director/dynamic_disks.go | Implements dynamic disk HTTP API calls and DirectorImpl delegations. |
| director/directorfakes/fake_dynamic_disk.go | New Counterfeiter fake for DynamicDisk. |
| director/directorfakes/fake_director.go | Regenerated fake to include new dynamic disk methods. |
| cmd/opts/opts.go | Adds new command option structs and --dynamic flag for bosh disks. |
| cmd/cmd.go | Wires new command opts to their command handlers. |
| cmd/provide_disk.go | Implements bosh provide-disk. |
| cmd/provide_disk_test.go | Adds tests for ProvideDiskCmd (needs gofmt). |
| cmd/create_dynamic_disk.go | Implements bosh create-dynamic-disk. |
| cmd/create_dynamic_disk_test.go | Adds tests for CreateDynamicDiskCmd. |
| cmd/attach_dynamic_disk.go | Implements bosh attach-dynamic-disk. |
| cmd/attach_dynamic_disk_test.go | Adds tests for AttachDynamicDiskCmd (needs gofmt). |
| cmd/detach_dynamic_disk.go | Implements bosh detach-dynamic-disk with confirmation. |
| cmd/detach_dynamic_disk_test.go | Adds tests for DetachDynamicDiskCmd. |
| cmd/delete_dynamic_disk.go | Implements bosh delete-dynamic-disk with confirmation. |
| cmd/delete_dynamic_disk_test.go | Adds tests for DeleteDynamicDiskCmd. |
| cmd/disks.go | Extends bosh disks to support --dynamic listing. |
| cmd/disks_test.go | Adds tests for bosh disks --dynamic and updated error message. |
Files not reviewed (2)
- director/directorfakes/fake_director.go: Generated file
- director/directorfakes/fake_dynamic_disk.go: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/attach_dynamic_disk_test.go`:
- Around line 33-40: The test setup block containing the slug initialization and
attachOpts assignment has incorrect indentation that is causing goimports/gofmt
linting failures. Fix the indentation by aligning the closing brace of the
AttachDynamicDiskOpts struct initialization so that it matches the indentation
level of the opening line where attachOpts is assigned. Ensure the closing brace
for the outer struct and the closing brace for the nested Args field are
properly aligned according to Go formatting standards.
In `@cmd/opts/opts.go`:
- Around line 126-132: The cmd/opts/opts.go file is failing goimports linting
checks. Run the goimports formatter on this file using the command goimports -w
cmd/opts/opts.go to automatically fix the import formatting issues, then commit
the formatted result. This will resolve the lint failures on both macOS and
Ubuntu CI jobs.
In `@cmd/provide_disk_test.go`:
- Around line 33-42: The ProvideDiskOpts struct initialization in the test has
improper indentation alignment. The DiskPool and Size fields within the
ProvideDiskOpts initialization are incorrectly indented and should be aligned at
the same level as the Args field. Fix the indentation of these nested fields so
they align properly according to Go's gofmt standards, ensuring the opening and
closing braces match their corresponding field declarations.
In `@director/dynamic_disks.go`:
- Around line 94-101: The function currently returns a nil error with an empty
DiskCID when the response body is empty or when the disk_cid field is missing
from the JSON response, which appears as a false success. After the
json.Unmarshal call completes (or when resultBytes is empty), add validation to
check that result.DiskCID is not empty and return an appropriate error if the
DiskCID is missing, ensuring the function fails fast on invalid responses before
returning.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 2bbbe253-7862-4302-86e1-a11acba294cb
📒 Files selected for processing (18)
cmd/attach_dynamic_disk.gocmd/attach_dynamic_disk_test.gocmd/cmd.gocmd/create_dynamic_disk.gocmd/create_dynamic_disk_test.gocmd/delete_dynamic_disk.gocmd/delete_dynamic_disk_test.gocmd/detach_dynamic_disk.gocmd/detach_dynamic_disk_test.gocmd/disks.gocmd/disks_test.gocmd/opts/opts.gocmd/provide_disk.gocmd/provide_disk_test.godirector/directorfakes/fake_director.godirector/directorfakes/fake_dynamic_disk.godirector/dynamic_disks.godirector/interfaces.go
after talking with the team, we decided only these two should be available via the CLI other operations will still be available through the API ai-assisted=yes [TNZ-99509] [TNZ-109499] Signed-off-by: Nishad Mathur <nishad.mathur@broadcom.com>
- Add DiskPoolName() to DynamicDisk interface and DynamicDiskImpl - Include disk_pool_name field in DynamicDiskResp (GET /dynamic_disks) - Show Disk Pool column in `bosh disks --dynamic` table output - Update FakeDynamicDisk with DiskPoolName() counterfeiter methods [TNZ-99509] [TNZ-109499] Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
cmd/disks.go (1)
22-27: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winReject conflicting disk-list selectors.
With the new early
opts.Dynamicbranch,bosh disks --orphaned --dynamicsilently ignores--orphanedand returns only dynamic disks. Validate the combination before dispatching so users cannot receive a different resource set from the flags they supplied.Suggested fix
func (c DisksCmd) Run(opts DisksOpts) error { + if opts.Orphaned && opts.Dynamic { + return errors.New("Only one of --orphaned or --dynamic may be used") + } if opts.Dynamic { return c.runDynamic() }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cmd/disks.go` around lines 22 - 27, Validate the --orphaned and --dynamic combination before the early opts.Dynamic dispatch in the disk-list command. Reject cases where both selectors are enabled, then preserve the existing runDynamic and unsupported-selector behavior for valid flag combinations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/opts/opts.go`:
- Around line 752-754: The DeleteDiskOpts positional argument is misleadingly
labeled CID when DeleteDiskCmd.Run forwards it to DeleteDynamicDisk as a name
under --dynamic. Update the positional argument’s label/field definition to a
mode-neutral name such as DISK-CID-OR-NAME, preserving its use for both regular
and dynamic deletion.
---
Outside diff comments:
In `@cmd/disks.go`:
- Around line 22-27: Validate the --orphaned and --dynamic combination before
the early opts.Dynamic dispatch in the disk-list command. Reject cases where
both selectors are enabled, then preserve the existing runDynamic and
unsupported-selector behavior for valid flag combinations.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 1aa9dd29-d514-453b-8937-90a2c9e1f231
📒 Files selected for processing (9)
cmd/delete_disk.gocmd/delete_disk_test.gocmd/disks.gocmd/disks_test.gocmd/opts/opts.gocmd/opts/opts_test.godirector/directorfakes/fake_dynamic_disk.godirector/dynamic_disks.godirector/interfaces.go
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 10 changed files in this pull request and generated 7 comments.
Files not reviewed (2)
- director/directorfakes/fake_director.go: Generated file
- director/directorfakes/fake_dynamic_disk.go: Generated file
Comments suppressed due to low confidence (4)
director/dynamic_disks.go:93
- JSON POST requests here pass nil header setters (e.g. ProvideDynamicDisk/CreateDynamicDisk/AttachDynamicDisk). Most other Director client methods explicitly set
Content-Type: application/jsonfor JSON payloads; without it these endpoints may fail against Directors that require the header.
resultBytes, err := c.taskClientRequest.PostResult("/dynamic_disks/provide", bodyBytes, nil)
if err != nil {
director/dynamic_disks.go:76
- There are no director-package HTTP client specs covering the new dynamic disk endpoints (provide/detach/delete/list/create/attach). The director package has extensive request/response tests for other endpoints; adding similar specs would help prevent request-path/body/tag regressions.
func (c Client) ProvideDynamicDisk(instanceID, diskName, diskPool string, sizeInMB int, metadata map[string]interface{}) (string, error) {
cmd/disks.go:28
DisksCmd.Runtreats--dynamicas higher priority than--orphaned. If a user supplies both flags, the command will silently ignore--orphaned, which is ambiguous; consider rejecting the combination with a clear error message.
func (c DisksCmd) Run(opts DisksOpts) error {
if opts.Dynamic {
return c.runDynamic()
}
if !opts.Orphaned {
return errors.New("Only --orphaned or --dynamic is supported") //nolint:staticcheck
}
cmd/opts/opts.go:760
DeleteDiskOpts --dynamicreusesDeleteDiskArgs.CIDwithpositional-arg-name:"CID", but the flag description says it deletes a dynamic disk by name. This will likely show confusing help output (CID vs disk name) and blurs the meaning of the positional argument.
type DeleteDiskOpts struct {
Args DeleteDiskArgs `positional-args:"true" required:"true"`
Dynamic bool `long:"dynamic" description:"Delete a dynamic disk by name"`
cmd
}
type DeleteDiskArgs struct {
CID string `positional-arg-name:"CID"`
}
disks --dynamic and delete-disk --dynamic
- disks: reject --orphaned and --dynamic used together - delete-disk: relabel positional arg CID -> CID-OR-NAME (deletes by name under --dynamic) - director: remove unwired provide/create/attach/detach dynamic disk methods (scope is list + delete) - director: validate non-empty disk name in DeleteDynamicDisk - director: add unit tests for DynamicDisks and DeleteDynamicDisk - regenerate director fakes ai-assisted=yes [TNZ-99509] Dynamic disk CLI commands Signed-off-by: Nishad Mathur <nishad.mathur@broadcom.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 11 changed files in this pull request and generated 1 comment.
Files not reviewed (2)
- director/directorfakes/fake_director.go: Generated file
- director/directorfakes/fake_dynamic_disk.go: Generated file
Comments suppressed due to low confidence (1)
cmd/opts/opts.go:749
DisksOptsadds a new--dynamicflag, but the opts-tag test suite only asserts theOrphanedtag for this struct. This makes it easy to accidentally break the CLI flag wiring forbosh disks --dynamicwithout a unit test catching it. Consider adding aDisksOpts.Dynamicstruct-tag assertion incmd/opts/opts_test.goalongside the existingDisksOpts.Orphanedtest.
type DisksOpts struct {
Orphaned bool `long:"orphaned" short:"o" description:"List orphaned disks"`
Dynamic bool `long:"dynamic" description:"List dynamic disks"`
cmd
- opts: assert DisksOpts.Dynamic struct tag in tests - director: drop unused client field from DynamicDiskImpl ai-assisted=yes [TNZ-99509] Dynamic disk CLI commands Signed-off-by: Nishad Mathur <nishad.mathur@broadcom.com>
Summary
Adds CLI support for BOSH Director dynamic disks, scoped to listing and deletion:
bosh disks --dynamic— list all dynamic disks (name, CID, size, disk pool,deployment, instance, AZ, CPI)
bosh delete-disk CID-OR-NAME --dynamic— delete a dynamic disk by name(with confirmation)
Provide/create/attach/detach are intentionally not included in this PR and
will follow once their Director endpoints land.
Changes
director/interfaces.go— addedDynamicDiskinterface +DynamicDisks()andDeleteDynamicDisk()Director methodsdirector/dynamic_disks.go— HTTP client implementation for the list + deleteendpoints (delete validates a non-empty disk name)
director/dynamic_disks_test.go— request-path/response-parsing/error specsdirector/directorfakes/— regeneratedFakeDirector+ newFakeDynamicDiskcmd/opts/opts.go—--dynamicflag onDisksOptsandDeleteDiskOpts(positional arg relabeled
CID-OR-NAME)cmd/disks.go—--dynamiclisting; rejects--orphaned --dynamictogethercmd/delete_disk.go—--dynamicdeletes by nameTest plan
go build ./...— clean buildgo test ./cmd/... ./director/...— all passinggo generate ./director/...— fakes regenerated cleanlygofmt -l— cleanRelated: TNZ-99509, TNZ-109499