Skip to content

Commit d1a943f

Browse files
authored
feat(iaas): implement server security group attach/detach commands (#1341)
relates to STACKITCLI-308 and #1216
1 parent 001684e commit d1a943f

File tree

11 files changed

+751
-1
lines changed

11 files changed

+751
-1
lines changed

docs/stackit_server.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ stackit server [flags]
4646
* [stackit server reboot](./stackit_server_reboot.md) - Reboots a server
4747
* [stackit server rescue](./stackit_server_rescue.md) - Rescues an existing server
4848
* [stackit server resize](./stackit_server_resize.md) - Resizes the server to the given machine type
49+
* [stackit server security-group](./stackit_server_security-group.md) - Allows attaching/detaching security groups to servers
4950
* [stackit server service-account](./stackit_server_service-account.md) - Allows attaching/detaching service accounts to servers
5051
* [stackit server start](./stackit_server_start.md) - Starts an existing server or allocates the server if deallocated
5152
* [stackit server stop](./stackit_server_stop.md) - Stops an existing server
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## stackit server security-group
2+
3+
Allows attaching/detaching security groups to servers
4+
5+
### Synopsis
6+
7+
Allows attaching/detaching security groups to servers.
8+
9+
```
10+
stackit server security-group [flags]
11+
```
12+
13+
### Options
14+
15+
```
16+
-h, --help Help for "stackit server security-group"
17+
```
18+
19+
### Options inherited from parent commands
20+
21+
```
22+
-y, --assume-yes If set, skips all confirmation prompts
23+
--async If set, runs the command asynchronously
24+
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
25+
-p, --project-id string Project ID
26+
--region string Target region for region-specific requests
27+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
28+
```
29+
30+
### SEE ALSO
31+
32+
* [stackit server](./stackit_server.md) - Provides functionality for servers
33+
* [stackit server security-group attach](./stackit_server_security-group_attach.md) - Attaches a security group to a server
34+
* [stackit server security-group detach](./stackit_server_security-group_detach.md) - Detaches a security group from a server
35+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
## stackit server security-group attach
2+
3+
Attaches a security group to a server
4+
5+
### Synopsis
6+
7+
Attaches a security group to a server.
8+
9+
```
10+
stackit server security-group attach [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
Attach a security group with ID "xxx" to a server with ID "yyy"
17+
$ stackit server security-group attach --server-id yyy --security-group-id xxx
18+
```
19+
20+
### Options
21+
22+
```
23+
-h, --help Help for "stackit server security-group attach"
24+
--security-group-id string Security Group ID
25+
--server-id string Server ID
26+
```
27+
28+
### Options inherited from parent commands
29+
30+
```
31+
-y, --assume-yes If set, skips all confirmation prompts
32+
--async If set, runs the command asynchronously
33+
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
34+
-p, --project-id string Project ID
35+
--region string Target region for region-specific requests
36+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
37+
```
38+
39+
### SEE ALSO
40+
41+
* [stackit server security-group](./stackit_server_security-group.md) - Allows attaching/detaching security groups to servers
42+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
## stackit server security-group detach
2+
3+
Detaches a security group from a server
4+
5+
### Synopsis
6+
7+
Detaches a security group from a server.
8+
9+
```
10+
stackit server security-group detach [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
Detach a security group with ID "xxx" from a server with ID "yyy"
17+
$ stackit server security-group detach --server-id yyy --security-group-id xxx
18+
```
19+
20+
### Options
21+
22+
```
23+
-h, --help Help for "stackit server security-group detach"
24+
--security-group-id string Security Group ID
25+
--server-id string Server ID
26+
```
27+
28+
### Options inherited from parent commands
29+
30+
```
31+
-y, --assume-yes If set, skips all confirmation prompts
32+
--async If set, runs the command asynchronously
33+
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
34+
-p, --project-id string Project ID
35+
--region string Target region for region-specific requests
36+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
37+
```
38+
39+
### SEE ALSO
40+
41+
* [stackit server security-group](./stackit_server_security-group.md) - Allows attaching/detaching security groups to servers
42+
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package attach
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
8+
9+
"github.com/spf13/cobra"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
11+
cliErr "github.com/stackitcloud/stackit-cli/internal/pkg/errors"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
15+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
16+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client"
17+
iaasUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/utils"
18+
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
19+
)
20+
21+
const (
22+
serverIdFlag = "server-id"
23+
securityGroupIdFlag = "security-group-id"
24+
)
25+
26+
type inputModel struct {
27+
*globalflags.GlobalFlagModel
28+
ServerId string
29+
SecurityGroupId string
30+
}
31+
32+
func NewCmd(params *types.CmdParams) *cobra.Command {
33+
cmd := &cobra.Command{
34+
Use: "attach",
35+
Short: "Attaches a security group to a server",
36+
Long: "Attaches a security group to a server.",
37+
Args: args.NoArgs,
38+
Example: examples.Build(
39+
examples.NewExample(
40+
`Attach a security group with ID "xxx" to a server with ID "yyy"`,
41+
`$ stackit server security-group attach --server-id yyy --security-group-id xxx`,
42+
),
43+
),
44+
RunE: func(cmd *cobra.Command, args []string) error {
45+
ctx := context.Background()
46+
model, err := parseInput(params.Printer, cmd, args)
47+
if err != nil {
48+
return err
49+
}
50+
51+
// Configure API client
52+
apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion)
53+
if err != nil {
54+
return err
55+
}
56+
57+
serverLabel, err := iaasUtils.GetServerName(ctx, apiClient, model.ProjectId, model.Region, model.ServerId)
58+
if err != nil {
59+
params.Printer.Debug(print.ErrorLevel, "get server name: %v", err)
60+
serverLabel = model.ServerId
61+
} else if serverLabel == "" {
62+
serverLabel = model.ServerId
63+
}
64+
65+
securityGroupLabel, err := iaasUtils.GetSecurityGroupName(ctx, apiClient, model.ProjectId, model.Region, model.SecurityGroupId)
66+
if err != nil {
67+
params.Printer.Debug(print.ErrorLevel, "get security group name: %v", err)
68+
securityGroupLabel = model.SecurityGroupId
69+
}
70+
71+
prompt := fmt.Sprintf("Are you sure you want to attach security group %q to server %q?", securityGroupLabel, serverLabel)
72+
err = params.Printer.PromptForConfirmation(prompt)
73+
if err != nil {
74+
return err
75+
}
76+
77+
// Call API
78+
req := buildRequest(ctx, model, apiClient)
79+
if err := req.Execute(); err != nil {
80+
return fmt.Errorf("attach security group to server: %w", err)
81+
}
82+
83+
params.Printer.Outputf("Attached security group %q to server %q\n", securityGroupLabel, serverLabel)
84+
85+
return nil
86+
},
87+
}
88+
configureFlags(cmd)
89+
return cmd
90+
}
91+
92+
func configureFlags(cmd *cobra.Command) {
93+
cmd.Flags().Var(flags.UUIDFlag(), serverIdFlag, "Server ID")
94+
cmd.Flags().Var(flags.UUIDFlag(), securityGroupIdFlag, "Security Group ID")
95+
96+
err := flags.MarkFlagsRequired(cmd, serverIdFlag, securityGroupIdFlag)
97+
cobra.CheckErr(err)
98+
}
99+
100+
func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) {
101+
globalFlags := globalflags.Parse(p, cmd)
102+
if globalFlags.ProjectId == "" {
103+
return nil, &cliErr.ProjectIdError{}
104+
}
105+
106+
model := inputModel{
107+
GlobalFlagModel: globalFlags,
108+
ServerId: flags.FlagToStringValue(p, cmd, serverIdFlag),
109+
SecurityGroupId: flags.FlagToStringValue(p, cmd, securityGroupIdFlag),
110+
}
111+
112+
p.DebugInputModel(model)
113+
return &model, nil
114+
}
115+
116+
func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiAddSecurityGroupToServerRequest {
117+
req := apiClient.AddSecurityGroupToServer(ctx, model.ProjectId, model.Region, model.ServerId, model.SecurityGroupId)
118+
return req
119+
}

0 commit comments

Comments
 (0)