Skip to content

Commit

Permalink
feat(objectstorage): add --delete-buckets flag to delete command
Browse files Browse the repository at this point in the history
Also, skip system policies when deleting policies as those can not be deleted by the user.
  • Loading branch information
kangasta committed Jan 7, 2025
1 parent 2e7cb98 commit e910060
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- Allow using unix style glob pattern as an argument. For example, if there are two servers available with titles `server-1` and `server-2`, these servers can be stopped with `upctl server stop server-*` command.
- `--delete-buckets` option to `objectstorage delete` command.

### Fixed

- In `objectstorage delete` command, delete only user defined policies when `--delete-policies` flag is enabled as trying to delete system defined policy will cause an error.

## [3.13.0] - 2024-12-13

Expand Down
59 changes: 59 additions & 0 deletions internal/commands/objectstorage/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package objectstorage

import (
"fmt"
"time"

"github.com/UpCloudLtd/upcloud-cli/v3/internal/commands"
"github.com/UpCloudLtd/upcloud-cli/v3/internal/completion"
Expand Down Expand Up @@ -31,13 +32,15 @@ type deleteCommand struct {

deleteUsers config.OptionalBoolean
deletePolicies config.OptionalBoolean
deleteBuckets config.OptionalBoolean
}

// InitCommand implements Command.InitCommand
func (c *deleteCommand) InitCommand() {
flags := &pflag.FlagSet{}
config.AddToggleFlag(flags, &c.deleteUsers, "delete-users", false, "Delete all users from the service before deleting the object storage instance.")
config.AddToggleFlag(flags, &c.deletePolicies, "delete-policies", false, "Delete all policies from the service before deleting the object storage instance.")
config.AddToggleFlag(flags, &c.deleteBuckets, "delete-buckets", false, "Delete all buckets from the service before deleting the object storage instance.")
c.AddFlags(flags)
}

Expand Down Expand Up @@ -75,6 +78,10 @@ func (c *deleteCommand) Execute(exec commands.Executor, arg string) (output.Outp
}

for _, policy := range policies {
if policy.System {
continue
}

err = svc.DeleteManagedObjectStoragePolicy(exec.Context(), &request.DeleteManagedObjectStoragePolicyRequest{
ServiceUUID: arg,
Name: policy.Name,
Expand All @@ -85,6 +92,32 @@ func (c *deleteCommand) Execute(exec commands.Executor, arg string) (output.Outp
}
}

if c.deleteBuckets.Value() {
exec.PushProgressUpdateMessage(msg, fmt.Sprintf("Deleting buckets from the service %s", arg))

buckets, err := svc.GetManagedObjectStorageBucketMetrics(exec.Context(), &request.GetManagedObjectStorageBucketMetricsRequest{ServiceUUID: arg})
if err != nil {
return commands.HandleError(exec, msg, err)
}

for _, bucket := range buckets {
err = svc.DeleteManagedObjectStorageBucket(exec.Context(), &request.DeleteManagedObjectStorageBucketRequest{
ServiceUUID: arg,
Name: bucket.Name,
})
if err != nil {
return commands.HandleError(exec, msg, err)
}
}

exec.PushProgressUpdateMessage(msg, fmt.Sprintf("Waiting buckets to be deleted from the service %s", arg))
err = waitUntilBucketsHaveBeenDeleted(exec, arg)
if err != nil {
return commands.HandleError(exec, msg, err)
}
}

exec.PushProgressUpdateMessage(msg, msg)
err := svc.DeleteManagedObjectStorage(exec.Context(), &request.DeleteManagedObjectStorageRequest{
UUID: arg,
})
Expand All @@ -96,3 +129,29 @@ func (c *deleteCommand) Execute(exec commands.Executor, arg string) (output.Outp

return output.None{}, nil
}

func waitUntilBucketsHaveBeenDeleted(exec commands.Executor, serviceUUID string) error {
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()

ctx := exec.Context()
svc := exec.All()

for i := 0; ; i++ {
select {
case <-ticker.C:
buckets, err := svc.GetManagedObjectStorageBucketMetrics(exec.Context(), &request.GetManagedObjectStorageBucketMetricsRequest{
ServiceUUID: serviceUUID,
})
if err != nil {
return err
}

if len(buckets) == 0 {
return nil
}
case <-ctx.Done():
return ctx.Err()
}
}
}
6 changes: 6 additions & 0 deletions internal/commands/objectstorage/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ func TestDeleteCommand(t *testing.T) {
flags: []string{"--delete-policies"},
req: request.DeleteManagedObjectStorageRequest{UUID: objectstorage.UUID},
},
{
name: "delete with UUID including buckets",
arg: objectstorage.UUID,
flags: []string{"--delete-buckets"},
req: request.DeleteManagedObjectStorageRequest{UUID: objectstorage.UUID},
},
{
name: "delete with UUID including users and policies",
arg: objectstorage.UUID,
Expand Down

0 comments on commit e910060

Please sign in to comment.