From 2329b3fdbd5d43861affb725d356d9aa93bdac3e Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Fri, 29 Nov 2024 15:55:24 +0000 Subject: [PATCH 1/7] feat: Add server public IP attach/detach commands --- Makefile | 8 +- README.md | 44 ++-- docs/stackit_beta_server_list.md | 2 +- .../network-interface/network-interface.go | 4 +- internal/cmd/beta/network/network.go | 4 +- internal/cmd/beta/server/backup/backup.go | 4 +- internal/cmd/beta/server/describe/describe.go | 52 ++-- .../beta/server/public-ip/attach/attach.go | 127 ++++++++++ .../server/public-ip/attach/attach_test.go | 227 ++++++++++++++++++ .../beta/server/public-ip/detach/detach.go | 129 ++++++++++ .../server/public-ip/detach/detach_test.go | 226 +++++++++++++++++ .../cmd/beta/server/public-ip/public_ip.go | 28 +++ internal/cmd/beta/server/server.go | 6 +- internal/cmd/beta/server/volume/volume.go | 4 +- internal/cmd/beta/volume/volume.go | 4 +- internal/pkg/services/iaas/utils/utils.go | 13 + .../pkg/services/iaas/utils/utils_test.go | 56 +++++ scripts/project.sh | 2 +- 18 files changed, 883 insertions(+), 57 deletions(-) create mode 100644 internal/cmd/beta/server/public-ip/attach/attach.go create mode 100644 internal/cmd/beta/server/public-ip/attach/attach_test.go create mode 100644 internal/cmd/beta/server/public-ip/detach/detach.go create mode 100644 internal/cmd/beta/server/public-ip/detach/detach_test.go create mode 100644 internal/cmd/beta/server/public-ip/public_ip.go diff --git a/Makefile b/Makefile index 9a6d08844..7657fc059 100644 --- a/Makefile +++ b/Makefile @@ -19,21 +19,21 @@ project-tools: # Lint lint-golangci-lint: - @echo "Linting with golangci-lint" + @echo ">> Linting with golangci-lint" @golangci-lint run ${GOLANG_CI_ARGS} lint-yamllint: - @echo "Linting with yamllint" + @echo ">> Linting with yamllint" @yamllint -c .yamllint.yaml . lint: lint-golangci-lint lint-yamllint # Test test: - @echo "Running tests for the CLI application" + @echo ">> Running tests for the CLI application" @go test ./... -count=1 # Generate docs generate-docs: - @echo "Generating docs..." + @echo ">> Generating docs..." @go run $(SCRIPTS_BASE)/generate.go diff --git a/README.md b/README.md index e15f0687b..eaae8e299 100644 --- a/README.md +++ b/README.md @@ -65,28 +65,28 @@ Help is available for any command by specifying the special flag `--help` (or si Below you can find a list of the STACKIT services already available in the CLI (along with their respective command names) and the ones that are currently planned to be integrated. -| Service | CLI Commands | Status | -| ---------------------------------- |----------------------------------------------------------------| ------------------------- | -| Observability | `observability` | :white_check_mark: | -| Infrastructure as a Service (IaaS) | `beta network-area`
`beta network`
`beta volume`
`beta network-interface`| :white_check_mark: (beta) | -| Authorization | `project`, `organization` | :white_check_mark: | -| DNS | `dns` | :white_check_mark: | -| Kubernetes Engine (SKE) | `ske` | :white_check_mark: | -| Load Balancer | `load-balancer` | :white_check_mark: | -| LogMe | `logme` | :white_check_mark: | -| MariaDB | `mariadb` | :white_check_mark: | -| MongoDB Flex | `mongodbflex` | :white_check_mark: | -| Object Storage | `object-storage` | :white_check_mark: | -| OpenSearch | `opensearch` | :white_check_mark: | -| PostgreSQL Flex | `postgresflex` | :white_check_mark: | -| RabbitMQ | `rabbitmq` | :white_check_mark: | -| Redis | `redis` | :white_check_mark: | -| Resource Manager | `project` | :white_check_mark: | -| Secrets Manager | `secrets-manager` | :white_check_mark: | -| Server Backup Management | `beta server backup` | :white_check_mark: (beta) | -| Server Command (Run Command) | `beta server command` | :white_check_mark: (beta) | -| Service Account | `service-account` | :white_check_mark: | -| SQLServer Flex | `beta sqlserverflex` | :white_check_mark: (beta) | +| Service | CLI Commands | Status | +| ---------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------- | +| Observability | `observability` | :white_check_mark: | +| Infrastructure as a Service (IaaS) | `beta network-area`
`beta network`
`beta volume`
`beta network-interface`
`beta server` | :white_check_mark: (beta) | +| Authorization | `project`, `organization` | :white_check_mark: | +| DNS | `dns` | :white_check_mark: | +| Kubernetes Engine (SKE) | `ske` | :white_check_mark: | +| Load Balancer | `load-balancer` | :white_check_mark: | +| LogMe | `logme` | :white_check_mark: | +| MariaDB | `mariadb` | :white_check_mark: | +| MongoDB Flex | `mongodbflex` | :white_check_mark: | +| Object Storage | `object-storage` | :white_check_mark: | +| OpenSearch | `opensearch` | :white_check_mark: | +| PostgreSQL Flex | `postgresflex` | :white_check_mark: | +| RabbitMQ | `rabbitmq` | :white_check_mark: | +| Redis | `redis` | :white_check_mark: | +| Resource Manager | `project` | :white_check_mark: | +| Secrets Manager | `secrets-manager` | :white_check_mark: | +| Server Backup Management | `beta server backup` | :white_check_mark: (beta) | +| Server Command (Run Command) | `beta server command` | :white_check_mark: (beta) | +| Service Account | `service-account` | :white_check_mark: | +| SQLServer Flex | `beta sqlserverflex` | :white_check_mark: (beta) | ## Authentication diff --git a/docs/stackit_beta_server_list.md b/docs/stackit_beta_server_list.md index 4641bea02..f2ed97364 100644 --- a/docs/stackit_beta_server_list.md +++ b/docs/stackit_beta_server_list.md @@ -46,5 +46,5 @@ stackit beta server list [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers diff --git a/internal/cmd/beta/network-interface/network-interface.go b/internal/cmd/beta/network-interface/network-interface.go index b1d648226..b67392d43 100644 --- a/internal/cmd/beta/network-interface/network-interface.go +++ b/internal/cmd/beta/network-interface/network-interface.go @@ -15,8 +15,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "network-interface", - Short: "Provides functionality for Network Interface", - Long: "Provides functionality for Network Interface.", + Short: "Provides functionality for network interfaces", + Long: "Provides functionality for network interfaces.", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/network/network.go b/internal/cmd/beta/network/network.go index cf4ccdd4d..30197e2ed 100644 --- a/internal/cmd/beta/network/network.go +++ b/internal/cmd/beta/network/network.go @@ -16,8 +16,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "network", - Short: "Provides functionality for Network", - Long: "Provides functionality for Network.", + Short: "Provides functionality for networks", + Long: "Provides functionality for networks.", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/server/backup/backup.go b/internal/cmd/beta/server/backup/backup.go index 37312d2a3..512f9bd66 100644 --- a/internal/cmd/beta/server/backup/backup.go +++ b/internal/cmd/beta/server/backup/backup.go @@ -20,8 +20,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "backup", - Short: "Provides functionality for Server Backup", - Long: "Provides functionality for Server Backup.", + Short: "Provides functionality for server backups", + Long: "Provides functionality for server backups.", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/server/describe/describe.go b/internal/cmd/beta/server/describe/describe.go index a9c105a93..a5a8efda0 100644 --- a/internal/cmd/beta/server/describe/describe.go +++ b/internal/cmd/beta/server/describe/describe.go @@ -142,6 +142,9 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro return nil default: table := tables.NewTable() + if model.Details { + table.SetTitle("Server") + } table.AddRow("ID", *server.Id) table.AddSeparator() table.AddRow("NAME", *server.Name) @@ -184,6 +187,11 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro table.AddSeparator() } + if server.ServiceAccountMails != nil && len(*server.ServiceAccountMails) > 0 { + table.AddRow("SERVICE ACCOUNTS", strings.Join(*server.ServiceAccountMails, "\n")) + table.AddSeparator() + } + if server.Volumes != nil && len(*server.Volumes) > 0 { volumes := []string{} volumes = append(volumes, *server.Volumes...) @@ -191,28 +199,38 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro table.AddSeparator() } - if model.Details { - if server.ServiceAccountMails != nil && len(*server.ServiceAccountMails) > 0 { - emails := []string{} - emails = append(emails, *server.ServiceAccountMails...) - table.AddRow("SERVICE ACCOUNTS", strings.Join(emails, "\n")) - table.AddSeparator() - } + err := table.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) + } + + if !model.Details { + return nil + } + + // Additional details to be displayed when --details flag is set + if server.Nics != nil && len(*server.Nics) > 0 { + for i, nic := range *server.Nics { + nicsTable := tables.NewTable() + nicsTable.SetTitle(fmt.Sprintf("Attached Network Interface #%d", i)) + + nicsTable.AddRow("ID", *nic.NicId) + nicsTable.AddSeparator() + nicsTable.AddRow("NETWORK ID", *nic.NetworkId) + nicsTable.AddSeparator() + nicsTable.AddRow("NETWORK NAME", *nic.NetworkName) + nicsTable.AddSeparator() + if nic.PublicIp != nil { + nicsTable.AddRow("PUBLIC IP", *nic.PublicIp) + } - if server.Nics != nil && len(*server.Nics) > 0 { - nics := []string{} - for _, nic := range *server.Nics { - nics = append(nics, *nic.NicId) + nicsTable.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) } - table.AddRow("NICS", strings.Join(nics, "\n")) - table.AddSeparator() } } - err := table.Display(p) - if err != nil { - return fmt.Errorf("render table: %w", err) - } return nil } } diff --git a/internal/cmd/beta/server/public-ip/attach/attach.go b/internal/cmd/beta/server/public-ip/attach/attach.go new file mode 100644 index 000000000..28c0b15b2 --- /dev/null +++ b/internal/cmd/beta/server/public-ip/attach/attach.go @@ -0,0 +1,127 @@ +package attach + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client" + iaasUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/iaas" +) + +const ( + publicIpIdArg = "PUBLIC_IP_ID" + + serverIdFlag = "server-id" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + ServerId *string + PublicIpId string +} + +func NewCmd(p *print.Printer) *cobra.Command { + cmd := &cobra.Command{ + Use: "attach", + Short: "Attaches a public IP to a server", + Long: "Attaches a public IP to a server.", + Args: args.SingleArg(publicIpIdArg, utils.ValidateUUID), + Example: examples.Build( + examples.NewExample( + `Attach a public IP with ID "xxx" to a server with ID "yyy"`, + `$ stackit beta server public-ip attach xxx --server-id yyy`, + )), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + model, err := parseInput(p, cmd, args) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(p) + if err != nil { + return err + } + + publicIpLabel, _, err := iaasUtils.GetPublicIP(ctx, apiClient, model.ProjectId, model.PublicIpId) + if err != nil { + p.Debug(print.ErrorLevel, "get public ip name: %v", err) + } + if publicIpLabel == "" { + publicIpLabel = model.PublicIpId + } + + serverLabel, err := iaasUtils.GetServerName(ctx, apiClient, model.ProjectId, *model.ServerId) + if err != nil { + p.Debug(print.ErrorLevel, "get server name: %v", err) + serverLabel = *model.ServerId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to attach public IP %q to server %q?", publicIpLabel, serverLabel) + err = p.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + err = req.Execute() + if err != nil { + return fmt.Errorf("attach server to public ip: %w", err) + } + + p.Info("Attached public IP %q to server %q\n", publicIpLabel, serverLabel) + return nil + }, + } + configureFlags(cmd) + return cmd +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), serverIdFlag, "Server ID") + + err := flags.MarkFlagsRequired(cmd, serverIdFlag) + cobra.CheckErr(err) +} + +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + volumeId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + ServerId: flags.FlagToStringPointer(p, cmd, serverIdFlag), + PublicIpId: volumeId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiAddPublicIpToServerRequest { + return apiClient.AddPublicIpToServer(ctx, model.ProjectId, *model.ServerId, model.PublicIpId) +} diff --git a/internal/cmd/beta/server/public-ip/attach/attach_test.go b/internal/cmd/beta/server/public-ip/attach/attach_test.go new file mode 100644 index 000000000..b8a80d6b2 --- /dev/null +++ b/internal/cmd/beta/server/public-ip/attach/attach_test.go @@ -0,0 +1,227 @@ +package attach + +import ( + "context" + "testing" + + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-sdk-go/services/iaas" +) + +var projectIdFlag = globalflags.ProjectIdFlag + +type testCtxKey struct{} + +var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") +var testClient = &iaas.APIClient{} +var testProjectId = uuid.NewString() +var testServerId = uuid.NewString() +var testPublicIpId = uuid.NewString() + +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testPublicIpId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + projectIdFlag: testProjectId, + serverIdFlag: testServerId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + Verbosity: globalflags.VerbosityDefault, + ProjectId: testProjectId, + }, + ServerId: utils.Ptr(testServerId), + PublicIpId: testPublicIpId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +func fixtureRequest(mods ...func(request *iaas.ApiAddPublicIpToServerRequest)) iaas.ApiAddPublicIpToServerRequest { + request := testClient.AddPublicIpToServer(testCtx, testProjectId, testServerId, testPublicIpId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + argValues []string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no values", + argValues: fixtureArgValues(), + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, projectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[projectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[projectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "server id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, serverIdFlag) + }), + isValid: false, + }, + { + description: "server id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[serverIdFlag] = "" + }), + isValid: false, + }, + { + description: "server id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[serverIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "volume id argument missing", + argValues: []string{}, + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + p := print.NewPrinter() + cmd := NewCmd(p) + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + for flag, value := range tt.flagValues { + err := cmd.Flags().Set(flag, value) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("setting flag --%s=%s: %v", flag, value, err) + } + } + + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error parsing args: %v", err) + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + model, err := parseInput(p, cmd, tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error parsing input: %v", err) + } + + if !tt.isValid { + t.Fatalf("did not fail on invalid input") + } + diff := cmp.Diff(model, tt.expectedModel) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest iaas.ApiAddPublicIpToServerRequest + }{ + { + description: "base", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/server/public-ip/detach/detach.go b/internal/cmd/beta/server/public-ip/detach/detach.go new file mode 100644 index 000000000..9a9533df2 --- /dev/null +++ b/internal/cmd/beta/server/public-ip/detach/detach.go @@ -0,0 +1,129 @@ +package detach + +import ( + "context" + "fmt" + + "github.com/spf13/cobra" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/errors" + "github.com/stackitcloud/stackit-cli/internal/pkg/examples" + "github.com/stackitcloud/stackit-cli/internal/pkg/flags" + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client" + iaasUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/utils" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + "github.com/stackitcloud/stackit-sdk-go/services/iaas" +) + +const ( + publicIpIdArg = "PUBLIC_IP_ID" + + serverIdFlag = "server-id" +) + +type inputModel struct { + *globalflags.GlobalFlagModel + ServerId *string + PublicIpId string +} + +func NewCmd(p *print.Printer) *cobra.Command { + cmd := &cobra.Command{ + Use: "detach", + Short: "Detaches a public IP from a server", + Long: "Detaches a public IP from a server.", + Args: args.SingleArg(publicIpIdArg, utils.ValidateUUID), + Example: examples.Build( + examples.NewExample( + `Detaches a public IP with ID "xxx" from a server with ID "yyy"`, + `$ stackit beta server public-ip detach xxx --server-id yyy`, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + model, err := parseInput(p, cmd, args) + if err != nil { + return err + } + + // Configure API client + apiClient, err := client.ConfigureClient(p) + if err != nil { + return err + } + + publicIpLabel, _, err := iaasUtils.GetPublicIP(ctx, apiClient, model.ProjectId, model.PublicIpId) + if err != nil { + p.Debug(print.ErrorLevel, "get public ip: %v", err) + publicIpLabel = model.PublicIpId + } + if publicIpLabel == "" { + publicIpLabel = model.PublicIpId + } + + serverLabel, err := iaasUtils.GetServerName(ctx, apiClient, model.ProjectId, *model.ServerId) + if err != nil { + p.Debug(print.ErrorLevel, "get server name: %v", err) + serverLabel = *model.ServerId + } + + if !model.AssumeYes { + prompt := fmt.Sprintf("Are you sure you want to detach public IP %q from server %q?", publicIpLabel, serverLabel) + err = p.PromptForConfirmation(prompt) + if err != nil { + return err + } + } + + // Call API + req := buildRequest(ctx, model, apiClient) + if err := req.Execute(); err != nil { + return fmt.Errorf("detach public ip from server: %w", err) + } + + p.Info("Detached public IP %q from server %q\n", publicIpLabel, serverLabel) + + return nil + }, + } + configureFlags(cmd) + return cmd +} + +func configureFlags(cmd *cobra.Command) { + cmd.Flags().Var(flags.UUIDFlag(), serverIdFlag, "Server ID") + + err := flags.MarkFlagsRequired(cmd, serverIdFlag) + cobra.CheckErr(err) +} + +func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { + publicIpId := inputArgs[0] + globalFlags := globalflags.Parse(p, cmd) + if globalFlags.ProjectId == "" { + return nil, &errors.ProjectIdError{} + } + + model := inputModel{ + GlobalFlagModel: globalFlags, + ServerId: flags.FlagToStringPointer(p, cmd, serverIdFlag), + PublicIpId: publicIpId, + } + + if p.IsVerbosityDebug() { + modelStr, err := print.BuildDebugStrFromInputModel(model) + if err != nil { + p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err) + } else { + p.Debug(print.DebugLevel, "parsed input values: %s", modelStr) + } + } + + return &model, nil +} + +func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiRemovePublicIpFromServerRequest { + return apiClient.RemovePublicIpFromServer(ctx, model.ProjectId, *model.ServerId, model.PublicIpId) +} diff --git a/internal/cmd/beta/server/public-ip/detach/detach_test.go b/internal/cmd/beta/server/public-ip/detach/detach_test.go new file mode 100644 index 000000000..b7ed5c286 --- /dev/null +++ b/internal/cmd/beta/server/public-ip/detach/detach_test.go @@ -0,0 +1,226 @@ +package detach + +import ( + "context" + "testing" + + "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/google/uuid" + "github.com/stackitcloud/stackit-sdk-go/services/iaas" +) + +var projectIdFlag = globalflags.ProjectIdFlag + +type testCtxKey struct{} + +var testCtx = context.WithValue(context.Background(), testCtxKey{}, "foo") +var testClient = &iaas.APIClient{} +var testProjectId = uuid.NewString() +var testServerId = uuid.NewString() +var testPublicIpId = uuid.NewString() + +func fixtureArgValues(mods ...func(argValues []string)) []string { + argValues := []string{ + testPublicIpId, + } + for _, mod := range mods { + mod(argValues) + } + return argValues +} + +func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { + flagValues := map[string]string{ + projectIdFlag: testProjectId, + serverIdFlag: testServerId, + } + for _, mod := range mods { + mod(flagValues) + } + return flagValues +} + +func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { + model := &inputModel{ + GlobalFlagModel: &globalflags.GlobalFlagModel{ + Verbosity: globalflags.VerbosityDefault, + ProjectId: testProjectId, + }, + ServerId: utils.Ptr(testServerId), + PublicIpId: testPublicIpId, + } + for _, mod := range mods { + mod(model) + } + return model +} + +func fixtureRequest(mods ...func(request *iaas.ApiRemovePublicIpFromServerRequest)) iaas.ApiRemovePublicIpFromServerRequest { + request := testClient.RemovePublicIpFromServer(testCtx, testProjectId, testServerId, testPublicIpId) + for _, mod := range mods { + mod(&request) + } + return request +} + +func TestParseInput(t *testing.T) { + tests := []struct { + description string + argValues []string + flagValues map[string]string + isValid bool + expectedModel *inputModel + }{ + { + description: "base", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(), + isValid: true, + expectedModel: fixtureInputModel(), + }, + { + description: "no values", + flagValues: map[string]string{}, + isValid: false, + }, + { + description: "project id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, projectIdFlag) + }), + isValid: false, + }, + { + description: "project id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[projectIdFlag] = "" + }), + isValid: false, + }, + { + description: "project id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[projectIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "server id missing", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + delete(flagValues, serverIdFlag) + }), + isValid: false, + }, + { + description: "server id invalid 1", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[serverIdFlag] = "" + }), + isValid: false, + }, + { + description: "server id invalid 2", + argValues: fixtureArgValues(), + flagValues: fixtureFlagValues(func(flagValues map[string]string) { + flagValues[serverIdFlag] = "invalid-uuid" + }), + isValid: false, + }, + { + description: "public ip id argument missing", + argValues: []string{}, + isValid: false, + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + p := print.NewPrinter() + cmd := NewCmd(p) + err := globalflags.Configure(cmd.Flags()) + if err != nil { + t.Fatalf("configure global flags: %v", err) + } + + for flag, value := range tt.flagValues { + err := cmd.Flags().Set(flag, value) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("setting flag --%s=%s: %v", flag, value, err) + } + } + + err = cmd.ValidateArgs(tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error parsing args: %v", err) + } + + err = cmd.ValidateRequiredFlags() + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error validating flags: %v", err) + } + + model, err := parseInput(p, cmd, tt.argValues) + if err != nil { + if !tt.isValid { + return + } + t.Fatalf("error parsing input: %v", err) + } + + if !tt.isValid { + t.Fatalf("did not fail on invalid input") + } + diff := cmp.Diff(model, tt.expectedModel) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} + +func TestBuildRequest(t *testing.T) { + tests := []struct { + description string + model *inputModel + expectedRequest iaas.ApiRemovePublicIpFromServerRequest + }{ + { + description: "base", + model: fixtureInputModel(), + expectedRequest: fixtureRequest(), + }, + } + + for _, tt := range tests { + t.Run(tt.description, func(t *testing.T) { + request := buildRequest(testCtx, tt.model, testClient) + + diff := cmp.Diff(request, tt.expectedRequest, + cmp.AllowUnexported(tt.expectedRequest), + cmpopts.EquateComparable(testCtx), + ) + if diff != "" { + t.Fatalf("Data does not match: %s", diff) + } + }) + } +} diff --git a/internal/cmd/beta/server/public-ip/public_ip.go b/internal/cmd/beta/server/public-ip/public_ip.go new file mode 100644 index 000000000..662d00aa5 --- /dev/null +++ b/internal/cmd/beta/server/public-ip/public_ip.go @@ -0,0 +1,28 @@ +package publicip + +import ( + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/public-ip/attach" + "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/public-ip/detach" + "github.com/stackitcloud/stackit-cli/internal/pkg/args" + "github.com/stackitcloud/stackit-cli/internal/pkg/print" + "github.com/stackitcloud/stackit-cli/internal/pkg/utils" + + "github.com/spf13/cobra" +) + +func NewCmd(p *print.Printer) *cobra.Command { + cmd := &cobra.Command{ + Use: "public-ip", + Short: "Allows attaching/detaching public IPs to servers", + Long: "Allows attaching/detaching public IPs to servers.", + Args: args.NoArgs, + Run: utils.CmdHelp, + } + addSubcommands(cmd, p) + return cmd +} + +func addSubcommands(cmd *cobra.Command, p *print.Printer) { + cmd.AddCommand(attach.NewCmd(p)) + cmd.AddCommand(detach.NewCmd(p)) +} diff --git a/internal/cmd/beta/server/server.go b/internal/cmd/beta/server/server.go index 7f205988f..4b8ba0fd4 100644 --- a/internal/cmd/beta/server/server.go +++ b/internal/cmd/beta/server/server.go @@ -7,6 +7,7 @@ import ( "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/delete" "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/describe" "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/list" + publicip "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/public-ip" "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/update" "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/volume" "github.com/stackitcloud/stackit-cli/internal/pkg/args" @@ -19,8 +20,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "server", - Short: "Provides functionality for Server", - Long: "Provides functionality for Server.", + Short: "Provides functionality for servers", + Long: "Provides functionality for servers.", Args: args.NoArgs, Run: utils.CmdHelp, } @@ -35,6 +36,7 @@ func addSubcommands(cmd *cobra.Command, p *print.Printer) { cmd.AddCommand(delete.NewCmd(p)) cmd.AddCommand(describe.NewCmd(p)) cmd.AddCommand(list.NewCmd(p)) + cmd.AddCommand(publicip.NewCmd(p)) cmd.AddCommand(update.NewCmd(p)) cmd.AddCommand(volume.NewCmd(p)) } diff --git a/internal/cmd/beta/server/volume/volume.go b/internal/cmd/beta/server/volume/volume.go index 7f8656021..77714f625 100644 --- a/internal/cmd/beta/server/volume/volume.go +++ b/internal/cmd/beta/server/volume/volume.go @@ -16,8 +16,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "volume", - Short: "Provides functionality for Server volumes", - Long: "Provides functionality for Server volumes.", + Short: "Provides functionality for server volumes", + Long: "Provides functionality for server volumes.", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/cmd/beta/volume/volume.go b/internal/cmd/beta/volume/volume.go index 0fa6f59f2..5b03326bf 100644 --- a/internal/cmd/beta/volume/volume.go +++ b/internal/cmd/beta/volume/volume.go @@ -18,8 +18,8 @@ import ( func NewCmd(p *print.Printer) *cobra.Command { cmd := &cobra.Command{ Use: "volume", - Short: "Provides functionality for Volume", - Long: "Provides functionality for Volume.", + Short: "Provides functionality for volumes", + Long: "Provides functionality for volumes.", Args: args.NoArgs, Run: utils.CmdHelp, } diff --git a/internal/pkg/services/iaas/utils/utils.go b/internal/pkg/services/iaas/utils/utils.go index c522633d5..fecc0872c 100644 --- a/internal/pkg/services/iaas/utils/utils.go +++ b/internal/pkg/services/iaas/utils/utils.go @@ -8,6 +8,7 @@ import ( ) type IaaSClient interface { + GetPublicIPExecute(ctx context.Context, projectId, publicIpId string) (*iaas.PublicIp, error) GetServerExecute(ctx context.Context, projectId, serverId string) (*iaas.Server, error) GetVolumeExecute(ctx context.Context, projectId, volumeId string) (*iaas.Volume, error) GetNetworkExecute(ctx context.Context, projectId, networkId string) (*iaas.Network, error) @@ -16,6 +17,18 @@ type IaaSClient interface { GetNetworkAreaRangeExecute(ctx context.Context, organizationId, areaId, networkRangeId string) (*iaas.NetworkRange, error) } +func GetPublicIP(ctx context.Context, apiClient IaaSClient, projectId, publicIpId string) (ip, associatedResource string, err error) { + resp, err := apiClient.GetPublicIPExecute(ctx, projectId, publicIpId) + if err != nil { + return "", "", fmt.Errorf("get public ip: %w", err) + } + associatedResourceId := "" + if resp.NetworkInterface != nil { + associatedResourceId = *resp.NetworkInterface.Get() + } + return *resp.Ip, associatedResourceId, nil +} + func GetServerName(ctx context.Context, apiClient IaaSClient, projectId, serverId string) (string, error) { resp, err := apiClient.GetServerExecute(ctx, projectId, serverId) if err != nil { diff --git a/internal/pkg/services/iaas/utils/utils_test.go b/internal/pkg/services/iaas/utils/utils_test.go index aeda9d6d3..408cc7404 100644 --- a/internal/pkg/services/iaas/utils/utils_test.go +++ b/internal/pkg/services/iaas/utils/utils_test.go @@ -11,6 +11,8 @@ import ( ) type IaaSClientMocked struct { + GetPublicIpFails bool + GetPublicIpResp *iaas.PublicIp GetServerFails bool GetServerResp *iaas.Server GetVolumeFails bool @@ -25,6 +27,13 @@ type IaaSClientMocked struct { GetNetworkAreaRangeResp *iaas.NetworkRange } +func (m *IaaSClientMocked) GetPublicIPExecute(_ context.Context, _, _ string) (*iaas.PublicIp, error) { + if m.GetPublicIpFails { + return nil, fmt.Errorf("could not get public ip") + } + return m.GetPublicIpResp, nil +} + func (m *IaaSClientMocked) GetServerExecute(_ context.Context, _, _ string) (*iaas.Server, error) { if m.GetServerFails { return nil, fmt.Errorf("could not get server") @@ -67,6 +76,53 @@ func (m *IaaSClientMocked) GetNetworkAreaRangeExecute(_ context.Context, _, _, _ return m.GetNetworkAreaRangeResp, nil } +func TestGetPublicIp(t *testing.T) { + type args struct { + getPublicIpFails bool + getPublicIpResp *iaas.PublicIp + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "base", + args: args{ + getPublicIpResp: &iaas.PublicIp{ + Ip: utils.Ptr("1.2.3.4"), + NetworkInterface: iaas.NewNullableString(utils.Ptr("1.2.3.4")), + }, + }, + want: "1.2.3.4", + }, + { + name: "get public ip fails", + args: args{ + getPublicIpFails: true, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + m := &IaaSClientMocked{ + GetPublicIpFails: tt.args.getPublicIpFails, + GetPublicIpResp: tt.args.getPublicIpResp, + } + got, _, err := GetPublicIP(context.Background(), m, "", "") + if (err != nil) != tt.wantErr { + t.Errorf("GetPublicIP() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetPublicIP() = %v, want %v", got, tt.want) + } + }) + } +} + func TestGetServerName(t *testing.T) { type args struct { getInstanceFails bool diff --git a/scripts/project.sh b/scripts/project.sh index 2786e509e..f8acf4e38 100755 --- a/scripts/project.sh +++ b/scripts/project.sh @@ -16,5 +16,5 @@ elif [ "$action" = "tools" ]; then go mod download go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 else - echo "Invalid action: '$action', please use $0 help for help" + echo "! Invalid action: '$action', please use $0 help for help" fi From 9f5aa87213558aa7dae7d60601f3619c3ecf98e2 Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Fri, 29 Nov 2024 15:55:39 +0000 Subject: [PATCH 2/7] feat: Generate docs --- docs/stackit_beta.md | 8 ++-- docs/stackit_beta_network-interface.md | 4 +- docs/stackit_beta_network-interface_create.md | 2 +- docs/stackit_beta_network-interface_delete.md | 2 +- ...stackit_beta_network-interface_describe.md | 2 +- docs/stackit_beta_network-interface_list.md | 2 +- docs/stackit_beta_network-interface_update.md | 2 +- docs/stackit_beta_network.md | 4 +- docs/stackit_beta_network_create.md | 2 +- docs/stackit_beta_network_delete.md | 2 +- docs/stackit_beta_network_describe.md | 2 +- docs/stackit_beta_network_list.md | 2 +- docs/stackit_beta_network_update.md | 2 +- docs/stackit_beta_server.md | 9 +++-- docs/stackit_beta_server_backup.md | 6 +-- docs/stackit_beta_server_backup_create.md | 2 +- docs/stackit_beta_server_backup_delete.md | 2 +- docs/stackit_beta_server_backup_describe.md | 2 +- docs/stackit_beta_server_backup_disable.md | 2 +- docs/stackit_beta_server_backup_enable.md | 2 +- docs/stackit_beta_server_backup_list.md | 2 +- docs/stackit_beta_server_backup_restore.md | 2 +- docs/stackit_beta_server_backup_schedule.md | 2 +- ...tackit_beta_server_backup_volume-backup.md | 2 +- docs/stackit_beta_server_command.md | 2 +- docs/stackit_beta_server_create.md | 2 +- docs/stackit_beta_server_delete.md | 2 +- docs/stackit_beta_server_describe.md | 2 +- docs/stackit_beta_server_public-ip.md | 34 ++++++++++++++++ docs/stackit_beta_server_public-ip_attach.md | 40 +++++++++++++++++++ docs/stackit_beta_server_public-ip_detach.md | 40 +++++++++++++++++++ docs/stackit_beta_server_update.md | 2 +- docs/stackit_beta_server_volume.md | 6 +-- docs/stackit_beta_server_volume_attach.md | 2 +- docs/stackit_beta_server_volume_describe.md | 2 +- docs/stackit_beta_server_volume_detach.md | 2 +- docs/stackit_beta_server_volume_list.md | 2 +- docs/stackit_beta_server_volume_update.md | 2 +- docs/stackit_beta_volume.md | 4 +- docs/stackit_beta_volume_create.md | 2 +- docs/stackit_beta_volume_delete.md | 2 +- docs/stackit_beta_volume_describe.md | 2 +- docs/stackit_beta_volume_list.md | 2 +- docs/stackit_beta_volume_performance-class.md | 2 +- docs/stackit_beta_volume_resize.md | 2 +- docs/stackit_beta_volume_update.md | 2 +- 46 files changed, 171 insertions(+), 56 deletions(-) create mode 100644 docs/stackit_beta_server_public-ip.md create mode 100644 docs/stackit_beta_server_public-ip_attach.md create mode 100644 docs/stackit_beta_server_public-ip_detach.md diff --git a/docs/stackit_beta.md b/docs/stackit_beta.md index 56453f281..edc19472c 100644 --- a/docs/stackit_beta.md +++ b/docs/stackit_beta.md @@ -40,10 +40,10 @@ stackit beta [flags] ### SEE ALSO * [stackit](./stackit.md) - Manage STACKIT resources using the command line -* [stackit beta network](./stackit_beta_network.md) - Provides functionality for Network +* [stackit beta network](./stackit_beta_network.md) - Provides functionality for networks * [stackit beta network-area](./stackit_beta_network-area.md) - Provides functionality for STACKIT Network Area (SNA) -* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for Network Interface -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for network interfaces +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers * [stackit beta sqlserverflex](./stackit_beta_sqlserverflex.md) - Provides functionality for SQLServer Flex -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes diff --git a/docs/stackit_beta_network-interface.md b/docs/stackit_beta_network-interface.md index 1832e4ef9..1d46a14e6 100644 --- a/docs/stackit_beta_network-interface.md +++ b/docs/stackit_beta_network-interface.md @@ -1,10 +1,10 @@ ## stackit beta network-interface -Provides functionality for Network Interface +Provides functionality for network interfaces ### Synopsis -Provides functionality for Network Interface. +Provides functionality for network interfaces. ``` stackit beta network-interface [flags] diff --git a/docs/stackit_beta_network-interface_create.md b/docs/stackit_beta_network-interface_create.md index a36ed217f..a9bf2c2d3 100644 --- a/docs/stackit_beta_network-interface_create.md +++ b/docs/stackit_beta_network-interface_create.md @@ -46,5 +46,5 @@ stackit beta network-interface create [flags] ### SEE ALSO -* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for Network Interface +* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for network interfaces diff --git a/docs/stackit_beta_network-interface_delete.md b/docs/stackit_beta_network-interface_delete.md index 954a7b472..a30564843 100644 --- a/docs/stackit_beta_network-interface_delete.md +++ b/docs/stackit_beta_network-interface_delete.md @@ -36,5 +36,5 @@ stackit beta network-interface delete [flags] ### SEE ALSO -* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for Network Interface +* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for network interfaces diff --git a/docs/stackit_beta_network-interface_describe.md b/docs/stackit_beta_network-interface_describe.md index a879d87aa..3f99be8f9 100644 --- a/docs/stackit_beta_network-interface_describe.md +++ b/docs/stackit_beta_network-interface_describe.md @@ -42,5 +42,5 @@ stackit beta network-interface describe [flags] ### SEE ALSO -* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for Network Interface +* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for network interfaces diff --git a/docs/stackit_beta_network-interface_list.md b/docs/stackit_beta_network-interface_list.md index 04707adcb..12e76737b 100644 --- a/docs/stackit_beta_network-interface_list.md +++ b/docs/stackit_beta_network-interface_list.md @@ -47,5 +47,5 @@ stackit beta network-interface list [flags] ### SEE ALSO -* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for Network Interface +* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for network interfaces diff --git a/docs/stackit_beta_network-interface_update.md b/docs/stackit_beta_network-interface_update.md index 506fb1ba4..5be029a85 100644 --- a/docs/stackit_beta_network-interface_update.md +++ b/docs/stackit_beta_network-interface_update.md @@ -47,5 +47,5 @@ stackit beta network-interface update [flags] ### SEE ALSO -* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for Network Interface +* [stackit beta network-interface](./stackit_beta_network-interface.md) - Provides functionality for network interfaces diff --git a/docs/stackit_beta_network.md b/docs/stackit_beta_network.md index cfde2f0c7..0a5636c39 100644 --- a/docs/stackit_beta_network.md +++ b/docs/stackit_beta_network.md @@ -1,10 +1,10 @@ ## stackit beta network -Provides functionality for Network +Provides functionality for networks ### Synopsis -Provides functionality for Network. +Provides functionality for networks. ``` stackit beta network [flags] diff --git a/docs/stackit_beta_network_create.md b/docs/stackit_beta_network_create.md index e9ac60921..954e64688 100644 --- a/docs/stackit_beta_network_create.md +++ b/docs/stackit_beta_network_create.md @@ -46,5 +46,5 @@ stackit beta network create [flags] ### SEE ALSO -* [stackit beta network](./stackit_beta_network.md) - Provides functionality for Network +* [stackit beta network](./stackit_beta_network.md) - Provides functionality for networks diff --git a/docs/stackit_beta_network_delete.md b/docs/stackit_beta_network_delete.md index 1e42ed58c..a2ff9cc84 100644 --- a/docs/stackit_beta_network_delete.md +++ b/docs/stackit_beta_network_delete.md @@ -37,5 +37,5 @@ stackit beta network delete [flags] ### SEE ALSO -* [stackit beta network](./stackit_beta_network.md) - Provides functionality for Network +* [stackit beta network](./stackit_beta_network.md) - Provides functionality for networks diff --git a/docs/stackit_beta_network_describe.md b/docs/stackit_beta_network_describe.md index 5c8a15752..ed449330c 100644 --- a/docs/stackit_beta_network_describe.md +++ b/docs/stackit_beta_network_describe.md @@ -38,5 +38,5 @@ stackit beta network describe [flags] ### SEE ALSO -* [stackit beta network](./stackit_beta_network.md) - Provides functionality for Network +* [stackit beta network](./stackit_beta_network.md) - Provides functionality for networks diff --git a/docs/stackit_beta_network_list.md b/docs/stackit_beta_network_list.md index 14f19bd40..5d5aef8b3 100644 --- a/docs/stackit_beta_network_list.md +++ b/docs/stackit_beta_network_list.md @@ -42,5 +42,5 @@ stackit beta network list [flags] ### SEE ALSO -* [stackit beta network](./stackit_beta_network.md) - Provides functionality for Network +* [stackit beta network](./stackit_beta_network.md) - Provides functionality for networks diff --git a/docs/stackit_beta_network_update.md b/docs/stackit_beta_network_update.md index b14bc9a8d..4afaa9d6d 100644 --- a/docs/stackit_beta_network_update.md +++ b/docs/stackit_beta_network_update.md @@ -44,5 +44,5 @@ stackit beta network update [flags] ### SEE ALSO -* [stackit beta network](./stackit_beta_network.md) - Provides functionality for Network +* [stackit beta network](./stackit_beta_network.md) - Provides functionality for networks diff --git a/docs/stackit_beta_server.md b/docs/stackit_beta_server.md index 4734979b3..5d2443980 100644 --- a/docs/stackit_beta_server.md +++ b/docs/stackit_beta_server.md @@ -1,10 +1,10 @@ ## stackit beta server -Provides functionality for Server +Provides functionality for servers ### Synopsis -Provides functionality for Server. +Provides functionality for servers. ``` stackit beta server [flags] @@ -29,12 +29,13 @@ stackit beta server [flags] ### SEE ALSO * [stackit beta](./stackit_beta.md) - Contains beta STACKIT CLI commands -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups * [stackit beta server command](./stackit_beta_server_command.md) - Provides functionality for Server Command * [stackit beta server create](./stackit_beta_server_create.md) - Creates a server * [stackit beta server delete](./stackit_beta_server_delete.md) - Deletes a server * [stackit beta server describe](./stackit_beta_server_describe.md) - Shows details of a server * [stackit beta server list](./stackit_beta_server_list.md) - Lists all servers of a project +* [stackit beta server public-ip](./stackit_beta_server_public-ip.md) - Allows attaching/detaching public IPs to servers * [stackit beta server update](./stackit_beta_server_update.md) - Updates a server -* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for Server volumes +* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes diff --git a/docs/stackit_beta_server_backup.md b/docs/stackit_beta_server_backup.md index 74164a5a1..324a45e9c 100644 --- a/docs/stackit_beta_server_backup.md +++ b/docs/stackit_beta_server_backup.md @@ -1,10 +1,10 @@ ## stackit beta server backup -Provides functionality for Server Backup +Provides functionality for server backups ### Synopsis -Provides functionality for Server Backup. +Provides functionality for server backups. ``` stackit beta server backup [flags] @@ -28,7 +28,7 @@ stackit beta server backup [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers * [stackit beta server backup create](./stackit_beta_server_backup_create.md) - Creates a Server Backup. * [stackit beta server backup delete](./stackit_beta_server_backup_delete.md) - Deletes a Server Backup. * [stackit beta server backup describe](./stackit_beta_server_backup_describe.md) - Shows details of a Server Backup diff --git a/docs/stackit_beta_server_backup_create.md b/docs/stackit_beta_server_backup_create.md index 713b10dd1..734fc5f96 100644 --- a/docs/stackit_beta_server_backup_create.md +++ b/docs/stackit_beta_server_backup_create.md @@ -42,5 +42,5 @@ stackit beta server backup create [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_delete.md b/docs/stackit_beta_server_backup_delete.md index 82c96299d..681311431 100644 --- a/docs/stackit_beta_server_backup_delete.md +++ b/docs/stackit_beta_server_backup_delete.md @@ -36,5 +36,5 @@ stackit beta server backup delete BACKUP_ID [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_describe.md b/docs/stackit_beta_server_backup_describe.md index 6ce6eb8be..232c6a656 100644 --- a/docs/stackit_beta_server_backup_describe.md +++ b/docs/stackit_beta_server_backup_describe.md @@ -39,5 +39,5 @@ stackit beta server backup describe BACKUP_ID [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_disable.md b/docs/stackit_beta_server_backup_disable.md index b2175dc86..813a3ca15 100644 --- a/docs/stackit_beta_server_backup_disable.md +++ b/docs/stackit_beta_server_backup_disable.md @@ -36,5 +36,5 @@ stackit beta server backup disable [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_enable.md b/docs/stackit_beta_server_backup_enable.md index 6a297f2ae..0f347dda1 100644 --- a/docs/stackit_beta_server_backup_enable.md +++ b/docs/stackit_beta_server_backup_enable.md @@ -36,5 +36,5 @@ stackit beta server backup enable [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_list.md b/docs/stackit_beta_server_backup_list.md index f7313d09f..35940e3b6 100644 --- a/docs/stackit_beta_server_backup_list.md +++ b/docs/stackit_beta_server_backup_list.md @@ -40,5 +40,5 @@ stackit beta server backup list [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_restore.md b/docs/stackit_beta_server_backup_restore.md index 8009a85ef..c2440165f 100644 --- a/docs/stackit_beta_server_backup_restore.md +++ b/docs/stackit_beta_server_backup_restore.md @@ -41,5 +41,5 @@ stackit beta server backup restore BACKUP_ID [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups diff --git a/docs/stackit_beta_server_backup_schedule.md b/docs/stackit_beta_server_backup_schedule.md index 43655d725..0acb68691 100644 --- a/docs/stackit_beta_server_backup_schedule.md +++ b/docs/stackit_beta_server_backup_schedule.md @@ -28,7 +28,7 @@ stackit beta server backup schedule [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups * [stackit beta server backup schedule create](./stackit_beta_server_backup_schedule_create.md) - Creates a Server Backup Schedule * [stackit beta server backup schedule delete](./stackit_beta_server_backup_schedule_delete.md) - Deletes a Server Backup Schedule * [stackit beta server backup schedule describe](./stackit_beta_server_backup_schedule_describe.md) - Shows details of a Server Backup Schedule diff --git a/docs/stackit_beta_server_backup_volume-backup.md b/docs/stackit_beta_server_backup_volume-backup.md index 5964784c8..5e1cad643 100644 --- a/docs/stackit_beta_server_backup_volume-backup.md +++ b/docs/stackit_beta_server_backup_volume-backup.md @@ -28,7 +28,7 @@ stackit beta server backup volume-backup [flags] ### SEE ALSO -* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for Server Backup +* [stackit beta server backup](./stackit_beta_server_backup.md) - Provides functionality for server backups * [stackit beta server backup volume-backup delete](./stackit_beta_server_backup_volume-backup_delete.md) - Deletes a Server Volume Backup. * [stackit beta server backup volume-backup restore](./stackit_beta_server_backup_volume-backup_restore.md) - Restore a Server Volume Backup to a volume. diff --git a/docs/stackit_beta_server_command.md b/docs/stackit_beta_server_command.md index 228a29930..eaa91d013 100644 --- a/docs/stackit_beta_server_command.md +++ b/docs/stackit_beta_server_command.md @@ -28,7 +28,7 @@ stackit beta server command [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers * [stackit beta server command create](./stackit_beta_server_command_create.md) - Creates a Server Command * [stackit beta server command describe](./stackit_beta_server_command_describe.md) - Shows details of a Server Command * [stackit beta server command list](./stackit_beta_server_command_list.md) - Lists all server commands diff --git a/docs/stackit_beta_server_create.md b/docs/stackit_beta_server_create.md index 6d8194715..7f8865139 100644 --- a/docs/stackit_beta_server_create.md +++ b/docs/stackit_beta_server_create.md @@ -77,5 +77,5 @@ stackit beta server create [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers diff --git a/docs/stackit_beta_server_delete.md b/docs/stackit_beta_server_delete.md index ffe1f941c..d12115e26 100644 --- a/docs/stackit_beta_server_delete.md +++ b/docs/stackit_beta_server_delete.md @@ -37,5 +37,5 @@ stackit beta server delete [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers diff --git a/docs/stackit_beta_server_describe.md b/docs/stackit_beta_server_describe.md index 1dab42995..bed25d275 100644 --- a/docs/stackit_beta_server_describe.md +++ b/docs/stackit_beta_server_describe.md @@ -42,5 +42,5 @@ stackit beta server describe [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers diff --git a/docs/stackit_beta_server_public-ip.md b/docs/stackit_beta_server_public-ip.md new file mode 100644 index 000000000..9cc341e4c --- /dev/null +++ b/docs/stackit_beta_server_public-ip.md @@ -0,0 +1,34 @@ +## stackit beta server public-ip + +Allows attaching/detaching public IPs to servers + +### Synopsis + +Allows attaching/detaching public IPs to servers. + +``` +stackit beta server public-ip [flags] +``` + +### Options + +``` + -h, --help Help for "stackit beta server public-ip" +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers +* [stackit beta server public-ip attach](./stackit_beta_server_public-ip_attach.md) - Attaches a public IP to a server +* [stackit beta server public-ip detach](./stackit_beta_server_public-ip_detach.md) - Detaches a public IP from a server + diff --git a/docs/stackit_beta_server_public-ip_attach.md b/docs/stackit_beta_server_public-ip_attach.md new file mode 100644 index 000000000..2bd1f1914 --- /dev/null +++ b/docs/stackit_beta_server_public-ip_attach.md @@ -0,0 +1,40 @@ +## stackit beta server public-ip attach + +Attaches a public IP to a server + +### Synopsis + +Attaches a public IP to a server. + +``` +stackit beta server public-ip attach [flags] +``` + +### Examples + +``` + Attach a public IP with ID "xxx" to a server with ID "yyy" + $ stackit beta server public-ip attach xxx --server-id yyy +``` + +### Options + +``` + -h, --help Help for "stackit beta server public-ip attach" + --server-id string Server ID +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta server public-ip](./stackit_beta_server_public-ip.md) - Allows attaching/detaching public IPs to servers + diff --git a/docs/stackit_beta_server_public-ip_detach.md b/docs/stackit_beta_server_public-ip_detach.md new file mode 100644 index 000000000..375ed68b6 --- /dev/null +++ b/docs/stackit_beta_server_public-ip_detach.md @@ -0,0 +1,40 @@ +## stackit beta server public-ip detach + +Detaches a public IP from a server + +### Synopsis + +Detaches a public IP from a server. + +``` +stackit beta server public-ip detach [flags] +``` + +### Examples + +``` + Detaches a public IP with ID "xxx" from a server with ID "yyy" + $ stackit beta server public-ip detach xxx --server-id yyy +``` + +### Options + +``` + -h, --help Help for "stackit beta server public-ip detach" + --server-id string Server ID +``` + +### Options inherited from parent commands + +``` + -y, --assume-yes If set, skips all confirmation prompts + --async If set, runs the command asynchronously + -o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"] + -p, --project-id string Project ID + --verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info") +``` + +### SEE ALSO + +* [stackit beta server public-ip](./stackit_beta_server_public-ip.md) - Allows attaching/detaching public IPs to servers + diff --git a/docs/stackit_beta_server_update.md b/docs/stackit_beta_server_update.md index 633b75fbd..499208bc3 100644 --- a/docs/stackit_beta_server_update.md +++ b/docs/stackit_beta_server_update.md @@ -40,5 +40,5 @@ stackit beta server update [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers diff --git a/docs/stackit_beta_server_volume.md b/docs/stackit_beta_server_volume.md index f2692f63f..42b0bc958 100644 --- a/docs/stackit_beta_server_volume.md +++ b/docs/stackit_beta_server_volume.md @@ -1,10 +1,10 @@ ## stackit beta server volume -Provides functionality for Server volumes +Provides functionality for server volumes ### Synopsis -Provides functionality for Server volumes. +Provides functionality for server volumes. ``` stackit beta server volume [flags] @@ -28,7 +28,7 @@ stackit beta server volume [flags] ### SEE ALSO -* [stackit beta server](./stackit_beta_server.md) - Provides functionality for Server +* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers * [stackit beta server volume attach](./stackit_beta_server_volume_attach.md) - Attaches a volume to a server * [stackit beta server volume describe](./stackit_beta_server_volume_describe.md) - Describes a server volume attachment * [stackit beta server volume detach](./stackit_beta_server_volume_detach.md) - Detaches a volume from a server diff --git a/docs/stackit_beta_server_volume_attach.md b/docs/stackit_beta_server_volume_attach.md index 43dcb6089..060fa0774 100644 --- a/docs/stackit_beta_server_volume_attach.md +++ b/docs/stackit_beta_server_volume_attach.md @@ -40,5 +40,5 @@ stackit beta server volume attach [flags] ### SEE ALSO -* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for Server volumes +* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes diff --git a/docs/stackit_beta_server_volume_describe.md b/docs/stackit_beta_server_volume_describe.md index 175931b86..3c31daa2b 100644 --- a/docs/stackit_beta_server_volume_describe.md +++ b/docs/stackit_beta_server_volume_describe.md @@ -42,5 +42,5 @@ stackit beta server volume describe [flags] ### SEE ALSO -* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for Server volumes +* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes diff --git a/docs/stackit_beta_server_volume_detach.md b/docs/stackit_beta_server_volume_detach.md index 5422aab8a..a45c8a636 100644 --- a/docs/stackit_beta_server_volume_detach.md +++ b/docs/stackit_beta_server_volume_detach.md @@ -36,5 +36,5 @@ stackit beta server volume detach [flags] ### SEE ALSO -* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for Server volumes +* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes diff --git a/docs/stackit_beta_server_volume_list.md b/docs/stackit_beta_server_volume_list.md index 68cf83bbc..68970d53c 100644 --- a/docs/stackit_beta_server_volume_list.md +++ b/docs/stackit_beta_server_volume_list.md @@ -39,5 +39,5 @@ stackit beta server volume list [flags] ### SEE ALSO -* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for Server volumes +* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes diff --git a/docs/stackit_beta_server_volume_update.md b/docs/stackit_beta_server_volume_update.md index 134cb81a4..18d45a4ac 100644 --- a/docs/stackit_beta_server_volume_update.md +++ b/docs/stackit_beta_server_volume_update.md @@ -37,5 +37,5 @@ stackit beta server volume update [flags] ### SEE ALSO -* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for Server volumes +* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes diff --git a/docs/stackit_beta_volume.md b/docs/stackit_beta_volume.md index 7255a1cec..4fe120bab 100644 --- a/docs/stackit_beta_volume.md +++ b/docs/stackit_beta_volume.md @@ -1,10 +1,10 @@ ## stackit beta volume -Provides functionality for Volume +Provides functionality for volumes ### Synopsis -Provides functionality for Volume. +Provides functionality for volumes. ``` stackit beta volume [flags] diff --git a/docs/stackit_beta_volume_create.md b/docs/stackit_beta_volume_create.md index dc44b1327..c7ce43275 100644 --- a/docs/stackit_beta_volume_create.md +++ b/docs/stackit_beta_volume_create.md @@ -52,5 +52,5 @@ stackit beta volume create [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes diff --git a/docs/stackit_beta_volume_delete.md b/docs/stackit_beta_volume_delete.md index 1ded8006d..d3de5b62d 100644 --- a/docs/stackit_beta_volume_delete.md +++ b/docs/stackit_beta_volume_delete.md @@ -37,5 +37,5 @@ stackit beta volume delete [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes diff --git a/docs/stackit_beta_volume_describe.md b/docs/stackit_beta_volume_describe.md index 387edf692..72e77fc96 100644 --- a/docs/stackit_beta_volume_describe.md +++ b/docs/stackit_beta_volume_describe.md @@ -38,5 +38,5 @@ stackit beta volume describe [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes diff --git a/docs/stackit_beta_volume_list.md b/docs/stackit_beta_volume_list.md index 985db2475..1f0c84b29 100644 --- a/docs/stackit_beta_volume_list.md +++ b/docs/stackit_beta_volume_list.md @@ -46,5 +46,5 @@ stackit beta volume list [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes diff --git a/docs/stackit_beta_volume_performance-class.md b/docs/stackit_beta_volume_performance-class.md index f1b125cab..3c92fdc51 100644 --- a/docs/stackit_beta_volume_performance-class.md +++ b/docs/stackit_beta_volume_performance-class.md @@ -28,7 +28,7 @@ stackit beta volume performance-class [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes * [stackit beta volume performance-class describe](./stackit_beta_volume_performance-class_describe.md) - Shows details of a volume performance class * [stackit beta volume performance-class list](./stackit_beta_volume_performance-class_list.md) - Lists all volume performance classes for a project diff --git a/docs/stackit_beta_volume_resize.md b/docs/stackit_beta_volume_resize.md index c2e7aea0f..a609c7c85 100644 --- a/docs/stackit_beta_volume_resize.md +++ b/docs/stackit_beta_volume_resize.md @@ -36,5 +36,5 @@ stackit beta volume resize [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes diff --git a/docs/stackit_beta_volume_update.md b/docs/stackit_beta_volume_update.md index 98ad0a94a..f85b37388 100644 --- a/docs/stackit_beta_volume_update.md +++ b/docs/stackit_beta_volume_update.md @@ -44,5 +44,5 @@ stackit beta volume update [flags] ### SEE ALSO -* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for Volume +* [stackit beta volume](./stackit_beta_volume.md) - Provides functionality for volumes From 6cc26037cd1aaf42e824a785802e7d81e881e03d Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Mon, 2 Dec 2024 15:03:59 +0000 Subject: [PATCH 3/7] fix: Linter --- internal/cmd/beta/server/describe/describe.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/server/describe/describe.go b/internal/cmd/beta/server/describe/describe.go index a5a8efda0..1fe930ae6 100644 --- a/internal/cmd/beta/server/describe/describe.go +++ b/internal/cmd/beta/server/describe/describe.go @@ -224,7 +224,7 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro nicsTable.AddRow("PUBLIC IP", *nic.PublicIp) } - nicsTable.Display(p) + err := nicsTable.Display(p) if err != nil { return fmt.Errorf("render table: %w", err) } From c9f032fdedc41120c83c2442e4b19cd1152b7bed Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Mon, 2 Dec 2024 15:08:00 +0000 Subject: [PATCH 4/7] feat: Improve comment --- internal/cmd/beta/server/describe/describe.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/cmd/beta/server/describe/describe.go b/internal/cmd/beta/server/describe/describe.go index 1fe930ae6..724e8a47f 100644 --- a/internal/cmd/beta/server/describe/describe.go +++ b/internal/cmd/beta/server/describe/describe.go @@ -204,11 +204,11 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro return fmt.Errorf("render table: %w", err) } + // If no --details is set, we only display the overview table if !model.Details { return nil } - // Additional details to be displayed when --details flag is set if server.Nics != nil && len(*server.Nics) > 0 { for i, nic := range *server.Nics { nicsTable := tables.NewTable() From 9c26cb68c0638890e4d58c6075b94fb99b41c48b Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Mon, 2 Dec 2024 15:11:22 +0000 Subject: [PATCH 5/7] feat: Improve unit test --- .../pkg/services/iaas/utils/utils_test.go | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/internal/pkg/services/iaas/utils/utils_test.go b/internal/pkg/services/iaas/utils/utils_test.go index 408cc7404..bc0d94299 100644 --- a/internal/pkg/services/iaas/utils/utils_test.go +++ b/internal/pkg/services/iaas/utils/utils_test.go @@ -82,20 +82,22 @@ func TestGetPublicIp(t *testing.T) { getPublicIpResp *iaas.PublicIp } tests := []struct { - name string - args args - want string - wantErr bool + name string + args args + wantPublicIp string + wantAssociatedResource string + wantErr bool }{ { name: "base", args: args{ getPublicIpResp: &iaas.PublicIp{ Ip: utils.Ptr("1.2.3.4"), - NetworkInterface: iaas.NewNullableString(utils.Ptr("1.2.3.4")), + NetworkInterface: iaas.NewNullableString(utils.Ptr("5.6.7.8")), }, }, - want: "1.2.3.4", + wantPublicIp: "1.2.3.4", + wantAssociatedResource: "5.6.7.8", }, { name: "get public ip fails", @@ -111,13 +113,16 @@ func TestGetPublicIp(t *testing.T) { GetPublicIpFails: tt.args.getPublicIpFails, GetPublicIpResp: tt.args.getPublicIpResp, } - got, _, err := GetPublicIP(context.Background(), m, "", "") + gotPublicIP, gotAssociatedResource, err := GetPublicIP(context.Background(), m, "", "") if (err != nil) != tt.wantErr { t.Errorf("GetPublicIP() error = %v, wantErr %v", err, tt.wantErr) return } - if got != tt.want { - t.Errorf("GetPublicIP() = %v, want %v", got, tt.want) + if gotPublicIP != tt.wantPublicIp { + t.Errorf("GetPublicIP() = %v, want public IP %v", gotPublicIP, tt.wantPublicIp) + } + if gotAssociatedResource != tt.wantAssociatedResource { + t.Errorf("GetPublicIP() = %v, want associated resource %v", gotAssociatedResource, tt.wantAssociatedResource) } }) } From 2696abbb6e83a8d70835aa24d18e591d985177dc Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Mon, 2 Dec 2024 15:32:37 +0000 Subject: [PATCH 6/7] feat: Improvement after review --- internal/cmd/beta/server/describe/describe.go | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/internal/cmd/beta/server/describe/describe.go b/internal/cmd/beta/server/describe/describe.go index 724e8a47f..eeccf838c 100644 --- a/internal/cmd/beta/server/describe/describe.go +++ b/internal/cmd/beta/server/describe/describe.go @@ -210,24 +210,22 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro } if server.Nics != nil && len(*server.Nics) > 0 { - for i, nic := range *server.Nics { - nicsTable := tables.NewTable() - nicsTable.SetTitle(fmt.Sprintf("Attached Network Interface #%d", i)) + nicsTable := tables.NewTable() + nicsTable.SetTitle("Attached Network Interfaces") + nicsTable.SetHeader("ID", "NETWORK ID", "NETWORK NAME", "PUBLIC IP") - nicsTable.AddRow("ID", *nic.NicId) - nicsTable.AddSeparator() - nicsTable.AddRow("NETWORK ID", *nic.NetworkId) - nicsTable.AddSeparator() - nicsTable.AddRow("NETWORK NAME", *nic.NetworkName) - nicsTable.AddSeparator() + for _, nic := range *server.Nics { + publicIp := "" if nic.PublicIp != nil { - nicsTable.AddRow("PUBLIC IP", *nic.PublicIp) + publicIp = *nic.PublicIp } + nicsTable.AddRow(*nic.NicId, *nic.NetworkId, *nic.NetworkName, publicIp) + nicsTable.AddSeparator() + } - err := nicsTable.Display(p) - if err != nil { - return fmt.Errorf("render table: %w", err) - } + err := nicsTable.Display(p) + if err != nil { + return fmt.Errorf("render table: %w", err) } } From ede5b1d463ce8f4d53549e341f983534e81bc3a4 Mon Sep 17 00:00:00 2001 From: "test.test@freiheit.com" Date: Mon, 2 Dec 2024 15:51:20 +0000 Subject: [PATCH 7/7] feat: Remove --details flag from server describe --- docs/stackit_beta_server_describe.md | 6 +--- internal/cmd/beta/server/describe/describe.go | 28 ++----------------- .../cmd/beta/server/describe/describe_test.go | 13 --------- 3 files changed, 4 insertions(+), 43 deletions(-) diff --git a/docs/stackit_beta_server_describe.md b/docs/stackit_beta_server_describe.md index bed25d275..fc35fbda0 100644 --- a/docs/stackit_beta_server_describe.md +++ b/docs/stackit_beta_server_describe.md @@ -16,9 +16,6 @@ stackit beta server describe [flags] Show details of a server with ID "xxx" $ stackit beta server describe xxx - Show detailed information of a server with ID "xxx" - $ stackit beta server describe xxx --details - Show details of a server with ID "xxx" in JSON format $ stackit beta server describe xxx --output-format json ``` @@ -26,8 +23,7 @@ stackit beta server describe [flags] ### Options ``` - --details Show detailed information about server - -h, --help Help for "stackit beta server describe" + -h, --help Help for "stackit beta server describe" ``` ### Options inherited from parent commands diff --git a/internal/cmd/beta/server/describe/describe.go b/internal/cmd/beta/server/describe/describe.go index eeccf838c..b425a227d 100644 --- a/internal/cmd/beta/server/describe/describe.go +++ b/internal/cmd/beta/server/describe/describe.go @@ -11,7 +11,6 @@ import ( "github.com/stackitcloud/stackit-cli/internal/pkg/args" "github.com/stackitcloud/stackit-cli/internal/pkg/errors" "github.com/stackitcloud/stackit-cli/internal/pkg/examples" - "github.com/stackitcloud/stackit-cli/internal/pkg/flags" "github.com/stackitcloud/stackit-cli/internal/pkg/globalflags" "github.com/stackitcloud/stackit-cli/internal/pkg/print" "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client" @@ -24,13 +23,11 @@ import ( const ( serverIdArg = "SERVER_ID" - detailsFlag = "details" ) type inputModel struct { *globalflags.GlobalFlagModel ServerId string - Details bool } func NewCmd(p *print.Printer) *cobra.Command { @@ -44,10 +41,6 @@ func NewCmd(p *print.Printer) *cobra.Command { `Show details of a server with ID "xxx"`, "$ stackit beta server describe xxx", ), - examples.NewExample( - `Show detailed information of a server with ID "xxx"`, - "$ stackit beta server describe xxx --details", - ), examples.NewExample( `Show details of a server with ID "xxx" in JSON format`, "$ stackit beta server describe xxx --output-format json", @@ -76,14 +69,9 @@ func NewCmd(p *print.Printer) *cobra.Command { return outputResult(p, model, resp) }, } - configureFlags(cmd) return cmd } -func configureFlags(cmd *cobra.Command) { - cmd.Flags().Bool(detailsFlag, false, "Show detailed information about server") -} - func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) { serverId := inputArgs[0] @@ -95,7 +83,6 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu model := inputModel{ GlobalFlagModel: globalFlags, ServerId: serverId, - Details: flags.FlagToBoolValue(p, cmd, detailsFlag), } if p.IsVerbosityDebug() { @@ -112,10 +99,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inpu func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiGetServerRequest { req := apiClient.GetServer(ctx, model.ProjectId, model.ServerId) - - if model.Details { - req = req.Details(true) - } + req = req.Details(true) return req } @@ -142,9 +126,8 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro return nil default: table := tables.NewTable() - if model.Details { - table.SetTitle("Server") - } + table.SetTitle("Server") + table.AddRow("ID", *server.Id) table.AddSeparator() table.AddRow("NAME", *server.Name) @@ -204,11 +187,6 @@ func outputResult(p *print.Printer, model *inputModel, server *iaas.Server) erro return fmt.Errorf("render table: %w", err) } - // If no --details is set, we only display the overview table - if !model.Details { - return nil - } - if server.Nics != nil && len(*server.Nics) > 0 { nicsTable := tables.NewTable() nicsTable.SetTitle("Attached Network Interfaces") diff --git a/internal/cmd/beta/server/describe/describe_test.go b/internal/cmd/beta/server/describe/describe_test.go index 0c8c2ff13..defc5dec6 100644 --- a/internal/cmd/beta/server/describe/describe_test.go +++ b/internal/cmd/beta/server/describe/describe_test.go @@ -35,7 +35,6 @@ func fixtureArgValues(mods ...func(argValues []string)) []string { func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string { flagValues := map[string]string{ projectIdFlag: testProjectId, - detailsFlag: "true", } for _, mod := range mods { mod(flagValues) @@ -50,7 +49,6 @@ func fixtureInputModel(mods ...func(model *inputModel)) *inputModel { Verbosity: globalflags.VerbosityDefault, }, ServerId: testServerId, - Details: true, } for _, mod := range mods { mod(model) @@ -136,17 +134,6 @@ func TestParseInput(t *testing.T) { flagValues: fixtureFlagValues(), isValid: false, }, - { - description: "details flag false", - argValues: fixtureArgValues(), - flagValues: fixtureFlagValues(func(flagValues map[string]string) { - flagValues[detailsFlag] = "false" - }), - isValid: true, - expectedModel: fixtureInputModel(func(model *inputModel) { - model.Details = false - }), - }, } for _, tt := range tests {