Skip to content

Commit 76fc58e

Browse files
committed
refactor(ufw):
- updated rules CRUD documentation
1 parent 23b6f0d commit 76fc58e

6 files changed

Lines changed: 66 additions & 26 deletions

File tree

internal/cmd/ufw/rules/create/create.go

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,11 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
6262
Args: args.NoArgs,
6363
Example: examples.Build(
6464
examples.NewExample(
65-
`Create a UFW rule instance of type ACL with sourceIp "1.1.1.1/32" of product "redis" for instance with id=ID`,
66-
"$ stackit ufw instance create --product redis --sourceIp 1.1.1.1/32 --type ACL --instanceId ID"),
67-
// TODO add more examples for creating Security Rule and Group types
65+
`Create a UFW rule instance of type ACL with sourceIp "1.1.1.1/32" of product "Redis" for instance with id=ID`,
66+
"$ stackit ufw rules create --product redis --sourceIp 1.1.1.1/32 --type ACL --instanceId ID"),
67+
examples.NewExample(
68+
`Create a UFW rule instance of type ACL with sourceIp "2.2.2.2/32" of product "Edge Cloud" for instance with id=ID`,
69+
"$ stackit ufw rules create --product edge-cloud --sourceIp 2.2.2.2/32 --type ACL --instanceId ID"),
6870
),
6971
RunE: func(cmd *cobra.Command, args []string) error {
7072
ctx := context.Background()
@@ -90,7 +92,10 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
9092
return err
9193
}
9294

93-
req := buildRequest(ctx, model, apiClient)
95+
req, err := buildRequest(ctx, model, apiClient)
96+
if err != nil {
97+
return err
98+
}
9499

95100
resp, err := req.Execute()
96101
if err != nil {
@@ -117,7 +122,7 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
117122

118123
func configureFlags(cmd *cobra.Command) {
119124
cmd.Flags().String(productFlag, "", "The source service (e.g., Load Balancer, Redis) where you want to attach a rule")
120-
cmd.Flags().StringP(typeFlag, "t", "", "Type (ACL/SecurityRule/SecurityGroup/PublicIP) You can check /provider-options route for them")
125+
cmd.Flags().StringP(typeFlag, "t", "", "Type (ACL/SecurityRule/SecurityGroup) You can check /provider-options route for them. Unfortunately, this field could be only ACL for the CLI version")
121126
cmd.Flags().StringP(sourceIpFlag, "s", "", "The IP (CIDR) to which the rule applies (e.g. 192.168.0.1/32)")
122127
cmd.Flags().StringP(instanceIdFlag, "i", "", "Instance ID that will have attached your rule")
123128
cmd.Flags().StringP(directionFlag, "d", "", "Direction (the direction of the traffic, typically ingress or egress, for security rules type)")
@@ -171,10 +176,18 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
171176
return &model, nil
172177
}
173178

174-
func buildRequest(ctx context.Context, model *inputModel, apiClient *ufw.APIClient) ufw.ApiCreateRuleRequest {
179+
func buildRequest(ctx context.Context, model *inputModel, apiClient *ufw.APIClient) (ufw.ApiCreateRuleRequest, error) {
175180
req := apiClient.DefaultAPI.CreateRule(ctx, model.ProjectId, model.Region)
176181

177-
// TODO - add logic for field checking: existing ACLs, correct product, type, instanceID maybe
182+
//providerOptions, err := apiClient.DefaultAPI.ListProviderOptions(ctx, model.Region).Execute()
183+
//
184+
//if err != nil {
185+
// return req, fmt.Errorf("get provider options: %w", err)
186+
//}
187+
//
188+
//if *model.Type != types.Types {
189+
// return req, fmt.Errorf("invalid rule type: %s", *model.Type)
190+
//}
178191

179192
req = req.CreateRulePayload(ufw.CreateRulePayload{
180193
Product: *model.Product,
@@ -190,7 +203,7 @@ func buildRequest(ctx context.Context, model *inputModel, apiClient *ufw.APIClie
190203
SecurityGroupId: model.SecurityGroupId,
191204
})
192205

193-
return req
206+
return req, nil
194207
}
195208

196209
func outputResult(p *print.Printer, outputFormat string, async bool, projectLabel string, rule *ufw.CreateRuleResponse) error {

internal/cmd/ufw/rules/create/create_test.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ var (
2525
)
2626

2727
const (
28-
testRegion = "eu01"
29-
testProduct = "redis"
30-
testType = "ACL"
31-
testSourceIp = "1.1.1.1/32"
28+
testRegion = "eu01"
29+
testProduct = "redis"
30+
testType = "ACL"
31+
testWrongType = "SecurityGroup"
32+
testSourceIp = "1.1.1.1/32"
3233
)
3334

3435
func fixtureFlagValues(mods ...func(flagValues map[string]string)) map[string]string {
@@ -182,6 +183,7 @@ func TestBuildRequest(t *testing.T) {
182183
description string
183184
model *inputModel
184185
expectedRequest ufw.ApiCreateRuleRequest
186+
isValid bool
185187
}{
186188
{
187189
description: "base",
@@ -209,11 +211,32 @@ func TestBuildRequest(t *testing.T) {
209211
InstanceId: testInstanceId,
210212
}),
211213
},
214+
{
215+
description: "required fields only, but wrong type",
216+
model: &inputModel{
217+
GlobalFlagModel: &globalflags.GlobalFlagModel{
218+
ProjectId: testProjectId,
219+
Region: testRegion,
220+
Verbosity: globalflags.VerbosityDefault,
221+
},
222+
Product: new(testProduct),
223+
Type: new(testWrongType),
224+
SourceIp: new(testSourceIp),
225+
InstanceId: new(testInstanceId),
226+
},
227+
expectedRequest: fixtureRequest(),
228+
},
212229
}
213230

214231
for _, tt := range tests {
215232
t.Run(tt.description, func(t *testing.T) {
216-
request := buildRequest(testCtx, tt.model, testClient)
233+
request, err := buildRequest(testCtx, tt.model, testClient)
234+
if err != nil {
235+
if !tt.isValid {
236+
return
237+
}
238+
t.Fatalf("error building request: %v", err)
239+
}
217240

218241
diff := cmp.Diff(request, tt.expectedRequest,
219242
cmp.AllowUnexported(tt.expectedRequest),

internal/cmd/ufw/rules/delete/delete.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
3232
cmd := &cobra.Command{
3333
Use: fmt.Sprintf("delete %s", instanceIdArg),
3434
Short: "Deletes a UFW rule instance",
35-
Long: "Deletes a UFW rule instance.",
35+
Long: "Deletes a STACKIT Unified Firewall (UFW) rule instance.",
3636
Args: args.SingleArg(instanceIdArg, utils.ValidateUUID),
3737
Example: examples.Build(
3838
examples.NewExample(
3939
`Delete a UFW rule instance with ID "xxx"`,
40-
"$ stackit ufw instance delete xxx"),
40+
"$ stackit ufw rules delete xxx"),
4141
),
4242
RunE: func(cmd *cobra.Command, args []string) error {
4343
ctx := context.Background()

internal/cmd/ufw/rules/describe/describe.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
3636
Example: examples.Build(
3737
examples.NewExample(
3838
`Get details of a UFW rule instance with ID "xxx"`,
39-
"$ stackit ufw rule instance describe xxx"),
39+
"$ stackit ufw rules describe xxx"),
4040
examples.NewExample(
4141
`Get details of a UFW rule instance with ID "xxx" in JSON format`,
42-
"$ stackit ufw rule instance describe xxx --output-format json"),
42+
"$ stackit ufw rules describe xxx --output-format json"),
4343
),
4444
RunE: func(cmd *cobra.Command, args []string) error {
4545
ctx := context.Background()

internal/cmd/ufw/rules/list/list.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,12 +152,13 @@ func outputResult(p *print.Printer, outputFormat, projectLabel string, resources
152152
}
153153

154154
table := tables.NewTable()
155-
table.SetHeader("PRODUCT", "SOURCE", "DEPLOYMENT TARGET", "PROTOCOL",
155+
table.SetHeader("PRODUCT", "SOURCE", "DEPLOYMENT TARGET", "INSTANCE ID", "PROTOCOL",
156156
"DIRECTION", "PORT RANGE", "ETHER TYPE", "STATUS")
157157
for i := range resources {
158158
resource := resources[i]
159-
table.AddRow(resource.Product, resource.SourceIP, utils.PtrString(resource.InstanceName), utils.PtrString(resource.Protocol),
160-
utils.PtrString(resource.Direction), utils.PtrString(resource.PortRange), utils.PtrString(resource.EtherType), resource.Status)
159+
table.AddRow(resource.Product, resource.SourceIP, utils.PtrString(resource.InstanceName), resource.InstanceId,
160+
utils.PtrString(resource.Protocol), utils.PtrString(resource.Direction), utils.PtrString(resource.PortRange),
161+
utils.PtrString(resource.EtherType), resource.Status)
161162
}
162163
err := table.Display(p)
163164
if err != nil {

internal/cmd/ufw/rules/update/update.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ const (
3535

3636
type inputModel struct {
3737
*globalflags.GlobalFlagModel
38-
RuleRefId string
38+
InstanceId string
3939

4040
SourceIp *string
4141
Direction *string
@@ -53,8 +53,8 @@ func NewCmd(params *types.CmdParams) *cobra.Command {
5353
Args: args.SingleArg(instanceIdArg, utils.ValidateUUID),
5454
Example: examples.Build(
5555
examples.NewExample(
56-
`Update a UFW rule instance with "1.1.1.1/32" as sourceIp for instance with id=ID`,
57-
"$ stackit ufw instance update ID --sourceIp 1.1.1.1/32"),
56+
`Update a UFW rule instance with "1.1.1.1/32" as sourceIp for instance with ID "xxx"`,
57+
"$ stackit ufw rules update xxx --sourceIp 1.1.1.1/32"),
5858
),
5959
RunE: func(cmd *cobra.Command, args []string) error {
6060
ctx := context.Background()
@@ -117,7 +117,9 @@ func configureFlags(cmd *cobra.Command) {
117117
cobra.CheckErr(err)
118118
}
119119

120-
func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel, error) {
120+
func parseInput(p *print.Printer, cmd *cobra.Command, inputArgs []string) (*inputModel, error) {
121+
instanceId := inputArgs[0]
122+
121123
globalFlags := globalflags.Parse(p, cmd)
122124
if globalFlags.ProjectId == "" {
123125
return nil, &errors.ProjectIdError{}
@@ -129,6 +131,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
129131

130132
model := inputModel{
131133
GlobalFlagModel: globalFlags,
134+
InstanceId: instanceId,
132135

133136
SourceIp: flags.FlagToStringPointer(p, cmd, sourceIpFlag),
134137
Direction: flags.FlagToStringPointer(p, cmd, directionFlag),
@@ -143,7 +146,7 @@ func parseInput(p *print.Printer, cmd *cobra.Command, _ []string) (*inputModel,
143146
}
144147

145148
func buildRequest(ctx context.Context, model *inputModel, apiClient *ufw.APIClient) ufw.ApiUpdateRuleRequest {
146-
req := apiClient.DefaultAPI.UpdateRule(ctx, model.ProjectId, model.Region, model.RuleRefId)
149+
req := apiClient.DefaultAPI.UpdateRule(ctx, model.ProjectId, model.Region, model.InstanceId)
147150

148151
// TODO - add logic for field checking: existing ACLs, correct product, type, instanceID maybe
149152

@@ -168,7 +171,7 @@ func outputResult(p *print.Printer, outputFormat string, async bool, projectLabe
168171
if async {
169172
operationState = "Triggered updating process of"
170173
}
171-
p.Outputf("%s rule for project %q. Rule refID: %s\n", operationState, projectLabel, utils.PtrString(rule.RefId))
174+
p.Outputf("%s rule for project %q. New rule refID: %s\n", operationState, projectLabel, utils.PtrString(rule.RefId))
172175
return nil
173176
})
174177
}

0 commit comments

Comments
 (0)