Allow reading a tenant router's external IP
Adds an external IPs field to the external gateway information for a router so the external IP address of the router can be read by the tenant. DocImpact Closes-Bug: #1255142 Change-Id: If4e77c445e9b855ff77deea6c8df4a0b3cf249d4
This commit is contained in:
parent
dd238d0aac
commit
c7baaa068e
@ -101,7 +101,11 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
|
|||||||
def _make_router_dict(self, router, fields=None, process_extensions=True):
|
def _make_router_dict(self, router, fields=None, process_extensions=True):
|
||||||
res = dict((key, router[key]) for key in CORE_ROUTER_ATTRS)
|
res = dict((key, router[key]) for key in CORE_ROUTER_ATTRS)
|
||||||
if router['gw_port_id']:
|
if router['gw_port_id']:
|
||||||
ext_gw_info = {'network_id': router.gw_port['network_id']}
|
ext_gw_info = {
|
||||||
|
'network_id': router.gw_port['network_id'],
|
||||||
|
'external_fixed_ips': [{'subnet_id': ip["subnet_id"],
|
||||||
|
'ip_address': ip["ip_address"]}
|
||||||
|
for ip in router.gw_port['fixed_ips']]}
|
||||||
else:
|
else:
|
||||||
ext_gw_info = None
|
ext_gw_info = None
|
||||||
res.update({
|
res.update({
|
||||||
|
@ -43,7 +43,13 @@ class L3_NAT_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
|
|||||||
nw_id = router_db.gw_port['network_id']
|
nw_id = router_db.gw_port['network_id']
|
||||||
router_res[EXTERNAL_GW_INFO] = {
|
router_res[EXTERNAL_GW_INFO] = {
|
||||||
'network_id': nw_id,
|
'network_id': nw_id,
|
||||||
'enable_snat': router_db.enable_snat}
|
'enable_snat': router_db.enable_snat,
|
||||||
|
'external_fixed_ips': [
|
||||||
|
{'subnet_id': ip["subnet_id"],
|
||||||
|
'ip_address': ip["ip_address"]}
|
||||||
|
for ip in router_db.gw_port['fixed_ips']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
def _update_router_gw_info(self, context, router_id, info, router=None):
|
def _update_router_gw_info(self, context, router_id, info, router=None):
|
||||||
# Load the router only if necessary
|
# Load the router only if necessary
|
||||||
|
@ -100,7 +100,20 @@ RESOURCE_ATTRIBUTE_MAP = {
|
|||||||
'is_visible': True},
|
'is_visible': True},
|
||||||
EXTERNAL_GW_INFO: {'allow_post': True, 'allow_put': True,
|
EXTERNAL_GW_INFO: {'allow_post': True, 'allow_put': True,
|
||||||
'is_visible': True, 'default': None,
|
'is_visible': True, 'default': None,
|
||||||
'enforce_policy': True}
|
'enforce_policy': True,
|
||||||
|
'validate': {
|
||||||
|
'type:dict_or_nodata': {
|
||||||
|
'network_id': {'type:uuid': None,
|
||||||
|
'required': True},
|
||||||
|
'external_fixed_ips': {
|
||||||
|
'convert_list_to':
|
||||||
|
attr.convert_kvp_list_to_dict,
|
||||||
|
'type:fixed_ips': None,
|
||||||
|
'default': None,
|
||||||
|
'required': False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
},
|
},
|
||||||
'floatingips': {
|
'floatingips': {
|
||||||
'id': {'allow_post': False, 'allow_put': False,
|
'id': {'allow_post': False, 'allow_put': False,
|
||||||
@ -174,6 +187,7 @@ class L3(extensions.ExtensionDescriptor):
|
|||||||
"""Returns Ext Resources."""
|
"""Returns Ext Resources."""
|
||||||
plural_mappings = resource_helper.build_plural_mappings(
|
plural_mappings = resource_helper.build_plural_mappings(
|
||||||
{}, RESOURCE_ATTRIBUTE_MAP)
|
{}, RESOURCE_ATTRIBUTE_MAP)
|
||||||
|
plural_mappings['external_fixed_ips'] = 'external_fixed_ip'
|
||||||
attr.PLURALS.update(plural_mappings)
|
attr.PLURALS.update(plural_mappings)
|
||||||
action_map = {'router': {'add_router_interface': 'PUT',
|
action_map = {'router': {'add_router_interface': 'PUT',
|
||||||
'remove_router_interface': 'PUT'}}
|
'remove_router_interface': 'PUT'}}
|
||||||
|
@ -29,7 +29,13 @@ EXTENDED_ATTRIBUTES_2_0 = {
|
|||||||
{'type:dict_or_nodata':
|
{'type:dict_or_nodata':
|
||||||
{'network_id': {'type:uuid': None, 'required': True},
|
{'network_id': {'type:uuid': None, 'required': True},
|
||||||
'enable_snat': {'type:boolean': None, 'required': False,
|
'enable_snat': {'type:boolean': None, 'required': False,
|
||||||
'convert_to': attrs.convert_to_boolean}}
|
'convert_to': attrs.convert_to_boolean},
|
||||||
|
'external_fixed_ips': {
|
||||||
|
'convert_list_to': attrs.convert_kvp_list_to_dict,
|
||||||
|
'validate': {'type:fixed_ips': None},
|
||||||
|
'default': None,
|
||||||
|
'required': False}
|
||||||
|
}
|
||||||
}}}}
|
}}}}
|
||||||
|
|
||||||
|
|
||||||
|
@ -245,14 +245,16 @@ class TestL3GwModeMixin(testlib_api.SqlTestCase,
|
|||||||
def test_make_router_dict_with_ext_gw(self):
|
def test_make_router_dict_with_ext_gw(self):
|
||||||
router_dict = self.target_object._make_router_dict(self.router)
|
router_dict = self.target_object._make_router_dict(self.router)
|
||||||
self.assertEqual({'network_id': self.ext_net_id,
|
self.assertEqual({'network_id': self.ext_net_id,
|
||||||
'enable_snat': True},
|
'enable_snat': True,
|
||||||
|
'external_fixed_ips': []},
|
||||||
router_dict[l3.EXTERNAL_GW_INFO])
|
router_dict[l3.EXTERNAL_GW_INFO])
|
||||||
|
|
||||||
def test_make_router_dict_with_ext_gw_snat_disabled(self):
|
def test_make_router_dict_with_ext_gw_snat_disabled(self):
|
||||||
self.router.enable_snat = False
|
self.router.enable_snat = False
|
||||||
router_dict = self.target_object._make_router_dict(self.router)
|
router_dict = self.target_object._make_router_dict(self.router)
|
||||||
self.assertEqual({'network_id': self.ext_net_id,
|
self.assertEqual({'network_id': self.ext_net_id,
|
||||||
'enable_snat': False},
|
'enable_snat': False,
|
||||||
|
'external_fixed_ips': []},
|
||||||
router_dict[l3.EXTERNAL_GW_INFO])
|
router_dict[l3.EXTERNAL_GW_INFO])
|
||||||
|
|
||||||
def test_build_routers_list_no_ext_gw(self):
|
def test_build_routers_list_no_ext_gw(self):
|
||||||
@ -364,7 +366,10 @@ class ExtGwModeIntTestCase(test_db_plugin.NeutronDbPluginV2TestCase,
|
|||||||
('admin_state_up', True), ('status', 'ACTIVE'),
|
('admin_state_up', True), ('status', 'ACTIVE'),
|
||||||
('external_gateway_info',
|
('external_gateway_info',
|
||||||
{'network_id': ext_net_id,
|
{'network_id': ext_net_id,
|
||||||
'enable_snat': snat_expected_value})]
|
'enable_snat': snat_expected_value,
|
||||||
|
'external_fixed_ips': [{
|
||||||
|
'ip_address': mock.ANY,
|
||||||
|
'subnet_id': s['subnet']['id']}]})]
|
||||||
with self.router(
|
with self.router(
|
||||||
name=name, admin_state_up=True, tenant_id=tenant_id,
|
name=name, admin_state_up=True, tenant_id=tenant_id,
|
||||||
external_gateway_info=input_value) as router:
|
external_gateway_info=input_value) as router:
|
||||||
|
@ -1094,11 +1094,17 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
|
|||||||
'remove', tenant_router['router']['id'],
|
'remove', tenant_router['router']['id'],
|
||||||
s['subnet']['id'], None, tenant_id='tenant_a')
|
s['subnet']['id'], None, tenant_id='tenant_a')
|
||||||
|
|
||||||
def test_router_add_gateway_invalid_network_returns_404(self):
|
def test_router_add_gateway_invalid_network_returns_400(self):
|
||||||
with self.router() as r:
|
with self.router() as r:
|
||||||
self._add_external_gateway_to_router(
|
self._add_external_gateway_to_router(
|
||||||
r['router']['id'],
|
r['router']['id'],
|
||||||
"foobar", expected_code=exc.HTTPNotFound.code)
|
"foobar", expected_code=exc.HTTPBadRequest.code)
|
||||||
|
|
||||||
|
def test_router_add_gateway_non_existent_network_returns_404(self):
|
||||||
|
with self.router() as r:
|
||||||
|
self._add_external_gateway_to_router(
|
||||||
|
r['router']['id'],
|
||||||
|
_uuid(), expected_code=exc.HTTPNotFound.code)
|
||||||
|
|
||||||
def test_router_add_gateway_net_not_external_returns_400(self):
|
def test_router_add_gateway_net_not_external_returns_400(self):
|
||||||
with self.router() as r:
|
with self.router() as r:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user