Skip to content

Commit 0c65fdb

Browse files
Correctly delete openstack_networking_router_interface_v2 resources (terraform-provider-openstack#1297)
When creating multiple openstack_networking_router_interface_v2 resources for different IPv6 subnets in the same network, openstack will attach these to the same port on the router. On destroy the current implementation will pass the port_id to routers.RemoveInterface, which will trigger the deletion of the whole port, including other openstack_networking_router_interface_v2 resources on the same port. This commit changes this behaviour (so that only the correct router interface gets deleted) and adds a test case that ensures this does not break again in the future.
1 parent 1f2bb78 commit 0c65fdb

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

‎openstack/networking_router_interface_v2.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ func resourceNetworkingRouterInterfaceV2DeleteRefreshFunc(networkingClient *goph
3838
PortID: d.Get("port_id").(string),
3939
}
4040

41+
if removeOpts.SubnetID != "" {
42+
// We need to make sure to only send subnet_id, because the port may have multiple
43+
// openstack_networking_router_interface_v2 attached. Otherwise openstack would delete them too.
44+
removeOpts.PortID = ""
45+
}
46+
4147
r, err := ports.Get(networkingClient, routerInterfaceID).Extract()
4248
if err != nil {
4349
if _, ok := err.(gophercloud.ErrDefault404); ok {

‎openstack/resource_openstack_networking_router_interface_v2_test.go‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,43 @@ func TestAccNetworkingV2RouterInterface_basic_subnet(t *testing.T) {
3939
})
4040
}
4141

42+
// TestAccNetworkingV2RouterInterface_v6_subnet tests that multiple router interfaces for IPv6 subnets
43+
// which are attached to the same port are handled properly.
44+
func TestAccNetworkingV2RouterInterface_v6_subnet(t *testing.T) {
45+
var network networks.Network
46+
var router routers.Router
47+
var subnet1 subnets.Subnet
48+
var subnet2 subnets.Subnet
49+
50+
resource.Test(t, resource.TestCase{
51+
PreCheck: func() {
52+
testAccPreCheck(t)
53+
testAccPreCheckNonAdminOnly(t)
54+
},
55+
ProviderFactories: testAccProviders,
56+
CheckDestroy: testAccCheckNetworkingV2RouterInterfaceDestroy,
57+
Steps: []resource.TestStep{
58+
{
59+
Config: testAccNetworkingV2RouterInterfaceV6Subnet + testAccNetworkingV2RouterInterfaceV6SubnetSecondInterface,
60+
Check: resource.ComposeTestCheckFunc(
61+
testAccCheckNetworkingV2NetworkExists("openstack_networking_network_v2.network_1", &network),
62+
testAccCheckNetworkingV2SubnetExists("openstack_networking_subnet_v2.subnet_1", &subnet1),
63+
testAccCheckNetworkingV2SubnetExists("openstack_networking_subnet_v2.subnet_2", &subnet2),
64+
testAccCheckNetworkingV2RouterExists("openstack_networking_router_v2.router_1", &router),
65+
testAccCheckNetworkingV2RouterInterfaceExists("openstack_networking_router_interface_v2.int_1"),
66+
testAccCheckNetworkingV2RouterInterfaceExists("openstack_networking_router_interface_v2.int_2"),
67+
),
68+
},
69+
{ // Make sure deleting one of the router interfaces does not remove the other one.
70+
Config: testAccNetworkingV2RouterInterfaceV6Subnet,
71+
Check: resource.ComposeTestCheckFunc(
72+
testAccCheckNetworkingV2RouterInterfaceExists("openstack_networking_router_interface_v2.int_1"),
73+
),
74+
},
75+
},
76+
})
77+
}
78+
4279
func TestAccNetworkingV2RouterInterface_basic_port(t *testing.T) {
4380
var network networks.Network
4481
var port ports.Port
@@ -167,6 +204,42 @@ resource "openstack_networking_subnet_v2" "subnet_1" {
167204
}
168205
`
169206

207+
const testAccNetworkingV2RouterInterfaceV6Subnet = `
208+
resource "openstack_networking_router_v2" "router_1" {
209+
name = "router_1"
210+
admin_state_up = "true"
211+
}
212+
213+
resource "openstack_networking_router_interface_v2" "int_1" {
214+
subnet_id = "${openstack_networking_subnet_v2.subnet_1.id}"
215+
router_id = "${openstack_networking_router_v2.router_1.id}"
216+
}
217+
218+
resource "openstack_networking_network_v2" "network_1" {
219+
name = "network_1"
220+
admin_state_up = "true"
221+
}
222+
223+
resource "openstack_networking_subnet_v2" "subnet_1" {
224+
cidr = "fd00:0:0:1::/64"
225+
ip_version = 6
226+
network_id = "${openstack_networking_network_v2.network_1.id}"
227+
}
228+
229+
resource "openstack_networking_subnet_v2" "subnet_2" {
230+
cidr = "fd00:0:0:2::/64"
231+
ip_version = 6
232+
network_id = "${openstack_networking_network_v2.network_1.id}"
233+
}
234+
`
235+
236+
const testAccNetworkingV2RouterInterfaceV6SubnetSecondInterface = `
237+
resource "openstack_networking_router_interface_v2" "int_2" {
238+
subnet_id = "${openstack_networking_subnet_v2.subnet_2.id}"
239+
router_id = "${openstack_networking_router_v2.router_1.id}"
240+
}
241+
`
242+
170243
const testAccNetworkingV2RouterInterfaceBasicPort = `
171244
resource "openstack_networking_router_v2" "router_1" {
172245
name = "router_1"

0 commit comments

Comments
 (0)