From 064ecdf4e9eb7067e4f8df91bb2ad6b8dcb36b54 Mon Sep 17 00:00:00 2001 From: Joe Topjian Date: Sun, 20 Nov 2016 05:53:12 +0000 Subject: [PATCH] provider/openstack: Fix Ordering of Port Allowed Address Pairs This commit changes allowed_address_pairs from a TypeList to a TypeSet allowing for arbitrary ordering. This solves the issue where a user specifies an address pair one way and OpenStack returns a different order. --- .../resource_openstack_networking_port_v2.go | 15 ++++++++-- ...ource_openstack_networking_port_v2_test.go | 28 +++++++++++++++---- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/builtin/providers/openstack/resource_openstack_networking_port_v2.go b/builtin/providers/openstack/resource_openstack_networking_port_v2.go index 54b0156f68ff..9db56e2c2f99 100644 --- a/builtin/providers/openstack/resource_openstack_networking_port_v2.go +++ b/builtin/providers/openstack/resource_openstack_networking_port_v2.go @@ -1,10 +1,12 @@ package openstack import ( + "bytes" "fmt" "log" "time" + "github.com/hashicorp/terraform/helper/hashcode" "github.com/hashicorp/terraform/helper/resource" "github.com/hashicorp/terraform/helper/schema" @@ -97,10 +99,11 @@ func resourceNetworkingPortV2() *schema.Resource { }, }, "allowed_address_pairs": &schema.Schema{ - Type: schema.TypeList, + Type: schema.TypeSet, Optional: true, ForceNew: false, Computed: true, + Set: allowedAddressPairsHash, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "ip_address": &schema.Schema{ @@ -318,7 +321,7 @@ func resourcePortFixedIpsV2(d *schema.ResourceData) interface{} { func resourceAllowedAddressPairsV2(d *schema.ResourceData) []ports.AddressPair { // ports.AddressPair - rawPairs := d.Get("allowed_address_pairs").([]interface{}) + rawPairs := d.Get("allowed_address_pairs").(*schema.Set).List() if len(rawPairs) == 0 { return nil @@ -345,6 +348,14 @@ func resourcePortAdminStateUpV2(d *schema.ResourceData) *bool { return &value } +func allowedAddressPairsHash(v interface{}) int { + var buf bytes.Buffer + m := v.(map[string]interface{}) + buf.WriteString(fmt.Sprintf("%s", m["ip_address"].(string))) + + return hashcode.String(buf.String()) +} + func waitForNetworkPortActive(networkingClient *gophercloud.ServiceClient, portId string) resource.StateRefreshFunc { return func() (interface{}, string, error) { p, err := ports.Get(networkingClient, portId).Extract() 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 fb8505c9a10d..a318f82a5f9d 100644 --- a/builtin/providers/openstack/resource_openstack_networking_port_v2_test.go +++ b/builtin/providers/openstack/resource_openstack_networking_port_v2_test.go @@ -59,7 +59,7 @@ func TestAccNetworkingV2Port_noip(t *testing.T) { func TestAccNetworkingV2Port_allowedAddressPairs(t *testing.T) { var network networks.Network var subnet subnets.Subnet - var vrrp_port, instance_port ports.Port + var vrrp_port_1, vrrp_port_2, instance_port ports.Port resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -71,7 +71,8 @@ func TestAccNetworkingV2Port_allowedAddressPairs(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckNetworkingV2SubnetExists(t, "openstack_networking_subnet_v2.vrrp_subnet", &subnet), testAccCheckNetworkingV2NetworkExists(t, "openstack_networking_network_v2.vrrp_network", &network), - testAccCheckNetworkingV2PortExists(t, "openstack_networking_port_v2.vrrp_port", &vrrp_port), + testAccCheckNetworkingV2PortExists(t, "openstack_networking_port_v2.vrrp_port_1", &vrrp_port_1), + testAccCheckNetworkingV2PortExists(t, "openstack_networking_port_v2.vrrp_port_2", &vrrp_port_2), testAccCheckNetworkingV2PortExists(t, "openstack_networking_port_v2.instance_port", &instance_port), ), }, @@ -202,8 +203,18 @@ var testAccNetworkingV2Port_allowedAddressPairs = fmt.Sprintf(` subnet_id = "${openstack_networking_subnet_v2.vrrp_subnet.id}" } - resource "openstack_networking_port_v2" "vrrp_port" { - name = "vrrp_port" + resource "openstack_networking_port_v2" "vrrp_port_1" { + name = "vrrp_port_1" + network_id = "${openstack_networking_network_v2.vrrp_network.id}" + admin_state_up = "true" + fixed_ip { + subnet_id = "${openstack_networking_subnet_v2.vrrp_subnet.id}" + ip_address = "10.0.0.202" + } + } + + resource "openstack_networking_port_v2" "vrrp_port_2" { + name = "vrrp_port_2" network_id = "${openstack_networking_network_v2.vrrp_network.id}" admin_state_up = "true" fixed_ip { @@ -218,7 +229,12 @@ var testAccNetworkingV2Port_allowedAddressPairs = fmt.Sprintf(` admin_state_up = "true" allowed_address_pairs { - ip_address = "${openstack_networking_port_v2.vrrp_port.fixed_ip.0.ip_address}" - mac_address = "${openstack_networking_port_v2.vrrp_port.mac_address}" + ip_address = "${openstack_networking_port_v2.vrrp_port_1.fixed_ip.0.ip_address}" + mac_address = "${openstack_networking_port_v2.vrrp_port_1.mac_address}" + } + + allowed_address_pairs { + ip_address = "${openstack_networking_port_v2.vrrp_port_2.fixed_ip.0.ip_address}" + mac_address = "${openstack_networking_port_v2.vrrp_port_2.mac_address}" } }`)