in cloudstack/resource_cloudstack_security_group_rule.go [243:311]
func createSecurityGroupRule(d *schema.ResourceData, meta interface{}, rule map[string]interface{}, p authorizeSecurityGroupParams, uuid string) error {
cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{})
// Set the protocol
p.SetProtocol(rule["protocol"].(string))
// If the protocol is ICMP set the needed ICMP parameters
if rule["protocol"].(string) == "icmp" {
p.SetIcmptype(rule["icmp_type"].(int))
p.SetIcmpcode(rule["icmp_code"].(int))
ruleID, err := createIngressOrEgressRule(cs, p)
if err != nil {
return err
}
uuids[uuid+"icmp"] = ruleID
rule["uuids"] = uuids
}
// If protocol is TCP or UDP, loop through all ports
if rule["protocol"].(string) == "tcp" || rule["protocol"].(string) == "udp" {
if ps := rule["ports"].(*schema.Set); ps.Len() > 0 {
// Create an empty schema.Set to hold all processed ports
ports := &schema.Set{F: schema.HashString}
for _, port := range ps.List() {
if _, ok := uuids[uuid+port.(string)]; ok {
ports.Add(port)
rule["ports"] = ports
continue
}
m := splitPorts.FindStringSubmatch(port.(string))
startPort, err := strconv.Atoi(m[1])
if err != nil {
return err
}
endPort := startPort
if m[2] != "" {
endPort, err = strconv.Atoi(m[2])
if err != nil {
return err
}
}
p.SetStartport(startPort)
p.SetEndport(endPort)
ruleID, err := createIngressOrEgressRule(cs, p)
if err != nil {
return err
}
ports.Add(port)
rule["ports"] = ports
uuids[uuid+port.(string)] = ruleID
rule["uuids"] = uuids
}
}
}
return nil
}