security group rule fix; still not exporting rule ID
This commit is contained in:
parent
4df32aebed
commit
633e98dffe
|
@ -477,9 +477,18 @@ func resourceComputeInstanceV2Update(d *schema.ResourceData, meta interface{}) e
|
||||||
for _, g := range secgroupsToRemove.List() {
|
for _, g := range secgroupsToRemove.List() {
|
||||||
err := secgroups.RemoveServerFromGroup(computeClient, d.Id(), g.(string)).ExtractErr()
|
err := secgroups.RemoveServerFromGroup(computeClient, d.Id(), g.(string)).ExtractErr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error removing security group from OpenStack server (%s): %s", d.Id(), err)
|
errCode, ok := err.(*perigee.UnexpectedResponseCodeError)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Error removing security group from OpenStack server (%s): %s", d.Id(), err)
|
||||||
|
}
|
||||||
|
if errCode.Actual == 404 {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Error removing security group from OpenStack server (%s): %s", d.Id(), err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] Removed security group (%s) from instance (%s)", g.(string), d.Id())
|
||||||
}
|
}
|
||||||
log.Printf("[DEBUG] Removed security group (%s) from instance (%s)", g.(string), d.Id())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/hashcode"
|
"github.com/hashicorp/terraform/helper/hashcode"
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
|
"github.com/racker/perigee"
|
||||||
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
|
"github.com/rackspace/gophercloud/openstack/compute/v2/extensions/secgroups"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,38 +36,41 @@ func resourceComputeSecGroupV2() *schema.Resource {
|
||||||
ForceNew: false,
|
ForceNew: false,
|
||||||
},
|
},
|
||||||
"rule": &schema.Schema{
|
"rule": &schema.Schema{
|
||||||
Type: schema.TypeSet,
|
Type: schema.TypeList,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
Elem: &schema.Resource{
|
Elem: &schema.Resource{
|
||||||
Schema: map[string]*schema.Schema{
|
Schema: map[string]*schema.Schema{
|
||||||
|
"id": &schema.Schema{
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
"from_port": &schema.Schema{
|
"from_port": &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: false,
|
||||||
},
|
},
|
||||||
"to_port": &schema.Schema{
|
"to_port": &schema.Schema{
|
||||||
Type: schema.TypeInt,
|
Type: schema.TypeInt,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: false,
|
||||||
},
|
},
|
||||||
"ip_protocol": &schema.Schema{
|
"ip_protocol": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Required: true,
|
||||||
ForceNew: true,
|
ForceNew: false,
|
||||||
},
|
},
|
||||||
"cidr": &schema.Schema{
|
"cidr": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: false,
|
||||||
},
|
},
|
||||||
"from_group_id": &schema.Schema{
|
"from_group_id": &schema.Schema{
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Set: resourceSecGroupRuleV2Hash,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -117,7 +121,8 @@ func resourceComputeSecGroupV2Read(d *schema.ResourceData, meta interface{}) err
|
||||||
d.Set("region", d.Get("region").(string))
|
d.Set("region", d.Get("region").(string))
|
||||||
d.Set("name", sg.Name)
|
d.Set("name", sg.Name)
|
||||||
d.Set("description", sg.Description)
|
d.Set("description", sg.Description)
|
||||||
d.Set("rule", sg.Rules)
|
log.Printf("[DEBUG] rulesToMap(sg.Rules): %+v", rulesToMap(sg.Rules))
|
||||||
|
d.Set("rules", rulesToMap(sg.Rules))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -143,16 +148,18 @@ func resourceComputeSecGroupV2Update(d *schema.ResourceData, meta interface{}) e
|
||||||
|
|
||||||
if d.HasChange("rule") {
|
if d.HasChange("rule") {
|
||||||
oldSGRaw, newSGRaw := d.GetChange("rule")
|
oldSGRaw, newSGRaw := d.GetChange("rule")
|
||||||
oldSGRSet, newSGRSet := oldSGRaw.(*schema.Set), newSGRaw.(*schema.Set)
|
oldSGRSlice, newSGRSlice := oldSGRaw.([]interface{}), newSGRaw.([]interface{})
|
||||||
|
oldSGRSet := schema.NewSet(secgroupRuleV2Hash, oldSGRSlice)
|
||||||
|
newSGRSet := schema.NewSet(secgroupRuleV2Hash, newSGRSlice)
|
||||||
secgrouprulesToAdd := newSGRSet.Difference(oldSGRSet)
|
secgrouprulesToAdd := newSGRSet.Difference(oldSGRSet)
|
||||||
secgrouprulesToRemove := oldSGRSet.Difference(newSGRSet)
|
secgrouprulesToRemove := oldSGRSet.Difference(newSGRSet)
|
||||||
|
|
||||||
log.Printf("[DEBUG] Security group rules to add: %v", secgrouprulesToAdd)
|
log.Printf("[DEBUG] Security group rules to add: %v", secgrouprulesToAdd)
|
||||||
|
|
||||||
log.Printf("[DEBUG] Security groups to remove: %v", secgrouprulesToRemove)
|
log.Printf("[DEBUG] Security groups rules to remove: %v", secgrouprulesToRemove)
|
||||||
|
|
||||||
for _, rawRule := range secgrouprulesToAdd.List() {
|
for _, rawRule := range secgrouprulesToAdd.List() {
|
||||||
createRuleOpts := resourceSecGroupRuleV2(d, rawRule)
|
createRuleOpts := resourceSecGroupRuleCreateOptsV2(d, rawRule)
|
||||||
rule, err := secgroups.CreateRule(computeClient, createRuleOpts).Extract()
|
rule, err := secgroups.CreateRule(computeClient, createRuleOpts).Extract()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error adding rule to OpenStack security group (%s): %s", d.Id(), err)
|
return fmt.Errorf("Error adding rule to OpenStack security group (%s): %s", d.Id(), err)
|
||||||
|
@ -161,12 +168,21 @@ func resourceComputeSecGroupV2Update(d *schema.ResourceData, meta interface{}) e
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range secgrouprulesToRemove.List() {
|
for _, r := range secgrouprulesToRemove.List() {
|
||||||
rule := r.(secgroups.Rule)
|
rule := resourceSecGroupRuleV2(d, r)
|
||||||
err := secgroups.DeleteRule(computeClient, "").ExtractErr()
|
err := secgroups.DeleteRule(computeClient, rule.ID).ExtractErr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error removing rule (%s) from OpenStack security group (%s): %s", rule.ID, d.Id(), err)
|
errCode, ok := err.(*perigee.UnexpectedResponseCodeError)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("Error removing rule (%s) from OpenStack security group (%s): %s", rule.ID, d.Id(), err)
|
||||||
|
}
|
||||||
|
if errCode.Actual == 404 {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("Error removing rule (%s) from OpenStack security group (%s)", rule.ID, d.Id())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] Removed rule (%s) from OpenStack security group (%s): %s", rule.ID, d.Id(), err)
|
||||||
}
|
}
|
||||||
log.Printf("[DEBUG] Removed rule (%s) from OpenStack security group (%s)", rule.ID, d.Id())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,22 +204,10 @@ func resourceComputeSecGroupV2Delete(d *schema.ResourceData, meta interface{}) e
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceSecGroupRuleV2Hash(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-", m["cidr"].(string)))
|
|
||||||
buf.WriteString(fmt.Sprintf("%s-", m["from_group_id"].(string)))
|
|
||||||
|
|
||||||
return hashcode.String(buf.String())
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSecGroupRulesV2(d *schema.ResourceData) []secgroups.CreateRuleOpts {
|
func resourceSecGroupRulesV2(d *schema.ResourceData) []secgroups.CreateRuleOpts {
|
||||||
rawRules := (d.Get("rule")).(*schema.Set)
|
rawRules := (d.Get("rule")).([]interface{})
|
||||||
createRuleOptsList := make([]secgroups.CreateRuleOpts, rawRules.Len())
|
createRuleOptsList := make([]secgroups.CreateRuleOpts, len(rawRules))
|
||||||
for i, raw := range rawRules.List() {
|
for i, raw := range rawRules {
|
||||||
rawMap := raw.(map[string]interface{})
|
rawMap := raw.(map[string]interface{})
|
||||||
createRuleOptsList[i] = secgroups.CreateRuleOpts{
|
createRuleOptsList[i] = secgroups.CreateRuleOpts{
|
||||||
ParentGroupID: d.Id(),
|
ParentGroupID: d.Id(),
|
||||||
|
@ -217,7 +221,7 @@ func resourceSecGroupRulesV2(d *schema.ResourceData) []secgroups.CreateRuleOpts
|
||||||
return createRuleOptsList
|
return createRuleOptsList
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourceSecGroupRuleV2(d *schema.ResourceData, raw interface{}) secgroups.CreateRuleOpts {
|
func resourceSecGroupRuleCreateOptsV2(d *schema.ResourceData, raw interface{}) secgroups.CreateRuleOpts {
|
||||||
rawMap := raw.(map[string]interface{})
|
rawMap := raw.(map[string]interface{})
|
||||||
return secgroups.CreateRuleOpts{
|
return secgroups.CreateRuleOpts{
|
||||||
ParentGroupID: d.Id(),
|
ParentGroupID: d.Id(),
|
||||||
|
@ -228,3 +232,41 @@ func resourceSecGroupRuleV2(d *schema.ResourceData, raw interface{}) secgroups.C
|
||||||
FromGroupID: rawMap["from_group_id"].(string),
|
FromGroupID: rawMap["from_group_id"].(string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func resourceSecGroupRuleV2(d *schema.ResourceData, raw interface{}) secgroups.Rule {
|
||||||
|
rawMap := raw.(map[string]interface{})
|
||||||
|
return secgroups.Rule{
|
||||||
|
ID: rawMap["id"].(string),
|
||||||
|
ParentGroupID: d.Id(),
|
||||||
|
FromPort: rawMap["from_port"].(int),
|
||||||
|
ToPort: rawMap["to_port"].(int),
|
||||||
|
IPProtocol: rawMap["ip_protocol"].(string),
|
||||||
|
IPRange: secgroups.IPRange{CIDR: rawMap["cidr"].(string)},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func rulesToMap(sgrs []secgroups.Rule) []map[string]interface{} {
|
||||||
|
sgrMap := make([]map[string]interface{}, len(sgrs))
|
||||||
|
for i, sgr := range sgrs {
|
||||||
|
sgrMap[i] = map[string]interface{}{
|
||||||
|
"to_port": sgr.ToPort,
|
||||||
|
"from_port": sgr.FromPort,
|
||||||
|
"id": sgr.ID,
|
||||||
|
"ruleID": sgr.ID,
|
||||||
|
"cidr": sgr.IPRange.CIDR,
|
||||||
|
"ip_protocol": sgr.IPProtocol,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sgrMap
|
||||||
|
}
|
||||||
|
|
||||||
|
func secgroupRuleV2Hash(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-", m["cidr"].(string)))
|
||||||
|
|
||||||
|
return hashcode.String(buf.String())
|
||||||
|
}
|
||||||
|
|
|
@ -9,14 +9,14 @@ import (
|
||||||
|
|
||||||
// CheckDeleted checks the error to see if it's a 404 (Not Found) and, if so,
|
// CheckDeleted checks the error to see if it's a 404 (Not Found) and, if so,
|
||||||
// sets the resource ID to the empty string instead of throwing an error.
|
// sets the resource ID to the empty string instead of throwing an error.
|
||||||
func CheckDeleted(d *schema.ResourceData, err error, resource string) error {
|
func CheckDeleted(d *schema.ResourceData, err error, msg string) error {
|
||||||
errCode, ok := err.(*perigee.UnexpectedResponseCodeError)
|
errCode, ok := err.(*perigee.UnexpectedResponseCodeError)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Error retrieving OpenStack %s: %s", resource, err)
|
return fmt.Errorf("%s: %s", msg, err)
|
||||||
}
|
}
|
||||||
if errCode.Actual == 404 {
|
if errCode.Actual == 404 {
|
||||||
d.SetId("")
|
d.SetId("")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Error retrieving OpenStack %s: %s", resource, err)
|
return fmt.Errorf("%s: %s", msg, err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue