terraform/vendor/github.com/terraform-providers/terraform-provider-openstack/openstack/compute_secgroup_v2.go

172 lines
5.1 KiB
Go

package openstack
import (
"bytes"
"fmt"
"log"
"strings"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/secgroups"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/helper/schema"
)
func computeSecGroupV2RulesCheckForErrors(d *schema.ResourceData) error {
rawRules := d.Get("rule").(*schema.Set).List()
for _, rawRule := range rawRules {
rawRuleMap := rawRule.(map[string]interface{})
// only one of cidr, from_group_id, or self can be set
cidr := rawRuleMap["cidr"].(string)
groupId := rawRuleMap["from_group_id"].(string)
self := rawRuleMap["self"].(bool)
errorMessage := fmt.Errorf("Only one of cidr, from_group_id, or self can be set.")
// if cidr is set, from_group_id and self cannot be set
if cidr != "" {
if groupId != "" || self {
return errorMessage
}
}
// if from_group_id is set, cidr and self cannot be set
if groupId != "" {
if cidr != "" || self {
return errorMessage
}
}
// if self is set, cidr and from_group_id cannot be set
if self {
if cidr != "" || groupId != "" {
return errorMessage
}
}
}
return nil
}
func expandComputeSecGroupV2CreateRules(d *schema.ResourceData) []secgroups.CreateRuleOpts {
rawRules := d.Get("rule").(*schema.Set).List()
createRuleOptsList := make([]secgroups.CreateRuleOpts, len(rawRules))
for i, rawRule := range rawRules {
createRuleOptsList[i] = expandComputeSecGroupV2CreateRule(d, rawRule)
}
return createRuleOptsList
}
func expandComputeSecGroupV2CreateRule(d *schema.ResourceData, rawRule interface{}) secgroups.CreateRuleOpts {
rawRuleMap := rawRule.(map[string]interface{})
groupId := rawRuleMap["from_group_id"].(string)
if rawRuleMap["self"].(bool) {
groupId = d.Id()
}
return secgroups.CreateRuleOpts{
ParentGroupID: d.Id(),
FromPort: rawRuleMap["from_port"].(int),
ToPort: rawRuleMap["to_port"].(int),
IPProtocol: rawRuleMap["ip_protocol"].(string),
CIDR: rawRuleMap["cidr"].(string),
FromGroupID: groupId,
}
}
func expandComputeSecGroupV2Rule(d *schema.ResourceData, rawRule interface{}) secgroups.Rule {
rawRuleMap := rawRule.(map[string]interface{})
return secgroups.Rule{
ID: rawRuleMap["id"].(string),
ParentGroupID: d.Id(),
FromPort: rawRuleMap["from_port"].(int),
ToPort: rawRuleMap["to_port"].(int),
IPProtocol: rawRuleMap["ip_protocol"].(string),
IPRange: secgroups.IPRange{CIDR: rawRuleMap["cidr"].(string)},
}
}
func flattenComputeSecGroupV2Rules(computeClient *gophercloud.ServiceClient, d *schema.ResourceData, sgrs []secgroups.Rule) ([]map[string]interface{}, error) {
sgrMap := make([]map[string]interface{}, len(sgrs))
for i, sgr := range sgrs {
groupId := ""
self := false
if sgr.Group.Name != "" {
if sgr.Group.Name == d.Get("name").(string) {
self = true
} else {
// Since Nova only returns the secgroup Name (and not the ID) for the group attribute,
// we need to look up all security groups and match the name.
// Nevermind that Nova wants the ID when setting the Group *and* that multiple groups
// with the same name can exist...
allPages, err := secgroups.List(computeClient).AllPages()
if err != nil {
return nil, err
}
securityGroups, err := secgroups.ExtractSecurityGroups(allPages)
if err != nil {
return nil, err
}
for _, sg := range securityGroups {
if sg.Name == sgr.Group.Name {
groupId = sg.ID
}
}
}
}
sgrMap[i] = map[string]interface{}{
"id": sgr.ID,
"from_port": sgr.FromPort,
"to_port": sgr.ToPort,
"ip_protocol": sgr.IPProtocol,
"cidr": sgr.IPRange.CIDR,
"self": self,
"from_group_id": groupId,
}
}
return sgrMap, nil
}
func computeSecGroupV2RuleHash(v interface{}) int {
var buf bytes.Buffer
m := v.(map[string]interface{})
buf.WriteString(fmt.Sprintf("%d-", m["from_port"].(int)))
buf.WriteString(fmt.Sprintf("%d-", m["to_port"].(int)))
buf.WriteString(fmt.Sprintf("%s-", m["ip_protocol"].(string)))
buf.WriteString(fmt.Sprintf("%s-", strings.ToLower(m["cidr"].(string))))
buf.WriteString(fmt.Sprintf("%s-", m["from_group_id"].(string)))
buf.WriteString(fmt.Sprintf("%t-", m["self"].(bool)))
return hashcode.String(buf.String())
}
func computeSecGroupV2StateRefreshFunc(computeClient *gophercloud.ServiceClient, d *schema.ResourceData) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
log.Printf("[DEBUG] Attempting to delete openstack_compute_secgroup_v2 %s", d.Id())
err := secgroups.Delete(computeClient, d.Id()).ExtractErr()
if err != nil {
return nil, "", err
}
s, err := secgroups.Get(computeClient, d.Id()).Extract()
if err != nil {
err = CheckDeleted(d, err, "Error retrieving openstack_compute_secgroup_v2")
if err != nil {
return s, "", err
}
log.Printf("[DEBUG] Successfully deleted openstack_compute_secgroup_v2 %s", d.Id())
return s, "DELETED", nil
}
log.Printf("[DEBUG] openstack_compute_secgroup_v2 %s still active", d.Id())
return s, "ACTIVE", nil
}
}