Merge pull request #823 from svanharmelen/f-provider/cloudstack-managed-fw

provider/cloudstack: managed fw and adding/updating docs
This commit is contained in:
Sander van Harmelen 2015-01-16 17:53:42 +01:00
commit 8e7ffc24a5
8 changed files with 169 additions and 36 deletions

View File

@ -35,7 +35,7 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
"rule": &schema.Schema{
Type: schema.TypeSet,
Required: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"source_cidr": &schema.Schema{
@ -84,6 +84,11 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
func resourceCloudStackEgressFirewallCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
// Make sure all required parameters are there
if err := verifyEgressFirewallParams(d); err != nil {
return err
}
// Retrieve the network UUID
networkid, e := retrieveUUID(cs, "network", d.Get("network").(string))
if e != nil {
@ -203,10 +208,6 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
F: resourceCloudStackEgressFirewallRuleHash,
}
if d.Get("managed").(bool) {
// Read all rules...
}
// Read all rules that are configured
if rs := d.Get("rule").(*schema.Set); rs.Len() > 0 {
for _, rule := range rs.List() {
@ -285,7 +286,8 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
}
// If this is a managed firewall, add all unknown rules into a single dummy rule
if d.Get("managed").(bool) {
managed := d.Get("managed").(bool)
if managed {
// Get all the rules from the running environment
p := cs.Firewall.NewListEgressFirewallRulesParams()
p.SetNetworkid(d.Id())
@ -297,7 +299,7 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
}
// Add all UUIDs to the uuids map
uuids := make(map[string]interface{})
uuids := make(map[string]interface{}, len(r.EgressFirewallRules))
for _, r := range r.EgressFirewallRules {
uuids[r.Id] = r.Id
}
@ -326,7 +328,7 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
if rules.Len() > 0 {
d.Set("rule", rules)
} else {
} else if !managed {
d.SetId("")
}
@ -334,6 +336,11 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
}
func resourceCloudStackEgressFirewallUpdate(d *schema.ResourceData, meta interface{}) error {
// Make sure all required parameters are there
if err := verifyEgressFirewallParams(d); err != nil {
return err
}
// Check if the rule set as a whole has changed
if d.HasChange("rule") {
o, n := d.GetChange("rule")
@ -462,6 +469,18 @@ func resourceCloudStackEgressFirewallRuleHash(v interface{}) int {
return hashcode.String(buf.String())
}
func verifyEgressFirewallParams(d *schema.ResourceData) error {
managed := d.Get("managed").(bool)
_, rules := d.GetOk("rule")
if !rules && !managed {
return fmt.Errorf(
"You must supply at least one 'rule' when not using the 'managed' firewall feature")
}
return nil
}
func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
protocol := rule["protocol"].(string)
if protocol != "tcp" && protocol != "udp" && protocol != "icmp" {

View File

@ -35,7 +35,7 @@ func resourceCloudStackFirewall() *schema.Resource {
"rule": &schema.Schema{
Type: schema.TypeSet,
Required: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"source_cidr": &schema.Schema{
@ -84,6 +84,11 @@ func resourceCloudStackFirewall() *schema.Resource {
func resourceCloudStackFirewallCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
// Make sure all required parameters are there
if err := verifyFirewallParams(d); err != nil {
return err
}
// Retrieve the ipaddress UUID
ipaddressid, e := retrieveUUID(cs, "ipaddress", d.Get("ipaddress").(string))
if e != nil {
@ -281,7 +286,8 @@ func resourceCloudStackFirewallRead(d *schema.ResourceData, meta interface{}) er
}
// If this is a managed firewall, add all unknown rules into a single dummy rule
if d.Get("managed").(bool) {
managed := d.Get("managed").(bool)
if managed {
// Get all the rules from the running environment
p := cs.Firewall.NewListFirewallRulesParams()
p.SetIpaddressid(d.Id())
@ -293,7 +299,7 @@ func resourceCloudStackFirewallRead(d *schema.ResourceData, meta interface{}) er
}
// Add all UUIDs to the uuids map
uuids := make(map[string]interface{})
uuids := make(map[string]interface{}, len(r.FirewallRules))
for _, r := range r.FirewallRules {
uuids[r.Id] = r.Id
}
@ -322,7 +328,7 @@ func resourceCloudStackFirewallRead(d *schema.ResourceData, meta interface{}) er
if rules.Len() > 0 {
d.Set("rule", rules)
} else {
} else if !managed {
d.SetId("")
}
@ -330,6 +336,11 @@ func resourceCloudStackFirewallRead(d *schema.ResourceData, meta interface{}) er
}
func resourceCloudStackFirewallUpdate(d *schema.ResourceData, meta interface{}) error {
// Make sure all required parameters are there
if err := verifyFirewallParams(d); err != nil {
return err
}
// Check if the rule set as a whole has changed
if d.HasChange("rule") {
o, n := d.GetChange("rule")
@ -458,6 +469,18 @@ func resourceCloudStackFirewallRuleHash(v interface{}) int {
return hashcode.String(buf.String())
}
func verifyFirewallParams(d *schema.ResourceData) error {
managed := d.Get("managed").(bool)
_, rules := d.GetOk("rule")
if !rules && !managed {
return fmt.Errorf(
"You must supply at least one 'rule' when not using the 'managed' firewall feature")
}
return nil
}
func verifyFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
protocol := rule["protocol"].(string)
if protocol != "tcp" && protocol != "udp" && protocol != "icmp" {

View File

@ -35,7 +35,7 @@ func resourceCloudStackNetworkACLRule() *schema.Resource {
"rule": &schema.Schema{
Type: schema.TypeSet,
Required: true,
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"action": &schema.Schema{
@ -94,11 +94,13 @@ func resourceCloudStackNetworkACLRule() *schema.Resource {
}
func resourceCloudStackNetworkACLRuleCreate(d *schema.ResourceData, meta interface{}) error {
// Get the acl UUID
aclid := d.Get("aclid").(string)
// Make sure all required parameters are there
if err := verifyNetworkACLParams(d); err != nil {
return err
}
// We need to set this upfront in order to be able to save a partial state
d.SetId(aclid)
d.SetId(d.Get("aclid").(string))
// Create all rules that are configured
if rs := d.Get("rule").(*schema.Set); rs.Len() > 0 {
@ -110,8 +112,7 @@ func resourceCloudStackNetworkACLRuleCreate(d *schema.ResourceData, meta interfa
for _, rule := range rs.List() {
// Create a single rule
err := resourceCloudStackNetworkACLRuleCreateRule(
d, meta, aclid, rule.(map[string]interface{}))
err := resourceCloudStackNetworkACLRuleCreateRule(d, meta, rule.(map[string]interface{}))
// We need to update this first to preserve the correct state
rules.Add(rule)
@ -127,7 +128,7 @@ func resourceCloudStackNetworkACLRuleCreate(d *schema.ResourceData, meta interfa
}
func resourceCloudStackNetworkACLRuleCreateRule(
d *schema.ResourceData, meta interface{}, aclid string, rule map[string]interface{}) error {
d *schema.ResourceData, meta interface{}, rule map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{})
@ -140,7 +141,7 @@ func resourceCloudStackNetworkACLRuleCreateRule(
p := cs.NetworkACL.NewCreateNetworkACLParams(rule["protocol"].(string))
// Set the acl ID
p.SetAclid(aclid)
p.SetAclid(d.Id())
// Set the action
p.SetAction(rule["action"].(string))
@ -302,7 +303,8 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
}
// If this is a managed firewall, add all unknown rules into a single dummy rule
if d.Get("managed").(bool) {
managed := d.Get("managed").(bool)
if managed {
// Get all the rules from the running environment
p := cs.NetworkACL.NewListNetworkACLsParams()
p.SetAclid(d.Id())
@ -314,7 +316,7 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
}
// Add all UUIDs to the uuids map
uuids := make(map[string]interface{})
uuids := make(map[string]interface{}, len(r.NetworkACLs))
for _, r := range r.NetworkACLs {
uuids[r.Id] = r.Id
}
@ -343,7 +345,7 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
if rules.Len() > 0 {
d.Set("rule", rules)
} else {
} else if !managed {
d.SetId("")
}
@ -351,8 +353,10 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
}
func resourceCloudStackNetworkACLRuleUpdate(d *schema.ResourceData, meta interface{}) error {
// Get the acl UUID
aclid := d.Get("aclid").(string)
// Make sure all required parameters are there
if err := verifyNetworkACLParams(d); err != nil {
return err
}
// Check if the rule set as a whole has changed
if d.HasChange("rule") {
@ -376,8 +380,7 @@ func resourceCloudStackNetworkACLRuleUpdate(d *schema.ResourceData, meta interfa
// Then loop through al the currently configured rules and create the new ones
for _, rule := range nrs.List() {
// When succesfully deleted, re-create it again if it still exists
err := resourceCloudStackNetworkACLRuleCreateRule(
d, meta, aclid, rule.(map[string]interface{}))
err := resourceCloudStackNetworkACLRuleCreateRule(d, meta, rule.(map[string]interface{}))
// We need to update this first to preserve the correct state
rules.Add(rule)
@ -486,6 +489,18 @@ func resourceCloudStackNetworkACLRuleHash(v interface{}) int {
return hashcode.String(buf.String())
}
func verifyNetworkACLParams(d *schema.ResourceData) error {
managed := d.Get("managed").(bool)
_, rules := d.GetOk("rule")
if !rules && !managed {
return fmt.Errorf(
"You must supply at least one 'rule' when not using the 'managed' firewall feature")
}
return nil
}
func verifyNetworkACLRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
action := rule["action"].(string)
if action != "allow" && action != "deny" {

View File

@ -0,0 +1,61 @@
---
layout: "cloudstack"
page_title: "CloudStack: cloudstack_egress_firewall"
sidebar_current: "docs-cloudstack-resource-egress-firewall"
description: |-
Creates egress firewall rules for a given network.
---
# cloudstack\_egress\_firewall
Creates egress firewall rules for a given network.
## Example Usage
```
resource "cloudstack_egress_firewall" "default" {
network = "test-network"
rule {
source_cidr = "10.0.0.0/8"
protocol = "tcp"
ports = ["80", "1000-2000"]
}
}
```
## Argument Reference
The following arguments are supported:
* `network` - (Required) The network for which to create the egress firewall
rules. Changing this forces a new resource to be created.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the egress firewall
rules for this network will be managed by this resource. This means it will
delete all firewall rules that are not in your config! (defaults false)
* `rule` - (Optional) Can be specified multiple times. Each rule block supports
fields documented below. If `managed = false` at least one rule is required!
The `rule` block supports:
* `source_cidr` - (Required) The source CIDR to allow access to the given ports.
* `protocol` - (Required) The name of the protocol to allow. Valid options are:
`tcp`, `udp` and `icmp`.
* `icmp_type` - (Optional) The ICMP type to allow. This can only be specified if
the protocol is ICMP.
* `icmp_code` - (Optional) The ICMP code to allow. This can only be specified if
the protocol is ICMP.
* `ports` - (Optional) List of ports and/or port ranges to allow. This can only
be specified if the protocol is TCP or UDP.
## Attributes Reference
The following attributes are exported:
* `ID` - The network ID for which the egress firewall rules are created.

View File

@ -31,8 +31,12 @@ The following arguments are supported:
* `ipaddress` - (Required) The IP address for which to create the firewall rules.
Changing this forces a new resource to be created.
* `rule` - (Required) Can be specified multiple times. Each rule block supports
fields documented below.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the firewall rules for
this IP address will be managed by this resource. This means it will delete
all firewall rules that are not in your config! (defaults false)
* `rule` - (Optional) Can be specified multiple times. Each rule block supports
fields documented below. If `managed = false` at least one rule is required!
The `rule` block supports:
@ -54,4 +58,4 @@ The `rule` block supports:
The following attributes are exported:
* `ipaddress` - The IP address for which the firewall rules are created.
* `ID` - The IP address ID for which the firewall rules are created.

View File

@ -23,9 +23,12 @@ resource "cloudstack_network_acl" "default" {
The following arguments are supported:
* `name` - (Required) The name of the ACL. Changing this forces a new resource to be created.
* `description` - (Optional) The description of the ACL. Changing this forces a new resource to be created.
* `vpc` - (Required) The name of the VPC to create this ACL for. Changing this forces a new resource to be created.
* `name` - (Required) The name of the ACL. Changing this forces a new resource
to be created.
* `description` - (Optional) The description of the ACL. Changing this forces a
new resource to be created.
* `vpc` - (Required) The name of the VPC to create this ACL for. Changing this
forces a new resource to be created.
## Attributes Reference

View File

@ -33,8 +33,12 @@ The following arguments are supported:
* `aclid` - (Required) The network ACL ID for which to create the rules.
Changing this forces a new resource to be created.
* `rule` - (Required) Can be specified multiple times. Each rule block supports
fields documented below.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the firewall rules for
this network ACL will be managed by this resource. This means it will delete
all firewall rules that are not in your config! (defaults false)
* `rule` - (Optional) Can be specified multiple times. Each rule block supports
fields documented below. If `managed = false` at least one rule is required!
The `rule` block supports:
@ -62,4 +66,4 @@ The `rule` block supports:
The following attributes are exported:
* `aclid` - The ACL ID for which the rules are created.
* `ID` - The ACL ID for which the rules are created.

View File

@ -17,6 +17,10 @@
<a href="/docs/providers/cloudstack/r/disk.html">cloudstack_disk</a>
</li>
<li<%= sidebar_current("docs-cloudstack-resource-egress-firewall") %>>
<a href="/docs/providers/cloudstack/r/egress_firewall.html">cloudstack_egress_firewall</a>
</li>
<li<%= sidebar_current("docs-cloudstack-resource-firewall") %>>
<a href="/docs/providers/cloudstack/r/firewall.html">cloudstack_firewall</a>
</li>