Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provider/openstack: Ensure valid Security Group Rule attribute combination #4466

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ func resourceComputeSecGroupV2Create(d *schema.ResourceData, meta interface{}) e
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{
Name: d.Get("name").(string),
Description: d.Get("description").(string),
Expand All @@ -106,6 +112,7 @@ func resourceComputeSecGroupV2Create(d *schema.ResourceData, meta interface{}) e

d.SetId(sg.ID)

// Now that the security group has been created, iterate through each rule and create it
createRuleOptsList := resourceSecGroupRulesV2(d)
for _, createRuleOpts := range createRuleOptsList {
_, err := secgroups.CreateRule(computeClient, createRuleOpts).Extract()
Expand Down Expand Up @@ -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 {
rawRuleMap := rawRule.(map[string]interface{})
return secgroups.Rule{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
this creates a new security group rule.

* `cidr` - (Optional) Required if `from_group_id` is empty. The IP range 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.
* `cidr` - (Optional) Required if `from_group_id` or `self` is empty. The IP range
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. Cannot
be combined with `from_group_id` or `self`.

* `from_group_id` - (Optional) Required if `cidr` is empty. The ID of a group
from which to forward traffic to the parent group. Changing
this creates a new security group rule.
* `from_group_id` - (Optional) Required if `cidr` or `self` is empty. The ID of a
group from which to forward traffic to the parent group. Changing this creates a
new security group rule. Cannot be combined with `cidr` or `self`.

* `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`
and `from_group_id` will be ignored if either are set while `self` is true.
the security group itself will be added as a source to this ingress rule. Cannot
be combined with `cidr` or `from_group_id`.

## Attributes Reference

Expand Down