@@ -19,10 +19,9 @@ var aclRuleActionMarshalSpecs = human.EnumMarshalSpecs{
1919}
2020
2121type rdbACLCustomArgs struct {
22- Region scw.Region
23- InstanceID string
24- ACLRuleIPs scw.IPNet
25- Description string
22+ Region scw.Region
23+ InstanceID string
24+ ACLRuleIPs []scw.IPNet
2625}
2726
2827type CustomACLResult struct {
@@ -45,28 +44,29 @@ func rdbACLCustomResultMarshalerFunc(i any, opt *human.MarshalOpt) (string, erro
4544}
4645
4746func aclAddBuilder (c * core.Command ) * core.Command {
48- c .ArgsType = reflect .TypeOf (rdbACLCustomArgs {})
47+ c .ArgsType = reflect .TypeOf (rdb. AddInstanceACLRulesRequest {})
4948 c .ArgSpecs = core.ArgSpecs {
50- {
51- Name : "acl-rule-ips" ,
52- Short : "IP addresses defined in the ACL rules of the Database Instance" ,
53- Required : true ,
54- Positional : true ,
55- },
5649 {
5750 Name : "instance-id" ,
5851 Short : "ID of the Database Instance" ,
5952 Required : true ,
6053 Positional : false ,
6154 },
6255 {
63- Name : "description" ,
64- Short : "Description of the ACL rule. Indexes are not yet supported so the description will be applied to all the rules of the command." ,
56+ Name : "rules.{index}.ip" ,
57+ Short : "IP addresses defined in the ACL rules of the Database Instance" ,
58+ Required : false ,
59+ Positional : false ,
60+ },
61+ {
62+ Name : "rules.{index}.description" ,
63+ Short : "Description of the ACL rule. Use rules.0.description, rules.1.description, etc. to specify individual descriptions for each rule." ,
6564 Required : false ,
6665 Positional : false ,
6766 },
6867 core .RegionArgSpec (),
6968 }
69+ c .AcceptMultiplePositionalArgs = true
7070
7171 c .Interceptor = func (ctx context.Context , argsI any , runner core.CommandRunner ) (any , error ) {
7272 respI , err := runner (ctx , argsI )
@@ -78,39 +78,40 @@ func aclAddBuilder(c *core.Command) *core.Command {
7878 }
7979
8080 c .Run = func (ctx context.Context , argsI any ) (i any , e error ) {
81- args := argsI .(* rdbACLCustomArgs )
81+ args := argsI .(* rdb. AddInstanceACLRulesRequest )
8282 client := core .ExtractClient (ctx )
8383 api := rdb .NewAPI (client )
8484
85- description := args .Description
86- if description == "" {
87- description = "Allow " + args .ACLRuleIPs .String ()
85+ // Set default descriptions for rules that don't have one
86+ for i , rule := range args .Rules {
87+ if rule .Description == "" {
88+ args .Rules [i ].Description = "Allow " + rule .IP .String ()
89+ }
8890 }
8991
90- rule , err := api .AddInstanceACLRules (& rdb.AddInstanceACLRulesRequest {
91- Region : args .Region ,
92- InstanceID : args .InstanceID ,
93- Rules : []* rdb.ACLRuleRequest {
94- {
95- IP : args .ACLRuleIPs ,
96- Description : description ,
97- },
98- },
99- }, scw .WithContext (ctx ))
92+ rule , err := api .AddInstanceACLRules (args , scw .WithContext (ctx ))
10093 if err != nil {
10194 return nil , fmt .Errorf ("failed to add ACL rule: %w" , err )
10295 }
10396
97+ // Create success message
98+ var message string
99+ if len (args .Rules ) == 1 {
100+ message = fmt .Sprintf ("ACL rule %s successfully added" , args .Rules [0 ].IP .String ())
101+ } else {
102+ message = fmt .Sprintf ("%d ACL rules successfully added" , len (args .Rules ))
103+ }
104+
104105 return & CustomACLResult {
105106 Rules : rule .Rules ,
106107 Success : core.SuccessResult {
107- Message : fmt . Sprintf ( "ACL rule %s successfully added" , args . ACLRuleIPs . String ()) ,
108+ Message : message ,
108109 },
109110 }, nil
110111 }
111112
112113 c .WaitFunc = func (ctx context.Context , argsI , respI any ) (any , error ) {
113- args := argsI .(* rdbACLCustomArgs )
114+ args := argsI .(* rdb. AddInstanceACLRulesRequest )
114115 api := rdb .NewAPI (core .ExtractClient (ctx ))
115116
116117 _ , err := api .WaitForInstance (& rdb.WaitForInstanceRequest {
@@ -146,6 +147,7 @@ func aclDeleteBuilder(c *core.Command) *core.Command {
146147 },
147148 core .RegionArgSpec (),
148149 }
150+ c .AcceptMultiplePositionalArgs = true
149151
150152 c .Interceptor = func (ctx context.Context , argsI any , runner core.CommandRunner ) (any , error ) {
151153 respI , err := runner (ctx , argsI )
@@ -175,34 +177,55 @@ func aclDeleteBuilder(c *core.Command) *core.Command {
175177
176178 // The API returns 200 OK even if the rule was not set in the first place, so we have to check if the rule was present
177179 // before deleting it to warn them if nothing was done
178- ruleWasSet := false
179180 rules , err := api .ListInstanceACLRules (& rdb.ListInstanceACLRulesRequest {
180181 Region : args .Region ,
181182 InstanceID : args .InstanceID ,
182183 }, scw .WithContext (ctx ), scw .WithAllPages ())
183184 if err != nil {
184185 return nil , fmt .Errorf ("failed to list ACL rules: %w" , err )
185186 }
187+
188+ // Check which rules were actually set
189+ existingIPs := make (map [string ]bool )
186190 for _ , rule := range rules .Rules {
187- if rule .IP .String () == args .ACLRuleIPs .String () {
188- ruleWasSet = true
189- }
191+ existingIPs [rule .IP .String ()] = true
192+ }
193+
194+ // Convert IPs to strings for deletion
195+ ipStrings := make ([]string , len (args .ACLRuleIPs ))
196+ for i , ip := range args .ACLRuleIPs {
197+ ipStrings [i ] = ip .String ()
190198 }
191199
192200 _ , err = api .DeleteInstanceACLRules (& rdb.DeleteInstanceACLRulesRequest {
193201 Region : args .Region ,
194202 InstanceID : args .InstanceID ,
195- ACLRuleIPs : [] string { args . ACLRuleIPs . String ()} ,
203+ ACLRuleIPs : ipStrings ,
196204 }, scw .WithContext (ctx ))
197205 if err != nil {
198- return nil , fmt .Errorf ("failed to remove ACL rule: %w" , err )
206+ return nil , fmt .Errorf ("failed to remove ACL rules: %w" , err )
207+ }
208+
209+ // Count how many rules were actually deleted
210+ deletedCount := 0
211+ for _ , ip := range args .ACLRuleIPs {
212+ if existingIPs [ip .String ()] {
213+ deletedCount ++
214+ }
199215 }
200216
201217 var message string
202- if ruleWasSet {
203- message = fmt .Sprintf ("ACL rule %s successfully deleted" , args .ACLRuleIPs .String ())
218+ if len (args .ACLRuleIPs ) == 1 {
219+ if deletedCount > 0 {
220+ message = fmt .Sprintf ("ACL rule %s successfully deleted" , args .ACLRuleIPs [0 ].String ())
221+ } else {
222+ message = fmt .Sprintf ("ACL rule %s was not set" , args .ACLRuleIPs [0 ].String ())
223+ }
204224 } else {
205- message = fmt .Sprintf ("ACL rule %s was not set" , args .ACLRuleIPs .String ())
225+ message = fmt .Sprintf ("%d ACL rules successfully deleted" , deletedCount )
226+ if deletedCount < len (args .ACLRuleIPs ) {
227+ message += fmt .Sprintf (" (%d were not set)" , len (args .ACLRuleIPs )- deletedCount )
228+ }
206229 }
207230
208231 return & CustomACLResult {
0 commit comments