Skip to content

Commit a7c378e

Browse files
feat(albwaf): onboard albwaf config
Relates to STACKITCLI-444
1 parent 1f3a279 commit a7c378e

10 files changed

Lines changed: 1461 additions & 0 deletions

File tree

internal/cmd/beta/alb-waf/alb-waf.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package albwaf
22

33
import (
4+
config "github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/config"
45
customrulegroup "github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/custom-rule-group"
56
managedruleset "github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/managed-rule-set"
67
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
@@ -27,5 +28,6 @@ func addSubcommands(cmd *cobra.Command, params *types.CmdParams) {
2728
cmd.AddCommand(
2829
managedruleset.NewCmd(params),
2930
customrulegroup.NewCmd(params),
31+
config.NewCmd(params),
3032
)
3133
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package config
2+
3+
import (
4+
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/config/create"
5+
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/config/delete"
6+
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/config/describe"
7+
"github.com/stackitcloud/stackit-cli/internal/cmd/beta/alb-waf/config/list"
8+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/utils"
11+
12+
"github.com/spf13/cobra"
13+
)
14+
15+
func NewCmd(params *types.CmdParams) *cobra.Command {
16+
cmd := &cobra.Command{
17+
Use: "config",
18+
Short: "Provides functionality for WAF configurations of the ALB WAF",
19+
Long: "Provides functionality for Web Application Firewall (WAF) configurations for application loadbalancers.",
20+
Args: args.NoArgs,
21+
Run: utils.CmdHelp,
22+
}
23+
addSubcommands(cmd, params)
24+
return cmd
25+
}
26+
27+
func addSubcommands(cmd *cobra.Command, params *types.CmdParams) {
28+
cmd.AddCommand(create.NewCmd(params))
29+
cmd.AddCommand(delete.NewCmd(params))
30+
cmd.AddCommand(describe.NewCmd(params))
31+
cmd.AddCommand(list.NewCmd(params))
32+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package create
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/stackitcloud/stackit-cli/internal/pkg/types"
8+
9+
"github.com/stackitcloud/stackit-cli/internal/pkg/args"
10+
"github.com/stackitcloud/stackit-cli/internal/pkg/errors"
11+
"github.com/stackitcloud/stackit-cli/internal/pkg/examples"
12+
"github.com/stackitcloud/stackit-cli/internal/pkg/flags"
13+
"github.com/stackitcloud/stackit-cli/internal/pkg/globalflags"
14+
"github.com/stackitcloud/stackit-cli/internal/pkg/print"
15+
"github.com/stackitcloud/stackit-cli/internal/pkg/projectname"
16+
"github.com/stackitcloud/stackit-cli/internal/pkg/services/albwaf/client"
17+
18+
"github.com/spf13/cobra"
19+
albwaf "github.com/stackitcloud/stackit-sdk-go/services/albwaf/v1api"
20+
)
21+
22+
const (
23+
nameFlag = "name"
24+
managedRuleSetNameFlag = "managed-rule-set-name"
25+
customRuleGroupNameFlag = "custom-rule-group-name"
26+
labelsFlag = "labels"
27+
)
28+
29+
type inputModel struct {
30+
*globalflags.GlobalFlagModel
31+
Name string
32+
ManagedRuleSetName *string
33+
CustomRuleGroupName *string
34+
Labels *map[string]string
35+
}
36+
37+
func NewCmd(params *types.CmdParams) *cobra.Command {
38+
cmd := &cobra.Command{
39+
Use: "create",
40+
Short: "Creates an ALB WAF configuration",
41+
Long: "Creates a STACKIT Application Load Balancer (ALB) Web Application Firewall (WAF) configuration.",
42+
Args: args.NoArgs,
43+
Example: examples.Build(
44+
examples.NewExample(
45+
`Create an ALB WAF configuration with name "my-waf-config"`,
46+
"$ stackit beta alb-waf config create --name my-waf-config"),
47+
examples.NewExample(
48+
`Create an ALB WAF configuration with a managed rule set, a custom rule group and labels`,
49+
"$ stackit beta alb-waf config create --name my-waf-config --managed-rule-set-name my-managed-rule-set --custom-rule-group-name my-custom-rule-group --labels key1=value1,key2=value2"),
50+
),
51+
RunE: func(cmd *cobra.Command, args []string) error {
52+
ctx := context.Background()
53+
model, err := parseInput(params.Printer, cmd, args)
54+
if err != nil {
55+
return err
56+
}
57+
58+
// Configure API client
59+
apiClient, err := client.ConfigureClient(params.Printer, params.CliVersion)
60+
if err != nil {
61+
return err
62+
}
63+
64+
projectLabel, err := projectname.GetProjectName(ctx, params.Printer, params.CliVersion, cmd)
65+
if err != nil {
66+
params.Printer.Debug(print.ErrorLevel, "get project name: %v", err)
67+
projectLabel = model.ProjectId
68+
}
69+
70+
prompt := fmt.Sprintf("Are you sure you want to create an ALB WAF configuration for project %q?", projectLabel)
71+
err = params.Printer.PromptForConfirmation(prompt)
72+
if err != nil {
73+
return err
74+
}
75+
76+
// Call API
77+
req := buildRequest(ctx, model, apiClient)
78+
resp, err := req.Execute()
79+
if err != nil {
80+
return fmt.Errorf("create ALB WAF configuration: %w", err)
81+
}
82+
83+
return outputResult(params.Printer, model.OutputFormat, projectLabel, resp)
84+
},
85+
}
86+
configureFlags(cmd)
87+
return cmd
88+
}
89+
90+
func configureFlags(cmd *cobra.Command) {
91+
cmd.Flags().String(nameFlag, "", "Name of the WAF configuration")
92+
cmd.Flags().String(managedRuleSetNameFlag, "", "Name of the managed rule set configuration to attach to the WAF")
93+
cmd.Flags().String(customRuleGroupNameFlag, "", "Name of the custom rule group configuration to attach to the WAF")
94+
cmd.Flags().StringToString(labelsFlag, nil, "Labels are key-value string pairs which can be attached to the WAF configuration. E.g. '--labels key1=value1,key2=value2,...'")
95+
96+
err := flags.MarkFlagsRequired(cmd, nameFlag)
97+
cobra.CheckErr(err)
98+
}
99+
100+
func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) {
101+
globalFlags := globalflags.Parse(p, cmd)
102+
if globalFlags.ProjectId == "" {
103+
return nil, &errors.ProjectIdError{}
104+
}
105+
106+
model := inputModel{
107+
GlobalFlagModel: globalFlags,
108+
Name: flags.FlagToStringValue(p, cmd, nameFlag),
109+
ManagedRuleSetName: flags.FlagToStringPointer(p, cmd, managedRuleSetNameFlag),
110+
CustomRuleGroupName: flags.FlagToStringPointer(p, cmd, customRuleGroupNameFlag),
111+
Labels: flags.FlagToStringToStringPointer(p, cmd, labelsFlag),
112+
}
113+
114+
p.DebugInputModel(model)
115+
return &model, nil
116+
}
117+
118+
func buildRequest(ctx context.Context, model *inputModel, apiClient *albwaf.APIClient) albwaf.ApiCreateWAFRequest {
119+
req := apiClient.DefaultAPI.CreateWAF(ctx, model.ProjectId, model.Region)
120+
payload := albwaf.CreateWAFPayload{
121+
Name: model.Name,
122+
ManagedRuleSetName: model.ManagedRuleSetName,
123+
CustomRuleGroupName: model.CustomRuleGroupName,
124+
Labels: model.Labels,
125+
}
126+
return req.CreateWAFPayload(payload)
127+
}
128+
129+
func outputResult(p *print.Printer, outputFormat, projectLabel string, resp *albwaf.GetWAFResponse) error {
130+
return p.OutputResult(outputFormat, resp, func() error {
131+
if resp == nil {
132+
return fmt.Errorf("create WAF configuration response is empty")
133+
}
134+
p.Outputf("Created WAF configuration %q for project %q.\n", resp.Name, projectLabel)
135+
return nil
136+
})
137+
}

0 commit comments

Comments
 (0)