Skip to content
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 @@ -35,6 +35,7 @@ stackit beta server [flags]
* [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 network-interface](./stackit_beta_server_network-interface.md) - Allows attaching/detaching network interfaces to servers
* [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
Expand Down
35 changes: 35 additions & 0 deletions docs/stackit_beta_server_network-interface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## stackit beta server network-interface

Allows attaching/detaching network interfaces to servers

### Synopsis

Allows attaching/detaching network interfaces to servers.

```
stackit beta server network-interface [flags]
```

### Options

```
-h, --help Help for "stackit beta server network-interface"
```

### 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 network-interface attach](./stackit_beta_server_network-interface_attach.md) - Attaches a network interface to a server
* [stackit beta server network-interface detach](./stackit_beta_server_network-interface_detach.md) - Detaches a network interface from a server
* [stackit beta server network-interface list](./stackit_beta_server_network-interface_list.md) - Lists all attached network interfaces of a server

46 changes: 46 additions & 0 deletions docs/stackit_beta_server_network-interface_attach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## stackit beta server network-interface attach

Attaches a network interface to a server

### Synopsis

Attaches a network interface to a server.

```
stackit beta server network-interface attach [flags]
```

### Examples

```
Attach a network interface with ID "xxx" to a server with ID "yyy"
$ stackit beta server network-interface attach --network-interface-id xxx --server-id yyy

Create a network interface for network with ID "xxx" and attach it to a server with ID "yyy"
$ stackit beta server network-interface attach --network-id xxx --server-id yyy --create
```

### Options

```
-b, --create If this is set a network interface will be created. (default false)
-h, --help Help for "stackit beta server network-interface attach"
--network-id string Network ID
--network-interface-id string Network Interface 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
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit beta server network-interface](./stackit_beta_server_network-interface.md) - Allows attaching/detaching network interfaces to servers

46 changes: 46 additions & 0 deletions docs/stackit_beta_server_network-interface_detach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
## stackit beta server network-interface detach

Detaches a network interface from a server

### Synopsis

Detaches a network interface from a server.

```
stackit beta server network-interface detach [flags]
```

### Examples

```
Detach a network interface with ID "xxx" from a server with ID "yyy"
$ stackit beta server network-interface detach --network-interface-id xxx --server-id yyy

Detach and delete all network interfaces for network with ID "xxx" and detach them from a server with ID "yyy"
$ stackit beta server network-interface detach --network-id xxx --server-id yyy --delete
```

### Options

```
-b, --delete If this is set all network interfaces will be deleted. (default false)
-h, --help Help for "stackit beta server network-interface detach"
--network-id string Network ID
--network-interface-id string Network Interface 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
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit beta server network-interface](./stackit_beta_server_network-interface.md) - Allows attaching/detaching network interfaces to servers

47 changes: 47 additions & 0 deletions docs/stackit_beta_server_network-interface_list.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## stackit beta server network-interface list

Lists all attached network interfaces of a server

### Synopsis

Lists all attached network interfaces of a server.

```
stackit beta server network-interface list [flags]
```

### Examples

```
Lists all attached network interfaces of server with ID "xxx"
$ stackit beta server network-interface list --server-id xxx

Lists all attached network interfaces of server with ID "xxx" in JSON format
$ stackit beta server network-interface list --server-id xxx --output-format json

Lists up to 10 attached network interfaces of server with ID "xxx"
$ stackit beta server network-interface list --server-id xxx --limit 10
```

### Options

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

171 changes: 171 additions & 0 deletions internal/cmd/beta/server/network-interface/attach/attach.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
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"
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"
networkInterfaceIdFlag = "network-interface-id"
createFlag = "create"
networkIdFlag = "network-id"

defaultCreateFlag = false
)

type inputModel struct {
*globalflags.GlobalFlagModel
ServerId *string
NicId *string
NetworkId *string
Create *bool
}

func NewCmd(p *print.Printer) *cobra.Command {
cmd := &cobra.Command{
Use: "attach",
Short: "Attaches a network interface to a server",
Long: "Attaches a network interface to a server.",
Args: args.NoArgs,
Example: examples.Build(
examples.NewExample(
`Attach a network interface with ID "xxx" to a server with ID "yyy"`,
`$ stackit beta server network-interface attach --network-interface-id xxx --server-id yyy`,
),
examples.NewExample(
`Create a network interface for network with ID "xxx" and attach it to a server with ID "yyy"`,
`$ stackit beta server network-interface attach --network-id xxx --server-id yyy --create`,
),
),
RunE: func(cmd *cobra.Command, _ []string) error {
ctx := context.Background()
model, err := parseInput(p, cmd)
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 the create flag is provided a network interface will be created and attached
if model.Create != nil && *model.Create {
networkLabel, err := iaasUtils.GetNetworkName(ctx, apiClient, model.ProjectId, *model.NetworkId)
if err != nil {
p.Debug(print.ErrorLevel, "get network name: %v", err)
networkLabel = *model.NetworkId
}
if !model.AssumeYes {
prompt := fmt.Sprintf("Are you sure you want to create a network interface for network %q and attach it to server %q?", networkLabel, serverLabel)
err = p.PromptForConfirmation(prompt)
if err != nil {
return err
}
}
// Call API
req := buildRequestCreateAndAttach(ctx, model, apiClient)
err = req.Execute()
if err != nil {
return fmt.Errorf("create and attach network interface: %w", err)
}
p.Info("Created a network interface for network %q and attached it to server %q\n", networkLabel, serverLabel)
return nil
}

if !model.AssumeYes {
prompt := fmt.Sprintf("Are you sure you want to attach network interface %q to server %q?", *model.NicId, serverLabel)
err = p.PromptForConfirmation(prompt)
if err != nil {
return err
}
}
// Call API
req := buildRequestAttach(ctx, model, apiClient)
err = req.Execute()
if err != nil {
return fmt.Errorf("attach network interface: %w", err)
}
p.Info("Attached network interface %q to server %q\n", *model.NicId, 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(), networkInterfaceIdFlag, "Network Interface ID")
cmd.Flags().Var(flags.UUIDFlag(), networkIdFlag, "Network ID")
cmd.Flags().BoolP(createFlag, "b", defaultCreateFlag, "If this is set a network interface will be created. (default false)")

cmd.MarkFlagsRequiredTogether(createFlag, networkIdFlag)
cmd.MarkFlagsMutuallyExclusive(createFlag, networkInterfaceIdFlag)
cmd.MarkFlagsMutuallyExclusive(networkIdFlag, networkInterfaceIdFlag)

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

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

// if create is not provided then network-interface-id is needed
networkInterfaceId := flags.FlagToStringPointer(p, cmd, networkInterfaceIdFlag)
create := flags.FlagToBoolPointer(p, cmd, createFlag)
if create == nil && networkInterfaceId == nil {
return nil, &cliErr.ServerNicAttachMissingNicIdError{Cmd: cmd}
}

model := inputModel{
GlobalFlagModel: globalFlags,
ServerId: flags.FlagToStringPointer(p, cmd, serverIdFlag),
NetworkId: flags.FlagToStringPointer(p, cmd, networkIdFlag),
NicId: networkInterfaceId,
Create: create,
}

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 buildRequestAttach(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiAddNicToServerRequest {
return apiClient.AddNicToServer(ctx, model.ProjectId, *model.ServerId, *model.NicId)
}

func buildRequestCreateAndAttach(ctx context.Context, model *inputModel, apiClient *iaas.APIClient) iaas.ApiAddNetworkToServerRequest {
return apiClient.AddNetworkToServer(ctx, model.ProjectId, *model.ServerId, *model.NetworkId)
}
Loading
Loading