Skip to content

Commit bd45cde

Browse files
authored
Optimize security group rule management and improve error handling (#227)
- Implement batch processing for ingress and egress rules (1000 at a time) to comply with API limitations - Refactor `createSecurityGroupRules` and `deleteSecurityGroupRules` to handle large numbers of rules efficiently - Improve error handling using deferred functions in multiple methods By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
1 parent 97c1044 commit bd45cde

File tree

1 file changed

+66
-12
lines changed

1 file changed

+66
-12
lines changed

pkg/resource/security_group/hooks.go

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func (rm *resourceManager) syncSGRules(
137137
) (err error) {
138138
rlog := ackrtlog.FromContext(ctx)
139139
exit := rlog.Trace("rm.syncSGRules")
140-
defer exit(err)
140+
defer func() { exit(err) }()
141141

142142
toAddIngress := []*svcapitypes.IPPermission{}
143143
toAddEgress := []*svcapitypes.IPPermission{}
@@ -218,7 +218,9 @@ func (rm *resourceManager) createSecurityGroupRules(
218218
) (err error) {
219219
rlog := ackrtlog.FromContext(ctx)
220220
exit := rlog.Trace("rm.createSecurityGroupRules")
221-
defer exit(err)
221+
defer func() { exit(err) }()
222+
223+
ingressRules := []*svcsdk.IpPermission{}
222224

223225
// Authorize ingress rules
224226
for _, i := range ingress {
@@ -235,18 +237,27 @@ func (rm *resourceManager) createSecurityGroupRules(
235237
userIDGroupPair.VpcId = r.ko.Spec.VPCID
236238
}
237239
}
240+
ingressRules = append(ingressRules, ipInput)
241+
}
242+
243+
// API can only handle 1000 rules at a time. Send in batches of 1000.
244+
for i := 0; i < len(ingressRules); i += 1000 {
245+
end := i + 1000
246+
if end > len(ingressRules) {
247+
end = len(ingressRules)
248+
}
238249
req := &svcsdk.AuthorizeSecurityGroupIngressInput{
239250
GroupId: r.ko.Status.ID,
240-
IpPermissions: []*svcsdk.IpPermission{ipInput},
241-
// TODO: TagSpecs
251+
IpPermissions: ingressRules[i:end],
242252
}
243-
_, err := rm.sdkapi.AuthorizeSecurityGroupIngressWithContext(ctx, req)
253+
_, err = rm.sdkapi.AuthorizeSecurityGroupIngressWithContext(ctx, req)
244254
rm.metrics.RecordAPICall("CREATE", "AuthorizeSecurityGroupIngress", err)
245255
if err != nil {
246256
return err
247257
}
248258
}
249259

260+
egressRules := []*svcsdk.IpPermission{}
250261
// Authorize egress rules
251262
for _, e := range egress {
252263
ipInput := rm.newIPPermission(*e)
@@ -262,10 +273,18 @@ func (rm *resourceManager) createSecurityGroupRules(
262273
userIDGroupPair.VpcId = r.ko.Spec.VPCID
263274
}
264275
}
276+
egressRules = append(egressRules, ipInput)
277+
}
278+
279+
// API can only handle 1000 rules at a time. Send in batches of 1000.
280+
for i := 0; i < len(egressRules); i += 1000 {
281+
end := i + 1000
282+
if end > len(egressRules) {
283+
end = len(egressRules)
284+
}
265285
req := &svcsdk.AuthorizeSecurityGroupEgressInput{
266286
GroupId: r.ko.Status.ID,
267-
IpPermissions: []*svcsdk.IpPermission{ipInput},
268-
// TODO: TagSpecs
287+
IpPermissions: egressRules[i:end],
269288
}
270289
_, err = rm.sdkapi.AuthorizeSecurityGroupEgressWithContext(ctx, req)
271290
rm.metrics.RecordAPICall("CREATE", "AuthorizeSecurityGroupEgress", err)
@@ -287,7 +306,7 @@ func (rm *resourceManager) deleteDefaultSecurityGroupRule(
287306
) (err error) {
288307
rlog := ackrtlog.FromContext(ctx)
289308
exit := rlog.Trace("rm.deleteDefaultSecurityGroupRule")
290-
defer exit(err)
309+
defer func() { exit(err) }()
291310

292311
ipRange := &svcsdk.IpRange{
293312
CidrIp: toStrPtr("0.0.0.0/0"),
@@ -328,14 +347,32 @@ func (rm *resourceManager) deleteSecurityGroupRules(
328347
) (err error) {
329348
rlog := ackrtlog.FromContext(ctx)
330349
exit := rlog.Trace("rm.deleteSecurityGroupRules")
331-
defer exit(err)
350+
defer func() { exit(err) }()
332351

333352
// Revoke ingress rules
353+
ingressRules := []*svcsdk.IpPermission{}
334354
for _, i := range ingress {
335355
ipInput := rm.newIPPermission(*i)
356+
for _, userIDGroupPair := range ipInput.UserIdGroupPairs {
357+
if userIDGroupPair.GroupId == nil && userIDGroupPair.GroupName == nil {
358+
userIDGroupPair.GroupId = r.ko.Status.ID
359+
}
360+
if userIDGroupPair.VpcId == nil {
361+
userIDGroupPair.VpcId = r.ko.Spec.VPCID
362+
}
363+
}
364+
ingressRules = append(ingressRules, ipInput)
365+
}
366+
367+
// API can only handle 1000 rules at a time. Send in batches of 1000.
368+
for i := 0; i < len(ingressRules); i += 1000 {
369+
end := i + 1000
370+
if end > len(ingressRules) {
371+
end = len(ingressRules)
372+
}
336373
req := &svcsdk.RevokeSecurityGroupIngressInput{
337374
GroupId: r.ko.Status.ID,
338-
IpPermissions: []*svcsdk.IpPermission{ipInput},
375+
IpPermissions: ingressRules[i:end],
339376
}
340377
_, err = rm.sdkapi.RevokeSecurityGroupIngressWithContext(ctx, req)
341378
rm.metrics.RecordAPICall("DELETE", "RevokeSecurityGroupIngress", err)
@@ -345,12 +382,29 @@ func (rm *resourceManager) deleteSecurityGroupRules(
345382
}
346383

347384
// Revoke egress rules
385+
egressRules := []*svcsdk.IpPermission{}
348386
for _, e := range egress {
349387
ipInput := rm.newIPPermission(*e)
388+
for _, userIDGroupPair := range ipInput.UserIdGroupPairs {
389+
if userIDGroupPair.GroupId == nil && userIDGroupPair.GroupName == nil {
390+
userIDGroupPair.GroupId = r.ko.Status.ID
391+
}
392+
if userIDGroupPair.VpcId == nil {
393+
userIDGroupPair.VpcId = r.ko.Spec.VPCID
394+
}
395+
}
396+
egressRules = append(egressRules, ipInput)
397+
}
398+
399+
// API can only handle 1000 rules at a time. Send in batches of 1000.
400+
for i := 0; i < len(egressRules); i += 1000 {
401+
end := i + 1000
402+
if end > len(egressRules) {
403+
end = len(egressRules)
404+
}
350405
req := &svcsdk.RevokeSecurityGroupEgressInput{
351406
GroupId: r.ko.Status.ID,
352-
IpPermissions: []*svcsdk.IpPermission{ipInput},
353-
// TODO: TagSpecs?
407+
IpPermissions: egressRules[i:end],
354408
}
355409
_, err = rm.sdkapi.RevokeSecurityGroupEgressWithContext(ctx, req)
356410
rm.metrics.RecordAPICall("DELETE", "RevokeSecurityGroupEgress", err)

0 commit comments

Comments
 (0)