provider/openstack: Ensure valid Security Group Rule attribute combination

This commit ensures that a valid combination of security group rule attributes
is set before creating the security group.
This commit is contained in:
Joe Topjian 2015-12-30 18:22:24 +00:00
parent ac9337fc03
commit 2503f0b01d
2 changed files with 52 additions and 8 deletions

View File

@ -93,6 +93,12 @@ func resourceComputeSecGroupV2Create(d *schema.ResourceData, meta interface{}) e
return fmt.Errorf("Error creating OpenStack compute client: %s", err) return fmt.Errorf("Error creating OpenStack compute client: %s", err)
} }
// Before creating the security group, make sure all rules are valid.
if err := checkSecGroupV2RulesForErrors(d); err != nil {
return err
}
// If all rules are valid, proceed with creating the security gruop.
createOpts := secgroups.CreateOpts{ createOpts := secgroups.CreateOpts{
Name: d.Get("name").(string), Name: d.Get("name").(string),
Description: d.Get("description").(string), Description: d.Get("description").(string),
@ -106,6 +112,7 @@ func resourceComputeSecGroupV2Create(d *schema.ResourceData, meta interface{}) e
d.SetId(sg.ID) d.SetId(sg.ID)
// Now that the security group has been created, iterate through each rule and create it
createRuleOptsList := resourceSecGroupRulesV2(d) createRuleOptsList := resourceSecGroupRulesV2(d)
for _, createRuleOpts := range createRuleOptsList { for _, createRuleOpts := range createRuleOptsList {
_, err := secgroups.CreateRule(computeClient, createRuleOpts).Extract() _, err := secgroups.CreateRule(computeClient, createRuleOpts).Extract()
@ -251,6 +258,42 @@ func resourceSecGroupRuleCreateOptsV2(d *schema.ResourceData, rawRule interface{
} }
} }
func checkSecGroupV2RulesForErrors(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 resourceSecGroupRuleV2(d *schema.ResourceData, rawRule interface{}) secgroups.Rule { func resourceSecGroupRuleV2(d *schema.ResourceData, rawRule interface{}) secgroups.Rule {
rawRuleMap := rawRule.(map[string]interface{}) rawRuleMap := rawRule.(map[string]interface{})
return secgroups.Rule{ return secgroups.Rule{

View File

@ -62,17 +62,18 @@ range to open. Changing this creates a new security group rule.
* `ip_protocol` - (Required) The protocol type that will be allowed. Changing * `ip_protocol` - (Required) The protocol type that will be allowed. Changing
this creates a new security group rule. this creates a new security group rule.
* `cidr` - (Optional) Required if `from_group_id` is empty. The IP range that * `cidr` - (Optional) Required if `from_group_id` or `self` is empty. The IP range
will be the source of network traffic to the security group. Use 0.0.0.0./0 that will be the source of network traffic to the security group. Use 0.0.0.0/0
to allow all IP addresses. Changing this creates a new security group rule. to allow all IP addresses. Changing this creates a new security group rule. Cannot
be combined with `from_group_id` or `self`.
* `from_group_id` - (Optional) Required if `cidr` is empty. The ID of a group * `from_group_id` - (Optional) Required if `cidr` or `self` is empty. The ID of a
from which to forward traffic to the parent group. Changing group from which to forward traffic to the parent group. Changing this creates a
this creates a new security group rule. new security group rule. Cannot be combined with `cidr` or `self`.
* `self` - (Optional) Required if `cidr` and `from_group_id` is empty. If true, * `self` - (Optional) Required if `cidr` and `from_group_id` is empty. If true,
the security group itself will be added as a source to this ingress rule. `cidr` the security group itself will be added as a source to this ingress rule. Cannot
and `from_group_id` will be ignored if either are set while `self` is true. be combined with `cidr` or `from_group_id`.
## Attributes Reference ## Attributes Reference