Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
41f5178
onboard-create-command
GokceGK Apr 29, 2024
c44c514
remove fields that are not needed for create
GokceGK Apr 29, 2024
b175d90
remove fields that are not needed for create from default payload
GokceGK Apr 29, 2024
2134243
remove privateAddress from update payload (read only field)
GokceGK Apr 30, 2024
6d01bc2
update generate payload to remove read-only fields from updatePayload
GokceGK Apr 30, 2024
a24bfd7
onboard update load balancer command
GokceGK Apr 30, 2024
48410e4
update description of update command
GokceGK Apr 30, 2024
db12c0b
Merge branch 'feature/onboard-load-balancer' into gg/onboard-load-bal…
GokceGK Apr 30, 2024
1308ed9
Update internal/cmd/load-balancer/create/create.go
GokceGK May 2, 2024
087b021
Update internal/cmd/load-balancer/create/create.go
GokceGK May 2, 2024
a0db037
add GetProjectName
GokceGK May 2, 2024
6e4b455
change instance name to load balancer name
GokceGK May 2, 2024
73c82fa
set listener name to nil
GokceGK May 2, 2024
f52ba4b
abstract set listener name to nil in a function // add unit test
GokceGK May 2, 2024
6c889b8
Merge branch 'feature/onboard-load-balancer' into gg/onboard-load-bal…
GokceGK May 2, 2024
9cf74c9
add debug logs to the create command
GokceGK May 2, 2024
a266f86
add debug logs to the generate payload command
GokceGK May 2, 2024
40bbfb9
add debug logs to the update command
GokceGK May 2, 2024
4c4c0be
Update test func name
GokceGK May 3, 2024
c679200
Merge branch 'feature/onboard-load-balancer' into gg/onboard-load-bal…
GokceGK May 3, 2024
a4f340a
add additional listener to the unit test
GokceGK May 3, 2024
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
2 changes: 2 additions & 0 deletions docs/stackit_load-balancer.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ stackit load-balancer [flags]
### SEE ALSO

* [stackit](./stackit.md) - Manage STACKIT resources using the command line
* [stackit load-balancer create](./stackit_load-balancer_create.md) - Creates a Load Balancer
* [stackit load-balancer describe](./stackit_load-balancer_describe.md) - Shows details of a Load Balancer
* [stackit load-balancer generate-payload](./stackit_load-balancer_generate-payload.md) - Generates a payload to create/update a Load Balancer
* [stackit load-balancer list](./stackit_load-balancer_list.md) - Lists all Load Balancers
* [stackit load-balancer quota](./stackit_load-balancer_quota.md) - Shows the configured Load Balancer quota
* [stackit load-balancer update](./stackit_load-balancer_update.md) - Updates a Load Balancer

50 changes: 50 additions & 0 deletions docs/stackit_load-balancer_create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## stackit load-balancer create

Creates a Load Balancer

### Synopsis

Creates a Load Balancer.
The payload can be provided as a JSON string or a file path prefixed with "@".
See https://docs.api.stackit.cloud/documentation/load-balancer/version/v1#tag/Load-Balancer/operation/APIService_CreateLoadBalancer for information regarding the payload structure.

```
stackit load-balancer create [flags]
```

### Examples

```
Create a load balancer using an API payload sourced from the file "./payload.json"
$ stackit load-balancer create --payload @./payload.json

Create a load balancer using an API payload provided as a JSON string
$ stackit load-balancer create --payload "{...}"

Generate a payload with default values, and adapt it with custom values for the different configuration options
$ stackit load-balancer generate-payload > ./payload.json
<Modify payload in file>
$ stackit load-balancer create --payload @./payload.json
```

### Options

```
-h, --help Help for "stackit load-balancer create"
--payload string Request payload (JSON). Can be a string or a file path, if prefixed with "@" (example: @./payload.json).
```

### 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"]
-p, --project-id string Project ID
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit load-balancer](./stackit_load-balancer.md) - Provides functionality for Load Balancer

8 changes: 4 additions & 4 deletions docs/stackit_load-balancer_generate-payload.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ stackit load-balancer generate-payload [flags]
$ stackit load-balancer create --payload @./payload.json

Generate a payload with values of an existing load balancer, and adapt it with custom values for the different configuration options
$ stackit load-balancer generate-payload --instance-name my-lb > ./payload.json
$ stackit load-balancer generate-payload --lb-name xxx > ./payload.json
<Modify payload in file>
$ stackit load-balancer update my-lb --payload @./payload.json
$ stackit load-balancer update xxx --payload @./payload.json
```

### Options

```
-h, --help Help for "stackit load-balancer generate-payload"
-n, --instance-name string If set, generates the payload with the current values of the given load balancer. If unset, generates the payload with empty values
-h, --help Help for "stackit load-balancer generate-payload"
-n, --lb-name string If set, generates the payload with the current values of the given load balancer. If unset, generates the payload with empty values
```

### Options inherited from parent commands
Expand Down
50 changes: 50 additions & 0 deletions docs/stackit_load-balancer_update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
## stackit load-balancer update

Updates a Load Balancer

### Synopsis

Updates a load balancer.
The payload can be provided as a JSON string or a file path prefixed with "@".
See https://docs.api.stackit.cloud/documentation/load-balancer/version/v1#tag/Load-Balancer/operation/APIService_UpdateLoadBalancer for information regarding the payload structure.

```
stackit load-balancer update LOAD_BALANCER_NAME [flags]
```

### Examples

```
Update a load balancer with name "xxx", using an API payload sourced from the file "./payload.json"
$ stackit load-balancer update xxx --payload @./payload.json

Update a load balancer with name "xxx", using an API payload provided as a JSON string
$ stackit load-balancer update xxx --payload "{...}"

Generate a payload with the current values of an existing load balancer xxx, and adapt it with custom values for the different configuration options
$ stackit load-balancer generate-payload --instance-name xxx > ./payload.json
<Modify payload in file>
$ stackit load-balancer update xxx --payload @./payload.json
```

### Options

```
-h, --help Help for "stackit load-balancer update"
--payload string Request payload (JSON). Can be a string or a file path, if prefixed with "@". Example: @./payload.json
```

### 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"]
-p, --project-id string Project ID
--verbosity string Verbosity of the CLI, one of ["debug" "info" "warning" "error"] (default "info")
```

### SEE ALSO

* [stackit load-balancer](./stackit_load-balancer.md) - Provides functionality for Load Balancer

164 changes: 164 additions & 0 deletions internal/cmd/load-balancer/create/create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package create

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

"github.com/google/uuid"

"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
"github.com/stackitcloud/stackit-sdk-go/services/loadbalancer"

"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/load-balancer/client"
"github.com/stackitcloud/stackit-cli/internal/pkg/spinner"

"github.com/spf13/cobra"
"github.com/stackitcloud/stackit-sdk-go/services/loadbalancer/wait"
)

const (
payloadFlag = "payload"
)

type inputModel struct {
*globalflags.GlobalFlagModel
Payload *loadbalancer.CreateLoadBalancerPayload
}

var (
xRequestId = uuid.NewString()
)

func NewCmd(p *print.Printer) *cobra.Command {
cmd := &cobra.Command{
Use: "create",
Short: "Creates a Load Balancer",
Long: fmt.Sprintf("%s\n%s\n%s",
"Creates a Load Balancer.",
"The payload can be provided as a JSON string or a file path prefixed with \"@\".",
"See https://docs.api.stackit.cloud/documentation/load-balancer/version/v1#tag/Load-Balancer/operation/APIService_CreateLoadBalancer for information regarding the payload structure.",
),
Args: args.NoArgs,
Example: examples.Build(
examples.NewExample(
`Create a load balancer using an API payload sourced from the file "./payload.json"`,
"$ stackit load-balancer create --payload @./payload.json"),
examples.NewExample(
`Create a load balancer using an API payload provided as a JSON string`,
`$ stackit load-balancer create --payload "{...}"`),
examples.NewExample(
`Generate a payload with default values, and adapt it with custom values for the different configuration options`,
`$ stackit load-balancer generate-payload > ./payload.json`,
`<Modify payload in file>`,
`$ stackit load-balancer create --payload @./payload.json`),
),
RunE: func(cmd *cobra.Command, args []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
}

projectLabel, err := projectname.GetProjectName(ctx, p, cmd)
if err != nil {
p.Debug(print.ErrorLevel, "get project name: %v", err)
projectLabel = model.ProjectId
}

if !model.AssumeYes {
prompt := fmt.Sprintf("Are you sure you want to create a load balancer for project %q?", projectLabel)
err = p.PromptForConfirmation(prompt)
if err != nil {
return err
}
}

// Call API
req := buildRequest(ctx, model, apiClient)
_, err = req.Execute()
if err != nil {
return fmt.Errorf("create load balancer: %w", err)
}

// Wait for async operation, if async mode not enabled
if !model.Async {
s := spinner.New(p)
s.Start("Creating load balancer")
_, err = wait.CreateLoadBalancerWaitHandler(ctx, apiClient, model.ProjectId, *model.Payload.Name).WaitWithContext(ctx)
if err != nil {
return fmt.Errorf("wait for load balancer creation: %w", err)
}
s.Stop()
}

operationState := "Created"
if model.Async {
operationState = "Triggered creation of"
}
p.Outputf("%s load balancer with name %q \n", operationState, *model.Payload.Name)
return nil
},
}
configureFlags(cmd)
return cmd
}

func configureFlags(cmd *cobra.Command) {
cmd.Flags().Var(flags.ReadFromFileFlag(), payloadFlag, `Request payload (JSON). Can be a string or a file path, if prefixed with "@" (example: @./payload.json).`)

err := flags.MarkFlagsRequired(cmd, payloadFlag)
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{}
}

payloadValue := flags.FlagToStringPointer(p, cmd, payloadFlag)
var payload *loadbalancer.CreateLoadBalancerPayload
if payloadValue != nil {
payload = &loadbalancer.CreateLoadBalancerPayload{}
err := json.Unmarshal([]byte(*payloadValue), payload)
if err != nil {
return nil, fmt.Errorf("encode payload: %w", err)
}
}

model := inputModel{
GlobalFlagModel: globalFlags,
Payload: payload,
}

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 *loadbalancer.APIClient) loadbalancer.ApiCreateLoadBalancerRequest {
req := apiClient.CreateLoadBalancer(ctx, model.ProjectId)
req = req.CreateLoadBalancerPayload(*model.Payload)
req = req.XRequestID(xRequestId)
return req
}
Loading