Support to check if subnet is associated with router
Change-Id: I8041fbfdb01a7a1efa721c623ab3f43efd2cc0f0
This commit is contained in:
parent
1113980613
commit
8daade000c
@ -0,0 +1,7 @@
|
||||
---
|
||||
features:
|
||||
- Added a config option ``enable_access_check`` (default True) to decide if
|
||||
Trove should check the subnet of the user port is associated with a Neutron
|
||||
router. This check is needed for creating public-facing instances and the
|
||||
instance initialization. This check could be skipped When using Neutron
|
||||
provider network.
|
@ -1396,7 +1396,14 @@ network_opts = [
|
||||
help='ID of the Neutron public network to create floating IP for the '
|
||||
'public trove instance. If not given, Trove will try to query '
|
||||
'all the public networks and use the first one in the list.'
|
||||
)
|
||||
),
|
||||
cfg.BoolOpt(
|
||||
'enable_access_check', default=True,
|
||||
help='Check if the user provided network is associated with router. '
|
||||
'This is needed for the instance initialization. The check is '
|
||||
'also necessary when creating public facing instance. A scenario '
|
||||
'to set this option False is when using Neutron provider '
|
||||
'network.')
|
||||
]
|
||||
|
||||
service_credentials_group = cfg.OptGroup(
|
||||
|
@ -54,8 +54,21 @@ def reset_management_networks():
|
||||
MGMT_NETWORKS = None
|
||||
|
||||
|
||||
def check_subnet_router(client, subnet_id):
|
||||
"""Check if the subnet is associated with a router."""
|
||||
router_ports = client.list_ports(
|
||||
device_owner="network:router_interface",
|
||||
fixed_ips=f"subnet_id={subnet_id}")["ports"]
|
||||
if not router_ports:
|
||||
raise exception.TroveError(f"Subnet {subnet_id} is not "
|
||||
f"associated with router.")
|
||||
|
||||
|
||||
def create_port(client, name, description, network_id, security_groups,
|
||||
is_public=False, subnet_id=None, ip=None):
|
||||
is_public=False, subnet_id=None, ip=None, is_mgmt=False):
|
||||
enable_access_check = (not is_mgmt and
|
||||
(CONF.network.enable_access_check or is_public))
|
||||
|
||||
port_body = {
|
||||
"port": {
|
||||
"name": name,
|
||||
@ -66,6 +79,9 @@ def create_port(client, name, description, network_id, security_groups,
|
||||
}
|
||||
|
||||
if subnet_id:
|
||||
if enable_access_check:
|
||||
check_subnet_router(client, subnet_id)
|
||||
|
||||
fixed_ips = {
|
||||
"fixed_ips": [{"subnet_id": subnet_id}]
|
||||
}
|
||||
@ -76,6 +92,11 @@ def create_port(client, name, description, network_id, security_groups,
|
||||
port = client.create_port(body=port_body)
|
||||
port_id = port['port']['id']
|
||||
|
||||
if not subnet_id and enable_access_check:
|
||||
# Check if the subnet has been associated with a router.
|
||||
subnet_id = port['port']['fixed_ips'][0]['subnet_id']
|
||||
check_subnet_router(client, subnet_id)
|
||||
|
||||
if is_public:
|
||||
make_port_public(client, port_id)
|
||||
|
||||
|
@ -471,15 +471,15 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
security_groups,
|
||||
is_public=is_public,
|
||||
subnet_id=network_info.get('subnet_id'),
|
||||
ip=network_info.get('ip_address')
|
||||
ip=network_info.get('ip_address'),
|
||||
is_mgmt=is_mgmt
|
||||
)
|
||||
except Exception:
|
||||
error = ("Failed to create %s port for instance %s"
|
||||
% (type, self.id))
|
||||
LOG.exception(error)
|
||||
except Exception as e:
|
||||
self.update_db(
|
||||
task_status=inst_models.InstanceTasks.BUILDING_ERROR_PORT
|
||||
)
|
||||
error = (f"Failed to create {type} port for instance {self.id}: "
|
||||
f"{str(e)}")
|
||||
raise TroveError(message=error)
|
||||
|
||||
return port_id
|
||||
@ -518,7 +518,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
port_id = self._create_port(
|
||||
{'network_id': CONF.management_networks[-1]},
|
||||
port_sgs,
|
||||
is_mgmt=True
|
||||
is_mgmt=True,
|
||||
)
|
||||
LOG.info("Management port %s created for instance: %s", port_id,
|
||||
self.id)
|
||||
@ -533,7 +533,7 @@ class FreshInstanceTasks(FreshInstance, NotifyMixin, ConfigurationMixin):
|
||||
network_info,
|
||||
port_sgs,
|
||||
is_mgmt=False,
|
||||
is_public=access.get('is_public', False)
|
||||
is_public=access.get('is_public', False),
|
||||
)
|
||||
LOG.info("User port %s created for instance %s", port_id,
|
||||
self.id)
|
||||
|
@ -417,12 +417,21 @@ class FreshInstanceTasksTest(BaseFreshInstanceTasksTest):
|
||||
}
|
||||
mock_client.create_port.side_effect = [
|
||||
{'port': {'id': 'fake-mgmt-port-id'}},
|
||||
{'port': {'id': 'fake-user-port-id'}}
|
||||
{
|
||||
'port': {
|
||||
'id': 'fake-user-port-id',
|
||||
'fixed_ips': [{'subnet_id': 'fake-subnet-id'}]
|
||||
}
|
||||
}
|
||||
]
|
||||
mock_client.list_networks.return_value = {
|
||||
'networks': [{'id': 'fake-public-net-id'}]
|
||||
}
|
||||
mock_client.list_ports.return_value = {
|
||||
'ports': [{'id': 'fake-port-id'}]
|
||||
}
|
||||
mock_neutron_client.return_value = mock_client
|
||||
|
||||
mock_flavor = {'id': 8, 'ram': 768, 'name': 'bigger_flavor'}
|
||||
config_content = {'config_contents': 'some junk'}
|
||||
mock_single_instance_template.return_value.config_contents = (
|
||||
|
Loading…
Reference in New Issue
Block a user