Merge pull request #7330 from svanharmelen/f-remove-deprecated

provider/cloudstack: delete all deprecated parameters before the 0.7 release
This commit is contained in:
Sander van Harmelen 2016-06-27 17:43:49 +02:00 committed by GitHub
commit 85ccf3b6b4
34 changed files with 438 additions and 1249 deletions

View File

@ -51,7 +51,7 @@ func resourceCloudStackDisk() *schema.Resource {
Default: false, Default: false,
}, },
"virtual_machine": &schema.Schema{ "virtual_machine_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
}, },
@ -119,7 +119,7 @@ func resourceCloudStackDiskCreate(d *schema.ResourceData, meta interface{}) erro
d.SetPartial("device") d.SetPartial("device")
d.SetPartial("disk_offering") d.SetPartial("disk_offering")
d.SetPartial("size") d.SetPartial("size")
d.SetPartial("virtual_machine") d.SetPartial("virtual_machine_id")
d.SetPartial("project") d.SetPartial("project")
d.SetPartial("zone") d.SetPartial("zone")
@ -185,7 +185,7 @@ func resourceCloudStackDiskRead(d *schema.ResourceData, meta interface{}) error
} }
d.Set("device", retrieveDeviceName(v.Deviceid, c.Name)) d.Set("device", retrieveDeviceName(v.Deviceid, c.Name))
setValueOrID(d, "virtual_machine", v.Vmname, v.Virtualmachineid) d.Set("virtual_machine_id", v.Virtualmachineid)
} }
return nil return nil
@ -254,7 +254,7 @@ func resourceCloudStackDiskUpdate(d *schema.ResourceData, meta interface{}) erro
// Set the additional partials // Set the additional partials
d.SetPartial("attach") d.SetPartial("attach")
d.SetPartial("device") d.SetPartial("device")
d.SetPartial("virtual_machine") d.SetPartial("virtual_machine_id")
} else { } else {
// Detach the volume // Detach the volume
if err := resourceCloudStackDiskDetach(d, meta); err != nil { if err := resourceCloudStackDiskDetach(d, meta); err != nil {
@ -295,43 +295,34 @@ func resourceCloudStackDiskDelete(d *schema.ResourceData, meta interface{}) erro
func resourceCloudStackDiskAttach(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackDiskAttach(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
// First check if the disk isn't already attached if virtualmachineid, ok := d.GetOk("virtual_machine_id"); ok {
if attached, err := isAttached(d, meta); err != nil || attached { // First check if the disk isn't already attached
return err if attached, err := isAttached(d, meta); err != nil || attached {
} return err
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(
cs,
"virtual_machine",
d.Get("virtual_machine").(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// Create a new parameter struct
p := cs.Volume.NewAttachVolumeParams(d.Id(), virtualmachineid)
if device, ok := d.GetOk("device"); ok {
// Retrieve the device ID
deviceid := retrieveDeviceID(device.(string))
if deviceid == -1 {
return fmt.Errorf("Device %s is not a valid device", device.(string))
} }
// Set the device ID // Create a new parameter struct
p.SetDeviceid(deviceid) p := cs.Volume.NewAttachVolumeParams(d.Id(), virtualmachineid.(string))
}
// Attach the new volume if device, ok := d.GetOk("device"); ok {
r, err := Retry(4, retryableAttachVolumeFunc(cs, p)) // Retrieve the device ID
if err != nil { deviceid := retrieveDeviceID(device.(string))
return err if deviceid == -1 {
} return fmt.Errorf("Device %s is not a valid device", device.(string))
}
d.SetId(r.(*cloudstack.AttachVolumeResponse).Id) // Set the device ID
p.SetDeviceid(deviceid)
}
// Attach the new volume
r, err := Retry(4, retryableAttachVolumeFunc(cs, p))
if err != nil {
return err
}
d.SetId(r.(*cloudstack.AttachVolumeResponse).Id)
}
return nil return nil
} }
@ -351,41 +342,33 @@ func resourceCloudStackDiskDetach(d *schema.ResourceData, meta interface{}) erro
p.SetId(d.Id()) p.SetId(d.Id())
// Detach the currently attached volume // Detach the currently attached volume
if _, err := cs.Volume.DetachVolume(p); err != nil { _, err := cs.Volume.DetachVolume(p)
// Retrieve the virtual_machine ID if err != nil {
virtualmachineid, e := retrieveID( if virtualmachineid, ok := d.GetOk("virtual_machine_id"); ok {
cs, // Create a new parameter struct
"virtual_machine", pd := cs.VirtualMachine.NewStopVirtualMachineParams(virtualmachineid.(string))
d.Get("virtual_machine").(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// Create a new parameter struct // Stop the virtual machine in order to be able to detach the disk
pd := cs.VirtualMachine.NewStopVirtualMachineParams(virtualmachineid) if _, err := cs.VirtualMachine.StopVirtualMachine(pd); err != nil {
return err
}
// Stop the virtual machine in order to be able to detach the disk // Try again to detach the currently attached volume
if _, err := cs.VirtualMachine.StopVirtualMachine(pd); err != nil { if _, err := cs.Volume.DetachVolume(p); err != nil {
return err return err
} }
// Try again to detach the currently attached volume // Create a new parameter struct
if _, err := cs.Volume.DetachVolume(p); err != nil { pu := cs.VirtualMachine.NewStartVirtualMachineParams(virtualmachineid.(string))
return err
}
// Create a new parameter struct // Start the virtual machine again
pu := cs.VirtualMachine.NewStartVirtualMachineParams(virtualmachineid) if _, err := cs.VirtualMachine.StartVirtualMachine(pu); err != nil {
return err
// Start the virtual machine again }
if _, err := cs.VirtualMachine.StartVirtualMachine(pu); err != nil {
return err
} }
} }
return nil return err
} }
func isAttached(d *schema.ResourceData, meta interface{}) (bool, error) { func isAttached(d *schema.ResourceData, meta interface{}) (bool, error) {

View File

@ -186,7 +186,7 @@ resource "cloudstack_disk" "foo" {
attach = true attach = true
device = "/dev/xvde" device = "/dev/xvde"
disk_offering = "%s" disk_offering = "%s"
virtual_machine = "${cloudstack_instance.foobar.name}" virtual_machine_id = "${cloudstack_instance.foobar.id}"
zone = "${cloudstack_instance.foobar.zone}" zone = "${cloudstack_instance.foobar.zone}"
}`, }`,
CLOUDSTACK_SERVICE_OFFERING_1, CLOUDSTACK_SERVICE_OFFERING_1,
@ -210,7 +210,7 @@ resource "cloudstack_disk" "foo" {
name = "terraform-disk" name = "terraform-disk"
attach = true attach = true
disk_offering = "%s" disk_offering = "%s"
virtual_machine = "${cloudstack_instance.foobar.name}" virtual_machine_id = "${cloudstack_instance.foobar.id}"
zone = "${cloudstack_instance.foobar.zone}" zone = "${cloudstack_instance.foobar.zone}"
}`, }`,
CLOUDSTACK_SERVICE_OFFERING_1, CLOUDSTACK_SERVICE_OFFERING_1,
@ -234,7 +234,7 @@ resource "cloudstack_disk" "foo" {
name = "terraform-disk" name = "terraform-disk"
attach = true attach = true
disk_offering = "%s" disk_offering = "%s"
virtual_machine = "${cloudstack_instance.foobar.name}" virtual_machine_id = "${cloudstack_instance.foobar.id}"
zone = "${cloudstack_instance.foobar.zone}" zone = "${cloudstack_instance.foobar.zone}"
}`, }`,
CLOUDSTACK_SERVICE_OFFERING_1, CLOUDSTACK_SERVICE_OFFERING_1,

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@ -22,18 +21,9 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"network_id": &schema.Schema{ "network_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
ForceNew: true, ForceNew: true,
ConflictsWith: []string{"network"},
},
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
ConflictsWith: []string{"network_id"},
}, },
"managed": &schema.Schema{ "managed": &schema.Schema{
@ -49,17 +39,11 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"cidr_list": &schema.Schema{ "cidr_list": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Required: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString, Set: schema.HashString,
}, },
"source_cidr": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Deprecated: "Please use the `cidr_list` field instead",
},
"protocol": &schema.Schema{ "protocol": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
@ -102,29 +86,13 @@ func resourceCloudStackEgressFirewall() *schema.Resource {
} }
func resourceCloudStackEgressFirewallCreate(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackEgressFirewallCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
// Make sure all required parameters are there // Make sure all required parameters are there
if err := verifyEgressFirewallParams(d); err != nil { if err := verifyEgressFirewallParams(d); err != nil {
return err return err
} }
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if !ok {
return errors.New("Either `network_id` or [deprecated] `network` must be provided.")
}
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
// We need to set this upfront in order to be able to save a partial state // We need to set this upfront in order to be able to save a partial state
d.SetId(networkid) d.SetId(d.Get("network_id").(string))
// Create all rules that are configured // Create all rules that are configured
if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 { if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 {
@ -144,11 +112,7 @@ func resourceCloudStackEgressFirewallCreate(d *schema.ResourceData, meta interfa
return resourceCloudStackEgressFirewallRead(d, meta) return resourceCloudStackEgressFirewallRead(d, meta)
} }
func createEgressFirewallRules( func createEgressFirewallRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, nrs *schema.Set) error {
d *schema.ResourceData,
meta interface{},
rules *schema.Set,
nrs *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -183,10 +147,7 @@ func createEgressFirewallRules(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func createEgressFirewallRule( func createEgressFirewallRule(d *schema.ResourceData, meta interface{}, rule map[string]interface{}) error {
d *schema.ResourceData,
meta interface{},
rule map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{}) uuids := rule["uuids"].(map[string]interface{})
@ -199,7 +160,11 @@ func createEgressFirewallRule(
p := cs.Firewall.NewCreateEgressFirewallRuleParams(d.Id(), rule["protocol"].(string)) p := cs.Firewall.NewCreateEgressFirewallRuleParams(d.Id(), rule["protocol"].(string))
// Set the CIDR list // Set the CIDR list
p.SetCidrlist(retrieveCidrList(rule)) var cidrList []string
for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
cidrList = append(cidrList, cidr.(string))
}
p.SetCidrlist(cidrList)
// If the protocol is ICMP set the needed ICMP parameters // If the protocol is ICMP set the needed ICMP parameters
if rule["protocol"].(string) == "icmp" { if rule["protocol"].(string) == "icmp" {
@ -307,11 +272,17 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
rule["icmp_type"] = r.Icmptype rule["icmp_type"] = r.Icmptype
rule["icmp_code"] = r.Icmpcode rule["icmp_code"] = r.Icmpcode
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
rules.Add(rule) rules.Add(rule)
} }
@ -339,9 +310,15 @@ func resourceCloudStackEgressFirewallRead(d *schema.ResourceData, meta interface
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
ports.Add(port) ports.Add(port)
} }
@ -451,11 +428,7 @@ func resourceCloudStackEgressFirewallDelete(d *schema.ResourceData, meta interfa
return nil return nil
} }
func deleteEgressFirewallRules( func deleteEgressFirewallRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, ors *schema.Set) error {
d *schema.ResourceData,
meta interface{},
rules *schema.Set,
ors *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -491,16 +464,13 @@ func deleteEgressFirewallRules(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func deleteEgressFirewallRule( func deleteEgressFirewallRule(d *schema.ResourceData, meta interface{}, rule map[string]interface{}) error {
d *schema.ResourceData,
meta interface{},
rule map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{}) uuids := rule["uuids"].(map[string]interface{})
for k, id := range uuids { for k, id := range uuids {
// We don't care about the count here, so just continue // We don't care about the count here, so just continue
if k == "#" { if k == "%" {
continue continue
} }
@ -542,17 +512,6 @@ func verifyEgressFirewallParams(d *schema.ResourceData) error {
} }
func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error { func verifyEgressFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
cidrList := rule["cidr_list"].(*schema.Set)
sourceCidr := rule["source_cidr"].(string)
if cidrList.Len() == 0 && sourceCidr == "" {
return fmt.Errorf(
"Parameter cidr_list is a required parameter")
}
if cidrList.Len() > 0 && sourceCidr != "" {
return fmt.Errorf(
"Parameter source_cidr is deprecated and cannot be used together with cidr_list")
}
protocol := rule["protocol"].(string) protocol := rule["protocol"].(string)
if protocol != "tcp" && protocol != "udp" && protocol != "icmp" { if protocol != "tcp" && protocol != "udp" && protocol != "icmp" {
return fmt.Errorf( return fmt.Errorf(

View File

@ -23,25 +23,15 @@ func TestAccCloudStackEgressFirewall_basic(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1), "cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.#", "2"), "cloudstack_egress_firewall.foo", "rule.#", "1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "cloudstack_egress_firewall.foo",
"rule.1081385056.cidr_list.3378711023", "rule.2905891128.cidr_list.3378711023",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"), CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1081385056.protocol", "tcp"), "cloudstack_egress_firewall.foo", "rule.2905891128.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1081385056.ports.32925333", "8080"), "cloudstack_egress_firewall.foo", "rule.2905891128.ports.32925333", "8080"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo",
"rule.1129999216.source_cidr",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.ports.1889509032", "80"),
), ),
}, },
}, },
@ -61,25 +51,15 @@ func TestAccCloudStackEgressFirewall_update(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1), "cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.#", "2"), "cloudstack_egress_firewall.foo", "rule.#", "1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "cloudstack_egress_firewall.foo",
"rule.1081385056.cidr_list.3378711023", "rule.2905891128.cidr_list.3378711023",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"), CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1081385056.protocol", "tcp"), "cloudstack_egress_firewall.foo", "rule.2905891128.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1081385056.ports.32925333", "8080"), "cloudstack_egress_firewall.foo", "rule.2905891128.ports.32925333", "8080"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo",
"rule.1129999216.source_cidr",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.ports.1889509032", "80"),
), ),
}, },
@ -90,37 +70,27 @@ func TestAccCloudStackEgressFirewall_update(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1), "cloudstack_egress_firewall.foo", "network_id", CLOUDSTACK_NETWORK_1),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.#", "3"), "cloudstack_egress_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "cloudstack_egress_firewall.foo",
"rule.59731059.cidr_list.1910468234", "rule.3593527682.cidr_list.1910468234",
CLOUDSTACK_NETWORK_1_IPADDRESS2+"/32"), CLOUDSTACK_NETWORK_1_IPADDRESS2+"/32"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "cloudstack_egress_firewall.foo",
"rule.59731059.cidr_list.3378711023", "rule.3593527682.cidr_list.3378711023",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"), CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.59731059.protocol", "tcp"), "cloudstack_egress_firewall.foo", "rule.3593527682.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.59731059.ports.32925333", "8080"), "cloudstack_egress_firewall.foo", "rule.3593527682.ports.32925333", "8080"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "cloudstack_egress_firewall.foo",
"rule.1052669680.source_cidr", "rule.739924765.cidr_list.3378711023",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"), CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1052669680.protocol", "tcp"), "cloudstack_egress_firewall.foo", "rule.739924765.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1052669680.ports.3638101695", "443"), "cloudstack_egress_firewall.foo", "rule.739924765.ports.1889509032", "80"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo",
"rule.1129999216.source_cidr",
CLOUDSTACK_NETWORK_1_IPADDRESS1+"/32"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.protocol", "tcp"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr(
"cloudstack_egress_firewall.foo", "rule.1129999216.ports.1889509032", "80"),
), ),
}, },
}, },
@ -139,7 +109,7 @@ func testAccCheckCloudStackEgressFirewallRulesExist(n string) resource.TestCheck
} }
for k, id := range rs.Primary.Attributes { for k, id := range rs.Primary.Attributes {
if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.#") { if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.%") {
continue continue
} }
@ -172,7 +142,7 @@ func testAccCheckCloudStackEgressFirewallDestroy(s *terraform.State) error {
} }
for k, id := range rs.Primary.Attributes { for k, id := range rs.Primary.Attributes {
if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.#") { if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.%") {
continue continue
} }
@ -195,15 +165,8 @@ resource "cloudstack_egress_firewall" "foo" {
protocol = "tcp" protocol = "tcp"
ports = ["8080"] ports = ["8080"]
} }
rule {
source_cidr = "%s/32"
protocol = "tcp"
ports = ["80", "1000-2000"]
}
}`, }`,
CLOUDSTACK_NETWORK_1, CLOUDSTACK_NETWORK_1,
CLOUDSTACK_NETWORK_1_IPADDRESS1,
CLOUDSTACK_NETWORK_1_IPADDRESS1) CLOUDSTACK_NETWORK_1_IPADDRESS1)
var testAccCloudStackEgressFirewall_update = fmt.Sprintf(` var testAccCloudStackEgressFirewall_update = fmt.Sprintf(`
@ -217,19 +180,12 @@ resource "cloudstack_egress_firewall" "foo" {
} }
rule { rule {
source_cidr = "%s/32" cidr_list = ["%s/32"]
protocol = "tcp" protocol = "tcp"
ports = ["80", "1000-2000"] ports = ["80", "1000-2000"]
} }
rule {
source_cidr = "%s/32"
protocol = "tcp"
ports = ["443"]
}
}`, }`,
CLOUDSTACK_NETWORK_1, CLOUDSTACK_NETWORK_1,
CLOUDSTACK_NETWORK_1_IPADDRESS1, CLOUDSTACK_NETWORK_1_IPADDRESS1,
CLOUDSTACK_NETWORK_1_IPADDRESS2, CLOUDSTACK_NETWORK_1_IPADDRESS2,
CLOUDSTACK_NETWORK_1_IPADDRESS1,
CLOUDSTACK_NETWORK_1_IPADDRESS1) CLOUDSTACK_NETWORK_1_IPADDRESS1)

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@ -22,18 +21,9 @@ func resourceCloudStackFirewall() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"ip_address_id": &schema.Schema{ "ip_address_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
ForceNew: true, ForceNew: true,
ConflictsWith: []string{"ipaddress"},
},
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address_id` field instead",
ConflictsWith: []string{"ip_address_id"},
}, },
"managed": &schema.Schema{ "managed": &schema.Schema{
@ -49,17 +39,11 @@ func resourceCloudStackFirewall() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"cidr_list": &schema.Schema{ "cidr_list": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Required: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString, Set: schema.HashString,
}, },
"source_cidr": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Deprecated: "Please use the `cidr_list` field instead",
},
"protocol": &schema.Schema{ "protocol": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
@ -102,29 +86,13 @@ func resourceCloudStackFirewall() *schema.Resource {
} }
func resourceCloudStackFirewallCreate(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackFirewallCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
// Make sure all required parameters are there // Make sure all required parameters are there
if err := verifyFirewallParams(d); err != nil { if err := verifyFirewallParams(d); err != nil {
return err return err
} }
ipaddress, ok := d.GetOk("ip_address_id")
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if !ok {
return errors.New("Either `ip_address_id` or [deprecated] `ipaddress` must be provided.")
}
// Retrieve the ipaddress ID
ipaddressid, e := retrieveID(cs, "ip_address", ipaddress.(string))
if e != nil {
return e.Error()
}
// We need to set this upfront in order to be able to save a partial state // We need to set this upfront in order to be able to save a partial state
d.SetId(ipaddressid) d.SetId(d.Get("ip_address_id").(string))
// Create all rules that are configured // Create all rules that are configured
if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 { if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 {
@ -143,11 +111,7 @@ func resourceCloudStackFirewallCreate(d *schema.ResourceData, meta interface{})
return resourceCloudStackFirewallRead(d, meta) return resourceCloudStackFirewallRead(d, meta)
} }
func createFirewallRules( func createFirewallRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, nrs *schema.Set) error {
d *schema.ResourceData,
meta interface{},
rules *schema.Set,
nrs *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -183,10 +147,7 @@ func createFirewallRules(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func createFirewallRule( func createFirewallRule(d *schema.ResourceData, meta interface{}, rule map[string]interface{}) error {
d *schema.ResourceData,
meta interface{},
rule map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{}) uuids := rule["uuids"].(map[string]interface{})
@ -199,7 +160,11 @@ func createFirewallRule(
p := cs.Firewall.NewCreateFirewallRuleParams(d.Id(), rule["protocol"].(string)) p := cs.Firewall.NewCreateFirewallRuleParams(d.Id(), rule["protocol"].(string))
// Set the CIDR list // Set the CIDR list
p.SetCidrlist(retrieveCidrList(rule)) var cidrList []string
for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
cidrList = append(cidrList, cidr.(string))
}
p.SetCidrlist(cidrList)
// If the protocol is ICMP set the needed ICMP parameters // If the protocol is ICMP set the needed ICMP parameters
if rule["protocol"].(string) == "icmp" { if rule["protocol"].(string) == "icmp" {
@ -308,11 +273,17 @@ func resourceCloudStackFirewallRead(d *schema.ResourceData, meta interface{}) er
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
rule["icmp_type"] = r.Icmptype rule["icmp_type"] = r.Icmptype
rule["icmp_code"] = r.Icmpcode rule["icmp_code"] = r.Icmpcode
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
rules.Add(rule) rules.Add(rule)
} }
@ -340,9 +311,15 @@ func resourceCloudStackFirewallRead(d *schema.ResourceData, meta interface{}) er
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
ports.Add(port) ports.Add(port)
} }
@ -452,11 +429,7 @@ func resourceCloudStackFirewallDelete(d *schema.ResourceData, meta interface{})
return nil return nil
} }
func deleteFirewallRules( func deleteFirewallRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, ors *schema.Set) error {
d *schema.ResourceData,
meta interface{},
rules *schema.Set,
ors *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -492,16 +465,13 @@ func deleteFirewallRules(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func deleteFirewallRule( func deleteFirewallRule(d *schema.ResourceData, meta interface{}, rule map[string]interface{}) error {
d *schema.ResourceData,
meta interface{},
rule map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{}) uuids := rule["uuids"].(map[string]interface{})
for k, id := range uuids { for k, id := range uuids {
// We don't care about the count here, so just continue // We don't care about the count here, so just continue
if k == "#" { if k == "%" {
continue continue
} }
@ -543,17 +513,6 @@ func verifyFirewallParams(d *schema.ResourceData) error {
} }
func verifyFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error { func verifyFirewallRuleParams(d *schema.ResourceData, rule map[string]interface{}) error {
cidrList := rule["cidr_list"].(*schema.Set)
sourceCidr := rule["source_cidr"].(string)
if cidrList.Len() == 0 && sourceCidr == "" {
return fmt.Errorf(
"Parameter cidr_list is a required parameter")
}
if cidrList.Len() > 0 && sourceCidr != "" {
return fmt.Errorf(
"Parameter source_cidr is deprecated and cannot be used together with cidr_list")
}
protocol := rule["protocol"].(string) protocol := rule["protocol"].(string)
if protocol != "tcp" && protocol != "udp" && protocol != "icmp" { if protocol != "tcp" && protocol != "udp" && protocol != "icmp" {
return fmt.Errorf( return fmt.Errorf(

View File

@ -25,19 +25,19 @@ func TestAccCloudStackFirewall_basic(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.#", "2"), "cloudstack_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.60926170.cidr_list.3482919157", "10.0.0.0/24"), "cloudstack_firewall.foo", "rule.2263505090.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.60926170.protocol", "tcp"), "cloudstack_firewall.foo", "rule.2263505090.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.60926170.ports.32925333", "8080"), "cloudstack_firewall.foo", "rule.2263505090.ports.32925333", "8080"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.cidr_list.3482919157", "10.0.0.0/24"), "cloudstack_firewall.foo", "rule.3782201428.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.protocol", "tcp"), "cloudstack_firewall.foo", "rule.3782201428.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.ports.1209010669", "1000-2000"), "cloudstack_firewall.foo", "rule.3782201428.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.ports.1889509032", "80"), "cloudstack_firewall.foo", "rule.3782201428.ports.1889509032", "80"),
), ),
}, },
}, },
@ -59,19 +59,19 @@ func TestAccCloudStackFirewall_update(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.#", "2"), "cloudstack_firewall.foo", "rule.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.60926170.cidr_list.3482919157", "10.0.0.0/24"), "cloudstack_firewall.foo", "rule.2263505090.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.60926170.protocol", "tcp"), "cloudstack_firewall.foo", "rule.2263505090.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.60926170.ports.32925333", "8080"), "cloudstack_firewall.foo", "rule.2263505090.ports.32925333", "8080"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.cidr_list.3482919157", "10.0.0.0/24"), "cloudstack_firewall.foo", "rule.3782201428.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.protocol", "tcp"), "cloudstack_firewall.foo", "rule.3782201428.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.ports.1209010669", "1000-2000"), "cloudstack_firewall.foo", "rule.3782201428.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.ports.1889509032", "80"), "cloudstack_firewall.foo", "rule.3782201428.ports.1889509032", "80"),
), ),
}, },
@ -84,29 +84,29 @@ func TestAccCloudStackFirewall_update(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.#", "3"), "cloudstack_firewall.foo", "rule.#", "3"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.2144925929.cidr_list.80081744", "10.0.1.0/24"), "cloudstack_firewall.foo", "rule.3529885171.cidr_list.80081744", "10.0.1.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.2144925929.cidr_list.3482919157", "10.0.0.0/24"), "cloudstack_firewall.foo", "rule.3529885171.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.2144925929.protocol", "tcp"), "cloudstack_firewall.foo", "rule.3529885171.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.2144925929.ports.32925333", "8080"), "cloudstack_firewall.foo", "rule.3529885171.ports.32925333", "8080"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.cidr_list.3482919157", "10.0.0.0/24"), "cloudstack_firewall.foo", "rule.3782201428.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.protocol", "tcp"), "cloudstack_firewall.foo", "rule.3782201428.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.ports.1209010669", "1000-2000"), "cloudstack_firewall.foo", "rule.3782201428.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.3832507136.ports.1889509032", "80"), "cloudstack_firewall.foo", "rule.3782201428.ports.1889509032", "80"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.302279047.cidr_list.2835005819", "172.16.100.0/24"), "cloudstack_firewall.foo", "rule.4160426500.cidr_list.2835005819", "172.16.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.302279047.protocol", "tcp"), "cloudstack_firewall.foo", "rule.4160426500.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.302279047.ports.1889509032", "80"), "cloudstack_firewall.foo", "rule.4160426500.ports.1889509032", "80"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_firewall.foo", "rule.302279047.ports.3638101695", "443"), "cloudstack_firewall.foo", "rule.4160426500.ports.3638101695", "443"),
), ),
}, },
}, },
@ -125,7 +125,7 @@ func testAccCheckCloudStackFirewallRulesExist(n string) resource.TestCheckFunc {
} }
for k, id := range rs.Primary.Attributes { for k, id := range rs.Primary.Attributes {
if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.#") { if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.%") {
continue continue
} }
@ -158,7 +158,7 @@ func testAccCheckCloudStackFirewallDestroy(s *terraform.State) error {
} }
for k, id := range rs.Primary.Attributes { for k, id := range rs.Primary.Attributes {
if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.#") { if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.%") {
continue continue
} }

View File

@ -4,7 +4,6 @@ import (
"crypto/sha1" "crypto/sha1"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -41,17 +40,9 @@ func resourceCloudStackInstance() *schema.Resource {
"network_id": &schema.Schema{ "network_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"ip_address": &schema.Schema{ "ip_address": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -59,20 +50,24 @@ func resourceCloudStackInstance() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
},
"template": &schema.Schema{ "template": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
ForceNew: true, ForceNew: true,
}, },
"root_disk_size": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
"group": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"affinity_group_ids": &schema.Schema{ "affinity_group_ids": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Optional: true,
@ -144,18 +139,6 @@ func resourceCloudStackInstance() *schema.Resource {
Optional: true, Optional: true,
Default: false, Default: false,
}, },
"group": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"root_disk_size": &schema.Schema{
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
},
}, },
} }
} }
@ -203,80 +186,59 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{})
p.SetDisplayname(name.(string)) p.SetDisplayname(name.(string))
} }
// If there is a root_disk_size supplied, add it to the parameter struct
if rootdisksize, ok := d.GetOk("root_disk_size"); ok {
p.SetRootdisksize(int64(rootdisksize.(int)))
}
if zone.Networktype == "Advanced" { if zone.Networktype == "Advanced" {
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if !ok {
return errors.New(
"Either `network_id` or [deprecated] `network` must be provided when using a zone with network type `advanced`.")
}
// Retrieve the network ID
networkid, e := retrieveID(
cs,
"network",
network.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// Set the default network ID // Set the default network ID
p.SetNetworkids([]string{networkid}) p.SetNetworkids([]string{d.Get("network_id").(string)})
} }
// If there is a ipaddres supplied, add it to the parameter struct // If there is a ipaddres supplied, add it to the parameter struct
ipaddress, ok := d.GetOk("ip_address") if ipaddress, ok := d.GetOk("ip_address"); ok {
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if ok {
p.SetIpaddress(ipaddress.(string)) p.SetIpaddress(ipaddress.(string))
} }
if ags := d.Get("affinity_group_ids").(*schema.Set); ags.Len() > 0 { // If there is a group supplied, add it to the parameter struct
var groups []string if group, ok := d.GetOk("group"); ok {
p.SetGroup(group.(string))
}
for _, group := range ags.List() { // If there are affinity group IDs supplied, add them to the parameter struct
if agIDs := d.Get("affinity_group_ids").(*schema.Set); agIDs.Len() > 0 {
var groups []string
for _, group := range agIDs.List() {
groups = append(groups, group.(string)) groups = append(groups, group.(string))
} }
p.SetAffinitygroupids(groups) p.SetAffinitygroupids(groups)
} }
// If there is a affinity_group_names supplied, add it to the parameter struct // If there are affinity group names supplied, add them to the parameter struct
if agns := d.Get("affinity_group_names").(*schema.Set); agns.Len() > 0 { if agNames := d.Get("affinity_group_names").(*schema.Set); agNames.Len() > 0 {
var groups []string var groups []string
for _, group := range agNames.List() {
for _, group := range agns.List() {
groups = append(groups, group.(string)) groups = append(groups, group.(string))
} }
p.SetAffinitygroupnames(groups) p.SetAffinitygroupnames(groups)
} }
// If there is a security_group_ids supplied, add it to the parameter struct // If there are security group IDs supplied, add them to the parameter struct
if sgids := d.Get("security_group_ids").(*schema.Set); sgids.Len() > 0 { if sgIDs := d.Get("security_group_ids").(*schema.Set); sgIDs.Len() > 0 {
var groups []string var groups []string
for _, group := range sgIDs.List() {
for _, group := range sgids.List() {
groups = append(groups, group.(string)) groups = append(groups, group.(string))
} }
p.SetSecuritygroupids(groups) p.SetSecuritygroupids(groups)
} }
// If there is a security_group_names supplied, add it to the parameter struct // If there are security group names supplied, add them to the parameter struct
if sgns := d.Get("security_group_names").(*schema.Set); sgns.Len() > 0 { if sgNames := d.Get("security_group_names").(*schema.Set); sgNames.Len() > 0 {
var groups []string var groups []string
for _, group := range sgNames.List() {
for _, group := range sgns.List() {
groups = append(groups, group.(string)) groups = append(groups, group.(string))
} }
p.SetSecuritygroupnames(groups) p.SetSecuritygroupnames(groups)
} }
@ -312,16 +274,6 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{})
p.SetUserdata(ud) p.SetUserdata(ud)
} }
// If there is a group supplied, add it to the parameter struct
if group, ok := d.GetOk("group"); ok {
p.SetGroup(group.(string))
}
// If there is a root_disk_size supplied, add it to the parameter struct
if rootdisksize, ok := d.GetOk("root_disk_size"); ok {
p.SetRootdisksize(int64(rootdisksize.(int)))
}
// Create the new instance // Create the new instance
r, err := cs.VirtualMachine.DeployVirtualMachine(p) r, err := cs.VirtualMachine.DeployVirtualMachine(p)
if err != nil { if err != nil {
@ -364,47 +316,43 @@ func resourceCloudStackInstanceRead(d *schema.ResourceData, meta interface{}) er
d.Set("ip_address", vm.Nic[0].Ipaddress) d.Set("ip_address", vm.Nic[0].Ipaddress)
d.Set("group", vm.Group) d.Set("group", vm.Group)
if _, ok := d.GetOk("affinity_group_ids"); ok {
groups := &schema.Set{F: schema.HashString}
for _, group := range vm.Affinitygroup {
groups.Add(group.Id)
}
d.Set("affinity_group_ids", groups)
}
if _, ok := d.GetOk("affinity_group_names"); ok {
groups := &schema.Set{F: schema.HashString}
for _, group := range vm.Affinitygroup {
groups.Add(group.Name)
}
d.Set("affinity_group_names", groups)
}
if _, ok := d.GetOk("security_group_ids"); ok {
groups := &schema.Set{F: schema.HashString}
for _, group := range vm.Securitygroup {
groups.Add(group.Id)
}
d.Set("security_group_ids", groups)
}
if _, ok := d.GetOk("security_group_names"); ok {
groups := &schema.Set{F: schema.HashString}
for _, group := range vm.Securitygroup {
groups.Add(group.Name)
}
d.Set("security_group_names", groups)
}
setValueOrID(d, "service_offering", vm.Serviceofferingname, vm.Serviceofferingid) setValueOrID(d, "service_offering", vm.Serviceofferingname, vm.Serviceofferingid)
setValueOrID(d, "template", vm.Templatename, vm.Templateid) setValueOrID(d, "template", vm.Templatename, vm.Templateid)
setValueOrID(d, "project", vm.Project, vm.Projectid) setValueOrID(d, "project", vm.Project, vm.Projectid)
setValueOrID(d, "zone", vm.Zonename, vm.Zoneid) setValueOrID(d, "zone", vm.Zonename, vm.Zoneid)
groups := &schema.Set{F: schema.HashString}
for _, group := range vm.Affinitygroup {
groups.Add(group.Id)
}
if groups.Len() > 0 {
d.Set("affinity_group_ids", groups)
}
agns := &schema.Set{F: schema.HashString}
for _, group := range vm.Affinitygroup {
agns.Add(group.Name)
}
if agns.Len() > 0 {
d.Set("affinity_group_names", agns)
}
sgids := &schema.Set{F: schema.HashString}
for _, group := range vm.Securitygroup {
sgids.Add(group.Id)
}
if sgids.Len() > 0 {
d.Set("security_group_ids", sgids)
}
sgns := &schema.Set{F: schema.HashString}
for _, group := range vm.Securitygroup {
sgns.Add(group.Name)
}
if sgns.Len() > 0 {
d.Set("security_group_names", sgns)
}
return nil return nil
} }
@ -455,7 +403,7 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{})
} }
// Attributes that require reboot to update // Attributes that require reboot to update
if d.HasChange("name") || d.HasChange("service_offering") || d.HasChange("affinity_group_ids") || d.HasChange("keypair") { if d.HasChange("name") || d.HasChange("service_offering") || d.HasChange("affinity_group_ids") || d.HasChange("affinity_group_names") || d.HasChange("keypair") {
// Before we can actually make these changes, the virtual machine must be stopped // Before we can actually make these changes, the virtual machine must be stopped
_, err := cs.VirtualMachine.StopVirtualMachine( _, err := cs.VirtualMachine.StopVirtualMachine(
cs.VirtualMachine.NewStopVirtualMachineParams(d.Id())) cs.VirtualMachine.NewStopVirtualMachineParams(d.Id()))
@ -510,8 +458,21 @@ func resourceCloudStackInstanceUpdate(d *schema.ResourceData, meta interface{})
p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id()) p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id())
groups := []string{} groups := []string{}
if ags := d.Get("affinity_group_ids").(*schema.Set); ags.Len() > 0 { if agIDs := d.Get("affinity_group_ids").(*schema.Set); agIDs.Len() > 0 {
for _, group := range ags.List() { for _, group := range agIDs.List() {
groups = append(groups, group.(string))
}
}
p.SetAffinitygroupids(groups)
}
if d.HasChange("affinity_group_names") {
p := cs.AffinityGroup.NewUpdateVMAffinityGroupParams(d.Id())
groups := []string{}
if agNames := d.Get("affinity_group_names").(*schema.Set); agNames.Len() > 0 {
for _, group := range agNames.List() {
groups = append(groups, group.(string)) groups = append(groups, group.(string))
} }
} }

View File

@ -19,31 +19,15 @@ func resourceCloudStackIPAddress() *schema.Resource {
"network_id": &schema.Schema{ "network_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"vpc_id": &schema.Schema{ "vpc_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"vpc": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
"project": &schema.Schema{ "project": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -68,44 +52,14 @@ func resourceCloudStackIPAddressCreate(d *schema.ResourceData, meta interface{})
// Create a new parameter struct // Create a new parameter struct
p := cs.Address.NewAssociateIpAddressParams() p := cs.Address.NewAssociateIpAddressParams()
network, ok := d.GetOk("network_id") if networkid, ok := d.GetOk("network_id"); ok {
if !ok {
network, ok = d.GetOk("network")
}
if ok {
// Retrieve the network ID
networkid, e := retrieveID(
cs,
"network",
network.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// Set the networkid // Set the networkid
p.SetNetworkid(networkid) p.SetNetworkid(networkid.(string))
} }
vpc, ok := d.GetOk("vpc_id") if vpcid, ok := d.GetOk("vpc_id"); ok {
if !ok {
vpc, ok = d.GetOk("vpc")
}
if ok {
// Retrieve the vpc ID
vpcid, e := retrieveID(
cs,
"vpc",
vpc.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// Set the vpcid // Set the vpcid
p.SetVpcid(vpcid) p.SetVpcid(vpcid.(string))
} }
// If there is a project supplied, we retrieve and set the project id // If there is a project supplied, we retrieve and set the project id
@ -146,15 +100,11 @@ func resourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) e
// Updated the IP address // Updated the IP address
d.Set("ip_address", ip.Ipaddress) d.Set("ip_address", ip.Ipaddress)
_, networkID := d.GetOk("network_id") if _, ok := d.GetOk("network_id"); ok {
_, network := d.GetOk("network")
if networkID || network {
d.Set("network_id", ip.Associatednetworkid) d.Set("network_id", ip.Associatednetworkid)
} }
_, vpcID := d.GetOk("vpc_id") if _, ok := d.GetOk("vpc_id"); ok {
_, vpc := d.GetOk("vpc")
if vpcID || vpc {
d.Set("vpc_id", ip.Vpcid) d.Set("vpc_id", ip.Vpcid)
} }
@ -185,12 +135,10 @@ func resourceCloudStackIPAddressDelete(d *schema.ResourceData, meta interface{})
} }
func verifyIPAddressParams(d *schema.ResourceData) error { func verifyIPAddressParams(d *schema.ResourceData) error {
_, networkID := d.GetOk("network_id") _, network := d.GetOk("network_id")
_, network := d.GetOk("network") _, vpc := d.GetOk("vpc_id")
_, vpcID := d.GetOk("vpc_id")
_, vpc := d.GetOk("vpc")
if (networkID || network) && (vpcID || vpc) || (!networkID && !network) && (!vpcID && !vpc) { if (network && vpc) || (!network && !vpc) {
return fmt.Errorf( return fmt.Errorf(
"You must supply a value for either (so not both) the 'network_id' or 'vpc_id' parameter") "You must supply a value for either (so not both) the 'network_id' or 'vpc_id' parameter")
} }

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -31,32 +30,16 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource {
"ip_address_id": &schema.Schema{ "ip_address_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address_id` field instead",
},
"network_id": &schema.Schema{ "network_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"algorithm": &schema.Schema{ "algorithm": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
@ -75,20 +58,10 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource {
}, },
"member_ids": &schema.Schema{ "member_ids": &schema.Schema{
Type: schema.TypeList, Type: schema.TypeList,
Optional: true, Required: true,
ForceNew: true, ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
ConflictsWith: []string{"members"},
},
"members": &schema.Schema{
Type: schema.TypeList,
Optional: true,
ForceNew: true,
Elem: &schema.Schema{Type: schema.TypeString},
Deprecated: "Please use the `member_ids` field instead",
ConflictsWith: []string{"member_ids"},
}, },
}, },
} }
@ -116,35 +89,13 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
p.SetDescription(d.Get("name").(string)) p.SetDescription(d.Get("name").(string))
} }
network, ok := d.GetOk("network_id") if networkid, ok := d.GetOk("network_id"); ok {
if !ok { // Set the network id
network, ok = d.GetOk("network") p.SetNetworkid(networkid.(string))
}
if ok {
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
// Set the networkid
p.SetNetworkid(networkid)
} }
ipaddress, ok := d.GetOk("ip_address_id") // Set the ipaddress id
if !ok { p.SetPublicipid(d.Get("ip_address_id").(string))
ipaddress, ok = d.GetOk("ipaddress")
}
if !ok {
return errors.New("Either `ip_address_id` or [deprecated] `ipaddress` must be provided.")
}
// Retrieve the ipaddress ID
ipaddressid, e := retrieveID(cs, "ip_address", ipaddress.(string))
if e != nil {
return e.Error()
}
p.SetPublicipid(ipaddressid)
// Create the load balancer rule // Create the load balancer rule
r, err := cs.LoadBalancer.CreateLoadBalancerRule(p) r, err := cs.LoadBalancer.CreateLoadBalancerRule(p)
@ -165,16 +116,8 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
// Create a new parameter struct // Create a new parameter struct
ap := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id) ap := cs.LoadBalancer.NewAssignToLoadBalancerRuleParams(r.Id)
members, ok := d.GetOk("member_ids")
if !ok {
members, ok = d.GetOk("members")
}
if !ok {
return errors.New("Either `member_ids` or [deprecated] `members` must be provided.")
}
var mbs []string var mbs []string
for _, id := range members.([]interface{}) { for _, id := range d.Get("member_ids").([]interface{}) {
mbs = append(mbs, id.(string)) mbs = append(mbs, id.(string))
} }
@ -186,7 +129,6 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter
} }
d.SetPartial("member_ids") d.SetPartial("member_ids")
d.SetPartial("members")
d.Partial(false) d.Partial(false)
return resourceCloudStackLoadBalancerRuleRead(d, meta) return resourceCloudStackLoadBalancerRuleRead(d, meta)
@ -213,9 +155,7 @@ func resourceCloudStackLoadBalancerRuleRead(d *schema.ResourceData, meta interfa
d.Set("ip_address_id", lb.Publicipid) d.Set("ip_address_id", lb.Publicipid)
// Only set network if user specified it to avoid spurious diffs // Only set network if user specified it to avoid spurious diffs
_, networkID := d.GetOk("network_id") if _, ok := d.GetOk("network_id"); ok {
_, network := d.GetOk("network")
if networkID || network {
d.Set("network_id", lb.Networkid) d.Set("network_id", lb.Networkid)
} }

View File

@ -15,10 +15,9 @@ const none = "none"
func resourceCloudStackNetwork() *schema.Resource { func resourceCloudStackNetwork() *schema.Resource {
aclidSchema := &schema.Schema{ aclidSchema := &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Default: none, Default: none,
ConflictsWith: []string{"aclid"},
} }
aclidSchema.StateFunc = func(v interface{}) string { aclidSchema.StateFunc = func(v interface{}) string {
@ -90,25 +89,11 @@ func resourceCloudStackNetwork() *schema.Resource {
"vpc_id": &schema.Schema{ "vpc_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"vpc": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
"acl_id": aclidSchema, "acl_id": aclidSchema,
"aclid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Deprecated: "Please use the `acl_id` field instead",
},
"project": &schema.Schema{ "project": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -167,31 +152,12 @@ func resourceCloudStackNetworkCreate(d *schema.ResourceData, meta interface{}) e
} }
// Check is this network needs to be created in a VPC // Check is this network needs to be created in a VPC
vpc, ok := d.GetOk("vpc_id") if vpcid, ok := d.GetOk("vpc_id"); ok {
if !ok { // Set the vpc id
vpc, ok = d.GetOk("vpc") p.SetVpcid(vpcid.(string))
}
if ok {
// Retrieve the vpc ID
vpcid, e := retrieveID(
cs,
"vpc",
vpc.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// Set the vpcid
p.SetVpcid(vpcid)
// Since we're in a VPC, check if we want to assiciate an ACL list // Since we're in a VPC, check if we want to assiciate an ACL list
aclid, ok := d.GetOk("acl_id") if aclid, ok := d.GetOk("acl_id"); ok && aclid.(string) != none {
if !ok {
aclid, ok = d.GetOk("acl")
}
if ok && aclid != none {
// Set the acl ID // Set the acl ID
p.SetAclid(aclid.(string)) p.SetAclid(aclid.(string))
} }
@ -241,19 +207,12 @@ func resourceCloudStackNetworkRead(d *schema.ResourceData, meta interface{}) err
d.Set("display_text", n.Displaytext) d.Set("display_text", n.Displaytext)
d.Set("cidr", n.Cidr) d.Set("cidr", n.Cidr)
d.Set("gateway", n.Gateway) d.Set("gateway", n.Gateway)
d.Set("vpc_id", n.Vpcid)
_, vpcID := d.GetOk("vpc_id") if n.Aclid == "" {
_, vpc := d.GetOk("vpc") n.Aclid = none
if vpcID || vpc {
d.Set("vpc_id", n.Vpcid)
// Since we're in a VPC, also update the ACL ID. If we don't
// have an ACL ID make sure we set the default value instead.
if n.Aclid == "" {
n.Aclid = none
}
d.Set("acl_id", n.Aclid)
} }
d.Set("acl_id", n.Aclid)
// Read the tags and store them in a map // Read the tags and store them in a map
tags := make(map[string]interface{}) tags := make(map[string]interface{})
@ -312,16 +271,8 @@ func resourceCloudStackNetworkUpdate(d *schema.ResourceData, meta interface{}) e
} }
// Replace the ACL if the ID has changed // Replace the ACL if the ID has changed
if d.HasChange("acl_id") || d.HasChange("acl") { if d.HasChange("acl_id") {
aclid, ok := d.GetOk("acl_id") p := cs.NetworkACL.NewReplaceNetworkACLListParams(d.Get("acl_id").(string))
if !ok {
aclid, ok = d.GetOk("acl")
}
if !ok {
return fmt.Errorf("Replacing the ACL requires a valid ACL ID")
}
p := cs.NetworkACL.NewReplaceNetworkACLListParams(aclid.(string))
p.SetNetworkid(d.Id()) p.SetNetworkid(d.Id())
_, err := cs.NetworkACL.ReplaceNetworkACLList(p) _, err := cs.NetworkACL.ReplaceNetworkACLList(p)

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -32,17 +31,9 @@ func resourceCloudStackNetworkACL() *schema.Resource {
"vpc_id": &schema.Schema{ "vpc_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"vpc": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
}, },
} }
} }
@ -52,22 +43,8 @@ func resourceCloudStackNetworkACLCreate(d *schema.ResourceData, meta interface{}
name := d.Get("name").(string) name := d.Get("name").(string)
vpc, ok := d.GetOk("vpc_id")
if !ok {
vpc, ok = d.GetOk("vpc")
}
if !ok {
return errors.New("Either `vpc_id` or [deprecated] `vpc` must be provided.")
}
// Retrieve the vpc ID
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
return e.Error()
}
// Create a new parameter struct // Create a new parameter struct
p := cs.NetworkACL.NewCreateNetworkACLListParams(name, vpcid) p := cs.NetworkACL.NewCreateNetworkACLListParams(name, d.Get("vpc_id").(string))
// Set the description // Set the description
if description, ok := d.GetOk("description"); ok { if description, ok := d.GetOk("description"); ok {
@ -90,22 +67,11 @@ func resourceCloudStackNetworkACLCreate(d *schema.ResourceData, meta interface{}
func resourceCloudStackNetworkACLRead(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackNetworkACLRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
vpc, ok := d.GetOk("vpc_id")
if !ok {
vpc, ok = d.GetOk("vpc")
}
if !ok {
return errors.New("Either `vpc_id` or [deprecated] `vpc` must be provided.")
}
// Retrieve the vpc ID
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
return e.Error()
}
// Get the network ACL list details // Get the network ACL list details
f, count, err := cs.NetworkACL.GetNetworkACLListByID(d.Id(), cloudstack.WithVPCID(vpcid)) f, count, err := cs.NetworkACL.GetNetworkACLListByID(
d.Id(),
cloudstack.WithVPCID(d.Get("vpc_id").(string)),
)
if err != nil { if err != nil {
if count == 0 { if count == 0 {
log.Printf( log.Printf(

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"strconv" "strconv"
"strings" "strings"
@ -22,18 +21,9 @@ func resourceCloudStackNetworkACLRule() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"acl_id": &schema.Schema{ "acl_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
ForceNew: true, ForceNew: true,
ConflictsWith: []string{"aclid"},
},
"aclid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `acl_id` field instead",
ConflictsWith: []string{"acl_id"},
}, },
"managed": &schema.Schema{ "managed": &schema.Schema{
@ -55,17 +45,11 @@ func resourceCloudStackNetworkACLRule() *schema.Resource {
"cidr_list": &schema.Schema{ "cidr_list": &schema.Schema{
Type: schema.TypeSet, Type: schema.TypeSet,
Optional: true, Required: true,
Elem: &schema.Schema{Type: schema.TypeString}, Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString, Set: schema.HashString,
}, },
"source_cidr": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Deprecated: "Please use the `cidr_list` field instead",
},
"protocol": &schema.Schema{ "protocol": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Required: true,
@ -119,16 +103,8 @@ func resourceCloudStackNetworkACLRuleCreate(d *schema.ResourceData, meta interfa
return err return err
} }
aclid, ok := d.GetOk("acl_id")
if !ok {
aclid, ok = d.GetOk("aclid")
}
if !ok {
return errors.New("Either `acl_id` or [deprecated] `aclid` must be provided.")
}
// We need to set this upfront in order to be able to save a partial state // We need to set this upfront in order to be able to save a partial state
d.SetId(aclid.(string)) d.SetId(d.Get("acl_id").(string))
// Create all rules that are configured // Create all rules that are configured
if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 { if nrs := d.Get("rule").(*schema.Set); nrs.Len() > 0 {
@ -148,11 +124,7 @@ func resourceCloudStackNetworkACLRuleCreate(d *schema.ResourceData, meta interfa
return resourceCloudStackNetworkACLRuleRead(d, meta) return resourceCloudStackNetworkACLRuleRead(d, meta)
} }
func createNetworkACLRules( func createNetworkACLRules(d *schema.ResourceData, meta interface{}, rules *schema.Set, nrs *schema.Set) error {
d *schema.ResourceData,
meta interface{},
rules *schema.Set,
nrs *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -188,10 +160,7 @@ func createNetworkACLRules(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func createNetworkACLRule( func createNetworkACLRule(d *schema.ResourceData, meta interface{}, rule map[string]interface{}) error {
d *schema.ResourceData,
meta interface{},
rule map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
uuids := rule["uuids"].(map[string]interface{}) uuids := rule["uuids"].(map[string]interface{})
@ -210,7 +179,11 @@ func createNetworkACLRule(
p.SetAction(rule["action"].(string)) p.SetAction(rule["action"].(string))
// Set the CIDR list // Set the CIDR list
p.SetCidrlist(retrieveCidrList(rule)) var cidrList []string
for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
cidrList = append(cidrList, cidr.(string))
}
p.SetCidrlist(cidrList)
// Set the traffic type // Set the traffic type
p.SetTraffictype(rule["traffic_type"].(string)) p.SetTraffictype(rule["traffic_type"].(string))
@ -333,13 +306,19 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["action"] = strings.ToLower(r.Action) rule["action"] = strings.ToLower(r.Action)
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
rule["icmp_type"] = r.Icmptype rule["icmp_type"] = r.Icmptype
rule["icmp_code"] = r.Icmpcode rule["icmp_code"] = r.Icmpcode
rule["traffic_type"] = strings.ToLower(r.Traffictype) rule["traffic_type"] = strings.ToLower(r.Traffictype)
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
rules.Add(rule) rules.Add(rule)
} }
@ -359,11 +338,17 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["action"] = strings.ToLower(r.Action) rule["action"] = strings.ToLower(r.Action)
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
rule["traffic_type"] = strings.ToLower(r.Traffictype) rule["traffic_type"] = strings.ToLower(r.Traffictype)
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
rules.Add(rule) rules.Add(rule)
} }
@ -391,11 +376,17 @@ func resourceCloudStackNetworkACLRuleRead(d *schema.ResourceData, meta interface
// Delete the known rule so only unknown rules remain in the ruleMap // Delete the known rule so only unknown rules remain in the ruleMap
delete(ruleMap, id.(string)) delete(ruleMap, id.(string))
// Create a set with all CIDR's
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(r.Cidrlist, ",") {
cidrs.Add(cidr)
}
// Update the values // Update the values
rule["action"] = strings.ToLower(r.Action) rule["action"] = strings.ToLower(r.Action)
rule["protocol"] = r.Protocol rule["protocol"] = r.Protocol
rule["traffic_type"] = strings.ToLower(r.Traffictype) rule["traffic_type"] = strings.ToLower(r.Traffictype)
setCidrList(rule, r.Cidrlist) rule["cidr_list"] = cidrs
ports.Add(port) ports.Add(port)
} }
@ -554,7 +545,7 @@ func deleteNetworkACLRule(
for k, id := range uuids { for k, id := range uuids {
// We don't care about the count here, so just continue // We don't care about the count here, so just continue
if k == "#" { if k == "%" {
continue continue
} }
@ -602,17 +593,6 @@ func verifyNetworkACLRuleParams(d *schema.ResourceData, rule map[string]interfac
return fmt.Errorf("Parameter action only accepts 'allow' or 'deny' as values") return fmt.Errorf("Parameter action only accepts 'allow' or 'deny' as values")
} }
cidrList := rule["cidr_list"].(*schema.Set)
sourceCidr := rule["source_cidr"].(string)
if cidrList.Len() == 0 && sourceCidr == "" {
return fmt.Errorf(
"Parameter cidr_list is a required parameter")
}
if cidrList.Len() > 0 && sourceCidr != "" {
return fmt.Errorf(
"Parameter source_cidr is deprecated and cannot be used together with cidr_list")
}
protocol := rule["protocol"].(string) protocol := rule["protocol"].(string)
switch protocol { switch protocol {
case "icmp": case "icmp":

View File

@ -23,31 +23,31 @@ func TestAccCloudStackNetworkACLRule_basic(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.#", "3"), "cloudstack_network_acl_rule.foo", "rule.#", "3"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.action", "allow"), "cloudstack_network_acl_rule.foo", "rule.2898748868.action", "allow"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.source_cidr", "172.16.100.0/24"), "cloudstack_network_acl_rule.foo", "rule.2898748868.cidr_list.2835005819", "172.16.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.protocol", "tcp"), "cloudstack_network_acl_rule.foo", "rule.2898748868.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.#", "2"), "cloudstack_network_acl_rule.foo", "rule.2898748868.ports.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.1889509032", "80"), "cloudstack_network_acl_rule.foo", "rule.2898748868.ports.1889509032", "80"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.3638101695", "443"), "cloudstack_network_acl_rule.foo", "rule.2898748868.ports.3638101695", "443"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.traffic_type", "ingress"), "cloudstack_network_acl_rule.foo", "rule.2898748868.traffic_type", "ingress"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.action", "allow"), "cloudstack_network_acl_rule.foo", "rule.1480917538.action", "allow"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.cidr_list.#", "1"), "cloudstack_network_acl_rule.foo", "rule.1480917538.cidr_list.#", "1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.cidr_list.3056857544", "172.18.100.0/24"), "cloudstack_network_acl_rule.foo", "rule.1480917538.cidr_list.3056857544", "172.18.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.icmp_code", "-1"), "cloudstack_network_acl_rule.foo", "rule.1480917538.icmp_code", "-1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.icmp_type", "-1"), "cloudstack_network_acl_rule.foo", "rule.1480917538.icmp_type", "-1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.traffic_type", "ingress"), "cloudstack_network_acl_rule.foo", "rule.1480917538.traffic_type", "ingress"),
), ),
}, },
}, },
@ -67,31 +67,31 @@ func TestAccCloudStackNetworkACLRule_update(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.#", "3"), "cloudstack_network_acl_rule.foo", "rule.#", "3"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.action", "allow"), "cloudstack_network_acl_rule.foo", "rule.2898748868.action", "allow"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.source_cidr", "172.16.100.0/24"), "cloudstack_network_acl_rule.foo", "rule.2898748868.cidr_list.2835005819", "172.16.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.protocol", "tcp"), "cloudstack_network_acl_rule.foo", "rule.2898748868.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.#", "2"), "cloudstack_network_acl_rule.foo", "rule.2898748868.ports.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.1889509032", "80"), "cloudstack_network_acl_rule.foo", "rule.2898748868.ports.1889509032", "80"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.3638101695", "443"), "cloudstack_network_acl_rule.foo", "rule.2898748868.ports.3638101695", "443"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.traffic_type", "ingress"), "cloudstack_network_acl_rule.foo", "rule.2898748868.traffic_type", "ingress"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.action", "allow"), "cloudstack_network_acl_rule.foo", "rule.1480917538.action", "allow"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.cidr_list.#", "1"), "cloudstack_network_acl_rule.foo", "rule.1480917538.cidr_list.#", "1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.cidr_list.3056857544", "172.18.100.0/24"), "cloudstack_network_acl_rule.foo", "rule.1480917538.cidr_list.3056857544", "172.18.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.icmp_code", "-1"), "cloudstack_network_acl_rule.foo", "rule.1480917538.icmp_code", "-1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.icmp_type", "-1"), "cloudstack_network_acl_rule.foo", "rule.1480917538.icmp_type", "-1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.4029966697.traffic_type", "ingress"), "cloudstack_network_acl_rule.foo", "rule.1480917538.traffic_type", "ingress"),
), ),
}, },
@ -102,47 +102,47 @@ func TestAccCloudStackNetworkACLRule_update(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.#", "4"), "cloudstack_network_acl_rule.foo", "rule.#", "4"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.action", "deny"), "cloudstack_network_acl_rule.foo", "rule.1724235854.action", "deny"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.source_cidr", "10.0.0.0/24"), "cloudstack_network_acl_rule.foo", "rule.1724235854.cidr_list.3482919157", "10.0.0.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.protocol", "tcp"), "cloudstack_network_acl_rule.foo", "rule.1724235854.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.ports.#", "2"), "cloudstack_network_acl_rule.foo", "rule.1724235854.ports.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.ports.1209010669", "1000-2000"), "cloudstack_network_acl_rule.foo", "rule.1724235854.ports.1209010669", "1000-2000"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.ports.1889509032", "80"), "cloudstack_network_acl_rule.foo", "rule.1724235854.ports.1889509032", "80"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2254982534.traffic_type", "egress"), "cloudstack_network_acl_rule.foo", "rule.1724235854.traffic_type", "egress"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.action", "deny"), "cloudstack_network_acl_rule.foo", "rule.2090315355.action", "deny"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.cidr_list.#", "2"), "cloudstack_network_acl_rule.foo", "rule.2090315355.cidr_list.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.cidr_list.2104435309", "172.18.101.0/24"), "cloudstack_network_acl_rule.foo", "rule.2090315355.cidr_list.2104435309", "172.18.101.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.cidr_list.3056857544", "172.18.100.0/24"), "cloudstack_network_acl_rule.foo", "rule.2090315355.cidr_list.3056857544", "172.18.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.icmp_code", "-1"), "cloudstack_network_acl_rule.foo", "rule.2090315355.icmp_code", "-1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.icmp_type", "-1"), "cloudstack_network_acl_rule.foo", "rule.2090315355.icmp_type", "-1"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2704020556.traffic_type", "ingress"), "cloudstack_network_acl_rule.foo", "rule.2090315355.traffic_type", "ingress"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.action", "allow"), "cloudstack_network_acl_rule.foo", "rule.2576683033.action", "allow"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.source_cidr", "172.16.100.0/24"), "cloudstack_network_acl_rule.foo", "rule.2576683033.cidr_list.3056857544", "172.18.100.0/24"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.protocol", "tcp"), "cloudstack_network_acl_rule.foo", "rule.2576683033.protocol", "tcp"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.#", "2"), "cloudstack_network_acl_rule.foo", "rule.2576683033.ports.#", "2"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.1889509032", "80"), "cloudstack_network_acl_rule.foo", "rule.2576683033.ports.1889509032", "80"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.ports.3638101695", "443"), "cloudstack_network_acl_rule.foo", "rule.2576683033.ports.3638101695", "443"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"cloudstack_network_acl_rule.foo", "rule.2792403380.traffic_type", "ingress"), "cloudstack_network_acl_rule.foo", "rule.2576683033.traffic_type", "ingress"),
), ),
}, },
}, },
@ -161,7 +161,7 @@ func testAccCheckCloudStackNetworkACLRulesExist(n string) resource.TestCheckFunc
} }
for k, id := range rs.Primary.Attributes { for k, id := range rs.Primary.Attributes {
if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.#") { if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.%") {
continue continue
} }
@ -194,7 +194,7 @@ func testAccCheckCloudStackNetworkACLRuleDestroy(s *terraform.State) error {
} }
for k, id := range rs.Primary.Attributes { for k, id := range rs.Primary.Attributes {
if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.#") { if !strings.Contains(k, ".uuids.") || strings.HasSuffix(k, ".uuids.%") {
continue continue
} }
@ -227,7 +227,7 @@ resource "cloudstack_network_acl_rule" "foo" {
rule { rule {
action = "allow" action = "allow"
source_cidr = "172.18.100.0/24" cidr_list = ["172.18.100.0/24"]
protocol = "all" protocol = "all"
traffic_type = "ingress" traffic_type = "ingress"
} }
@ -242,7 +242,7 @@ resource "cloudstack_network_acl_rule" "foo" {
} }
rule { rule {
source_cidr = "172.16.100.0/24" cidr_list = ["172.16.100.0/24"]
protocol = "tcp" protocol = "tcp"
ports = ["80", "443"] ports = ["80", "443"]
traffic_type = "ingress" traffic_type = "ingress"
@ -271,7 +271,7 @@ resource "cloudstack_network_acl_rule" "foo" {
rule { rule {
action = "deny" action = "deny"
source_cidr = "172.18.100.0/24" cidr_list = ["172.18.100.0/24"]
protocol = "all" protocol = "all"
traffic_type = "ingress" traffic_type = "ingress"
} }
@ -287,7 +287,7 @@ resource "cloudstack_network_acl_rule" "foo" {
rule { rule {
action = "allow" action = "allow"
source_cidr = "172.16.100.0/24" cidr_list = ["172.18.100.0/24"]
protocol = "tcp" protocol = "tcp"
ports = ["80", "443"] ports = ["80", "443"]
traffic_type = "ingress" traffic_type = "ingress"
@ -295,7 +295,7 @@ resource "cloudstack_network_acl_rule" "foo" {
rule { rule {
action = "deny" action = "deny"
source_cidr = "10.0.0.0/24" cidr_list = ["10.0.0.0/24"]
protocol = "tcp" protocol = "tcp"
ports = ["80", "1000-2000"] ports = ["80", "1000-2000"]
traffic_type = "egress" traffic_type = "egress"

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -19,18 +18,10 @@ func resourceCloudStackNIC() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"network_id": &schema.Schema{ "network_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"network": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `network_id` field instead",
},
"ip_address": &schema.Schema{ "ip_address": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -38,26 +29,11 @@ func resourceCloudStackNIC() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
},
"virtual_machine_id": &schema.Schema{ "virtual_machine_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"virtual_machine": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `virtual_machine_id` field instead",
},
}, },
} }
} }
@ -65,44 +41,14 @@ func resourceCloudStackNIC() *schema.Resource {
func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
network, ok := d.GetOk("network_id")
if !ok {
network, ok = d.GetOk("network")
}
if !ok {
return errors.New("Either `network_id` or [deprecated] `network` must be provided.")
}
// Retrieve the network ID
networkid, e := retrieveID(cs, "network", network.(string))
if e != nil {
return e.Error()
}
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
// Create a new parameter struct // Create a new parameter struct
p := cs.VirtualMachine.NewAddNicToVirtualMachineParams(networkid, virtualmachineid) p := cs.VirtualMachine.NewAddNicToVirtualMachineParams(
d.Get("network_id").(string),
d.Get("virtual_machine_id").(string),
)
// If there is a ipaddres supplied, add it to the parameter struct // If there is a ipaddres supplied, add it to the parameter struct
ipaddress, ok := d.GetOk("ip_address") if ipaddress, ok := d.GetOk("ip_address"); ok {
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if ok {
p.SetIpaddress(ipaddress.(string)) p.SetIpaddress(ipaddress.(string))
} }
@ -114,7 +60,7 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error
found := false found := false
for _, n := range r.Nic { for _, n := range r.Nic {
if n.Networkid == networkid { if n.Networkid == d.Get("network_id").(string) {
d.SetId(n.Id) d.SetId(n.Id)
found = true found = true
break break
@ -122,7 +68,7 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error
} }
if !found { if !found {
return fmt.Errorf("Could not find NIC ID for network ID: %s", networkid) return fmt.Errorf("Could not find NIC ID for network ID: %s", d.Get("network_id").(string))
} }
return resourceCloudStackNICRead(d, meta) return resourceCloudStackNICRead(d, meta)
@ -131,26 +77,11 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error
func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
// Get the virtual machine details // Get the virtual machine details
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid) vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(d.Get("virtual_machine_id").(string))
if err != nil { if err != nil {
if count == 0 { if count == 0 {
log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine").(string)) log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine_id").(string))
d.SetId("") d.SetId("")
return nil return nil
} }
@ -181,23 +112,11 @@ func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error {
func resourceCloudStackNICDelete(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackNICDelete(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
// Create a new parameter struct // Create a new parameter struct
p := cs.VirtualMachine.NewRemoveNicFromVirtualMachineParams(d.Id(), virtualmachineid) p := cs.VirtualMachine.NewRemoveNicFromVirtualMachineParams(
d.Id(),
d.Get("virtual_machine_id").(string),
)
// Remove the NIC // Remove the NIC
_, err := cs.VirtualMachine.RemoveNicFromVirtualMachine(p) _, err := cs.VirtualMachine.RemoveNicFromVirtualMachine(p)

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"sync" "sync"
"time" "time"
@ -23,18 +22,9 @@ func resourceCloudStackPortForward() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"ip_address_id": &schema.Schema{ "ip_address_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
ForceNew: true, ForceNew: true,
ConflictsWith: []string{"ipaddress"},
},
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address_id` field instead",
ConflictsWith: []string{"ip_address_id"},
}, },
"managed": &schema.Schema{ "managed": &schema.Schema{
@ -71,13 +61,7 @@ func resourceCloudStackPortForward() *schema.Resource {
"virtual_machine_id": &schema.Schema{ "virtual_machine_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
},
"virtual_machine": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Deprecated: "Please use the `virtual_machine_id` field instead",
}, },
"uuid": &schema.Schema{ "uuid": &schema.Schema{
@ -92,29 +76,8 @@ func resourceCloudStackPortForward() *schema.Resource {
} }
func resourceCloudStackPortForwardCreate(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackPortForwardCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient)
ipaddress, ok := d.GetOk("ip_address_id")
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if !ok {
return errors.New("Either `ip_address_id` or [deprecated] `ipaddress` must be provided.")
}
// Retrieve the ipaddress ID
ipaddressid, e := retrieveID(
cs,
"ip_address",
ipaddress.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
// We need to set this upfront in order to be able to save a partial state // We need to set this upfront in order to be able to save a partial state
d.SetId(ipaddressid) d.SetId(d.Get("ip_address_id").(string))
// Create all forwards that are configured // Create all forwards that are configured
if nrs := d.Get("forward").(*schema.Set); nrs.Len() > 0 { if nrs := d.Get("forward").(*schema.Set); nrs.Len() > 0 {
@ -134,11 +97,7 @@ func resourceCloudStackPortForwardCreate(d *schema.ResourceData, meta interface{
return resourceCloudStackPortForwardRead(d, meta) return resourceCloudStackPortForwardRead(d, meta)
} }
func createPortForwards( func createPortForwards(d *schema.ResourceData, meta interface{}, forwards *schema.Set, nrs *schema.Set) error {
d *schema.ResourceData,
meta interface{},
forwards *schema.Set,
nrs *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -173,10 +132,8 @@ func createPortForwards(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func createPortForward(
d *schema.ResourceData, func createPortForward(d *schema.ResourceData, meta interface{}, forward map[string]interface{}) error {
meta interface{},
forward map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
// Make sure all required parameters are there // Make sure all required parameters are there
@ -184,28 +141,8 @@ func createPortForward(
return err return err
} }
virtualmachine, ok := forward["virtual_machine_id"]
if !ok {
virtualmachine, ok = forward["virtual_machine"]
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(
cs,
"virtual_machine",
virtualmachine.(string),
cloudstack.WithProject(d.Get("project").(string)),
)
if e != nil {
return e.Error()
}
vm, _, err := cs.VirtualMachine.GetVirtualMachineByID( vm, _, err := cs.VirtualMachine.GetVirtualMachineByID(
virtualmachineid, forward["virtual_machine_id"].(string),
cloudstack.WithProject(d.Get("project").(string)), cloudstack.WithProject(d.Get("project").(string)),
) )
if err != nil { if err != nil {
@ -387,11 +324,7 @@ func resourceCloudStackPortForwardDelete(d *schema.ResourceData, meta interface{
return nil return nil
} }
func deletePortForwards( func deletePortForwards(d *schema.ResourceData, meta interface{}, forwards *schema.Set, ors *schema.Set) error {
d *schema.ResourceData,
meta interface{},
forwards *schema.Set,
ors *schema.Set) error {
var errs *multierror.Error var errs *multierror.Error
var wg sync.WaitGroup var wg sync.WaitGroup
@ -427,10 +360,7 @@ func deletePortForwards(
return errs.ErrorOrNil() return errs.ErrorOrNil()
} }
func deletePortForward( func deletePortForward(d *schema.ResourceData, meta interface{}, forward map[string]interface{}) error {
d *schema.ResourceData,
meta interface{},
forward map[string]interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
// Create the parameter struct // Create the parameter struct

View File

@ -124,7 +124,7 @@ var testAccCloudStackPortForward_basic = fmt.Sprintf(`
resource "cloudstack_instance" "foobar" { resource "cloudstack_instance" "foobar" {
name = "terraform-test" name = "terraform-test"
service_offering= "%s" service_offering= "%s"
network = "%s" network_id = "%s"
template = "%s" template = "%s"
zone = "%s" zone = "%s"
expunge = true expunge = true
@ -150,7 +150,7 @@ var testAccCloudStackPortForward_update = fmt.Sprintf(`
resource "cloudstack_instance" "foobar" { resource "cloudstack_instance" "foobar" {
name = "terraform-test" name = "terraform-test"
service_offering= "%s" service_offering= "%s"
network = "%s" network_id = "%s"
template = "%s" template = "%s"
zone = "%s" zone = "%s"
expunge = true expunge = true

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -24,13 +23,6 @@ func resourceCloudStackSecondaryIPAddress() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
"ipaddress": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `ip_address` field instead",
},
"nic_id": &schema.Schema{ "nic_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Optional: true,
@ -38,26 +30,11 @@ func resourceCloudStackSecondaryIPAddress() *schema.Resource {
ForceNew: true, ForceNew: true,
}, },
"nicid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `nic_id` field instead",
},
"virtual_machine_id": &schema.Schema{ "virtual_machine_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"virtual_machine": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `virtual_machine_id` field instead",
},
}, },
} }
} }
@ -67,23 +44,7 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int
nicid, ok := d.GetOk("nic_id") nicid, ok := d.GetOk("nic_id")
if !ok { if !ok {
nicid, ok = d.GetOk("nicid") virtualmachineid := d.Get("virtual_machine_id").(string)
}
if !ok {
virtualmachine, ok := d.GetOk("virtual_machine_id")
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
// Get the virtual machine details // Get the virtual machine details
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid) vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid)
@ -103,11 +64,7 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int
p := cs.Nic.NewAddIpToNicParams(nicid.(string)) p := cs.Nic.NewAddIpToNicParams(nicid.(string))
// If there is a ipaddres supplied, add it to the parameter struct // If there is a ipaddres supplied, add it to the parameter struct
ipaddress, ok := d.GetOk("ip_address") if ipaddress, ok := d.GetOk("ip_address"); ok {
if !ok {
ipaddress, ok = d.GetOk("ipaddress")
}
if ok {
p.SetIpaddress(ipaddress.(string)) p.SetIpaddress(ipaddress.(string))
} }
@ -124,20 +81,7 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int
func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
virtualmachine, ok := d.GetOk("virtual_machine_id") virtualmachineid := d.Get("virtual_machine_id").(string)
if !ok {
virtualmachine, ok = d.GetOk("virtual_machine")
}
if !ok {
return errors.New(
"Either `virtual_machine_id` or [deprecated] `virtual_machine` must be provided.")
}
// Retrieve the virtual_machine ID
virtualmachineid, e := retrieveID(cs, "virtual_machine", virtualmachine.(string))
if e != nil {
return e.Error()
}
// Get the virtual machine details // Get the virtual machine details
vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid) vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid)
@ -151,9 +95,6 @@ func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta inter
} }
nicid, ok := d.GetOk("nic_id") nicid, ok := d.GetOk("nic_id")
if !ok {
nicid, ok = d.GetOk("nicid")
}
if !ok { if !ok {
nicid = vm.Nic[0].Id nicid = vm.Nic[0].Id
} }
@ -167,7 +108,7 @@ func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta inter
} }
if l.Count == 0 { if l.Count == 0 {
log.Printf("[DEBUG] NIC %s does no longer exist", d.Get("nicid").(string)) log.Printf("[DEBUG] NIC %s does no longer exist", d.Get("nic_id").(string))
d.SetId("") d.SetId("")
return nil return nil
} }

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -19,31 +18,15 @@ func resourceCloudStackVPNConnection() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"customer_gateway_id": &schema.Schema{ "customer_gateway_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"customergatewayid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `customer_gateway_id` field instead",
},
"vpn_gateway_id": &schema.Schema{ "vpn_gateway_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"vpngatewayid": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpn_gateway_id` field instead",
},
}, },
} }
} }
@ -51,27 +34,10 @@ func resourceCloudStackVPNConnection() *schema.Resource {
func resourceCloudStackVPNConnectionCreate(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackVPNConnectionCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
customergatewayid, ok := d.GetOk("customer_gateway_id")
if !ok {
customergatewayid, ok = d.GetOk("customergatewayid")
}
if !ok {
return errors.New(
"Either `customer_gateway_id` or [deprecated] `customergatewayid` must be provided.")
}
vpngatewayid, ok := d.GetOk("vpn_gateway_id")
if !ok {
vpngatewayid, ok = d.GetOk("vpngatewayid")
}
if !ok {
return errors.New("Either `vpn_gateway_id` or [deprecated] `vpngatewayid` must be provided.")
}
// Create a new parameter struct // Create a new parameter struct
p := cs.VPN.NewCreateVpnConnectionParams( p := cs.VPN.NewCreateVpnConnectionParams(
customergatewayid.(string), d.Get("customer_gateway_id").(string),
vpngatewayid.(string), d.Get("vpn_gateway_id").(string),
) )
// Create the new VPN Connection // Create the new VPN Connection

View File

@ -1,7 +1,6 @@
package cloudstack package cloudstack
import ( import (
"errors"
"fmt" "fmt"
"log" "log"
"strings" "strings"
@ -19,18 +18,10 @@ func resourceCloudStackVPNGateway() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"vpc_id": &schema.Schema{ "vpc_id": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Optional: true, Required: true,
Computed: true,
ForceNew: true, ForceNew: true,
}, },
"vpc": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Deprecated: "Please use the `vpc_id` field instead",
},
"public_ip": &schema.Schema{ "public_ip": &schema.Schema{
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
@ -42,21 +33,7 @@ func resourceCloudStackVPNGateway() *schema.Resource {
func resourceCloudStackVPNGatewayCreate(d *schema.ResourceData, meta interface{}) error { func resourceCloudStackVPNGatewayCreate(d *schema.ResourceData, meta interface{}) error {
cs := meta.(*cloudstack.CloudStackClient) cs := meta.(*cloudstack.CloudStackClient)
vpc, ok := d.GetOk("vpc_id") vpcid := d.Get("vpc_id").(string)
if !ok {
vpc, ok = d.GetOk("vpc")
}
if !ok {
return errors.New("Either `vpc_id` or [deprecated] `vpc` must be provided.")
}
// Retrieve the VPC ID
vpcid, e := retrieveID(cs, "vpc", vpc.(string))
if e != nil {
return e.Error()
}
// Create a new parameter struct
p := cs.VPN.NewCreateVpnGatewayParams(vpcid) p := cs.VPN.NewCreateVpnGatewayParams(vpcid)
// Create the new VPN Gateway // Create the new VPN Gateway

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"log" "log"
"regexp" "regexp"
"strings"
"time" "time"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
@ -38,11 +37,7 @@ func setValueOrID(d *schema.ResourceData, key string, value string, id string) {
} }
} }
func retrieveID( func retrieveID(cs *cloudstack.CloudStackClient, name string, value string, opts ...cloudstack.OptionFunc) (id string, e *retrieveError) {
cs *cloudstack.CloudStackClient,
name string,
value string,
opts ...cloudstack.OptionFunc) (id string, e *retrieveError) {
// If the supplied value isn't a ID, try to retrieve the ID ourselves // If the supplied value isn't a ID, try to retrieve the ID ourselves
if cloudstack.IsID(value) { if cloudstack.IsID(value) {
return value, nil return value, nil
@ -54,8 +49,6 @@ func retrieveID(
switch name { switch name {
case "disk_offering": case "disk_offering":
id, err = cs.DiskOffering.GetDiskOfferingID(value) id, err = cs.DiskOffering.GetDiskOfferingID(value)
case "virtual_machine":
id, err = cs.VirtualMachine.GetVirtualMachineID(value, opts...)
case "service_offering": case "service_offering":
id, err = cs.ServiceOffering.GetServiceOfferingID(value) id, err = cs.ServiceOffering.GetServiceOfferingID(value)
case "network_offering": case "network_offering":
@ -64,31 +57,8 @@ func retrieveID(
id, err = cs.Project.GetProjectID(value) id, err = cs.Project.GetProjectID(value)
case "vpc_offering": case "vpc_offering":
id, err = cs.VPC.GetVPCOfferingID(value) id, err = cs.VPC.GetVPCOfferingID(value)
case "vpc":
id, err = cs.VPC.GetVPCID(value, opts...)
case "network":
id, err = cs.Network.GetNetworkID(value, opts...)
case "zone": case "zone":
id, err = cs.Zone.GetZoneID(value) id, err = cs.Zone.GetZoneID(value)
case "ip_address":
p := cs.Address.NewListPublicIpAddressesParams()
p.SetIpaddress(value)
for _, fn := range opts {
if e := fn(cs, p); e != nil {
err = e
break
}
}
l, e := cs.Address.ListPublicIpAddresses(p)
if e != nil {
err = e
break
}
if l.Count == 1 {
id = l.PublicIpAddresses[0].Id
break
}
err = fmt.Errorf("Could not find ID of IP address: %s", value)
case "os_type": case "os_type":
p := cs.GuestOS.NewListOsTypesParams() p := cs.GuestOS.NewListOsTypesParams()
p.SetDescription(value) p.SetDescription(value)
@ -151,39 +121,6 @@ func Retry(n int, f RetryFunc) (interface{}, error) {
return nil, lastErr return nil, lastErr
} }
// This is a temporary helper function to support both the new
// cidr_list and the deprecated source_cidr parameter
func retrieveCidrList(rule map[string]interface{}) []string {
sourceCidr := rule["source_cidr"].(string)
if sourceCidr != "" {
return []string{sourceCidr}
}
var cidrList []string
for _, cidr := range rule["cidr_list"].(*schema.Set).List() {
cidrList = append(cidrList, cidr.(string))
}
return cidrList
}
// This is a temporary helper function to support both the new
// cidr_list and the deprecated source_cidr parameter
func setCidrList(rule map[string]interface{}, cidrList string) {
sourceCidr := rule["source_cidr"].(string)
if sourceCidr != "" {
rule["source_cidr"] = cidrList
return
}
cidrs := &schema.Set{F: schema.HashString}
for _, cidr := range strings.Split(cidrList, ",") {
cidrs.Add(cidr)
}
rule["cidr_list"] = cidrs
}
// If there is a project supplied, we retrieve and set the project id // If there is a project supplied, we retrieve and set the project id
func setProjectid(p cloudstack.ProjectIDSetter, cs *cloudstack.CloudStackClient, d *schema.ResourceData) error { func setProjectid(p cloudstack.ProjectIDSetter, cs *cloudstack.CloudStackClient, d *schema.ResourceData) error {
if project, ok := d.GetOk("project"); ok { if project, ok := d.GetOk("project"); ok {

View File

@ -44,8 +44,8 @@ The following arguments are supported:
* `shrink_ok` - (Optional) Verifies if the disk volume is allowed to shrink when * `shrink_ok` - (Optional) Verifies if the disk volume is allowed to shrink when
resizing (defaults false). resizing (defaults false).
* `virtual_machine` - (Optional) The name or ID of the virtual machine to which you * `virtual_machine_id` - (Optional) The ID of the virtual machine to which you want
want to attach the disk volume. to attach the disk volume.
* `project` - (Optional) The name or ID of the project to deploy this * `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created. instance to. Changing this forces a new resource to be created.

View File

@ -31,9 +31,6 @@ The following arguments are supported:
* `network_id` - (Required) The network ID for which to create the egress * `network_id` - (Required) The network ID for which to create the egress
firewall rules. Changing this forces a new resource to be created. firewall rules. Changing this forces a new resource to be created.
* `network` - (Required, Deprecated) 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 * `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 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) delete all firewall rules that are not in your config! (defaults false)
@ -48,9 +45,6 @@ The `rule` block supports:
* `cidr_list` - (Required) A CIDR list to allow access to the given ports. * `cidr_list` - (Required) A CIDR list to allow access to the given ports.
* `source_cidr` - (Optional, Deprecated) The source CIDR to allow access to the
given ports. This attribute is deprecated, please use `cidr_list` instead.
* `protocol` - (Required) The name of the protocol to allow. Valid options are: * `protocol` - (Required) The name of the protocol to allow. Valid options are:
`tcp`, `udp` and `icmp`. `tcp`, `udp` and `icmp`.

View File

@ -31,9 +31,6 @@ The following arguments are supported:
* `ip_address_id` - (Required) The IP address ID for which to create the * `ip_address_id` - (Required) The IP address ID for which to create the
firewall rules. Changing this forces a new resource to be created. firewall rules. Changing this forces a new resource to be created.
* `ipaddress` - (Required, Deprecated) The IP address or ID for which to create
the firewall rules. Changing this forces a new resource to be created.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the firewall rules for * `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 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) all firewall rules that are not in your config! (defaults false)
@ -48,9 +45,6 @@ The `rule` block supports:
* `cidr_list` - (Required) A CIDR list to allow access to the given ports. * `cidr_list` - (Required) A CIDR list to allow access to the given ports.
* `source_cidr` - (Optional, Deprecated) The source CIDR to allow access to the
given ports. This attribute is deprecated, please use `cidr_list` instead.
* `protocol` - (Required) The name of the protocol to allow. Valid options are: * `protocol` - (Required) The name of the protocol to allow. Valid options are:
`tcp`, `udp` and `icmp`. `tcp`, `udp` and `icmp`.

View File

@ -31,26 +31,36 @@ The following arguments are supported:
* `display_name` - (Optional) The display name of the instance. * `display_name` - (Optional) The display name of the instance.
* `group` - (Optional) The group name of the instance.
* `service_offering` - (Required) The name or ID of the service offering used * `service_offering` - (Required) The name or ID of the service offering used
for this instance. for this instance.
* `network_id` - (Optional) The ID of the network to connect this instance * `network_id` - (Optional) The ID of the network to connect this instance
to. Changing this forces a new resource to be created. to. Changing this forces a new resource to be created.
* `network` - (Optional, Deprecated) The name or ID of the network to connect
this instance to. Changing this forces a new resource to be created.
* `ip_address` - (Optional) The IP address to assign to this instance. Changing * `ip_address` - (Optional) The IP address to assign to this instance. Changing
this forces a new resource to be created. this forces a new resource to be created.
* `ipaddress` - (Optional, Deprecated) The IP address to assign to this instance.
Changing this forces a new resource to be created.
* `template` - (Required) The name or ID of the template used for this * `template` - (Required) The name or ID of the template used for this
instance. Changing this forces a new resource to be created. instance. Changing this forces a new resource to be created.
* `root_disk_size` - (Optional) The size of the root disk in gigabytes. The
root disk is resized on deploy. Only applies to template-based deployments.
Changing this forces a new resource to be created.
* `group` - (Optional) The group name of the instance.
* `affinity_group_ids` - (Optional) List of affinity group IDs to apply to this
instance.
* `affinity_group_names` - (Optional) List of affinity group names to apply to
this instance.
* `security_group_ids` - (Optional) List of security group IDs to apply to this
instance. Changing this forces a new resource to be created.
* `security_group_names` - (Optional) List of security group names to apply to
this instance. Changing this forces a new resource to be created.
* `project` - (Optional) The name or ID of the project to deploy this * `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created. instance to. Changing this forces a new resource to be created.
@ -66,22 +76,10 @@ The following arguments are supported:
* `expunge` - (Optional) This determines if the instance is expunged when it is * `expunge` - (Optional) This determines if the instance is expunged when it is
destroyed (defaults false) destroyed (defaults false)
* `root_disk_size` - (Optional) The size of the root disk in
gigabytes. The root disk is resized on deploy. Only applies to
template-based deployments.
* `affinity_group_names` - (Optional) List of affinity groups to apply to this
instance. Changing this forces a new resource to be created.
* `security_group_ids` - (Optional) List of security groups id to apply to this
isnstance. Changing this forces a new resource to be created.
* `security_group_names` - (Optional) List of security groups to apply to this
isnstance. Changing this forces a new resource to be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:
* `id` - The instance ID. * `id` - The instance ID.
* `display_name` - The display name of the instance. * `display_name` - The display name of the instance.

View File

@ -25,17 +25,9 @@ The following arguments are supported:
* `network_id` - (Optional) The ID of the network for which an IP address should * `network_id` - (Optional) The ID of the network for which an IP address should
be acquired and associated. Changing this forces a new resource to be created. be acquired and associated. Changing this forces a new resource to be created.
* `network` - (Optional, Deprecated) The name or ID of the network for which an IP
addess should be acquired and associated. Changing this forces a new resource
to be created.
* `vpc_id` - (Optional) The ID of the VPC for which an IP address should be * `vpc_id` - (Optional) The ID of the VPC for which an IP address should be
acquired and associated. Changing this forces a new resource to be created. acquired and associated. Changing this forces a new resource to be created.
* `vpc` - (Optional, Deprecated) The name or ID of the VPC for which an IP address
should be acquired and associated. Changing this forces a new resource to be
created.
* `project` - (Optional) The name or ID of the project to deploy this * `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created. instance to. Changing this forces a new resource to be created.

View File

@ -37,18 +37,10 @@ The following arguments are supported:
traffic will be load balanced from. Changing this forces a new resource traffic will be load balanced from. Changing this forces a new resource
to be created. to be created.
* `ipaddress` - (Required, Deprecated) Public IP address from where the
network traffic will be load balanced from. Changing this forces a new
resource to be created.
* `network_id` - (Optional) The network ID this rule will be created for. * `network_id` - (Optional) The network ID this rule will be created for.
Required when public IP address is not associated with any network yet Required when public IP address is not associated with any network yet
(VPC case). (VPC case).
* `network` - (Optional, Deprecated) The network this rule will be created
for. Required when public IP address is not associated with any network
yet (VPC case).
* `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin, * `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin,
leastconn). Changing this forces a new resource to be created. leastconn). Changing this forces a new resource to be created.
@ -63,9 +55,6 @@ The following arguments are supported:
* `member_ids` - (Required) List of instance IDs to assign to the load balancer * `member_ids` - (Required) List of instance IDs to assign to the load balancer
rule. Changing this forces a new resource to be created. rule. Changing this forces a new resource to be created.
* `members` - (Required, Deprecated) List of instances to assign to the load
balancer rule. Changing this forces a new resource to be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:

View File

@ -50,19 +50,13 @@ The following arguments are supported:
required by the Network Offering if specifyVlan=true is set. Only the ROOT required by the Network Offering if specifyVlan=true is set. Only the ROOT
admin can set this value. admin can set this value.
* `vpc_id` - (Optional) The ID of the VPC to create this network for. Changing * `vpc_id` - (Optional) The VPC ID in which to create this network. Changing
this forces a new resource to be created. this forces a new resource to be created.
* `vpc` - (Optional, Deprecated) The name or ID of the VPC to create this network
for. Changing this forces a new resource to be created.
* `acl_id` - (Optional) The ACL ID that should be attached to the network or * `acl_id` - (Optional) The ACL ID that should be attached to the network or
`none` if you do not want to attach an ACL. You can dynamically attach and `none` if you do not want to attach an ACL. You can dynamically attach and
swap ACL's, but if you want to detach an attached ACL and revert to using swap ACL's, but if you want to detach an attached ACL and revert to using
`none`, this will force a new resource to be created. Defaults to `none`. `none`, this will force a new resource to be created. (defaults `none`)
* `aclid` - (Optional, Deprecated) The ID of a ACL that should be attached
to the network.
* `project` - (Optional) The name or ID of the project to deploy this * `project` - (Optional) The name or ID of the project to deploy this
instance to. Changing this forces a new resource to be created. instance to. Changing this forces a new resource to be created.

View File

@ -32,9 +32,6 @@ The following arguments are supported:
* `vpc_id` - (Required) The ID of the VPC to create this ACL for. Changing this * `vpc_id` - (Required) The ID of the VPC to create this ACL for. Changing this
forces a new resource to be created. forces a new resource to be created.
* `vpc` - (Required, Deprecated) The name or ID of the VPC to create this ACL
for. Changing this forces a new resource to be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:

View File

@ -33,9 +33,6 @@ The following arguments are supported:
* `acl_id` - (Required) The network ACL ID for which to create the rules. * `acl_id` - (Required) The network ACL ID for which to create the rules.
Changing this forces a new resource to be created. Changing this forces a new resource to be created.
* `aclid` - (Required, Deprecated) The network ACL ID for which to create
the rules. Changing this forces a new resource to be created.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the firewall rules for * `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 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) all firewall rules that are not in your config! (defaults false)
@ -53,17 +50,14 @@ The `rule` block supports:
* `cidr_list` - (Required) A CIDR list to allow access to the given ports. * `cidr_list` - (Required) A CIDR list to allow access to the given ports.
* `source_cidr` - (Optional, Deprecated) The source CIDR to allow access to the
given ports. This attribute is deprecated, please use `cidr_list` instead.
* `protocol` - (Required) The name of the protocol to allow. Valid options are: * `protocol` - (Required) The name of the protocol to allow. Valid options are:
`tcp`, `udp`, `icmp`, `all` or a valid protocol number. `tcp`, `udp`, `icmp`, `all` or a valid protocol number.
* `icmp_type` - (Optional) The ICMP type to allow. This can only be specified if * `icmp_type` - (Optional) The ICMP type to allow, or `-1` to allow `any`. This
the protocol is ICMP. can only be specified if the protocol is ICMP. (defaults 0)
* `icmp_code` - (Optional) The ICMP code to allow. This can only be specified if * `icmp_code` - (Optional) The ICMP code to allow, or `-1` to allow `any`. This
the protocol is ICMP. can only be specified if the protocol is ICMP. (defaults 0)
* `ports` - (Optional) List of ports and/or port ranges to allow. This can only * `ports` - (Optional) List of ports and/or port ranges to allow. This can only
be specified if the protocol is TCP, UDP, ALL or a valid protocol number. be specified if the protocol is TCP, UDP, ALL or a valid protocol number.

View File

@ -29,22 +29,12 @@ The following arguments are supported:
* `network_id` - (Required) The ID of the network to plug the NIC into. Changing * `network_id` - (Required) The ID of the network to plug the NIC into. Changing
this forces a new resource to be created. this forces a new resource to be created.
* `network` - (Required, Deprecated) The name or ID of the network to plug the
NIC into. Changing this forces a new resource to be created.
* `ip_address` - (Optional) The IP address to assign to the NIC. Changing this * `ip_address` - (Optional) The IP address to assign to the NIC. Changing this
forces a new resource to be created. forces a new resource to be created.
* `ipaddress` - (Optional, Deprecated) The IP address to assign to the NIC.
Changing this forces a new resource to be created.
* `virtual_machine_id` - (Required) The ID of the virtual machine to which to * `virtual_machine_id` - (Required) The ID of the virtual machine to which to
attach the NIC. Changing this forces a new resource to be created. attach the NIC. Changing this forces a new resource to be created.
* `virtual_machine` - (Required, Deprecated) The name or ID of the virtual
machine to which to attach the NIC. Changing this forces a new resource to
be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:

View File

@ -32,9 +32,6 @@ The following arguments are supported:
* `ip_address_id` - (Required) The IP address ID for which to create the port * `ip_address_id` - (Required) The IP address ID for which to create the port
forwards. Changing this forces a new resource to be created. forwards. Changing this forces a new resource to be created.
* `ipaddress` - (Required, Deprecated) The IP address for which to create the port
forwards. Changing this forces a new resource to be created.
* `managed` - (Optional) USE WITH CAUTION! If enabled all the port forwards for * `managed` - (Optional) USE WITH CAUTION! If enabled all the port forwards for
this IP address will be managed by this resource. This means it will delete this IP address will be managed by this resource. This means it will delete
all port forwards that are not in your config! (defaults false) all port forwards that are not in your config! (defaults false)
@ -53,11 +50,9 @@ The `forward` block supports:
* `virtual_machine_id` - (Required) The ID of the virtual machine to forward to. * `virtual_machine_id` - (Required) The ID of the virtual machine to forward to.
* `virtual_machine` - (Required, Deprecated) The name or ID of the virtual
machine to forward to.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:
* `ip_address` - The IP address for which the port forwards are created. * `id` - The ID of the IP address for which the port forwards are created.

View File

@ -22,30 +22,18 @@ resource "cloudstack_secondary_ipaddress" "default" {
The following arguments are supported: The following arguments are supported:
* `ip_address` - (Optional) The IP address to attach the to NIC. If not supplied * `ip_address` - (Optional) The IP address to bind the to NIC. If not supplied
an IP address will be selected randomly. Changing this forces a new resource an IP address will be selected randomly. Changing this forces a new resource
to be created. to be created.
* `ipaddress` - (Optional, Deprecated) The IP address to attach the to NIC. If
not supplied an IP address will be selected randomly. Changing this forces
a new resource to be created.
* `nic_id` - (Optional) The NIC ID to which you want to attach the secondary IP * `nic_id` - (Optional) The NIC ID to which you want to attach the secondary IP
address. Changing this forces a new resource to be created (defaults to the address. Changing this forces a new resource to be created (defaults to the
ID of the primary NIC) ID of the primary NIC)
* `nicid` - (Optional, Deprecated) The ID of the NIC to which you want to attach
the secondary IP address. Changing this forces a new resource to be created
(defaults to the ID of the primary NIC)
* `virtual_machine_id` - (Required) The ID of the virtual machine to which you * `virtual_machine_id` - (Required) The ID of the virtual machine to which you
want to attach the secondary IP address. Changing this forces a new resource want to attach the secondary IP address. Changing this forces a new resource
to be created. to be created.
* `virtual_machine` - (Required, Deprecated) The name or ID of the virtual
machine to which you want to attach the secondary IP address. Changing this
forces a new resource to be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:

View File

@ -28,15 +28,9 @@ The following arguments are supported:
* `customer_gateway_id` - (Required) The Customer Gateway ID to connect. * `customer_gateway_id` - (Required) The Customer Gateway ID to connect.
Changing this forces a new resource to be created. Changing this forces a new resource to be created.
* `customergatewayid` - (Required, Deprecated) The Customer Gateway ID
to connect. Changing this forces a new resource to be created.
* `vpn_gateway_id` - (Required) The VPN Gateway ID to connect. Changing * `vpn_gateway_id` - (Required) The VPN Gateway ID to connect. Changing
this forces a new resource to be created. this forces a new resource to be created.
* `vpngatewayid` - (Required, Deprecated) The VPN Gateway ID to connect.
Changing this forces a new resource to be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported:

View File

@ -27,9 +27,6 @@ The following arguments are supported:
* `vpc_id` - (Required) The ID of the VPC for which to create the VPN Gateway. * `vpc_id` - (Required) The ID of the VPC for which to create the VPN Gateway.
Changing this forces a new resource to be created. Changing this forces a new resource to be created.
* `vpc` - (Required, Deprecated) The name or ID of the VPC for which to create
the VPN Gateway. Changing this forces a new resource to be created.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported: