in cloudstack/resource_cloudstack_security_group_rule.go [154:241]
func createSecurityGroupRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, nrs *schema.Set) error {
cs := meta.(*cloudstack.CloudStackClient)
var errs *multierror.Error
var wg sync.WaitGroup
wg.Add(nrs.Len())
sem := make(chan struct{}, d.Get("parallelism").(int))
for _, rule := range nrs.List() {
// Put in a tiny sleep here to avoid DoS'ing the API
time.Sleep(500 * time.Millisecond)
go func(rule map[string]interface{}) {
defer wg.Done()
sem <- struct{}{}
// Make sure all required parameters are there
if err := verifySecurityGroupRuleParams(d, rule); err != nil {
errs = multierror.Append(errs, err)
return
}
var p authorizeSecurityGroupParams
if cidrList, ok := rule["cidr_list"].(*schema.Set); ok && cidrList.Len() > 0 {
for _, cidr := range cidrList.List() {
// Create a new parameter struct
switch rule["traffic_type"].(string) {
case "ingress":
p = cs.SecurityGroup.NewAuthorizeSecurityGroupIngressParams()
case "egress":
p = cs.SecurityGroup.NewAuthorizeSecurityGroupEgressParams()
}
p.SetSecuritygroupid(d.Id())
p.SetCidrlist([]string{cidr.(string)})
// Create a single rule
err := createSecurityGroupRule(d, meta, rule, p, cidr.(string))
if err != nil {
errs = multierror.Append(errs, err)
}
}
}
if usgList, ok := rule["user_security_group_list"].(*schema.Set); ok && usgList.Len() > 0 {
for _, usg := range usgList.List() {
sg, _, err := cs.SecurityGroup.GetSecurityGroupByName(
usg.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if err != nil {
errs = multierror.Append(errs, err)
continue
}
// Create a new parameter struct
switch rule["traffic_type"].(string) {
case "ingress":
p = cs.SecurityGroup.NewAuthorizeSecurityGroupIngressParams()
case "egress":
p = cs.SecurityGroup.NewAuthorizeSecurityGroupEgressParams()
}
p.SetSecuritygroupid(d.Id())
p.SetUsersecuritygrouplist(map[string]string{sg.Account: usg.(string)})
// Create a single rule
err = createSecurityGroupRule(d, meta, rule, p, usg.(string))
if err != nil {
errs = multierror.Append(errs, err)
}
}
}
// If we have at least one UUID, we need to save the rule
if len(rule["uuids"].(map[string]interface{})) > 0 {
rules.Add(rule)
}
<-sem
}(rule.(map[string]interface{}))
}
wg.Wait()
return errs.ErrorOrNil()
}