From cfd2d1f773a011da21382cc335befc8f52193489 Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Wed, 17 Jan 2024 17:11:20 +0000 Subject: [PATCH] router: Allow specifying external network name in a different project If a router is created in a specific project, the router module tried to find its external network in the same project. This would fail with 'No Network found for ' if the external network is in a different project. This behaviour has changed, most likely in [1] when the project scoping was added to the find_network function call. This change modifies the network query to first check the project, then fall back to a global search if the network is not found. This ensures that if there are multiple networks with the name we will choose one in the project first, while allowing use of a network in a different project. A regression test has been added to cover this case. [1] https://opendev.org/openstack/ansible-collections-openstack/commit/3fdbd56a585f4079ef348ad7060fd9836e85e578 Closes-Bug: #2049658 Change-Id: Iddc0c63a2ce3c500d7be2f8802f718a22f2895ae --- ci/roles/router/tasks/main.yml | 2 + ci/roles/router/tasks/shared_ext_network.yml | 99 ++++++++++++++++++++ plugins/modules/router.py | 6 +- 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 ci/roles/router/tasks/shared_ext_network.yml diff --git a/ci/roles/router/tasks/main.yml b/ci/roles/router/tasks/main.yml index fb4cc168..10f605b5 100644 --- a/ci/roles/router/tasks/main.yml +++ b/ci/roles/router/tasks/main.yml @@ -720,3 +720,5 @@ name: "{{ external_network_name }}" - include_tasks: shared_network.yml + +- include_tasks: shared_ext_network.yml diff --git a/ci/roles/router/tasks/shared_ext_network.yml b/ci/roles/router/tasks/shared_ext_network.yml new file mode 100644 index 00000000..2e9d2d7d --- /dev/null +++ b/ci/roles/router/tasks/shared_ext_network.yml @@ -0,0 +1,99 @@ +--- +# Test the case where we have a shared external network in one project used as +# the gateway on a router in a second project. +# See https://bugs.launchpad.net/ansible-collections-openstack/+bug/2049658 + +- name: Create the first project + openstack.cloud.project: + cloud: "{{ cloud }}" + state: present + name: "shared_ext_net_test_1" + description: "Project that contains the external network to be shared" + domain: default + is_enabled: True + register: project_1 + +- name: Create the external network to be shared + openstack.cloud.network: + cloud: "{{ cloud }}" + state: present + name: "{{ external_network_name }}" + project: "shared_ext_net_test_1" + external: true + shared: true + register: shared_ext_network + +- name: Create subnet on external network + openstack.cloud.subnet: + cloud: "{{ cloud }}" + state: present + network_name: "{{ shared_ext_network.id }}" + name: "shared_ext_subnet" + project: "shared_ext_net_test_1" + cidr: "10.6.6.0/24" + register: shared_subnet + +- name: Create the second project + openstack.cloud.project: + cloud: "{{ cloud }}" + state: present + name: "shared_ext_net_test_2" + description: "Project that contains the subnet to be shared" + domain: default + is_enabled: True + register: project_2 + +- name: Create router with gateway on shared external network + openstack.cloud.router: + cloud: "{{ cloud }}" + state: present + name: "shared_ext_net_test2_router" + project: "shared_ext_net_test_2" + network: "{{ external_network_name }}" + register: router + +- name: Gather routers info + openstack.cloud.routers_info: + cloud: "{{ cloud }}" + name: "shared_ext_net_test2_router" + register: routers + +- name: Verify routers info + assert: + that: + - routers.routers.0.id == router.router.id + - routers.routers.0.external_gateway_info.external_fixed_ips|length == 1 + +- name: Delete router + openstack.cloud.router: + cloud: "{{ cloud }}" + state: absent + name: "shared_ext_net_test2_router" + project: "shared_ext_net_test_2" + +- name: Delete subnet + openstack.cloud.subnet: + cloud: "{{ cloud }}" + state: absent + network_name: "{{ shared_ext_network.id }}" + name: "shared_ext_subnet" + project: "shared_ext_net_test_1" + +- name: Delete network + openstack.cloud.network: + cloud: "{{ cloud }}" + state: absent + name: "{{ external_network_name }}" + project: "shared_ext_net_test_1" + +- name: Delete project 2 + openstack.cloud.project: + cloud: "{{ cloud }}" + state: absent + name: "shared_ext_net_test_2" + +- name: Delete project 1 + openstack.cloud.project: + cloud: "{{ cloud }}" + state: absent + name: "shared_ext_net_test_1" diff --git a/plugins/modules/router.py b/plugins/modules/router.py index 7002a411..a90a1472 100644 --- a/plugins/modules/router.py +++ b/plugins/modules/router.py @@ -616,9 +616,13 @@ class RouterModule(OpenStackModule): router = self.conn.network.find_router(name, **query_filters) network = None if network_name_or_id: + # First try to find a network in the specified project. network = self.conn.network.find_network(network_name_or_id, - ignore_missing=False, **query_filters) + if not network: + # Fall back to a global search for the network. + network = self.conn.network.find_network(network_name_or_id, + ignore_missing=False) # Validate and cache the subnet IDs so we can avoid duplicate checks # and expensive API calls.