Merge "SDK for Neutron Routers"

This commit is contained in:
Zuul 2025-01-07 22:49:30 +00:00 committed by Gerrit Code Review
commit 21eceecbfb
5 changed files with 128 additions and 122 deletions

View File

@ -1927,11 +1927,9 @@ def port_update(request, port_id, **kwargs):
@profiler.trace
def router_create(request, **kwargs):
LOG.debug("router_create():, kwargs=%s", kwargs)
body = {'router': {}}
if 'tenant_id' not in kwargs:
kwargs['tenant_id'] = request.user.project_id
body['router'].update(kwargs)
router = neutronclient(request).create_router(body=body).get('router')
router = networkclient(request).create_router(**kwargs)
return Router(router)
@ -1939,70 +1937,66 @@ def router_create(request, **kwargs):
def router_update(request, r_id, **kwargs):
LOG.debug("router_update(): router_id=%(r_id)s, kwargs=%(kwargs)s",
{'r_id': r_id, 'kwargs': kwargs})
body = {'router': {}}
body['router'].update(kwargs)
router = neutronclient(request).update_router(r_id, body=body)
return Router(router['router'])
router = networkclient(request).update_router(r_id, **kwargs).to_dict()
return Router(router)
@profiler.trace
def router_get(request, router_id, **params):
router = neutronclient(request).show_router(router_id,
**params).get('router')
router = networkclient(request).get_router(router_id)
return Router(router)
@profiler.trace
def router_list(request, **params):
routers = neutronclient(request).list_routers(**params).get('routers')
routers = networkclient(request).routers(**params)
if not isinstance(routers, (types.GeneratorType, list)):
routers = [routers]
return [Router(r) for r in routers]
@profiler.trace
def router_list_on_l3_agent(request, l3_agent_id, **params):
routers = neutronclient(request).\
list_routers_on_l3_agent(l3_agent_id,
**params).get('routers')
routers = networkclient(request).agent_hosted_routers(l3_agent_id,
**params)
if not isinstance(routers, (types.GeneratorType, list)):
routers = [routers]
return [Router(r) for r in routers]
@profiler.trace
def router_delete(request, router_id):
neutronclient(request).delete_router(router_id)
networkclient(request).delete_router(router_id)
@profiler.trace
def router_add_interface(request, router_id, subnet_id=None, port_id=None):
body = {}
if subnet_id:
body['subnet_id'] = subnet_id
if port_id:
body['port_id'] = port_id
client = neutronclient(request)
return client.add_interface_router(router_id, body)
client = networkclient(request)
return client.add_interface_to_router(router=router_id,
port_id=port_id,
subnet_id=subnet_id)
@profiler.trace
def router_remove_interface(request, router_id, subnet_id=None, port_id=None):
body = {}
if subnet_id:
body['subnet_id'] = subnet_id
if port_id:
body['port_id'] = port_id
neutronclient(request).remove_interface_router(router_id, body)
client = networkclient(request)
return client.remove_interface_from_router(router=router_id,
port_id=port_id,
subnet_id=subnet_id)
@profiler.trace
def router_add_gateway(request, router_id, network_id, enable_snat=None):
body = {'network_id': network_id}
body = {'external_gateway_info': {'network_id': network_id}}
if enable_snat is not None:
body['enable_snat'] = enable_snat
neutronclient(request).add_gateway_router(router_id, body)
body['external_gateway_info']['enable_snat'] = enable_snat
networkclient(request).update_router(router_id, **body)
@profiler.trace
def router_remove_gateway(request, router_id):
neutronclient(request).remove_gateway_router(router_id)
networkclient(request).update_router(router_id,
**{'external_gateway_info': {}})
@profiler.trace

View File

@ -219,16 +219,16 @@ class RoutersTable(tables.DataTable):
verbose_name=_("Status"),
status=True,
display_choices=STATUS_DISPLAY_CHOICES)
distributed = tables.Column("distributed",
distributed = tables.Column("is_distributed",
filters=(filters.yesno, filters.capfirst),
verbose_name=_("Distributed"))
ha = tables.Column("ha",
ha = tables.Column("is_ha",
filters=(filters.yesno, filters.capfirst),
# Translators: High Availability mode of Neutron router
verbose_name=_("HA mode"))
ext_net = tables.Column(get_external_network,
verbose_name=_("External Network"))
admin_state = tables.Column("admin_state",
admin_state = tables.Column("is_admin_state_up",
verbose_name=_("Admin State"),
display_choices=ADMIN_STATE_DISPLAY_CHOICES)
availability_zones = tables.Column(get_availability_zones,

View File

@ -161,7 +161,7 @@ class DetailView(tabs.TabbedTableView):
router.status_label = filters.get_display_label(choices, router.status)
choices = rtables.ADMIN_STATE_DISPLAY_CHOICES
router.admin_state_label = (
filters.get_display_label(choices, router.admin_state))
filters.get_display_label(choices, router.is_admin_state_up))
return context
def get_tabs(self, request, *args, **kwargs):
@ -222,10 +222,10 @@ class UpdateView(forms.ModalFormView):
initial = {'router_id': router['id'],
'tenant_id': router['tenant_id'],
'name': router['name'],
'admin_state': router['admin_state_up']}
if hasattr(router, 'distributed'):
initial['mode'] = ('distributed' if router.distributed
'admin_state': router['is_admin_state_up']}
if hasattr(router, 'is_distributed'):
initial['mode'] = ('distributed' if router.is_distributed
else 'centralized')
if hasattr(router, 'ha'):
initial['ha'] = router.ha
if hasattr(router, 'is_ha'):
initial['ha'] = router.is_ha
return initial

View File

@ -16,6 +16,7 @@ import copy
from openstack.network.v2 import network as sdk_net
from openstack.network.v2 import port as sdk_port
from openstack.network.v2 import router as sdk_router
from openstack.network.v2 import subnet as sdk_subnet
from openstack.network.v2 import subnet_pool as sdk_subnet_pool
from openstack.network.v2 import trunk as sdk_trunk
@ -95,6 +96,8 @@ def data(TEST):
TEST.api_ports_sdk = list()
TEST.api_tp_ports_sdk = list()
TEST.api_subnetpools_sdk = list()
TEST.api_routers_sdk = list()
TEST.api_routers_with_routes_sdk = list()
# 1st network.
network_dict = {'is_admin_state_up': True,
@ -665,27 +668,35 @@ def data(TEST):
'name': 'router1',
'status': 'ACTIVE',
'admin_state_up': True,
'is_admin_state_up': True,
'distributed': True,
'is_distributed': True,
'external_gateway_info':
{'network_id': ext_net['id']},
'tenant_id': '1',
'availability_zone_hints': ['nova']}
TEST.api_routers.add(router_dict)
TEST.api_routers_sdk.append(sdk_router.Router(**router_dict))
TEST.routers.add(neutron.Router(router_dict))
router_dict = {'id': '10e3dc42-1ce1-4d48-87cf-7fc333055d6c',
'name': 'router2',
'status': 'ACTIVE',
'admin_state_up': False,
'is_admin_state_up': False,
'distributed': False,
'is_distributed': False,
'external_gateway_info': None,
'tenant_id': '1'}
TEST.api_routers.add(router_dict)
TEST.api_routers_sdk.append(sdk_router.Router(**router_dict))
TEST.routers.add(neutron.Router(router_dict))
router_dict = {'id': '7180cede-bcd8-4334-b19f-f7ef2f331f53',
'name': 'rulerouter',
'status': 'ACTIVE',
'admin_state_up': True,
'is_admin_state_up': True,
'distributed': False,
'is_distributed': False,
'external_gateway_info':
{'network_id': ext_net['id']},
'tenant_id': '1',
@ -700,12 +711,15 @@ def data(TEST):
'destination': '8.8.8.8/32',
'nexthops': ['1.0.0.2', '1.0.0.1']}]}
TEST.api_routers.add(router_dict)
TEST.api_routers_sdk.append(sdk_router.Router(**router_dict))
TEST.routers_with_rules.add(neutron.Router(router_dict))
router_dict_with_route = {'id': '725c24c9-061b-416b-b9d4-012392b32fd9',
'name': 'routerouter',
'status': 'ACTIVE',
'admin_state_up': True,
'is_admin_state_up': True,
'distributed': False,
'is_distributed': False,
'external_gateway_info':
{'network_id': ext_net['id']},
'tenant_id': '1',
@ -714,6 +728,8 @@ def data(TEST):
{'nexthop': '10.0.0.2',
'destination': '172.1.0.0/24'}]}
TEST.api_routers_with_routes.add(router_dict_with_route)
TEST.api_routers_with_routes_sdk.append(
sdk_router.Router(**router_dict_with_route))
TEST.routers_with_routes.add(neutron.Router(router_dict_with_route))
# Floating IP.

View File

@ -1482,85 +1482,85 @@ class NeutronApiTests(test.APIMockTestCase):
[{'port_id': old_trunk['sub_ports'][0]['port_id']}]
)
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_list(self, mock_neutronclient):
routers = {'routers': self.api_routers.list()}
@mock.patch.object(api.neutron, 'networkclient')
def test_router_list(self, mock_networkclient):
routers = {'routers': self.api_routers_sdk}
neutronclient = mock_neutronclient.return_value
neutronclient.list_routers.return_value = routers
networklient = mock_networkclient.return_value
networklient.routers.return_value = routers
ret_val = api.neutron.router_list(self.request)
for n in ret_val:
self.assertIsInstance(n, api.neutron.Router)
neutronclient.list_routers.assert_called_once_with()
networklient.routers.assert_called_once_with()
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_get(self, mock_neutronclient):
router = {'router': self.api_routers.first()}
router_id = self.api_routers.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_get(self, mock_networkclient):
router = {'router': self.api_routers_sdk[0]}
router_id = self.api_routers_sdk[0]['id']
neutronclient = mock_neutronclient.return_value
neutronclient.show_router.return_value = router
networkclient = mock_networkclient.return_value
networkclient.get_router.return_value = router
ret_val = api.neutron.router_get(self.request, router_id)
self.assertIsInstance(ret_val, api.neutron.Router)
neutronclient.show_router.assert_called_once_with(router_id)
networkclient.get_router.assert_called_once_with(router_id)
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_create(self, mock_neutronclient):
router = {'router': self.api_routers.first()}
@mock.patch.object(api.neutron, 'networkclient')
def test_router_create(self, mock_networkclient):
router = {'router': self.api_routers_sdk[0]}
neutronclient = mock_neutronclient.return_value
form_data = {'router': {'name': 'router1',
'tenant_id': self.request.user.project_id}}
neutronclient.create_router.return_value = router
networkclient = mock_networkclient.return_value
networkclient.create_router.return_value = router
ret_val = api.neutron.router_create(self.request, name='router1')
self.assertIsInstance(ret_val, api.neutron.Router)
neutronclient.create_router.assert_called_once_with(body=form_data)
networkclient.create_router.assert_called_once_with(
name=self.api_routers_sdk[0]['name'],
tenant_id=self.request.user.project_id
)
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_delete(self, mock_neutronclient):
router_id = self.api_routers.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_delete(self, mock_networkclient):
router_id = self.api_routers_sdk[0]['id']
neutronclient = mock_neutronclient.return_value
neutronclient.delete_router.return_value = None
networkclient = mock_networkclient.return_value
networkclient.delete_router.return_value = None
api.neutron.router_delete(self.request, router_id)
neutronclient.delete_router.assert_called_once_with(router_id)
networkclient.delete_router.assert_called_once_with(router_id)
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_add_interface(self, mock_neutronclient):
subnet_id = self.api_subnets.first()['id']
router_id = self.api_routers.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_add_interface(self, mock_networklient):
subnet_id = self.api_subnets_sdk[0]['id']
router_id = self.api_routers_sdk[0]['id']
neutronclient = mock_neutronclient.return_value
form_data = {'subnet_id': subnet_id}
neutronclient.add_interface_router.return_value = None
networkclient = mock_networklient.return_value
networkclient.add_interface_to_router.return_value = None
api.neutron.router_add_interface(
self.request, router_id, subnet_id=subnet_id)
neutronclient.add_interface_router.assert_called_once_with(router_id,
form_data)
networkclient.add_interface_to_router.assert_called_once_with(
router=router_id, port_id=None, subnet_id=subnet_id)
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_remove_interface(self, mock_neutronclient):
router_id = self.api_routers.first()['id']
fake_port = self.api_ports.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_remove_interface(self, mock_networkclient):
router_id = self.api_routers_sdk[0]['id']
fake_port = self.api_ports_sdk[0]['id']
neutronclient = mock_neutronclient.return_value
neutronclient.remove_interface_router.return_value = None
networkclient = mock_networkclient.return_value
networkclient.remove_interface_from_router.return_value = None
api.neutron.router_remove_interface(
self.request, router_id, port_id=fake_port)
neutronclient.remove_interface_router.assert_called_once_with(
router_id, {'port_id': fake_port})
networkclient.remove_interface_from_router.assert_called_once_with(
router=router_id, port_id=fake_port, subnet_id=None)
# Mocking neutronclient() does not work because api.neutron.list_extensions
# is decorated with memoized_with_request, so we need to mock
@ -1576,57 +1576,55 @@ class NeutronApiTests(test.APIMockTestCase):
mock_list_extensions.assert_called_once_with()
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_static_route_list(self, mock_neutronclient):
router = {'router': self.api_routers_with_routes.first()}
router_id = self.api_routers_with_routes.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_static_route_list(self, mock_networkclient):
router = self.api_routers_with_routes_sdk[0]
router_id = self.api_routers_with_routes_sdk[0]['id']
neutronclient = mock_neutronclient.return_value
neutronclient.show_router.return_value = router
networkclient = mock_networkclient.return_value
networkclient.get_router.return_value = router
ret_val = api.neutron.router_static_route_list(self.request, router_id)
self.assertIsInstance(ret_val[0], api.neutron.RouterStaticRoute)
neutronclient.show_router.assert_called_once_with(router_id)
networkclient.get_router.assert_called_once_with(router_id)
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_static_route_remove(self, mock_neutronclient):
router = {'router': self.api_routers_with_routes.first()}
router_id = self.api_routers_with_routes.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_static_route_remove(self, mock_networkclient):
router = self.api_routers_with_routes_sdk[0]
router_id = self.api_routers_with_routes_sdk[0]['id']
post_router = copy.deepcopy(router)
route = api.neutron.RouterStaticRoute(post_router['router']
['routes'].pop())
route = api.neutron.RouterStaticRoute(
post_router['routes'].pop())
neutronclient = mock_neutronclient.return_value
neutronclient.show_router.return_value = router
neutronclient.update_router.return_value = post_router
networkclient = mock_networkclient.return_value
networkclient.get_router.return_value = router
networkclient.update_router.return_value = post_router
api.neutron.router_static_route_remove(self.request,
router_id, route.id)
neutronclient.show_router.assert_called_once_with(router_id)
body = {'router': {'routes': post_router['router']['routes']}}
neutronclient.update_router.assert_called_once_with(
router_id, body=body)
networkclient.get_router.assert_called_once_with(router_id)
networkclient.update_router.assert_called_once_with(
router_id, routes=post_router['routes'])
@mock.patch.object(api.neutron, 'neutronclient')
def test_router_static_route_add(self, mock_neutronclient):
router = {'router': self.api_routers_with_routes.first()}
router_id = self.api_routers_with_routes.first()['id']
@mock.patch.object(api.neutron, 'networkclient')
def test_router_static_route_add(self, mock_networkclient):
router = self.api_routers_with_routes_sdk[0]
router_id = self.api_routers_with_routes_sdk[0]['id']
post_router = copy.deepcopy(router)
route = {'nexthop': '10.0.0.5', 'destination': '40.0.1.0/24'}
post_router['router']['routes'].insert(0, route)
body = {'router': {'routes': post_router['router']['routes']}}
post_router['routes'].insert(0, route)
neutronclient = mock_neutronclient.return_value
neutronclient.show_router.return_value = router
neutronclient.update_router.return_value = post_router
networkclient = mock_networkclient.return_value
networkclient.get_router.return_value = router
networkclient.update_router.return_value = post_router
api.neutron.router_static_route_add(self.request, router_id, route)
neutronclient.show_router.assert_called_once_with(router_id)
neutronclient.update_router.assert_called_once_with(router_id,
body=body)
networkclient.get_router.assert_called_once_with(router_id)
networkclient.update_router.assert_called_once_with(
router_id, routes=post_router['routes'])
# NOTE(amotoki): "dvr" permission tests check most of
# get_feature_permission features.
@ -2615,8 +2613,7 @@ class NeutronApiFloatingIpTests(test.APIMockTestCase):
if n['is_router_external']]
list_networks_retvals = [ext_nets, shared_nets]
self.netclient.networks.side_effect = list_networks_retvals
self.qclient.list_routers.return_value = {'routers':
self.api_routers.list()}
self.netclient.routers.return_value = self.api_routers_sdk
shared_subs = [s for s in self.api_subnets_sdk
if s['id'] in shared_subnet_ids]
self.netclient.subnets.return_value = shared_subs
@ -2638,7 +2635,7 @@ class NeutronApiFloatingIpTests(test.APIMockTestCase):
mock.call(**{'router:external': True}),
mock.call(is_shared=True),
])
self.qclient.list_routers.assert_called_once_with()
self.netclient.routers.assert_called_once_with()
self.netclient.subnets.assert_called_once_with()
@mock.patch.object(api._nova, 'novaclient')
@ -2659,8 +2656,7 @@ class NeutronApiFloatingIpTests(test.APIMockTestCase):
if n['is_router_external']]
list_nets_retvals.append(ext_nets)
self.qclient.list_routers.side_effect = [{'routers':
self.api_routers.list()}]
self.netclient.routers.side_effect = self.api_routers_sdk
rinfs = [p for p in ports
if p['device_owner'] in api.neutron.ROUTER_INTERFACE_OWNERS]
list_ports_retvals.append(rinfs)
@ -2688,7 +2684,7 @@ class NeutronApiFloatingIpTests(test.APIMockTestCase):
mock.call(**{'router:external': True}),
mock.call(is_shared=True),
])
self.qclient.list_routers.assert_called_once_with()
self.netclient.routers.assert_called_once_with()
self.netclient.subnets.assert_called_once_with()
novaclient.versions.get_current.assert_called_once_with()
novaclient.servers.get.assert_called_once_with(server.id)