Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cmd/delete_disk.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ func (c DeleteDiskCmd) Run(opts DeleteDiskOpts) error {
return err
}

if opts.Dynamic {
return c.director.DeleteDynamicDisk(opts.Args.CID)
}

disk, err := c.director.FindOrphanDisk(opts.Args.CID)
if err != nil {
return err
Expand Down
34 changes: 34 additions & 0 deletions cmd/delete_disk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,39 @@ var _ = Describe("DeleteDiskCmd", func() {
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})

Context("when --dynamic", func() {
BeforeEach(func() {
deleteDiskOpts = opts.DeleteDiskOpts{
Args: opts.DeleteDiskArgs{CID: "my-disk"},
Dynamic: true,
}
})

It("deletes the dynamic disk", func() {
err := act()
Expect(err).ToNot(HaveOccurred())

Expect(director.DeleteDynamicDiskArgsForCall(0)).To(Equal("my-disk"))
})

It("returns error if deletion fails", func() {
director.DeleteDynamicDiskReturns(errors.New("fake-err"))

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})

It("does not delete if confirmation is rejected", func() {
ui.AskedConfirmationErr = errors.New("stop")

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("stop"))

Expect(director.DeleteDynamicDiskCallCount()).To(Equal(0))
})
})
})
})
49 changes: 48 additions & 1 deletion cmd/disks.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,16 @@ func NewDisksCmd(ui boshui.UI, director boshdir.Director) DisksCmd {
}

func (c DisksCmd) Run(opts DisksOpts) error {
if opts.Orphaned && opts.Dynamic {
return errors.New("Only one of --orphaned or --dynamic is supported") //nolint:staticcheck
}

if opts.Dynamic {
return c.runDynamic()
}
Comment thread
julian-hj marked this conversation as resolved.

Comment thread
julian-hj marked this conversation as resolved.
if !opts.Orphaned {
return errors.New("Only --orphaned is supported") //nolint:staticcheck
return errors.New("Only --orphaned or --dynamic is supported") //nolint:staticcheck
}

disks, err := c.director.OrphanDisks()
Expand Down Expand Up @@ -56,3 +64,42 @@ func (c DisksCmd) Run(opts DisksOpts) error {

return nil
}

func (c DisksCmd) runDynamic() error {
disks, err := c.director.DynamicDisks()
if err != nil {
return err
}

table := boshtbl.Table{
Content: "dynamic disks",
Header: []boshtbl.Header{
boshtbl.NewHeader("Name"),
boshtbl.NewHeader("Disk CID"),
boshtbl.NewHeader("Size"),
boshtbl.NewHeader("Disk Pool"),
boshtbl.NewHeader("Deployment"),
boshtbl.NewHeader("Instance"),
boshtbl.NewHeader("AZ"),
boshtbl.NewHeader("CPI"),
},
SortBy: []boshtbl.ColumnSort{{Column: 0}},
}

for _, d := range disks {
table.Rows = append(table.Rows, []boshtbl.Value{
boshtbl.NewValueString(d.Name()),
boshtbl.NewValueString(d.DiskCID()),
boshtbl.NewValueMegaBytes(d.Size()),
boshtbl.NewValueString(d.DiskPoolName()),
boshtbl.NewValueString(d.DeploymentName()),
boshtbl.NewValueString(d.InstanceName()),
boshtbl.NewValueString(d.AvailabilityZone()),
boshtbl.NewValueString(d.CPI()),
})
}

c.ui.PrintTable(table)

return nil
}
72 changes: 71 additions & 1 deletion cmd/disks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,77 @@ var _ = Describe("DisksCmd", func() {
})

It("returns error if orphaned disks were not requested", func() {
Expect(act()).To(Equal(errors.New("Only --orphaned is supported")))
Expect(act()).To(Equal(errors.New("Only --orphaned or --dynamic is supported")))
})

It("returns error if both --orphaned and --dynamic are requested", func() {
disksOpts.Orphaned = true
disksOpts.Dynamic = true
Expect(act()).To(Equal(errors.New("Only one of --orphaned or --dynamic is supported")))
})

Context("when dynamic disks requested", func() {
BeforeEach(func() {
disksOpts.Dynamic = true
})

It("lists dynamic disks", func() {
disks := []boshdir.DynamicDisk{
&fakedir.FakeDynamicDisk{
NameStub: func() string { return "my-disk" },
DiskCIDStub: func() string { return "disk-cid-1" },
SizeStub: func() uint64 { return 2048 },
DiskPoolNameStub: func() string { return "large" },
DeploymentNameStub: func() string { return "my-deployment" },
InstanceNameStub: func() string { return "api/abc123" },
AvailabilityZoneStub: func() string { return "z1" },
CPIStub: func() string { return "aws_cpi" },
},
}

director.DynamicDisksReturns(disks, nil)

err := act()
Expect(err).ToNot(HaveOccurred())

Expect(ui.Table).To(Equal(boshtbl.Table{
Content: "dynamic disks",

Header: []boshtbl.Header{
boshtbl.NewHeader("Name"),
boshtbl.NewHeader("Disk CID"),
boshtbl.NewHeader("Size"),
boshtbl.NewHeader("Disk Pool"),
boshtbl.NewHeader("Deployment"),
boshtbl.NewHeader("Instance"),
boshtbl.NewHeader("AZ"),
boshtbl.NewHeader("CPI"),
},

SortBy: []boshtbl.ColumnSort{{Column: 0}},

Rows: [][]boshtbl.Value{
{
boshtbl.NewValueString("my-disk"),
boshtbl.NewValueString("disk-cid-1"),
boshtbl.NewValueMegaBytes(2048),
boshtbl.NewValueString("large"),
boshtbl.NewValueString("my-deployment"),
boshtbl.NewValueString("api/abc123"),
boshtbl.NewValueString("z1"),
boshtbl.NewValueString("aws_cpi"),
},
},
}))
})

It("returns error if dynamic disks cannot be retrieved", func() {
director.DynamicDisksReturns(nil, errors.New("fake-err"))

err := act()
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("fake-err"))
})
})
})
})
6 changes: 4 additions & 2 deletions cmd/opts/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -745,16 +745,18 @@ type DeleteNetworkArgs struct {

type DisksOpts struct {
Orphaned bool `long:"orphaned" short:"o" description:"List orphaned disks"`
Dynamic bool `long:"dynamic" description:"List dynamic disks"`
cmd
Comment thread
julian-hj marked this conversation as resolved.
}

type DeleteDiskOpts struct {
Args DeleteDiskArgs `positional-args:"true" required:"true"`
Args DeleteDiskArgs `positional-args:"true" required:"true"`
Dynamic bool `long:"dynamic" description:"Delete a dynamic disk by name"`
Comment thread
coderabbitai[bot] marked this conversation as resolved.
cmd
}

type DeleteDiskArgs struct {
CID string `positional-arg-name:"CID"`
CID string `positional-arg-name:"CID-OR-NAME"`
}

type OrphanDiskOpts struct {
Expand Down
18 changes: 17 additions & 1 deletion cmd/opts/opts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2205,6 +2205,14 @@ var _ = Describe("Opts", func() {
))
})
})

Describe("Dynamic", func() {
It("contains desired values", func() {
Expect(getStructTagForName("Dynamic", opts)).To(Equal(
`long:"dynamic" description:"List dynamic disks"`,
))
})
})
})

Describe("DeleteDiskOpts", func() {
Expand All @@ -2219,6 +2227,14 @@ var _ = Describe("Opts", func() {
Expect(getStructTagForName("Args", opts)).To(Equal(`positional-args:"true" required:"true"`))
})
})

Describe("Dynamic", func() {
It("contains desired values", func() {
Expect(getStructTagForName("Dynamic", opts)).To(Equal(
`long:"dynamic" description:"Delete a dynamic disk by name"`,
))
})
})
})

Describe("DeleteDiskArgs", func() {
Expand All @@ -2231,7 +2247,7 @@ var _ = Describe("Opts", func() {
Describe("CID", func() {
It("contains desired values", func() {
Expect(getStructTagForName("CID", opts)).To(Equal(
`positional-arg-name:"CID"`,
`positional-arg-name:"CID-OR-NAME"`,
))
})
})
Expand Down
Loading