From fddf3eccc6b6992409f8b1cefbe7226eb484086f Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Mon, 4 Apr 2016 22:13:27 +0200 Subject: [PATCH] Make the CloudStack provider more inline with the other provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It turns out all other providers use `ip_address` where the CloudStack provider uses `ipaddress`. To make this more consistent this PR deprecates `ipaddress` and adds `ip_address` where needed… --- .../resource_cloudstack_firewall.go | 26 ++++++-- .../resource_cloudstack_firewall_test.go | 56 +++++++++--------- .../resource_cloudstack_instance.go | 20 +++++-- .../resource_cloudstack_instance_test.go | 6 +- .../resource_cloudstack_ipaddress.go | 16 ++--- ... resource_cloudstack_loadbalancer_rule.go} | 30 ++++++++-- ...urce_cloudstack_loadbalancer_rule_test.go} | 59 ++++--------------- .../cloudstack/resource_cloudstack_nic.go | 22 +++++-- .../resource_cloudstack_nic_test.go | 4 +- .../resource_cloudstack_port_forward.go | 26 ++++++-- .../resource_cloudstack_port_forward_test.go | 10 ++-- ...resource_cloudstack_secondary_ipaddress.go | 25 ++++++-- ...rce_cloudstack_secondary_ipaddress_test.go | 6 +- builtin/providers/cloudstack/resources.go | 2 +- .../cloudstack/r/firewall.html.markdown | 7 ++- .../cloudstack/r/instance.html.markdown | 5 +- .../cloudstack/r/ipaddress.html.markdown | 2 +- .../r/loadbalancer_rule.html.markdown | 40 ++++++++----- .../providers/cloudstack/r/nic.html.markdown | 9 ++- .../cloudstack/r/port_forward.html.markdown | 9 ++- .../r/secondary_ipaddress.html.markdown | 6 +- website/source/layouts/cloudstack.erb | 4 ++ 22 files changed, 235 insertions(+), 155 deletions(-) rename builtin/providers/cloudstack/{resource_cloudstack_loadbalancer.go => resource_cloudstack_loadbalancer_rule.go} (88%) rename builtin/providers/cloudstack/{resource_cloudstack_loadbalancer_test.go => resource_cloudstack_loadbalancer_rule_test.go} (88%) diff --git a/builtin/providers/cloudstack/resource_cloudstack_firewall.go b/builtin/providers/cloudstack/resource_cloudstack_firewall.go index cfe3531f7..f10f5a638 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_firewall.go +++ b/builtin/providers/cloudstack/resource_cloudstack_firewall.go @@ -1,6 +1,7 @@ package cloudstack import ( + "errors" "fmt" "strconv" "strings" @@ -20,10 +21,19 @@ func resourceCloudStackFirewall() *schema.Resource { Delete: resourceCloudStackFirewallDelete, Schema: map[string]*schema.Schema{ + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"ipaddress"}, + }, + "ipaddress": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Deprecated: "Please use the `ip_address` field instead", + ConflictsWith: []string{"ip_address"}, }, "managed": &schema.Schema{ @@ -99,8 +109,16 @@ func resourceCloudStackFirewallCreate(d *schema.ResourceData, meta interface{}) return err } + ipaddress, ok := d.GetOk("ip_address") + if !ok { + ipaddress, ok = d.GetOk("ipaddress") + } + if !ok { + return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.") + } + // Retrieve the ipaddress ID - ipaddressid, e := retrieveID(cs, "ipaddress", d.Get("ipaddress").(string)) + ipaddressid, e := retrieveID(cs, "ip_address", ipaddress.(string)) if e != nil { return e.Error() } diff --git a/builtin/providers/cloudstack/resource_cloudstack_firewall_test.go b/builtin/providers/cloudstack/resource_cloudstack_firewall_test.go index d93a2c73e..f7fda8110 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_firewall_test.go +++ b/builtin/providers/cloudstack/resource_cloudstack_firewall_test.go @@ -21,7 +21,7 @@ func TestAccCloudStackFirewall_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackFirewallRulesExist("cloudstack_firewall.foo"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "ipaddress", CLOUDSTACK_PUBLIC_IPADDRESS), + "cloudstack_firewall.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS), resource.TestCheckResourceAttr( "cloudstack_firewall.foo", "rule.#", "2"), resource.TestCheckResourceAttr( @@ -31,13 +31,13 @@ func TestAccCloudStackFirewall_basic(t *testing.T) { resource.TestCheckResourceAttr( "cloudstack_firewall.foo", "rule.60926170.ports.32925333", "8080"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.source_cidr", "10.0.0.0/24"), + "cloudstack_firewall.foo", "rule.3832507136.cidr_list.3482919157", "10.0.0.0/24"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.protocol", "tcp"), + "cloudstack_firewall.foo", "rule.3832507136.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.ports.1209010669", "1000-2000"), + "cloudstack_firewall.foo", "rule.3832507136.ports.1209010669", "1000-2000"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.ports.1889509032", "80"), + "cloudstack_firewall.foo", "rule.3832507136.ports.1889509032", "80"), ), }, }, @@ -55,7 +55,7 @@ func TestAccCloudStackFirewall_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackFirewallRulesExist("cloudstack_firewall.foo"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "ipaddress", CLOUDSTACK_PUBLIC_IPADDRESS), + "cloudstack_firewall.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS), resource.TestCheckResourceAttr( "cloudstack_firewall.foo", "rule.#", "2"), resource.TestCheckResourceAttr( @@ -65,13 +65,13 @@ func TestAccCloudStackFirewall_update(t *testing.T) { resource.TestCheckResourceAttr( "cloudstack_firewall.foo", "rule.60926170.ports.32925333", "8080"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.source_cidr", "10.0.0.0/24"), + "cloudstack_firewall.foo", "rule.3832507136.cidr_list.3482919157", "10.0.0.0/24"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.protocol", "tcp"), + "cloudstack_firewall.foo", "rule.3832507136.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.ports.1209010669", "1000-2000"), + "cloudstack_firewall.foo", "rule.3832507136.ports.1209010669", "1000-2000"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.ports.1889509032", "80"), + "cloudstack_firewall.foo", "rule.3832507136.ports.1889509032", "80"), ), }, @@ -80,33 +80,33 @@ func TestAccCloudStackFirewall_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackFirewallRulesExist("cloudstack_firewall.foo"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "ipaddress", CLOUDSTACK_PUBLIC_IPADDRESS), + "cloudstack_firewall.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS), resource.TestCheckResourceAttr( "cloudstack_firewall.foo", "rule.#", "3"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.2207610982.cidr_list.80081744", "10.0.1.0/24"), + "cloudstack_firewall.foo", "rule.2144925929.cidr_list.80081744", "10.0.1.0/24"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.2207610982.cidr_list.3482919157", "10.0.0.0/24"), + "cloudstack_firewall.foo", "rule.2144925929.cidr_list.3482919157", "10.0.0.0/24"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.2207610982.protocol", "tcp"), + "cloudstack_firewall.foo", "rule.2144925929.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.2207610982.ports.32925333", "8080"), + "cloudstack_firewall.foo", "rule.2144925929.ports.32925333", "8080"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.source_cidr", "10.0.0.0/24"), + "cloudstack_firewall.foo", "rule.3832507136.cidr_list.3482919157", "10.0.0.0/24"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.protocol", "tcp"), + "cloudstack_firewall.foo", "rule.3832507136.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.ports.1209010669", "1000-2000"), + "cloudstack_firewall.foo", "rule.3832507136.ports.1209010669", "1000-2000"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.716592205.ports.1889509032", "80"), + "cloudstack_firewall.foo", "rule.3832507136.ports.1889509032", "80"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.4449157.source_cidr", "172.16.100.0/24"), + "cloudstack_firewall.foo", "rule.302279047.cidr_list.2835005819", "172.16.100.0/24"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.4449157.protocol", "tcp"), + "cloudstack_firewall.foo", "rule.302279047.protocol", "tcp"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.4449157.ports.1889509032", "80"), + "cloudstack_firewall.foo", "rule.302279047.ports.1889509032", "80"), resource.TestCheckResourceAttr( - "cloudstack_firewall.foo", "rule.4449157.ports.3638101695", "443"), + "cloudstack_firewall.foo", "rule.302279047.ports.3638101695", "443"), ), }, }, @@ -174,7 +174,7 @@ func testAccCheckCloudStackFirewallDestroy(s *terraform.State) error { var testAccCloudStackFirewall_basic = fmt.Sprintf(` resource "cloudstack_firewall" "foo" { - ipaddress = "%s" + ip_address = "%s" rule { cidr_list = ["10.0.0.0/24"] @@ -183,7 +183,7 @@ resource "cloudstack_firewall" "foo" { } rule { - source_cidr = "10.0.0.0/24" + cidr_list = ["10.0.0.0/24"] protocol = "tcp" ports = ["80", "1000-2000"] } @@ -191,7 +191,7 @@ resource "cloudstack_firewall" "foo" { var testAccCloudStackFirewall_update = fmt.Sprintf(` resource "cloudstack_firewall" "foo" { - ipaddress = "%s" + ip_address = "%s" rule { cidr_list = ["10.0.0.0/24", "10.0.1.0/24"] @@ -200,13 +200,13 @@ resource "cloudstack_firewall" "foo" { } rule { - source_cidr = "10.0.0.0/24" + cidr_list = ["10.0.0.0/24"] protocol = "tcp" ports = ["80", "1000-2000"] } rule { - source_cidr = "172.16.100.0/24" + cidr_list = ["172.16.100.0/24"] protocol = "tcp" ports = ["80", "443"] } diff --git a/builtin/providers/cloudstack/resource_cloudstack_instance.go b/builtin/providers/cloudstack/resource_cloudstack_instance.go index 05898dc23..6408faaa0 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_instance.go +++ b/builtin/providers/cloudstack/resource_cloudstack_instance.go @@ -43,13 +43,21 @@ func resourceCloudStackInstance() *schema.Resource { ForceNew: true, }, - "ipaddress": &schema.Schema{ + "ip_address": &schema.Schema{ Type: schema.TypeString, Optional: true, Computed: 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{ Type: schema.TypeString, Required: true, @@ -151,8 +159,12 @@ func resourceCloudStackInstanceCreate(d *schema.ResourceData, meta interface{}) } // If there is a ipaddres supplied, add it to the parameter struct - if ipaddres, ok := d.GetOk("ipaddress"); ok { - p.SetIpaddress(ipaddres.(string)) + ipaddress, ok := d.GetOk("ip_address") + if !ok { + ipaddress, ok = d.GetOk("ipaddress") + } + if ok { + p.SetIpaddress(ipaddress.(string)) } // If there is a project supplied, we retrieve and set the project id @@ -228,7 +240,7 @@ func resourceCloudStackInstanceRead(d *schema.ResourceData, meta interface{}) er // Update the config d.Set("name", vm.Name) d.Set("display_name", vm.Displayname) - d.Set("ipaddress", vm.Nic[0].Ipaddress) + d.Set("ip_address", vm.Nic[0].Ipaddress) //NB cloudstack sometimes sends back the wrong keypair name, so dont update it setValueOrID(d, "network", vm.Nic[0].Networkname, vm.Nic[0].Networkid) diff --git a/builtin/providers/cloudstack/resource_cloudstack_instance_test.go b/builtin/providers/cloudstack/resource_cloudstack_instance_test.go index 4d95068c4..f6416b8cf 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_instance_test.go +++ b/builtin/providers/cloudstack/resource_cloudstack_instance_test.go @@ -82,7 +82,7 @@ func TestAccCloudStackInstance_fixedIP(t *testing.T) { testAccCheckCloudStackInstanceExists( "cloudstack_instance.foobar", &instance), resource.TestCheckResourceAttr( - "cloudstack_instance.foobar", "ipaddress", CLOUDSTACK_NETWORK_1_IPADDRESS1), + "cloudstack_instance.foobar", "ip_address", CLOUDSTACK_NETWORK_1_IPADDRESS1), ), }, }, @@ -267,7 +267,7 @@ resource "cloudstack_instance" "foobar" { display_name = "terraform-test" service_offering= "%s" network = "%s" - ipaddress = "%s" + ip_address = "%s" template = "%s" zone = "%s" expunge = true @@ -288,7 +288,7 @@ resource "cloudstack_instance" "foobar" { display_name = "terraform-test" service_offering= "%s" network = "%s" - ipaddress = "%s" + ip_address = "%s" template = "%s" zone = "%s" keypair = "${cloudstack_ssh_keypair.foo.name}" diff --git a/builtin/providers/cloudstack/resource_cloudstack_ipaddress.go b/builtin/providers/cloudstack/resource_cloudstack_ipaddress.go index 41d9b0851..4c140639a 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_ipaddress.go +++ b/builtin/providers/cloudstack/resource_cloudstack_ipaddress.go @@ -34,7 +34,7 @@ func resourceCloudStackIPAddress() *schema.Resource { ForceNew: true, }, - "ipaddress": &schema.Schema{ + "ip_address": &schema.Schema{ Type: schema.TypeString, Computed: true, }, @@ -100,7 +100,7 @@ func resourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) e cs := meta.(*cloudstack.CloudStackClient) // Get the IP address details - f, count, err := cs.Address.GetPublicIpAddressByID(d.Id()) + ip, count, err := cs.Address.GetPublicIpAddressByID(d.Id()) if err != nil { if count == 0 { log.Printf( @@ -113,29 +113,29 @@ func resourceCloudStackIPAddressRead(d *schema.ResourceData, meta interface{}) e } // Updated the IP address - d.Set("ipaddress", f.Ipaddress) + d.Set("ip_address", ip.Ipaddress) if _, ok := d.GetOk("network"); ok { // Get the network details - n, _, err := cs.Network.GetNetworkByID(f.Associatednetworkid) + n, _, err := cs.Network.GetNetworkByID(ip.Associatednetworkid) if err != nil { return err } - setValueOrID(d, "network", n.Name, f.Associatednetworkid) + setValueOrID(d, "network", n.Name, ip.Associatednetworkid) } if _, ok := d.GetOk("vpc"); ok { // Get the VPC details - v, _, err := cs.VPC.GetVPCByID(f.Vpcid) + v, _, err := cs.VPC.GetVPCByID(ip.Vpcid) if err != nil { return err } - setValueOrID(d, "vpc", v.Name, f.Vpcid) + setValueOrID(d, "vpc", v.Name, ip.Vpcid) } - setValueOrID(d, "project", f.Project, f.Projectid) + setValueOrID(d, "project", ip.Project, ip.Projectid) return nil } diff --git a/builtin/providers/cloudstack/resource_cloudstack_loadbalancer.go b/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule.go similarity index 88% rename from builtin/providers/cloudstack/resource_cloudstack_loadbalancer.go rename to builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule.go index 6f8d5473f..d4f3143cc 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_loadbalancer.go +++ b/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule.go @@ -1,6 +1,7 @@ package cloudstack import ( + "errors" "fmt" "log" "strings" @@ -28,10 +29,19 @@ func resourceCloudStackLoadBalancerRule() *schema.Resource { Computed: true, }, + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"ipaddress"}, + }, + "ipaddress": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Deprecated: "Please use the `ip_address` field instead", + ConflictsWith: []string{"ip_address"}, }, "network": &schema.Schema{ @@ -100,8 +110,16 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter p.SetNetworkid(networkid) } + ipaddress, ok := d.GetOk("ip_address") + if !ok { + ipaddress, ok = d.GetOk("ipaddress") + } + if !ok { + return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.") + } + // Retrieve the ipaddress ID - ipaddressid, e := retrieveID(cs, "ipaddress", d.Get("ipaddress").(string)) + ipaddressid, e := retrieveID(cs, "ip_address", ipaddress.(string)) if e != nil { return e.Error() } @@ -117,7 +135,7 @@ func resourceCloudStackLoadBalancerRuleCreate(d *schema.ResourceData, meta inter d.SetId(r.Id) d.SetPartial("name") d.SetPartial("description") - d.SetPartial("ipaddress") + d.SetPartial("ip_address") d.SetPartial("network") d.SetPartial("algorithm") d.SetPartial("private_port") @@ -163,7 +181,7 @@ func resourceCloudStackLoadBalancerRuleRead(d *schema.ResourceData, meta interfa d.Set("public_port", lb.Publicport) d.Set("private_port", lb.Privateport) - setValueOrID(d, "ipaddress", lb.Publicip, lb.Publicipid) + setValueOrID(d, "ip_address", lb.Publicip, lb.Publicipid) // Only set network if user specified it to avoid spurious diffs if _, ok := d.GetOk("network"); ok { diff --git a/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_test.go b/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule_test.go similarity index 88% rename from builtin/providers/cloudstack/resource_cloudstack_loadbalancer_test.go rename to builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule_test.go index a316d5988..b34c4f555 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_test.go +++ b/builtin/providers/cloudstack/resource_cloudstack_loadbalancer_rule_test.go @@ -251,24 +251,12 @@ resource "cloudstack_instance" "foobar1" { resource "cloudstack_loadbalancer_rule" "foo" { name = "terraform-lb" - ipaddress = "%s" - # network omitted, inferred from IP + ip_address = "%s" algorithm = "roundrobin" public_port = 80 private_port = 80 members = ["${cloudstack_instance.foobar1.id}"] } - -# attempt to create dependent firewall rule -# this will clash if cloudstack creates the implicit rule as it does by default -resource "cloudstack_firewall" "foo" { - ipaddress = "${cloudstack_loadbalancer_rule.foo.ipaddress}" - rule { - source_cidr = "0.0.0.0/0" - protocol = "tcp" - ports = ["${cloudstack_loadbalancer_rule.foo.public_port}"] - } -} `, CLOUDSTACK_SERVICE_OFFERING_1, CLOUDSTACK_NETWORK_1, @@ -289,24 +277,12 @@ resource "cloudstack_instance" "foobar1" { resource "cloudstack_loadbalancer_rule" "foo" { name = "terraform-lb-update" - ipaddress = "%s" - # network omitted, inferred from IP + ip_address = "%s" algorithm = "leastconn" public_port = 80 private_port = 80 members = ["${cloudstack_instance.foobar1.id}"] } - -# attempt to create dependent firewall rule -# this will clash if cloudstack creates the implicit rule as it does by default -resource "cloudstack_firewall" "foo" { - ipaddress = "${cloudstack_loadbalancer_rule.foo.ipaddress}" - rule { - source_cidr = "0.0.0.0/0" - protocol = "tcp" - ports = ["${cloudstack_loadbalancer_rule.foo.public_port}"] - } -} `, CLOUDSTACK_SERVICE_OFFERING_1, CLOUDSTACK_NETWORK_1, @@ -327,24 +303,12 @@ resource "cloudstack_instance" "foobar1" { resource "cloudstack_loadbalancer_rule" "foo" { name = "terraform-lb-update" - ipaddress = "%s" - # network omitted, inferred from IP + ip_address = "%s" algorithm = "leastconn" public_port = 443 private_port = 443 members = ["${cloudstack_instance.foobar1.id}"] } - -# attempt to create dependent firewall rule -# this will clash if cloudstack creates the implicit rule as it does by default -resource "cloudstack_firewall" "foo" { - ipaddress = "${cloudstack_loadbalancer_rule.foo.ipaddress}" - rule { - source_cidr = "0.0.0.0/0" - protocol = "tcp" - ports = ["${cloudstack_loadbalancer_rule.foo.public_port}"] - } -} `, CLOUDSTACK_SERVICE_OFFERING_1, CLOUDSTACK_NETWORK_1, @@ -379,13 +343,12 @@ resource "cloudstack_instance" "foobar1" { network = "${cloudstack_network.foo.name}" template = "%s" zone = "${cloudstack_network.foo.zone}" - user_data = "foobar\nfoo\nbar" expunge = true } resource "cloudstack_loadbalancer_rule" "foo" { name = "terraform-lb" - ipaddress = "${cloudstack_ipaddress.foo.ipaddress}" + ip_address = "${cloudstack_ipaddress.foo.ip_address}" algorithm = "roundrobin" network = "${cloudstack_network.foo.id}" public_port = 80 @@ -402,10 +365,10 @@ resource "cloudstack_loadbalancer_rule" "foo" { var testAccCloudStackLoadBalancerRule_vpc_update = fmt.Sprintf(` resource "cloudstack_vpc" "foobar" { - name = "terraform-vpc" - cidr = "%s" - vpc_offering = "%s" - zone = "%s" + name = "terraform-vpc" + cidr = "%s" + vpc_offering = "%s" + zone = "%s" } resource "cloudstack_network" "foo" { @@ -427,7 +390,6 @@ resource "cloudstack_instance" "foobar1" { network = "${cloudstack_network.foo.name}" template = "%s" zone = "${cloudstack_network.foo.zone}" - user_data = "foobar\nfoo\nbar" expunge = true } @@ -438,18 +400,17 @@ resource "cloudstack_instance" "foobar2" { network = "${cloudstack_network.foo.name}" template = "%s" zone = "${cloudstack_network.foo.zone}" - user_data = "foobar\nfoo\nbar" expunge = true } resource "cloudstack_loadbalancer_rule" "foo" { name = "terraform-lb-update" - ipaddress = "${cloudstack_ipaddress.foo.ipaddress}" + ip_address = "${cloudstack_ipaddress.foo.ip_address}" algorithm = "leastconn" network = "${cloudstack_network.foo.id}" public_port = 443 private_port = 443 - members = ["${cloudstack_instance.foobar2.id}", "${cloudstack_instance.foobar1.id}"] + members = ["${cloudstack_instance.foobar1.id}", "${cloudstack_instance.foobar2.id}"] }`, CLOUDSTACK_VPC_CIDR_1, CLOUDSTACK_VPC_OFFERING, diff --git a/builtin/providers/cloudstack/resource_cloudstack_nic.go b/builtin/providers/cloudstack/resource_cloudstack_nic.go index e118a5fe9..6902f197e 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_nic.go +++ b/builtin/providers/cloudstack/resource_cloudstack_nic.go @@ -22,13 +22,21 @@ func resourceCloudStackNIC() *schema.Resource { ForceNew: true, }, - "ipaddress": &schema.Schema{ + "ip_address": &schema.Schema{ Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, + "ipaddress": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Deprecated: "Please use the `ip_address` field instead", + }, + "virtual_machine": &schema.Schema{ Type: schema.TypeString, Required: true, @@ -57,7 +65,11 @@ func resourceCloudStackNICCreate(d *schema.ResourceData, meta interface{}) error p := cs.VirtualMachine.NewAddNicToVirtualMachineParams(networkid, virtualmachineid) // If there is a ipaddres supplied, add it to the parameter struct - if ipaddress, ok := d.GetOk("ipaddress"); ok { + ipaddress, ok := d.GetOk("ip_address") + if !ok { + ipaddress, ok = d.GetOk("ipaddress") + } + if ok { p.SetIpaddress(ipaddress.(string)) } @@ -93,16 +105,16 @@ func resourceCloudStackNICRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[DEBUG] Instance %s does no longer exist", d.Get("virtual_machine").(string)) d.SetId("") return nil - } else { - return err } + + return err } // Read NIC info found := false for _, n := range vm.Nic { if n.Id == d.Id() { - d.Set("ipaddress", n.Ipaddress) + d.Set("ip_address", n.Ipaddress) setValueOrID(d, "network", n.Networkname, n.Networkid) setValueOrID(d, "virtual_machine", vm.Name, vm.Id) found = true diff --git a/builtin/providers/cloudstack/resource_cloudstack_nic_test.go b/builtin/providers/cloudstack/resource_cloudstack_nic_test.go index ef302cbd7..249c02d89 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_nic_test.go +++ b/builtin/providers/cloudstack/resource_cloudstack_nic_test.go @@ -53,7 +53,7 @@ func TestAccCloudStackNIC_update(t *testing.T) { "cloudstack_instance.foobar", "cloudstack_nic.foo", &nic), testAccCheckCloudStackNICIPAddress(&nic), resource.TestCheckResourceAttr( - "cloudstack_nic.foo", "ipaddress", CLOUDSTACK_2ND_NIC_IPADDRESS), + "cloudstack_nic.foo", "ip_address", CLOUDSTACK_2ND_NIC_IPADDRESS), ), }, }, @@ -183,7 +183,7 @@ resource "cloudstack_instance" "foobar" { resource "cloudstack_nic" "foo" { network = "%s" - ipaddress = "%s" + ip_address = "%s" virtual_machine = "${cloudstack_instance.foobar.name}" }`, CLOUDSTACK_SERVICE_OFFERING_1, diff --git a/builtin/providers/cloudstack/resource_cloudstack_port_forward.go b/builtin/providers/cloudstack/resource_cloudstack_port_forward.go index 044482bcb..46fadce4c 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_port_forward.go +++ b/builtin/providers/cloudstack/resource_cloudstack_port_forward.go @@ -1,6 +1,7 @@ package cloudstack import ( + "errors" "fmt" "sync" "time" @@ -21,10 +22,19 @@ func resourceCloudStackPortForward() *schema.Resource { Delete: resourceCloudStackPortForwardDelete, Schema: map[string]*schema.Schema{ + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"ipaddress"}, + }, + "ipaddress": &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Deprecated: "Please use the `ip_address` field instead", + ConflictsWith: []string{"ip_address"}, }, "managed": &schema.Schema{ @@ -72,8 +82,16 @@ func resourceCloudStackPortForward() *schema.Resource { func resourceCloudStackPortForwardCreate(d *schema.ResourceData, meta interface{}) error { cs := meta.(*cloudstack.CloudStackClient) + ipaddress, ok := d.GetOk("ip_address") + if !ok { + ipaddress, ok = d.GetOk("ipaddress") + } + if !ok { + return errors.New("Either `ip_address` or [deprecated] `ipaddress` must be provided.") + } + // Retrieve the ipaddress ID - ipaddressid, e := retrieveID(cs, "ipaddress", d.Get("ipaddress").(string)) + ipaddressid, e := retrieveID(cs, "ip_address", ipaddress.(string)) if e != nil { return e.Error() } diff --git a/builtin/providers/cloudstack/resource_cloudstack_port_forward_test.go b/builtin/providers/cloudstack/resource_cloudstack_port_forward_test.go index 63dcdb001..8e9104ea1 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_port_forward_test.go +++ b/builtin/providers/cloudstack/resource_cloudstack_port_forward_test.go @@ -21,7 +21,7 @@ func TestAccCloudStackPortForward_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackPortForwardsExist("cloudstack_port_forward.foo"), resource.TestCheckResourceAttr( - "cloudstack_port_forward.foo", "ipaddress", CLOUDSTACK_PUBLIC_IPADDRESS), + "cloudstack_port_forward.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS), resource.TestCheckResourceAttr( "cloudstack_port_forward.foo", "forward.952396423.protocol", "tcp"), resource.TestCheckResourceAttr( @@ -47,7 +47,7 @@ func TestAccCloudStackPortForward_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackPortForwardsExist("cloudstack_port_forward.foo"), resource.TestCheckResourceAttr( - "cloudstack_port_forward.foo", "ipaddress", CLOUDSTACK_PUBLIC_IPADDRESS), + "cloudstack_port_forward.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS), resource.TestCheckResourceAttr( "cloudstack_port_forward.foo", "forward.#", "1"), resource.TestCheckResourceAttr( @@ -66,7 +66,7 @@ func TestAccCloudStackPortForward_update(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckCloudStackPortForwardsExist("cloudstack_port_forward.foo"), resource.TestCheckResourceAttr( - "cloudstack_port_forward.foo", "ipaddress", CLOUDSTACK_PUBLIC_IPADDRESS), + "cloudstack_port_forward.foo", "ip_address", CLOUDSTACK_PUBLIC_IPADDRESS), resource.TestCheckResourceAttr( "cloudstack_port_forward.foo", "forward.#", "2"), resource.TestCheckResourceAttr( @@ -161,7 +161,7 @@ resource "cloudstack_instance" "foobar" { } resource "cloudstack_port_forward" "foo" { - ipaddress = "%s" + ip_address = "%s" forward { protocol = "tcp" @@ -187,7 +187,7 @@ resource "cloudstack_instance" "foobar" { } resource "cloudstack_port_forward" "foo" { - ipaddress = "%s" + ip_address = "%s" forward { protocol = "tcp" diff --git a/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress.go b/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress.go index 697e55eb4..cac479791 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress.go +++ b/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress.go @@ -16,13 +16,21 @@ func resourceCloudStackSecondaryIPAddress() *schema.Resource { Delete: resourceCloudStackSecondaryIPAddressDelete, Schema: map[string]*schema.Schema{ - "ipaddress": &schema.Schema{ + "ip_address": &schema.Schema{ Type: schema.TypeString, Optional: true, Computed: true, ForceNew: true, }, + "ipaddress": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + Deprecated: "Please use the `ip_address` field instead", + }, + "nicid": &schema.Schema{ Type: schema.TypeString, Optional: true, @@ -67,8 +75,13 @@ func resourceCloudStackSecondaryIPAddressCreate(d *schema.ResourceData, meta int // Create a new parameter struct p := cs.Nic.NewAddIpToNicParams(nicid) - if addr := d.Get("ipaddress").(string); addr != "" { - p.SetIpaddress(addr) + // If there is a ipaddres supplied, add it to the parameter struct + ipaddress, ok := d.GetOk("ip_address") + if !ok { + ipaddress, ok = d.GetOk("ipaddress") + } + if ok { + p.SetIpaddress(ipaddress.(string)) } ip, err := cs.Nic.AddIpToNic(p) @@ -126,13 +139,13 @@ func resourceCloudStackSecondaryIPAddressRead(d *schema.ResourceData, meta inter for _, ip := range l.Nics[0].Secondaryip { if ip.Id == d.Id() { - d.Set("ipaddress", ip.Ipaddress) + d.Set("ip_address", ip.Ipaddress) d.Set("nicid", l.Nics[0].Id) return nil } } - log.Printf("[DEBUG] IP %s no longer exist", d.Get("ipaddress").(string)) + log.Printf("[DEBUG] IP %s no longer exist", d.Get("ip_address").(string)) d.SetId("") return nil @@ -144,7 +157,7 @@ func resourceCloudStackSecondaryIPAddressDelete(d *schema.ResourceData, meta int // Create a new parameter struct p := cs.Nic.NewRemoveIpFromNicParams(d.Id()) - log.Printf("[INFO] Removing secondary IP address: %s", d.Get("ipaddress").(string)) + log.Printf("[INFO] Removing secondary IP address: %s", d.Get("ip_address").(string)) if _, err := cs.Nic.RemoveIpFromNic(p); err != nil { // This is a very poor way to be told the ID does no longer exist :( if strings.Contains(err.Error(), fmt.Sprintf( diff --git a/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress_test.go b/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress_test.go index dd59ca3f4..8b9614831 100644 --- a/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress_test.go +++ b/builtin/providers/cloudstack/resource_cloudstack_secondary_ipaddress_test.go @@ -43,7 +43,7 @@ func TestAccCloudStackSecondaryIPAddress_fixedIP(t *testing.T) { "cloudstack_secondary_ipaddress.foo", &ip), testAccCheckCloudStackSecondaryIPAddressAttributes(&ip), resource.TestCheckResourceAttr( - "cloudstack_secondary_ipaddress.foo", "ipaddress", CLOUDSTACK_NETWORK_1_IPADDRESS1), + "cloudstack_secondary_ipaddress.foo", "ip_address", CLOUDSTACK_NETWORK_1_IPADDRESS1), ), }, }, @@ -147,7 +147,7 @@ func testAccCheckCloudStackSecondaryIPAddressDestroy(s *terraform.State) error { vm, count, err := cs.VirtualMachine.GetVirtualMachineByID(virtualmachineid) if err != nil { if count == 0 { - return fmt.Errorf("Instance not found") + return nil } return err } @@ -215,7 +215,7 @@ resource "cloudstack_instance" "foobar" { } resource "cloudstack_secondary_ipaddress" "foo" { - ipaddress = "%s" + ip_address = "%s" virtual_machine = "${cloudstack_instance.foobar.id}" }`, CLOUDSTACK_SERVICE_OFFERING_1, diff --git a/builtin/providers/cloudstack/resources.go b/builtin/providers/cloudstack/resources.go index 5421cb101..d404e38c6 100644 --- a/builtin/providers/cloudstack/resources.go +++ b/builtin/providers/cloudstack/resources.go @@ -69,7 +69,7 @@ func retrieveID(cs *cloudstack.CloudStackClient, name, value string) (id string, id, err = cs.Network.GetNetworkID(value) case "zone": id, err = cs.Zone.GetZoneID(value) - case "ipaddress": + case "ip_address": p := cs.Address.NewListPublicIpAddressesParams() p.SetIpaddress(value) l, e := cs.Address.ListPublicIpAddresses(p) diff --git a/website/source/docs/providers/cloudstack/r/firewall.html.markdown b/website/source/docs/providers/cloudstack/r/firewall.html.markdown index 01a93cbf7..4120306f5 100644 --- a/website/source/docs/providers/cloudstack/r/firewall.html.markdown +++ b/website/source/docs/providers/cloudstack/r/firewall.html.markdown @@ -14,7 +14,7 @@ Creates firewall rules for a given IP address. ``` resource "cloudstack_firewall" "default" { - ipaddress = "192.168.0.1" + ip_address = "192.168.0.1" rule { cidr_list = ["10.0.0.0/8"] @@ -28,9 +28,12 @@ resource "cloudstack_firewall" "default" { The following arguments are supported: -* `ipaddress` - (Required) The IP address or ID for which to create the firewall +* `ip_address` - (Required) The IP address or ID for which to create the 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 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) diff --git a/website/source/docs/providers/cloudstack/r/instance.html.markdown b/website/source/docs/providers/cloudstack/r/instance.html.markdown index 1351ab107..40bbc6d82 100644 --- a/website/source/docs/providers/cloudstack/r/instance.html.markdown +++ b/website/source/docs/providers/cloudstack/r/instance.html.markdown @@ -37,9 +37,12 @@ The following arguments are supported: * `network` - (Optional) The name or ID of the network to connect this instance to. Changing this forces a new resource to be created. -* `ipaddress` - (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. +* `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 instance. Changing this forces a new resource to be created. diff --git a/website/source/docs/providers/cloudstack/r/ipaddress.html.markdown b/website/source/docs/providers/cloudstack/r/ipaddress.html.markdown index 5b542993c..45315a0f7 100644 --- a/website/source/docs/providers/cloudstack/r/ipaddress.html.markdown +++ b/website/source/docs/providers/cloudstack/r/ipaddress.html.markdown @@ -38,4 +38,4 @@ The following arguments are supported: The following attributes are exported: * `id` - The ID of the acquired and associated IP address. -* `ipaddress` - The IP address that was acquired and associated. +* `ip_address` - The IP address that was acquired and associated. diff --git a/website/source/docs/providers/cloudstack/r/loadbalancer_rule.html.markdown b/website/source/docs/providers/cloudstack/r/loadbalancer_rule.html.markdown index 18a2d5ae1..eb374096b 100644 --- a/website/source/docs/providers/cloudstack/r/loadbalancer_rule.html.markdown +++ b/website/source/docs/providers/cloudstack/r/loadbalancer_rule.html.markdown @@ -16,7 +16,7 @@ Creates a loadbalancer rule. resource "cloudstack_loadbalancer_rule" "default" { name = "loadbalancer-rule-1" description = "Loadbalancer rule 1" - ipaddress = "192.168.0.1" + ip_address = "192.168.0.1" algorithm = "roundrobin" private_port = 80 public_port = 80 @@ -33,24 +33,32 @@ The following arguments are supported: * `description` - (Optional) The description of the load balancer rule. -* `ipaddress` - (Required) Public ip address from where the network traffic will be load balanced from. - Changing this forces a new resource to be created. +* `ip_address` - (Required) Public ip address from where the network traffic + will be load balanced from. Changing this forces a new resource to be + created. -* `network` - (Optional) The guest network this rule will be created for. Required when public Ip address is - not associated with any Guest network yet (VPC case). - -* `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin, leastconn).Changing this forces - a new resource to be created. - -* `private_port` - (Required) The private port of the private ip address/virtual machine where the network - traffic will be load balanced to. Changing this forces a new resource to be created. - -* `public_port` - (Required) The public port from where the network traffic will be load balanced from. - Changing this forces a new resource to be created. - -* `members` - (Required) List of instances to assign to the load balancer rule. Changing this forces a new +* `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` - (Optional) The guest network this rule will be created for. + Required when public IP address is not associated with any Guest network + yet (VPC case). + +* `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin, + leastconn). Changing this forces a new resource to be created. + +* `private_port` - (Required) The private port of the private IP address + (virtual machine) where the network traffic will be load balanced to. + Changing this forces a new resource to be created. + +* `public_port` - (Required) The public port from where the network traffic + will be load balanced from. Changing this forces a new resource to be + created. + +* `members` - (Required) List of instances to assign to the load balancer rule. + Changing this forces a new resource to be created. + ## Attributes Reference The following attributes are exported: diff --git a/website/source/docs/providers/cloudstack/r/nic.html.markdown b/website/source/docs/providers/cloudstack/r/nic.html.markdown index 09bfb0bd4..38aacd87d 100644 --- a/website/source/docs/providers/cloudstack/r/nic.html.markdown +++ b/website/source/docs/providers/cloudstack/r/nic.html.markdown @@ -17,7 +17,7 @@ Basic usage: ``` resource "cloudstack_nic" "test" { network = "network-2" - ipaddress = "192.168.1.1" + ip_address = "192.168.1.1" virtual_machine = "server-1" } ``` @@ -29,9 +29,12 @@ The following arguments are supported: * `network` - (Required) The name or ID of the network to plug the NIC into. Changing this forces a new resource to be created. -* `ipaddress` - (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. +* `ipaddress` - (Optional, Deprecated) The IP address to assign to the NIC. Changing + this forces a new resource to be created. + * `virtual_machine` - (Required) The name or ID of the virtual machine to which to attach the NIC. Changing this forces a new resource to be created. @@ -40,4 +43,4 @@ The following arguments are supported: The following attributes are exported: * `id` - The ID of the NIC. -* `ipaddress` - The assigned IP address. +* `ip_address` - The assigned IP address. diff --git a/website/source/docs/providers/cloudstack/r/port_forward.html.markdown b/website/source/docs/providers/cloudstack/r/port_forward.html.markdown index ddf42c75d..41e3b0b39 100644 --- a/website/source/docs/providers/cloudstack/r/port_forward.html.markdown +++ b/website/source/docs/providers/cloudstack/r/port_forward.html.markdown @@ -14,7 +14,7 @@ Creates port forwards. ``` resource "cloudstack_port_forward" "default" { - ipaddress = "192.168.0.1" + ip_address = "192.168.0.1" forward { protocol = "tcp" @@ -29,9 +29,12 @@ resource "cloudstack_port_forward" "default" { The following arguments are supported: -* `ipaddress` - (Required) The IP address for which to create the port forwards. +* `ip_address` - (Required) The IP address for which to create the port 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 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) @@ -54,4 +57,4 @@ The `forward` block supports: The following attributes are exported: -* `ipaddress` - The IP address for which the port forwards are created. +* `ip_address` - The IP address for which the port forwards are created. diff --git a/website/source/docs/providers/cloudstack/r/secondary_ipaddress.html.markdown b/website/source/docs/providers/cloudstack/r/secondary_ipaddress.html.markdown index 757673e6a..6907796f5 100644 --- a/website/source/docs/providers/cloudstack/r/secondary_ipaddress.html.markdown +++ b/website/source/docs/providers/cloudstack/r/secondary_ipaddress.html.markdown @@ -22,10 +22,14 @@ resource "cloudstack_secondary_ipaddress" "default" { The following arguments are supported: -* `ipaddress` - (Optional) The IP address to attach the to NIC. If not supplied +* `ip_address` - (Optional) 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. +* `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. + * `nicid` - (Optional) 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) diff --git a/website/source/layouts/cloudstack.erb b/website/source/layouts/cloudstack.erb index 56abd5fa2..263920656 100644 --- a/website/source/layouts/cloudstack.erb +++ b/website/source/layouts/cloudstack.erb @@ -65,6 +65,10 @@ cloudstack_ssh_keypair + > + cloudstack_static_nat + + > cloudstack_template