From 4793430b728f54e4249858c85c2de740a2048bd7 Mon Sep 17 00:00:00 2001 From: Toni Kangas Date: Fri, 1 Jul 2022 16:21:17 +0300 Subject: [PATCH] feat(db): add database start and database stop commands --- CHANGELOG.md | 2 +- internal/commands/all/all.go | 2 + internal/commands/database/start.go | 53 ++++++++++++++++++++++ internal/commands/database/start_test.go | 44 ++++++++++++++++++ internal/commands/database/stop.go | 58 ++++++++++++++++++++++++ internal/commands/database/stop_test.go | 44 ++++++++++++++++++ internal/mock/mock.go | 12 ++++- 7 files changed, 212 insertions(+), 3 deletions(-) create mode 100644 internal/commands/database/start.go create mode 100644 internal/commands/database/start_test.go create mode 100644 internal/commands/database/stop.go create mode 100644 internal/commands/database/stop_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 780c89d1d..91a441968 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Add `--show-ip-addresses` flag to `server list` command to optionally include IP addresses in command output. -- Add `database connection list`, and `database connection cancel` commands. +- Add `database connection list`, `database connection cancel`, `database start`, and `database stop` commands. ### Changed - Make `--family` parameter of `server firewall create` command optional to allow editing the default rules. diff --git a/internal/commands/all/all.go b/internal/commands/all/all.go index 5ceb00b5f..27f02ba34 100644 --- a/internal/commands/all/all.go +++ b/internal/commands/all/all.go @@ -107,6 +107,8 @@ func BuildCommands(rootCmd *cobra.Command, conf *config.Config) { commands.BuildCommand(database.ShowCommand(), databaseCommand.Cobra(), conf) commands.BuildCommand(database.TypesCommand(), databaseCommand.Cobra(), conf) commands.BuildCommand(database.PlansCommand(), databaseCommand.Cobra(), conf) + commands.BuildCommand(database.StartCommand(), databaseCommand.Cobra(), conf) + commands.BuildCommand(database.StopCommand(), databaseCommand.Cobra(), conf) // Database connections connectionsCommand := commands.BuildCommand(databaseconnection.BaseConnectionCommand(), databaseCommand.Cobra(), conf) diff --git a/internal/commands/database/start.go b/internal/commands/database/start.go new file mode 100644 index 000000000..b3c7d2d3a --- /dev/null +++ b/internal/commands/database/start.go @@ -0,0 +1,53 @@ +package database + +import ( + "fmt" + + "github.com/UpCloudLtd/upcloud-cli/internal/commands" + "github.com/UpCloudLtd/upcloud-cli/internal/completion" + "github.com/UpCloudLtd/upcloud-cli/internal/output" + "github.com/UpCloudLtd/upcloud-cli/internal/resolver" + + "github.com/UpCloudLtd/upcloud-go-api/v4/upcloud/request" +) + +// StartCommand creates the "database start" command +func StartCommand() commands.Command { + return &startCommand{ + BaseCommand: commands.New( + "start", + "Start on a managed database", + "upctl database start b0952286-1193-4a81-a1af-62efc014ae4b", + "upctl database start b0952286-1193-4a81-a1af-62efc014ae4b 666bcd3c-5c63-428d-a4fd-07c27469a5a6", + "upctl database start pg-1x1xcpu-2gb-25gb-pl-waw1", + ), + } +} + +type startCommand struct { + *commands.BaseCommand + completion.Database + resolver.CachingDatabase +} + +// Execute implements commands.MultipleArgumentCommand +func (s *startCommand) Execute(exec commands.Executor, uuid string) (output.Output, error) { + svc := exec.All() + msg := fmt.Sprintf("Starting database %v", uuid) + logline := exec.NewLogEntry(msg) + + logline.StartedNow() + logline.SetMessage(fmt.Sprintf("%s: sending request", msg)) + + res, err := svc.StartManagedDatabase(&request.StartManagedDatabaseRequest{ + UUID: uuid, + }) + if err != nil { + return commands.HandleError(logline, fmt.Sprintf("%s: failed", msg), err) + } + + logline.SetMessage(fmt.Sprintf("%s: done", msg)) + logline.MarkDone() + + return output.OnlyMarshaled{Value: res}, nil +} diff --git a/internal/commands/database/start_test.go b/internal/commands/database/start_test.go new file mode 100644 index 000000000..61a3e56bc --- /dev/null +++ b/internal/commands/database/start_test.go @@ -0,0 +1,44 @@ +package database + +import ( + "testing" + + "github.com/UpCloudLtd/upcloud-cli/internal/commands" + "github.com/UpCloudLtd/upcloud-cli/internal/config" + smock "github.com/UpCloudLtd/upcloud-cli/internal/mock" + "github.com/UpCloudLtd/upcloud-cli/internal/mockexecute" + internal "github.com/UpCloudLtd/upcloud-cli/internal/service" + + "github.com/UpCloudLtd/upcloud-go-api/v4/upcloud" + "github.com/UpCloudLtd/upcloud-go-api/v4/upcloud/request" + "github.com/stretchr/testify/assert" +) + +func TestStartCommand(t *testing.T) { + targetMethod := "StartManagedDatabase" + + var db = upcloud.ManagedDatabase{ + State: upcloud.ManagedDatabaseStateRunning, + Title: "database-title", + UUID: "1fdfda29-ead1-4855-b71f-1e33eb2ca9de", + } + + req := request.StartManagedDatabaseRequest{ + UUID: db.UUID, + } + + conf := config.New() + testCmd := StartCommand() + mService := new(smock.Service) + + conf.Service = internal.Wrapper{Service: mService} + mService.On(targetMethod, &req).Return(&db, nil) + + command := commands.BuildCommand(testCmd, nil, conf) + + command.Cobra().SetArgs([]string{db.UUID}) + _, err := mockexecute.MockExecute(command, mService, conf) + + assert.NoError(t, err) + mService.AssertNumberOfCalls(t, targetMethod, 1) +} diff --git a/internal/commands/database/stop.go b/internal/commands/database/stop.go new file mode 100644 index 000000000..a10f929d9 --- /dev/null +++ b/internal/commands/database/stop.go @@ -0,0 +1,58 @@ +package database + +import ( + "fmt" + + "github.com/UpCloudLtd/upcloud-cli/internal/commands" + "github.com/UpCloudLtd/upcloud-cli/internal/completion" + "github.com/UpCloudLtd/upcloud-cli/internal/output" + "github.com/UpCloudLtd/upcloud-cli/internal/resolver" + + "github.com/UpCloudLtd/upcloud-go-api/v4/upcloud/request" +) + +// StopCommand creates the "database stop" command +func StopCommand() commands.Command { + return &stopCommand{ + BaseCommand: commands.New( + "stop", + "Stop a managed database", + "upctl database stop b0952286-1193-4a81-a1af-62efc014ae4b", + "upctl database stop b0952286-1193-4a81-a1af-62efc014ae4b 666bcd3c-5c63-428d-a4fd-07c27469a5a6", + "upctl database stop pg-1x1xcpu-2gb-25gb-pl-waw1", + ), + } +} + +type stopCommand struct { + *commands.BaseCommand + completion.Database + resolver.CachingDatabase +} + +// InitCommand implements Command.InitCommand +func (s *stopCommand) InitCommand() { + s.Cobra().Aliases = []string{"shutdown"} +} + +// Execute implements commands.MultipleArgumentCommand +func (s *stopCommand) Execute(exec commands.Executor, uuid string) (output.Output, error) { + svc := exec.All() + msg := fmt.Sprintf("Stopping database %v", uuid) + logline := exec.NewLogEntry(msg) + + logline.StartedNow() + logline.SetMessage(fmt.Sprintf("%s: sending request", msg)) + + res, err := svc.ShutdownManagedDatabase(&request.ShutdownManagedDatabaseRequest{ + UUID: uuid, + }) + if err != nil { + return commands.HandleError(logline, fmt.Sprintf("%s: failed", msg), err) + } + + logline.SetMessage(fmt.Sprintf("%s: done", msg)) + logline.MarkDone() + + return output.OnlyMarshaled{Value: res}, nil +} diff --git a/internal/commands/database/stop_test.go b/internal/commands/database/stop_test.go new file mode 100644 index 000000000..f0ab863ad --- /dev/null +++ b/internal/commands/database/stop_test.go @@ -0,0 +1,44 @@ +package database + +import ( + "testing" + + "github.com/UpCloudLtd/upcloud-cli/internal/commands" + "github.com/UpCloudLtd/upcloud-cli/internal/config" + smock "github.com/UpCloudLtd/upcloud-cli/internal/mock" + "github.com/UpCloudLtd/upcloud-cli/internal/mockexecute" + internal "github.com/UpCloudLtd/upcloud-cli/internal/service" + + "github.com/UpCloudLtd/upcloud-go-api/v4/upcloud" + "github.com/UpCloudLtd/upcloud-go-api/v4/upcloud/request" + "github.com/stretchr/testify/assert" +) + +func TestStopCommand(t *testing.T) { + targetMethod := "ShutdownManagedDatabase" + + var db = upcloud.ManagedDatabase{ + State: upcloud.ManagedDatabaseStateRunning, + Title: "database-title", + UUID: "1fdfda29-ead1-4855-b71f-1e33eb2ca9de", + } + + req := request.ShutdownManagedDatabaseRequest{ + UUID: db.UUID, + } + + conf := config.New() + testCmd := StopCommand() + mService := new(smock.Service) + + conf.Service = internal.Wrapper{Service: mService} + mService.On(targetMethod, &req).Return(&db, nil) + + command := commands.BuildCommand(testCmd, nil, conf) + + command.Cobra().SetArgs([]string{db.UUID}) + _, err := mockexecute.MockExecute(command, mService, conf) + + assert.NoError(t, err) + mService.AssertNumberOfCalls(t, targetMethod, 1) +} diff --git a/internal/mock/mock.go b/internal/mock/mock.go index 877aeabdd..de3263a1a 100644 --- a/internal/mock/mock.go +++ b/internal/mock/mock.go @@ -639,11 +639,19 @@ func (m *Service) GetManagedDatabaseVersions(r *request.GetManagedDatabaseVersio } func (m *Service) StartManagedDatabase(r *request.StartManagedDatabaseRequest) (*upcloud.ManagedDatabase, error) { - return nil, nil + args := m.Called(r) + if args[0] == nil { + return nil, args.Error(1) + } + return args[0].(*upcloud.ManagedDatabase), args.Error(1) } func (m *Service) ShutdownManagedDatabase(r *request.ShutdownManagedDatabaseRequest) (*upcloud.ManagedDatabase, error) { - return nil, nil + args := m.Called(r) + if args[0] == nil { + return nil, args.Error(1) + } + return args[0].(*upcloud.ManagedDatabase), args.Error(1) } func (m *Service) WaitForManagedDatabaseState(r *request.WaitForManagedDatabaseStateRequest) (*upcloud.ManagedDatabase, error) {