Skip to content

Commit 7a1be16

Browse files
author
João Palet
committed
Implement add-target command
1 parent 53b93cc commit 7a1be16

6 files changed

Lines changed: 612 additions & 20 deletions

File tree

internal/cmd/load-balancer/load_balancer.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/stackitcloud/stackit-cli/internal/cmd/load-balancer/list"
99
observabilitycredentials "github.com/stackitcloud/stackit-cli/internal/cmd/load-balancer/observability-credentials"
1010
"github.com/stackitcloud/stackit-cli/internal/cmd/load-balancer/quota"
11+
targetpool "github.com/stackitcloud/stackit-cli/internal/cmd/load-balancer/target-pool"
1112
"github.com/stackitcloud/stackit-cli/internal/cmd/load-balancer/update"
1213

1314
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
@@ -31,12 +32,13 @@ func NewCmd(p *print.Printer) *cobra.Command {
3132
}
3233

3334
func addSubcommands(cmd *cobra.Command, p *print.Printer) {
34-
cmd.AddCommand(describe.NewCmd(p))
35+
cmd.AddCommand(create.NewCmd(p))
3536
cmd.AddCommand(delete.NewCmd(p))
37+
cmd.AddCommand(describe.NewCmd(p))
38+
cmd.AddCommand(generatepayload.NewCmd(p))
3639
cmd.AddCommand(list.NewCmd(p))
3740
cmd.AddCommand(quota.NewCmd(p))
38-
cmd.AddCommand(generatepayload.NewCmd(p))
3941
cmd.AddCommand(observabilitycredentials.NewCmd(p))
40-
cmd.AddCommand(create.NewCmd(p))
42+
cmd.AddCommand(targetpool.NewCmd(p))
4143
cmd.AddCommand(update.NewCmd(p))
4244
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package addtarget
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
8+
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/load-balancer/client"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/load-balancer/utils"
15+
"github.com/stackitcloud/stackit-sdk-go/services/loadbalancer"
16+
17+
"github.com/spf13/cobra"
18+
)
19+
20+
const (
21+
loadBalancerNameArg = "LOAD_BALANCER_NAME"
22+
23+
targetPoolNameFlag = "target-pool-name"
24+
targetNameFlag = "target-name"
25+
ipFlag = "ip"
26+
)
27+
28+
type inputModel struct {
29+
*globalflags.GlobalFlagModel
30+
31+
LoadBalancerName string
32+
TargetPoolName string
33+
TargetName string
34+
Ip string
35+
}
36+
37+
func NewCmd(p *print.Printer) *cobra.Command {
38+
cmd := &cobra.Command{
39+
Use: fmt.Sprintf("add-target %s", loadBalancerNameArg),
40+
Short: "Adds a target to a target pool",
41+
Long: "Adds a target to a target pool.",
42+
Args: args.SingleArg(loadBalancerNameArg, nil),
43+
Example: examples.Build(
44+
examples.NewExample(
45+
`Add a target to target pool "my-target-pool" of load balancer with name "my-load-balancer"`,
46+
"$ stackit load-balancer target-pool add-target my-load-balancer --target-pool-name my-target-pool --target-name my-new-target --ip 1.2.3.4/32"),
47+
),
48+
RunE: func(cmd *cobra.Command, args []string) error {
49+
ctx := context.Background()
50+
model, err := parseInput(p, cmd, args)
51+
if err != nil {
52+
return err
53+
}
54+
55+
// Configure API client
56+
apiClient, err := client.ConfigureClient(p)
57+
if err != nil {
58+
return err
59+
}
60+
61+
if !model.AssumeYes {
62+
prompt := fmt.Sprintf("Are you sure you want to add a target with IP %q to target pool %q of load balancer %q?", model.Ip, model.TargetPoolName, model.LoadBalancerName)
63+
err = p.PromptForConfirmation(prompt)
64+
if err != nil {
65+
return err
66+
}
67+
}
68+
69+
// Call API
70+
req, err := buildRequest(ctx, model, apiClient)
71+
if err != nil {
72+
return fmt.Errorf("build request: %w", err)
73+
}
74+
_, err = req.Execute()
75+
if err != nil {
76+
return fmt.Errorf("add target to target pool: %w", err)
77+
}
78+
79+
p.Info("Added target to target pool of load balancer %q\n", model.LoadBalancerName)
80+
return nil
81+
},
82+
}
83+
configureFlags(cmd)
84+
return cmd
85+
}
86+
87+
func configureFlags(cmd *cobra.Command) {
88+
cmd.Flags().String(targetPoolNameFlag, "", "Target pool name")
89+
cmd.Flags().String(targetNameFlag, "", "Target name")
90+
cmd.Flags().String(ipFlag, "", "Target IP. Must by unique within a target pool")
91+
92+
err := flags.MarkFlagsRequired(cmd, targetPoolNameFlag, targetNameFlag, ipFlag)
93+
cobra.CheckErr(err)
94+
}
95+
96+
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) {
97+
lbName := inputArgs[0]
98+
99+
globalFlags := globalflags.Parse(p, cmd)
100+
if globalFlags.ProjectId == "" {
101+
return nil, &errors.ProjectIdError{}
102+
}
103+
104+
model := inputModel{
105+
GlobalFlagModel: globalFlags,
106+
LoadBalancerName: lbName,
107+
TargetPoolName: cmd.Flag(targetPoolNameFlag).Value.String(),
108+
TargetName: cmd.Flag(targetNameFlag).Value.String(),
109+
Ip: cmd.Flag(ipFlag).Value.String(),
110+
}
111+
112+
if p.IsVerbosityDebug() {
113+
modelStr, err := print.BuildDebugStrFromInputModel(model)
114+
if err != nil {
115+
p.Debug(print.ErrorLevel, "convert model to string for debugging: %v", err)
116+
} else {
117+
p.Debug(print.DebugLevel, "parsed input values: %s", modelStr)
118+
}
119+
}
120+
121+
return &model, nil
122+
}
123+
124+
func buildRequest(ctx context.Context, model *inputModel, apiClient utils.LoadBalancerClient) (loadbalancer.ApiUpdateTargetPoolRequest, error) {
125+
req := apiClient.UpdateTargetPool(ctx, model.ProjectId, model.LoadBalancerName, model.TargetPoolName)
126+
127+
targetPool, err := utils.GetLoadBalancerTargetPool(ctx, apiClient, model.ProjectId, model.LoadBalancerName, model.TargetPoolName)
128+
if err != nil {
129+
return req, fmt.Errorf("get load balancer target pool: %w", err)
130+
}
131+
132+
newTarget := &loadbalancer.Target{
133+
DisplayName: &model.TargetName,
134+
Ip: &model.Ip,
135+
}
136+
utils.AddTargetToTargetPool(targetPool, newTarget)
137+
138+
payload := utils.ToPayloadTargetPool(targetPool)
139+
if payload == nil {
140+
return req, fmt.Errorf("nil payload")
141+
}
142+
143+
return req.UpdateTargetPoolPayload(*payload), nil
144+
}

0 commit comments

Comments
 (0)