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 | 32 ++++++---- .../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, 231 insertions(+), 151 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 cfe3531f71ec..f10f5a6384b6 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 d93a2c73eb4a..f7fda8110bbf 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 05898dc23b4c..6408faaa0f09 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 4d95068c4c83..f6416b8cf211 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 41d9b08515d1..4c140639a8f6 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 6f8d5473f037..d4f3143ccc48 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 a316d5988b20..b34c4f555f59 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 e118a5fe98d9..6902f197e5fe 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 ef302cbd7620..249c02d89d9c 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 044482bcb6e1..46fadce4cabe 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 63dcdb001b8c..8e9104ea13fd 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 697e55eb4654..cac479791e9e 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 dd59ca3f4954..8b9614831ea3 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 5421cb1011d0..d404e38c6be9 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 01a93cbf7935..4120306f53b5 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 1351ab107346..40bbc6d82761 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 5b542993c15c..45315a0f7821 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 18a2d5ae1172..eb374096bc6f 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,23 +33,31 @@ 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). +* `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. -* `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin, leastconn).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). -* `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. +* `algorithm` - (Required) Load balancer rule algorithm (source, roundrobin, + leastconn). 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. +* `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. -* `members` - (Required) List of instances to assign to the load balancer rule. 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 diff --git a/website/source/docs/providers/cloudstack/r/nic.html.markdown b/website/source/docs/providers/cloudstack/r/nic.html.markdown index 09bfb0bd467f..38aacd87d48c 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 ddf42c75dcd7..41e3b0b39f72 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 757673e6a35d..6907796f5603 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 56abd5fa2d66..263920656e51 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