commit 5efbc159859c67212bc3f0221c40ab3a1e505dd7 Author: Lingxian Kong Date: Mon Oct 12 10:31:30 2020 +1300 Create floating IP in the user's project From the perspective of the public cloud, the floating IP should be created in the user's own project. Story: #2008246 Task: #41093 Change-Id: Ic358a2844c1b1f94a1b77ee67102b1c9c236a365 diff --git a/trove/common/neutron.py b/trove/common/neutron.py index 25690ad..1f9d65e 100644 --- a/trove/common/neutron.py +++ b/trove/common/neutron.py @@ -65,7 +65,8 @@ def check_subnet_router(client, subnet_id): def create_port(client, name, description, network_id, security_groups, - is_public=False, subnet_id=None, ip=None, is_mgmt=False): + is_public=False, subnet_id=None, ip=None, is_mgmt=False, + project_id=None): enable_access_check = (not is_mgmt and (CONF.network.enable_access_check or is_public)) @@ -98,7 +99,7 @@ def create_port(client, name, description, network_id, security_groups, check_subnet_router(client, subnet_id) if is_public: - make_port_public(client, port_id) + make_port_public(client, port_id, project_id) return port_id @@ -118,7 +119,8 @@ def delete_port(client, id): client.delete_port(id) -def make_port_public(client, port_id): +def make_port_public(client, port_id, project_id): + """Associate floating IP with the port.""" public_network_id = get_public_network(client) if not public_network_id: raise exception.PublicNetworkNotFound() @@ -129,11 +131,18 @@ def make_port_public(client, port_id): 'port_id': port_id, } } + if project_id: + fip_body['floatingip']['project_id'] = project_id try: - client.create_floatingip(fip_body) + LOG.debug(f"Creating floating IP for the port {port_id}, " + f"request body: {fip_body}") + ret = client.create_floatingip(fip_body) + LOG.info(f"Successfully created floating IP " + f"{ret['floatingip']['floating_ip_address']} for port " + f"{port_id}") except Exception as e: - LOG.error(f"Failed to associate public IP with port {port_id}: " + LOG.error(f"Failed to create public IP with port {port_id}: " f"{str(e)}") raise exception.TroveError('Failed to expose instance port to public.') @@ -156,13 +165,13 @@ def get_public_network(client): return ret['networks'][0].get('id') -def ensure_port_access(client, port_id, is_public): +def ensure_port_access(client, port_id, is_public, project_id): fips = client.list_floatingips(port_id=port_id)["floatingips"] if is_public and not fips: # Associate floating IP LOG.debug(f"Associate public IP with port {port_id}") - make_port_public(client, port_id) + make_port_public(client, port_id, project_id) return if not is_public and fips: diff --git a/trove/instance/models.py b/trove/instance/models.py index de2ffdd..089b0e1 100644 --- a/trove/instance/models.py +++ b/trove/instance/models.py @@ -924,6 +924,13 @@ class BaseInstance(SimpleInstance): self.context, region_name=self.db_info.region_id) return self._neutron_client + @property + def user_neutron_client(self): + if not self._user_neutron_client: + self._user_neutron_client = clients.neutron_client( + self.context, region_name=self.db_info.region_id) + return self._user_neutron_client + def reset_task_status(self): self.update_db(task_status=InstanceTasks.NONE) diff --git a/trove/taskmanager/models.py b/trove/taskmanager/models.py index 5ddfc85..df62966 100755 --- a/trove/taskmanager/models.py +++ b/trove/taskmanager/models.py @@ -472,7 +472,8 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin): is_public=is_public, subnet_id=network_info.get('subnet_id'), ip=network_info.get('ip_address'), - is_mgmt=is_mgmt + is_mgmt=is_mgmt, + project_id=self.tenant_id ) except Exception as e: self.update_db( @@ -1375,7 +1376,7 @@ class BuiltInstanceTasks(BuiltInstance, NotifyMixin, ConfigurationMixin): LOG.debug(f"Updating port {port['id']}, is_public: " f"{new_is_public}") neutron.ensure_port_access(self.neutron_client, port['id'], - new_is_public) + new_is_public, self.tenant_id) if CONF.trove_security_groups_support: if allowed_cidrs != new_allowed_cidrs: diff --git a/trove/tests/unittests/taskmanager/test_models.py b/trove/tests/unittests/taskmanager/test_models.py index ece9113..1db929d 100644 --- a/trove/tests/unittests/taskmanager/test_models.py +++ b/trove/tests/unittests/taskmanager/test_models.py @@ -212,7 +212,7 @@ class BaseFreshInstanceTasksTest(trove_testtools.TestCase): self.guestconfig = f.name f.write(self.guestconfig_content) self.freshinstancetasks = taskmanager_models.FreshInstanceTasks( - None, Mock(), None, None) + None, MagicMock(), None, None) self.freshinstancetasks.context = trove.common.context.TroveContext( user='test_user') @@ -419,7 +419,7 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest): *args): self.patch_conf_property('management_networks', ['fake-mgmt-uuid']) - mock_client = Mock() + mock_client = MagicMock() mock_client.create_security_group.return_value = { 'security_group': {'id': 'fake-sg-id'} } @@ -476,6 +476,7 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest): "floatingip": { 'floating_network_id': 'fake-public-net-id', 'port_id': 'fake-user-port-id', + 'project_id': mock.ANY } } mock_client.create_floatingip.assert_called_once_with(