diff --git a/builtin/providers/openstack/resource_openstack_networking_network_v2_test.go b/builtin/providers/openstack/resource_openstack_networking_network_v2_test.go index faa007e32..32a0c96be 100644 --- a/builtin/providers/openstack/resource_openstack_networking_network_v2_test.go +++ b/builtin/providers/openstack/resource_openstack_networking_network_v2_test.go @@ -150,7 +150,10 @@ func TestAccNetworkingV2Network_fullstack(t *testing.T) { admin_state_up = "true" security_groups = ["${openstack_compute_secgroup_v2.foo.id}"] - depends_on = ["openstack_networking_subnet_v2.foo"] + fixed_ips { + "subnet_id" = "${openstack_networking_subnet_v2.foo.id}" + "ip_address" = "192.168.199.23" + } } resource "openstack_compute_instance_v2" "foo" { diff --git a/builtin/providers/openstack/resource_openstack_networking_port_v2.go b/builtin/providers/openstack/resource_openstack_networking_port_v2.go index 701e42c05..318f0097b 100644 --- a/builtin/providers/openstack/resource_openstack_networking_port_v2.go +++ b/builtin/providers/openstack/resource_openstack_networking_port_v2.go @@ -78,6 +78,23 @@ func resourceNetworkingPortV2() *schema.Resource { ForceNew: true, Computed: true, }, + "fixed_ips": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + ForceNew: false, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "subnet_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "ip_address": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, }, } } @@ -98,6 +115,7 @@ func resourceNetworkingPortV2Create(d *schema.ResourceData, meta interface{}) er DeviceOwner: d.Get("device_owner").(string), SecurityGroups: resourcePortSecurityGroupsV2(d), DeviceID: d.Get("device_id").(string), + FixedIPs: resourcePortFixedIpsV2(d), } log.Printf("[DEBUG] Create Options: %#v", createOpts) @@ -146,6 +164,7 @@ func resourceNetworkingPortV2Read(d *schema.ResourceData, meta interface{}) erro d.Set("device_owner", p.DeviceOwner) d.Set("security_groups", p.SecurityGroups) d.Set("device_id", p.DeviceID) + d.Set("fixed_ips", p.FixedIPs) return nil } @@ -179,6 +198,10 @@ func resourceNetworkingPortV2Update(d *schema.ResourceData, meta interface{}) er updateOpts.DeviceID = d.Get("device_id").(string) } + if d.HasChange("fixed_ips") { + updateOpts.FixedIPs = resourcePortFixedIpsV2(d) + } + log.Printf("[DEBUG] Updating Port %s with options: %+v", d.Id(), updateOpts) _, err = ports.Update(networkingClient, d.Id(), updateOpts).Extract() @@ -223,6 +246,20 @@ func resourcePortSecurityGroupsV2(d *schema.ResourceData) []string { return groups } +func resourcePortFixedIpsV2(d *schema.ResourceData) []ports.IP { + rawIP := d.Get("fixed_ips").([]interface{}) + ip := make([]ports.IP, len(rawIP)) + for i, raw := range rawIP { + rawMap := raw.(map[string]interface{}) + ip[i] = ports.IP{ + SubnetID: rawMap["subnet_id"].(string), + IPAddress: rawMap["ip_address"].(string), + } + } + + return ip +} + func resourcePortAdminStateUpV2(d *schema.ResourceData) *bool { value := false diff --git a/builtin/providers/openstack/resource_openstack_networking_port_v2_test.go b/builtin/providers/openstack/resource_openstack_networking_port_v2_test.go index edeb61901..c1e100d4f 100644 --- a/builtin/providers/openstack/resource_openstack_networking_port_v2_test.go +++ b/builtin/providers/openstack/resource_openstack_networking_port_v2_test.go @@ -10,6 +10,7 @@ import ( "github.com/rackspace/gophercloud/openstack/networking/v2/networks" "github.com/rackspace/gophercloud/openstack/networking/v2/ports" + "github.com/rackspace/gophercloud/openstack/networking/v2/subnets" ) func TestAccNetworkingV2Port_basic(t *testing.T) { @@ -17,6 +18,7 @@ func TestAccNetworkingV2Port_basic(t *testing.T) { var network networks.Network var port ports.Port + var subnet subnets.Subnet var testAccNetworkingV2Port_basic = fmt.Sprintf(` resource "openstack_networking_network_v2" "foo" { @@ -25,12 +27,24 @@ func TestAccNetworkingV2Port_basic(t *testing.T) { admin_state_up = "true" } + resource "openstack_networking_subnet_v2" "foo" { + region = "%s" + name = "subnet_1" + network_id = "${openstack_networking_network_v2.foo.id}" + cidr = "192.168.199.0/24" + ip_version = 4 + } + resource "openstack_networking_port_v2" "foo" { region = "%s" name = "port_1" network_id = "${openstack_networking_network_v2.foo.id}" admin_state_up = "true" - }`, region, region) + fixed_ips { + subnet_id = "${openstack_networking_subnet_v2.foo.id}" + ip_address = "192.168.199.23" + } + }`, region, region, region) resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -40,6 +54,7 @@ func TestAccNetworkingV2Port_basic(t *testing.T) { resource.TestStep{ Config: testAccNetworkingV2Port_basic, Check: resource.ComposeTestCheckFunc( + testAccCheckNetworkingV2SubnetExists(t, "openstack_networking_subnet_v2.foo", &subnet), testAccCheckNetworkingV2NetworkExists(t, "openstack_networking_network_v2.foo", &network), testAccCheckNetworkingV2PortExists(t, "openstack_networking_port_v2.foo", &port), ), diff --git a/website/source/docs/providers/openstack/r/networking_network_v2.html.markdown b/website/source/docs/providers/openstack/r/networking_network_v2.html.markdown index 9a9eab935..ce4f46db8 100644 --- a/website/source/docs/providers/openstack/r/networking_network_v2.html.markdown +++ b/website/source/docs/providers/openstack/r/networking_network_v2.html.markdown @@ -42,7 +42,10 @@ resource "openstack_networking_port_v2" "port_1" { admin_state_up = "true" security_groups = ["${openstack_compute_secgroup_v2.secgroup_1.id}"] - depends_on = ["openstack_networking_subnet_v2.subnet_1"] + fixed_ips { + "subnet_id" = "008ba151-0b8c-4a67-98b5-0d2b87666062" + "ip_address" = "172.24.4.2" + } } resource "openstack_compute_instance_v2" "instance_1" { diff --git a/website/source/docs/providers/openstack/r/networking_port_v2.html.markdown b/website/source/docs/providers/openstack/r/networking_port_v2.html.markdown index d10130a56..df1e1c914 100644 --- a/website/source/docs/providers/openstack/r/networking_port_v2.html.markdown +++ b/website/source/docs/providers/openstack/r/networking_port_v2.html.markdown @@ -60,6 +60,17 @@ The following arguments are supported: * `device_id` - (Optional) The ID of the device attached to the port. Changing this creates a new port. +* `fixed_ips` - (Optional) An array of desired IPs for this port. + + +The `fixed_ips` block supports: + +* `subnet_id` - (Required) Subnet in which to allocate IP address for +this port. + +* `ip_address` - (Required) IP address desired in the subnet for this +port. + ## Attributes Reference The following attributes are exported: