Skip to content

Commit f9bcc98

Browse files
yfodilLaure-di
authored andcommitted
feat(vpc): add edit mode for acls (scaleway#4655)
1 parent 43780d4 commit f9bcc98

File tree

5 files changed

+170
-0
lines changed

5 files changed

+170
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
2+
🟥🟥🟥 STDERR️️ 🟥🟥🟥️
3+
This command starts your default editor to edit a marshaled version of your resource
4+
Default editor will be taken from $VISUAL, then $EDITOR or an editor based on your system
5+
6+
USAGE:
7+
scw vpc rule edit [arg=value ...]
8+
9+
ARGS:
10+
vpc-id ID of the Network ACL's VPC
11+
[is-ipv6] Defines whether this set of ACL rules is for IPv6 (false = IPv4). Each Network ACL can have rules for only one IP type
12+
[default-policy] Action to take for packets which do not match any rules
13+
[mode=yaml] marshaling used when editing data (yaml | json)
14+
[region=fr-par] Region to target. If none is passed will use default region from the config
15+
16+
FLAGS:
17+
-h, --help help for edit
18+
19+
GLOBAL FLAGS:
20+
-c, --config string The path to the config file
21+
-D, --debug Enable debug mode
22+
-o, --output string Output format: json or human, see 'scw help output' for more info (default "human")
23+
-p, --profile string The config profile to use

cmd/scw/testdata/test-all-usage-vpc-rule-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ USAGE:
66
scw vpc rule <command>
77

88
AVAILABLE COMMANDS:
9+
edit Edit all ACL rules of a VPC
910
get Get ACL Rules for VPC
1011
set Set VPC ACL rules
1112

docs/commands/vpc.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ This API allows you to manage your Virtual Private Clouds (VPCs) and Private Net
1717
- [Return routes with associated next hop data](#return-routes-with-associated-next-hop-data)
1818
- [Update Route](#update-route)
1919
- [Rule management command](#rule-management-command)
20+
- [Edit all ACL rules of a VPC](#edit-all-acl-rules-of-a-vpc)
2021
- [Get ACL Rules for VPC](#get-acl-rules-for-vpc)
2122
- [Set VPC ACL rules](#set-vpc-acl-rules)
2223
- [Subnet management command](#subnet-management-command)
@@ -316,6 +317,30 @@ scw vpc route update <route-id ...> [arg=value ...]
316317
ACL Rules.
317318

318319

320+
### Edit all ACL rules of a VPC
321+
322+
This command starts your default editor to edit a marshaled version of your resource
323+
Default editor will be taken from $VISUAL, then $EDITOR or an editor based on your system
324+
325+
**Usage:**
326+
327+
```
328+
scw vpc rule edit [arg=value ...]
329+
```
330+
331+
332+
**Args:**
333+
334+
| Name | | Description |
335+
|------|---|-------------|
336+
| vpc-id | Required | ID of the Network ACL's VPC |
337+
| is-ipv6 | | Defines whether this set of ACL rules is for IPv6 (false = IPv4). Each Network ACL can have rules for only one IP type |
338+
| default-policy | | Action to take for packets which do not match any rules |
339+
| mode | Default: `yaml`<br />One of: `yaml`, `json` | marshaling used when editing data |
340+
| region | Default: `fr-par` | Region to target. If none is passed will use default region from the config |
341+
342+
343+
319344
### Get ACL Rules for VPC
320345

321346
Retrieve a list of ACL rules for a VPC, specified by its VPC ID.

internal/namespaces/vpc/v2/custom.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,9 @@ func GetCommands() *core.Commands {
1515
cmds.MustFind("vpc", "private-network", "get").Override(privateNetworkGetBuilder)
1616
human.RegisterMarshalerFunc(vpc.PrivateNetwork{}, privateNetworkMarshalerFunc)
1717

18+
cmds.Merge(core.NewCommands(
19+
vpcACLEditCommand(),
20+
))
21+
1822
return cmds
1923
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package vpc
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"reflect"
7+
8+
"github.com/scaleway/scaleway-cli/v2/core"
9+
"github.com/scaleway/scaleway-cli/v2/internal/editor"
10+
"github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
)
13+
14+
var vpcACLEditYamlExample = `default_policy: drop
15+
is_ipv6: false
16+
rules: [
17+
- protocol: TCP
18+
src_port_low: 0
19+
src_port_high: 0
20+
dst_port_low: 80
21+
dst_port_high: 80
22+
source: 0.0.0.0/0
23+
destination: 0.0.0.0/0
24+
description: Allow HTTP traffic from any source
25+
action: accept
26+
- protocol: TCP
27+
src_port_low: 0
28+
src_port_high: 0
29+
dst_port_low: 443
30+
dst_port_high: 443
31+
source: 0.0.0.0/0
32+
destination: 0.0.0.0/0
33+
description: Allow HTTPS traffic from any source
34+
action: accept
35+
]
36+
`
37+
38+
type vpcACLEditArgs struct {
39+
Region scw.Region
40+
VpcID string
41+
IsIPv6 bool
42+
DefaultPolicy vpc.Action
43+
Mode editor.MarshalMode
44+
}
45+
46+
func vpcACLEditCommand() *core.Command {
47+
return &core.Command{
48+
Short: "Edit all ACL rules of a VPC",
49+
Long: editor.LongDescription,
50+
Namespace: "vpc",
51+
Resource: "rule",
52+
Verb: "edit",
53+
ArgsType: reflect.TypeOf(vpcACLEditArgs{}),
54+
ArgSpecs: core.ArgSpecs{
55+
{
56+
Name: "vpc-id",
57+
Short: "ID of the Network ACL's VPC",
58+
Required: true,
59+
Positional: false,
60+
},
61+
{
62+
Name: "is-ipv6",
63+
Short: "Defines whether this set of ACL rules is for IPv6 (false = IPv4). Each Network ACL can have rules for only one IP type",
64+
Required: false,
65+
Positional: false,
66+
},
67+
{
68+
Name: "default-policy",
69+
Short: "Action to take for packets which do not match any rules",
70+
Required: false,
71+
Positional: false,
72+
},
73+
editor.MarshalModeArgSpec(),
74+
core.RegionArgSpec(),
75+
},
76+
Run: func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
77+
args := argsI.(*vpcACLEditArgs)
78+
79+
client := core.ExtractClient(ctx)
80+
api := vpc.NewAPI(client)
81+
82+
setRequest := &vpc.SetACLRequest{
83+
Region: args.Region,
84+
VpcID: args.VpcID,
85+
IsIPv6: args.IsIPv6,
86+
DefaultPolicy: args.DefaultPolicy,
87+
}
88+
89+
rules, err := api.GetACL(&vpc.GetACLRequest{
90+
Region: args.Region,
91+
VpcID: args.VpcID,
92+
IsIPv6: args.IsIPv6,
93+
}, scw.WithContext(ctx))
94+
if err != nil {
95+
return nil, fmt.Errorf("failed to list ACL rules: %w", err)
96+
}
97+
98+
editedSetRequest, err := editor.UpdateResourceEditor(rules, setRequest, &editor.Config{
99+
PutRequest: true,
100+
MarshalMode: args.Mode,
101+
Template: vpcACLEditYamlExample,
102+
})
103+
if err != nil {
104+
return nil, err
105+
}
106+
107+
setRequest = editedSetRequest.(*vpc.SetACLRequest)
108+
109+
resp, err := api.SetACL(setRequest, scw.WithContext(ctx))
110+
if err != nil {
111+
return nil, fmt.Errorf("failed to set ACL rules: %w", err)
112+
}
113+
114+
return resp.Rules, nil
115+
},
116+
}
117+
}

0 commit comments

Comments
 (0)