Skip to content

Commit 49e947c

Browse files
jremy42protobuf-ci-cd
andauthored
feat(redis): update acl rules (#4868)
Co-authored-by: protobuf-ci-cd <protobuf-ci-cd@scaleway.com>
1 parent 1fece1a commit 49e947c

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲
2+
🟥🟥🟥 STDERR️️ 🟥🟥🟥️
3+
Update an ACL rule (IP/description) for a Redis™ Database Instance (Redis™ cluster). This command simulates an update by fetching, deleting, and re-adding the rule.
4+
5+
USAGE:
6+
scw redis acl update <acl-id ...> [arg=value ...]
7+
8+
ARGS:
9+
cluster-id UUID of the Redis cluster
10+
acl-id UUID of the ACL rule to update
11+
[ip-cidr] New IPv4 network address of the rule (optional, defaults to current)
12+
[description] New description of the rule (optional, defaults to current)
13+
zone Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | nl-ams-1 | nl-ams-2 | pl-waw-1 | pl-waw-2)
14+
15+
FLAGS:
16+
-h, --help help for update
17+
18+
GLOBAL FLAGS:
19+
-c, --config string The path to the config file
20+
-D, --debug Enable debug mode
21+
-o, --output string Output format: json or human, see 'scw help output' for more info (default "human")
22+
-p, --profile string The config profile to use

cmd/scw/testdata/test-all-usage-redis-acl-usage.golden

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ AVAILABLE COMMANDS:
1010
delete Delete an ACL rule for a cluster
1111
get Get an ACL rule
1212
set Set ACL rules for a cluster
13+
update Update an ACL rule for a Redis™ Database Instance (network rule)
1314

1415
FLAGS:
1516
-h, --help help for acl

docs/commands/redis.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This API allows you to manage your Managed Databases for Redis™.
77
- [Delete an ACL rule for a cluster](#delete-an-acl-rule-for-a-cluster)
88
- [Get an ACL rule](#get-an-acl-rule)
99
- [Set ACL rules for a cluster](#set-acl-rules-for-a-cluster)
10+
- [Update an ACL rule for a Redis™ Database Instance (network rule)](#update-an-acl-rule-for-a-redis™-database-instance-(network-rule))
1011
- [Cluster management commands](#cluster-management-commands)
1112
- [Create a Redis™ Database Instance](#create-a-redis™-database-instance)
1213
- [Delete a Redis™ Database Instance](#delete-a-redis™-database-instance)
@@ -123,6 +124,29 @@ scw redis acl set [arg=value ...]
123124

124125

125126

127+
### Update an ACL rule for a Redis™ Database Instance (network rule)
128+
129+
Update an ACL rule (IP/description) for a Redis™ Database Instance (Redis™ cluster). This command simulates an update by fetching, deleting, and re-adding the rule.
130+
131+
**Usage:**
132+
133+
```
134+
scw redis acl update <acl-id ...> [arg=value ...]
135+
```
136+
137+
138+
**Args:**
139+
140+
| Name | | Description |
141+
|------|---|-------------|
142+
| cluster-id | Required | UUID of the Redis cluster |
143+
| acl-id | Required | UUID of the ACL rule to update |
144+
| ip-cidr | | New IPv4 network address of the rule (optional, defaults to current) |
145+
| description | | New description of the rule (optional, defaults to current) |
146+
| zone | Required | Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | nl-ams-1 | nl-ams-2 | pl-waw-1 | pl-waw-2) |
147+
148+
149+
126150
## Cluster management commands
127151

128152
A Redis™ Database Instance, also known as a Redis™ cluster, consists of either one standalone node or a cluster composed of three to six nodes. The cluster uses partitioning to split the keyspace. Each partition is replicated and can be reassigned or elected as the primary when necessary. Standalone mode creates a standalone database provisioned on a single node.

internal/namespaces/redis/v1/custom.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,7 @@ func GetCommands() *core.Commands {
2020
cmds.MustFind("redis", "setting", "add").Override(redisSettingAddBuilder)
2121
cmds.MustFind("redis", "cluster", "migrate").Override(redisClusterMigrateBuilder)
2222

23+
cmds.Merge(core.NewCommands(redisACLUpdateCommand()))
24+
2325
return cmds
2426
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package redis
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net"
7+
"reflect"
8+
9+
"github.com/scaleway/scaleway-cli/v2/core"
10+
"github.com/scaleway/scaleway-sdk-go/api/redis/v1"
11+
"github.com/scaleway/scaleway-sdk-go/scw"
12+
)
13+
14+
func redisACLUpdateCommand() *core.Command {
15+
return &core.Command{
16+
Short: "Update an ACL rule for a Redis™ Database Instance (network rule)",
17+
Long: "Update an ACL rule (IP/description) for a Redis™ Database Instance (Redis™ cluster). This command simulates an update by fetching, deleting, and re-adding the rule.",
18+
Namespace: "redis",
19+
Resource: "acl",
20+
Verb: "update",
21+
ArgsType: reflect.TypeOf(redisUpdateACLRuleRequest{}),
22+
ArgSpecs: core.ArgSpecs{
23+
{
24+
Name: "cluster-id",
25+
Short: "UUID of the Redis cluster",
26+
Required: true,
27+
Positional: false,
28+
},
29+
{
30+
Name: "acl-id",
31+
Short: "UUID of the ACL rule to update",
32+
Required: true,
33+
Positional: true,
34+
},
35+
{
36+
Name: "ip-cidr",
37+
Short: "New IPv4 network address of the rule (optional, defaults to current)",
38+
Required: false,
39+
},
40+
{
41+
Name: "description",
42+
Short: "New description of the rule (optional, defaults to current)",
43+
Required: false,
44+
},
45+
{
46+
Name: "zone",
47+
Short: "Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | nl-ams-1 | nl-ams-2 | pl-waw-1 | pl-waw-2)",
48+
Required: true,
49+
},
50+
},
51+
Run: func(ctx context.Context, argsI any) (any, error) {
52+
args := argsI.(*redisUpdateACLRuleRequest)
53+
api := redis.NewAPI(core.ExtractClient(ctx))
54+
55+
// 1. Get the existing rule
56+
rule, err := api.GetACLRule(&redis.GetACLRuleRequest{
57+
ACLID: args.ACLID,
58+
Zone: scw.Zone(args.Zone),
59+
})
60+
if err != nil {
61+
return nil, fmt.Errorf("failed to get ACL rule: %w", err)
62+
}
63+
64+
// 2. Delete the existing rule
65+
_, err = api.DeleteACLRule(&redis.DeleteACLRuleRequest{
66+
ACLID: args.ACLID,
67+
Zone: scw.Zone(args.Zone),
68+
})
69+
if err != nil {
70+
return nil, fmt.Errorf("failed to delete ACL rule: %w", err)
71+
}
72+
73+
waitReq := &redis.WaitForClusterRequest{
74+
ClusterID: args.ClusterID,
75+
Zone: scw.Zone(args.Zone),
76+
Timeout: scw.TimeDurationPtr(redisActionTimeout),
77+
}
78+
_, err = api.WaitForCluster(waitReq)
79+
if err != nil {
80+
return nil, fmt.Errorf("failed to wait for cluster to be ready: %w", err)
81+
}
82+
83+
// 3. Add a new rule with updated fields
84+
ipCIDR := args.IPCidr
85+
if ipCIDR == "" {
86+
ipCIDR = rule.IPCidr.String()
87+
}
88+
desc := args.Description
89+
if desc == "" {
90+
desc = *rule.Description
91+
}
92+
_, ipnet, err := net.ParseCIDR(ipCIDR)
93+
if err != nil {
94+
return nil, fmt.Errorf("invalid ip-cidr: %w", err)
95+
}
96+
scwIPNet := scw.IPNet{IPNet: *ipnet}
97+
addResp, err := api.AddACLRules(&redis.AddACLRulesRequest{
98+
ClusterID: args.ClusterID,
99+
Zone: scw.Zone(args.Zone),
100+
ACLRules: []*redis.ACLRuleSpec{
101+
{
102+
IPCidr: scwIPNet,
103+
Description: desc,
104+
},
105+
},
106+
})
107+
if err != nil {
108+
return nil, fmt.Errorf("failed to add updated ACL rule: %w", err)
109+
}
110+
111+
_, err = api.WaitForCluster(waitReq)
112+
if err != nil {
113+
return nil, fmt.Errorf("failed to wait for cluster to be ready: %w", err)
114+
}
115+
116+
return addResp.ACLRules, nil
117+
},
118+
}
119+
}
120+
121+
type redisUpdateACLRuleRequest struct {
122+
ClusterID string
123+
ACLID string
124+
IPCidr string
125+
Description string
126+
Zone string
127+
}

0 commit comments

Comments
 (0)