Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Onboard IaaS Server Service Account Commands #522

Merged
merged 5 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/stackit_beta_server.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ stackit beta server [flags]
* [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 service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts 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

35 changes: 35 additions & 0 deletions docs/stackit_beta_server_service-account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## stackit beta server service-account

Allows attaching/detaching service accounts to servers

### Synopsis

Allows attaching/detaching service accounts to servers

```
stackit beta server service-account [flags]
```

### Options

```
-h, --help Help for "stackit beta server service-account"
```

### 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 service-account attach](./stackit_beta_server_service-account_attach.md) - Attach a service account to a server
* [stackit beta server service-account detach](./stackit_beta_server_service-account_detach.md) - Detach a service account from a server
* [stackit beta server service-account list](./stackit_beta_server_service-account_list.md) - List all attached service accounts for a server

40 changes: 40 additions & 0 deletions docs/stackit_beta_server_service-account_attach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## stackit beta server service-account attach

Attach a service account to a server

### Synopsis

Attach a service account to a server

```
stackit beta server service-account attach [flags]
```

### Examples

```
Attach a service account with mail "xxx@sa.stackit.cloud" to a server with ID "yyy"
$ stackit beta server service-account attach xxx@sa.stackit.cloud --server-id yyy
```

### Options

```
-h, --help Help for "stackit beta server service-account attach"
-s, --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 service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers

40 changes: 40 additions & 0 deletions docs/stackit_beta_server_service-account_detach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
## stackit beta server service-account detach

Detach a service account from a server

### Synopsis

Detach a service account from a server

```
stackit beta server service-account detach [flags]
```

### Examples

```
Detach a service account with mail "xxx@sa.stackit.cloud" from a server "yyy"
$ stackit beta server service-account detach xxx@sa.stackit.cloud --server-id yyy
```

### Options

```
-h, --help Help for "stackit beta server service-account detach"
-s, --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 service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers

47 changes: 47 additions & 0 deletions docs/stackit_beta_server_service-account_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## stackit beta server service-account list

List all attached service accounts for a server

### Synopsis

List all attached service accounts for a server

```
stackit beta server service-account list [flags]
```

### Examples

```
List all attached service accounts for a server with ID "xxx"
$ stackit beta server service-account list --server-id xxx

List up to 10 attached service accounts for a server with ID "xxx"
$ stackit beta server service-account list --server-id xxx --limit 10

List all attached service accounts for a server with ID "xxx" in JSON format
$ stackit beta server service-account list --server-id xxx --output-format json
```

### Options

```
-h, --help Help for "stackit beta server service-account list"
--limit int Maximum number of entries to list
-s, --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 service-account](./stackit_beta_server_service-account.md) - Allows attaching/detaching service accounts to servers

3 changes: 3 additions & 0 deletions internal/cmd/beta/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import (
"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"
serviceaccount "github.com/stackitcloud/stackit-cli/internal/cmd/beta/server/service-account"
"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"
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
Expand Down Expand Up @@ -37,6 +39,7 @@ func addSubcommands(cmd *cobra.Command, p *print.Printer) {
cmd.AddCommand(describe.NewCmd(p))
cmd.AddCommand(list.NewCmd(p))
cmd.AddCommand(publicip.NewCmd(p))
cmd.AddCommand(serviceaccount.NewCmd(p))
cmd.AddCommand(update.NewCmd(p))
cmd.AddCommand(volume.NewCmd(p))
}
145 changes: 145 additions & 0 deletions internal/cmd/beta/server/service-account/attach/attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
package attach

import (
"context"
"encoding/json"
"fmt"

"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/goccy/go-yaml"
"github.com/spf13/cobra"
"github.com/stackitcloud/stackit-sdk-go/services/iaas"
)

const (
serviceAccMailArg = "SERVICE_ACCOUNT_EMAIL"

serverIdFlag = "server-id"
)

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

func NewCmd(p *print.Printer) *cobra.Command {
cmd := &cobra.Command{
Use: "attach",
Short: "Attach a service account to a server",
Long: "Attach a service account to a server",
Args: args.SingleArg(serviceAccMailArg, nil),
Example: examples.Build(
examples.NewExample(
`Attach a service account with mail "xxx@sa.stackit.cloud" to a server with ID "yyy"`,
"$ stackit beta server service-account attach xxx@sa.stackit.cloud --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
}
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 service account %q to server %q?", model.ServiceAccMail, serverLabel)
err = p.PromptForConfirmation(prompt)
if err != nil {
return err
}
}

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

return outputResult(p, model.OutputFormat, model.ServiceAccMail, serverLabel, resp)
},
}
configureFlags(cmd)
return cmd
}

func configureFlags(cmd *cobra.Command) {
cmd.Flags().VarP(flags.UUIDFlag(), serverIdFlag, "s", "Server ID")

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

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

model := inputModel{
GlobalFlagModel: globalFlags,
ServerId: flags.FlagToStringPointer(p, cmd, serverIdFlag),
ServiceAccMail: serviceAccMail,
}

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.ApiAddServiceAccountToServerRequest {
req := apiClient.AddServiceAccountToServer(ctx, model.ProjectId, *model.ServerId, model.ServiceAccMail)
return req
}

func outputResult(p *print.Printer, outputFormat, serviceAccMail, serverLabel string, serviceAccounts *iaas.ServiceAccountMailListResponse) error {
switch outputFormat {
case print.JSONOutputFormat:
details, err := json.MarshalIndent(serviceAccounts, "", " ")
if err != nil {
return fmt.Errorf("marshal service account: %w", err)
}
p.Outputln(string(details))

return nil
case print.YAMLOutputFormat:
details, err := yaml.MarshalWithOptions(serviceAccounts, yaml.IndentSequence(true))
if err != nil {
return fmt.Errorf("marshal service account: %w", err)
}
p.Outputln(string(details))

return nil
default:
p.Outputf("Attached service account %q to server %q\n", serviceAccMail, serverLabel)
return nil
}
}
Loading
Loading