Skip to content
1 change: 1 addition & 0 deletions docs/stackit_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ stackit server [flags]
* [stackit server reboot](./stackit_server_reboot.md) - Reboots a server
* [stackit server rescue](./stackit_server_rescue.md) - Rescues an existing server
* [stackit server resize](./stackit_server_resize.md) - Resizes the server to the given machine type
* [stackit server security-group](./stackit_server_security-group.md) - Allows attaching/detaching security groups to servers
* [stackit server service-account](./stackit_server_service-account.md) - Allows attaching/detaching service accounts to servers
* [stackit server start](./stackit_server_start.md) - Starts an existing server or allocates the server if deallocated
* [stackit server stop](./stackit_server_stop.md) - Stops an existing server
Expand Down
35 changes: 35 additions & 0 deletions docs/stackit_server_security-group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## stackit server security-group

Allows attaching/detaching security groups to servers

### Synopsis

Allows attaching/detaching security groups to servers.

```
stackit server security-group [flags]
```

### Options

```
-h, --help Help for "stackit server security-group"
```

### 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
--region string Target region for region-specific requests
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit server](./stackit_server.md) - Provides functionality for servers
* [stackit server security-group attach](./stackit_server_security-group_attach.md) - Attaches a security group to a server
* [stackit server security-group detach](./stackit_server_security-group_detach.md) - Detaches a security group from a server

42 changes: 42 additions & 0 deletions docs/stackit_server_security-group_attach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## stackit server security-group attach

Attaches a security group to a server

### Synopsis

Attaches a security group to a server.

```
stackit server security-group attach [flags]
```

### Examples

```
Attach a security group with ID "xxx" to a server with ID "yyy"
$ stackit server security-group attach --server-id yyy --security-group-id xxx
```

### Options

```
-h, --help Help for "stackit server security-group attach"
--security-group-id string Security Group ID
--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
--region string Target region for region-specific requests
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit server security-group](./stackit_server_security-group.md) - Allows attaching/detaching security groups to servers

42 changes: 42 additions & 0 deletions docs/stackit_server_security-group_detach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## stackit server security-group detach

Detaches a security group from a server

### Synopsis

Detaches a security group from a server.

```
stackit server security-group detach [flags]
```

### Examples

```
Detach a security group with ID "xxx" from a server with ID "yyy"
$ stackit server security-group detach --server-id yyy --security-group-id xxx
```

### Options

```
-h, --help Help for "stackit server security-group detach"
--security-group-id string Security Group ID
--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
--region string Target region for region-specific requests
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit server security-group](./stackit_server_security-group.md) - Allows attaching/detaching security groups to servers

119 changes: 119 additions & 0 deletions internal/cmd/server/security-group/attach/attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package attach

import (
"context"
"fmt"

"github.com/stackitcloud/stackit-cli/internal/pkg/types"

"github.com/spf13/cobra"
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
cliErr "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-sdk-go/services/iaas"
)

const (
serverIdFlag = "server-id"
securityGroupIdFlag = "security-group-id"
)

type inputModel struct {
*globalflags.GlobalFlagModel
ServerId string
SecurityGroupId string
}

func NewCmd(params *types.CmdParams) *cobra.Command {
cmd := &cobra.Command{
Use: "attach",
Short: "Attaches a security group to a server",
Long: "Attaches a security group to a server.",
Args: args.NoArgs,
Example: examples.Build(
examples.NewExample(
`Attach a security group with ID "xxx" to a server with ID "yyy"`,
`$ stackit server security-group attach --server-id yyy --security-group-id xxx`,
),
),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := context.Background()
model, err := parseInput(params.Printer, cmd, args)
if err != nil {
return err
}

// Configure API client
apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion)
if err != nil {
return err
}

serverLabel, err := iaasUtils.GetServerName(ctx, apiClient, model.ProjectId, model.Region, model.ServerId)
if err != nil {
params.Printer.Debug(print.ErrorLevel, "get server name: %v", err)
serverLabel = model.ServerId
} else if serverLabel == "" {
serverLabel = model.ServerId
}

securityGroupLabel, err := iaasUtils.GetSecurityGroupName(ctx, apiClient, model.ProjectId, model.Region, model.SecurityGroupId)
if err != nil {
params.Printer.Debug(print.ErrorLevel, "get security group name: %v", err)
securityGroupLabel = model.SecurityGroupId
}

prompt := fmt.Sprintf("Are you sure you want to attach security group %q to server %q?", securityGroupLabel, serverLabel)
err = params.Printer.PromptForConfirmation(prompt)
if err != nil {
return err
}

// Call API
req := buildRequest(ctx, model, apiClient)
if err := req.Execute(); err != nil {
return fmt.Errorf("attach security group to server: %w", err)
}

params.Printer.Info("Attached security group %q to server %q\n", securityGroupLabel, serverLabel)

return nil
},
}
configureFlags(cmd)
return cmd
}

func configureFlags(cmd *cobra.Command) {
cmd.Flags().Var(flags.UUIDFlag(), serverIdFlag, "Server ID")
cmd.Flags().Var(flags.UUIDFlag(), securityGroupIdFlag, "Security Group ID")

err := flags.MarkFlagsRequired(cmd, serverIdFlag, securityGroupIdFlag)
cobra.CheckErr(err)
}

func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) {
globalFlags := globalflags.Parse(p, cmd)
if globalFlags.ProjectId == "" {
return nil, &cliErr.ProjectIdError{}
}

model := inputModel{
GlobalFlagModel: globalFlags,
ServerId: flags.FlagToStringValue(p, cmd, serverIdFlag),
SecurityGroupId: flags.FlagToStringValue(p, cmd, securityGroupIdFlag),
}

p.DebugInputModel(model)
return &model, nil
}

func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiAddSecurityGroupToServerRequest {
req := apiClient.AddSecurityGroupToServer(ctx, model.ProjectId, model.Region, model.ServerId, model.SecurityGroupId)
return req
}
Loading
Loading