Merge pull request #823 from svanharmelen/f-provider/cloudstack-managed-fw
provider/cloudstack: managed fw and adding/updating docs
This commit is contained in:
commit
8e7ffc24a5
|
@ -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" {
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -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" {
|
||||
|
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue