Skip to content

Commit 0da6d09

Browse files
authored
Onboard IaaS Server Service Account Commands (#522)
* Add server service-account commands * Generate docs for server service-account commands
1 parent b9be7a6 commit 0da6d09

13 files changed

+1329
-0
lines changed

docs/stackit_beta_server.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ stackit beta server [flags]
3636
* [stackit beta server describe](./stackit_beta_server_describe.md) - Shows details of a server
3737
* [stackit beta server list](./stackit_beta_server_list.md) - Lists all servers of a project
3838
* [stackit beta server public-ip](./stackit_beta_server_public-ip.md) - Allows attaching/detaching public IPs to servers
39+
* [stackit beta server service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers
3940
* [stackit beta server update](./stackit_beta_server_update.md) - Updates a server
4041
* [stackit beta server volume](./stackit_beta_server_volume.md) - Provides functionality for server volumes
4142

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## stackit beta server service-account
2+
3+
Allows attaching/detaching service accounts to servers
4+
5+
### Synopsis
6+
7+
Allows attaching/detaching service accounts to servers
8+
9+
```
10+
stackit beta server service-account [flags]
11+
```
12+
13+
### Options
14+
15+
```
16+
-h, --help Help for "stackit beta server service-account"
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+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
27+
```
28+
29+
### SEE ALSO
30+
31+
* [stackit beta server](./stackit_beta_server.md) - Provides functionality for servers
32+
* [stackit beta server service-account attach](./stackit_beta_server_service-account_attach.md) - Attach a service account to a server
33+
* [stackit beta server service-account detach](./stackit_beta_server_service-account_detach.md) - Detach a service account from a server
34+
* [stackit beta server service-account list](./stackit_beta_server_service-account_list.md) - List all attached service accounts for a server
35+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## stackit beta server service-account attach
2+
3+
Attach a service account to a server
4+
5+
### Synopsis
6+
7+
Attach a service account to a server
8+
9+
```
10+
stackit beta server service-account attach [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
Attach a service account with mail "[email protected]" to a server with ID "yyy"
17+
$ stackit beta server service-account attach [email protected] --server-id yyy
18+
```
19+
20+
### Options
21+
22+
```
23+
-h, --help Help for "stackit beta server service-account attach"
24+
-s, --server-id string Server ID
25+
```
26+
27+
### Options inherited from parent commands
28+
29+
```
30+
-y, --assume-yes If set, skips all confirmation prompts
31+
--async If set, runs the command asynchronously
32+
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
33+
-p, --project-id string Project ID
34+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
35+
```
36+
37+
### SEE ALSO
38+
39+
* [stackit beta server service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers
40+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## stackit beta server service-account detach
2+
3+
Detach a service account from a server
4+
5+
### Synopsis
6+
7+
Detach a service account from a server
8+
9+
```
10+
stackit beta server service-account detach [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
Detach a service account with mail "[email protected]" from a server "yyy"
17+
$ stackit beta server service-account detach [email protected] --server-id yyy
18+
```
19+
20+
### Options
21+
22+
```
23+
-h, --help Help for "stackit beta server service-account detach"
24+
-s, --server-id string Server id
25+
```
26+
27+
### Options inherited from parent commands
28+
29+
```
30+
-y, --assume-yes If set, skips all confirmation prompts
31+
--async If set, runs the command asynchronously
32+
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
33+
-p, --project-id string Project ID
34+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
35+
```
36+
37+
### SEE ALSO
38+
39+
* [stackit beta server service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers
40+
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
## stackit beta server service-account list
2+
3+
List all attached service accounts for a server
4+
5+
### Synopsis
6+
7+
List all attached service accounts for a server
8+
9+
```
10+
stackit beta server service-account list [flags]
11+
```
12+
13+
### Examples
14+
15+
```
16+
List all attached service accounts for a server with ID "xxx"
17+
$ stackit beta server service-account list --server-id xxx
18+
19+
List up to 10 attached service accounts for a server with ID "xxx"
20+
$ stackit beta server service-account list --server-id xxx --limit 10
21+
22+
List all attached service accounts for a server with ID "xxx" in JSON format
23+
$ stackit beta server service-account list --server-id xxx --output-format json
24+
```
25+
26+
### Options
27+
28+
```
29+
-h, --help Help for "stackit beta server service-account list"
30+
--limit int Maximum number of entries to list
31+
-s, --server-id string Server ID
32+
```
33+
34+
### Options inherited from parent commands
35+
36+
```
37+
-y, --assume-yes If set, skips all confirmation prompts
38+
--async If set, runs the command asynchronously
39+
-o, --output-format string Output format, one of ["json" "pretty" "none" "yaml"]
40+
-p, --project-id string Project ID
41+
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
42+
```
43+
44+
### SEE ALSO
45+
46+
* [stackit beta server service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers
47+

internal/cmd/beta/server/server.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/describe"
99
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/list"
1010
publicip "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/public-ip"
11+
serviceaccount "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/service-account"
1112
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/update"
1213
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/volume"
14+
1315
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
1416
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
1517
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
@@ -37,6 +39,7 @@ func addSubcommands(cmd *cobra.Command, p *print.Printer) {
3739
cmd.AddCommand(describe.NewCmd(p))
3840
cmd.AddCommand(list.NewCmd(p))
3941
cmd.AddCommand(publicip.NewCmd(p))
42+
cmd.AddCommand(serviceaccount.NewCmd(p))
4043
cmd.AddCommand(update.NewCmd(p))
4144
cmd.AddCommand(volume.NewCmd(p))
4245
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package attach
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
8+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/client"
15+
iaasUtils "github.com/stackitcloud/stackit-cli/internal/pkg/services/iaas/utils"
16+
17+
"github.com/goccy/go-yaml"
18+
"github.com/spf13/cobra"
19+
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
20+
)
21+
22+
const (
23+
serviceAccMailArg = "SERVICE_ACCOUNT_EMAIL"
24+
25+
serverIdFlag = "server-id"
26+
)
27+
28+
type inputModel struct {
29+
*globalflags.GlobalFlagModel
30+
ServerId *string
31+
ServiceAccMail string
32+
}
33+
34+
func NewCmd(p *print.Printer) *cobra.Command {
35+
cmd := &cobra.Command{
36+
Use: "attach",
37+
Short: "Attach a service account to a server",
38+
Long: "Attach a service account to a server",
39+
Args: args.SingleArg(serviceAccMailArg, nil),
40+
Example: examples.Build(
41+
examples.NewExample(
42+
`Attach a service account with mail "[email protected]" to a server with ID "yyy"`,
43+
"$ stackit beta server service-account attach [email protected] --server-id yyy",
44+
),
45+
),
46+
RunE: func(cmd *cobra.Command, args []string) error {
47+
ctx := context.Background()
48+
model, err := parseInput(p, cmd, args)
49+
if err != nil {
50+
return err
51+
}
52+
53+
// Configure API client
54+
apiClient, err := client.ConfigureClient(p)
55+
if err != nil {
56+
return err
57+
}
58+
serverLabel, err := iaasUtils.GetServerName(ctx, apiClient, model.ProjectId, *model.ServerId)
59+
if err != nil {
60+
p.Debug(print.ErrorLevel, "get server name: %v", err)
61+
serverLabel = *model.ServerId
62+
}
63+
64+
if !model.AssumeYes {
65+
prompt := fmt.Sprintf("Are you sure you want to attach service account %q to server %q?", model.ServiceAccMail, serverLabel)
66+
err = p.PromptForConfirmation(prompt)
67+
if err != nil {
68+
return err
69+
}
70+
}
71+
72+
// Call API
73+
req := buildRequest(ctx, model, apiClient)
74+
resp, err := req.Execute()
75+
if err != nil {
76+
return fmt.Errorf("attach service account to server: %w", err)
77+
}
78+
79+
return outputResult(p, model.OutputFormat, model.ServiceAccMail, serverLabel, resp)
80+
},
81+
}
82+
configureFlags(cmd)
83+
return cmd
84+
}
85+
86+
func configureFlags(cmd *cobra.Command) {
87+
cmd.Flags().VarP(flags.UUIDFlag(), serverIdFlag, "s", "Server ID")
88+
89+
err := flags.MarkFlagsRequired(cmd, serverIdFlag)
90+
cobra.CheckErr(err)
91+
}
92+
93+
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) {
94+
serviceAccMail := inputArgs[0]
95+
globalFlags := globalflags.Parse(p, cmd)
96+
if globalFlags.ProjectId == "" {
97+
return nil, &errors.ProjectIdError{}
98+
}
99+
100+
model := inputModel{
101+
GlobalFlagModel: globalFlags,
102+
ServerId: flags.FlagToStringPointer(p, cmd, serverIdFlag),
103+
ServiceAccMail: serviceAccMail,
104+
}
105+
106+
if p.IsVerbosityDebug() {
107+
modelStr, err := print.BuildDebugStrFromInputModel(model)
108+
if err != nil {
109+
p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err)
110+
} else {
111+
p.Debug(print.DebugLevel, "parsed input values: %s", modelStr)
112+
}
113+
}
114+
115+
return &model, nil
116+
}
117+
118+
func buildRequest(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiAddServiceAccountToServerRequest {
119+
req := apiClient.AddServiceAccountToServer(ctx, model.ProjectId, *model.ServerId, model.ServiceAccMail)
120+
return req
121+
}
122+
123+
func outputResult(p *print.Printer, outputFormat, serviceAccMail, serverLabel string, serviceAccounts *iaas.ServiceAccountMailListResponse) error {
124+
switch outputFormat {
125+
case print.JSONOutputFormat:
126+
details, err := json.MarshalIndent(serviceAccounts, "", " ")
127+
if err != nil {
128+
return fmt.Errorf("marshal service account: %w", err)
129+
}
130+
p.Outputln(string(details))
131+
132+
return nil
133+
case print.YAMLOutputFormat:
134+
details, err := yaml.MarshalWithOptions(serviceAccounts, yaml.IndentSequence(true))
135+
if err != nil {
136+
return fmt.Errorf("marshal service account: %w", err)
137+
}
138+
p.Outputln(string(details))
139+
140+
return nil
141+
default:
142+
p.Outputf("Attached service account %q to server %q\n", serviceAccMail, serverLabel)
143+
return nil
144+
}
145+
}

0 commit comments

Comments
 (0)