summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Benton <blak111@gmail.com>2014-06-18 12:03:01 -0700
committerKyle Mestery <mestery@mestery.com>2014-10-07 16:13:29 +0000
commitb1282b8410ca546bfa15e1174ab9bafe1c29ee43 (patch)
treecc634eb0e520b29d9516be6c4fb93fb7f53f45ce
parent205162f58050fcb94db53cd51b674d2093dfe700 (diff)
downloadneutron-b1282b8410ca546bfa15e1174ab9bafe1c29ee43.tar.gz
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 (cherry picked from commit c7baaa068ed1d3c8b02717232edef60ba1b655f6)
-rw-r--r--neutron/db/l3_db.py6
-rw-r--r--neutron/db/l3_gwmode_db.py8
-rw-r--r--neutron/extensions/l3.py16
-rw-r--r--neutron/extensions/l3_ext_gw_mode.py8
-rw-r--r--neutron/tests/unit/test_extension_ext_gw_mode.py11
-rw-r--r--neutron/tests/unit/test_l3_plugin.py10
6 files changed, 50 insertions, 9 deletions
diff --git a/neutron/db/l3_db.py b/neutron/db/l3_db.py
index afc01a33bb..709c99cb0d 100644
--- a/neutron/db/l3_db.py
+++ b/neutron/db/l3_db.py
@@ -101,7 +101,11 @@ class L3_NAT_dbonly_mixin(l3.RouterPluginBase):
def _make_router_dict(self, router, fields=None, process_extensions=True):
res = dict((key, router[key]) for key in CORE_ROUTER_ATTRS)
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:
ext_gw_info = None
res.update({
diff --git a/neutron/db/l3_gwmode_db.py b/neutron/db/l3_gwmode_db.py
index dce6cafe90..e9f081f6fc 100644
--- a/neutron/db/l3_gwmode_db.py
+++ b/neutron/db/l3_gwmode_db.py
@@ -43,7 +43,13 @@ class L3_NAT_dbonly_mixin(l3_db.L3_NAT_dbonly_mixin):
nw_id = router_db.gw_port['network_id']
router_res[EXTERNAL_GW_INFO] = {
'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):
# Load the router only if necessary
diff --git a/neutron/extensions/l3.py b/neutron/extensions/l3.py
index b02c9337b6..1497d9fb45 100644
--- a/neutron/extensions/l3.py
+++ b/neutron/extensions/l3.py
@@ -100,7 +100,20 @@ RESOURCE_ATTRIBUTE_MAP = {
'is_visible': True},
EXTERNAL_GW_INFO: {'allow_post': True, 'allow_put': True,
'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': {
'id': {'allow_post': False, 'allow_put': False,
@@ -174,6 +187,7 @@ class L3(extensions.ExtensionDescriptor):
"""Returns Ext Resources."""
plural_mappings = resource_helper.build_plural_mappings(
{}, RESOURCE_ATTRIBUTE_MAP)
+ plural_mappings['external_fixed_ips'] = 'external_fixed_ip'
attr.PLURALS.update(plural_mappings)
action_map = {'router': {'add_router_interface': 'PUT',
'remove_router_interface': 'PUT'}}
diff --git a/neutron/extensions/l3_ext_gw_mode.py b/neutron/extensions/l3_ext_gw_mode.py
index 31c943a9c8..ae0ab1d54b 100644
--- a/neutron/extensions/l3_ext_gw_mode.py
+++ b/neutron/extensions/l3_ext_gw_mode.py
@@ -29,7 +29,13 @@ EXTENDED_ATTRIBUTES_2_0 = {
{'type:dict_or_nodata':
{'network_id': {'type:uuid': None, 'required': True},
'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}
+ }
}}}}
diff --git a/neutron/tests/unit/test_extension_ext_gw_mode.py b/neutron/tests/unit/test_extension_ext_gw_mode.py
index c119470d39..502fd1c0f9 100644
--- a/neutron/tests/unit/test_extension_ext_gw_mode.py
+++ b/neutron/tests/unit/test_extension_ext_gw_mode.py
@@ -245,14 +245,16 @@ class TestL3GwModeMixin(testlib_api.SqlTestCase,
def test_make_router_dict_with_ext_gw(self):
router_dict = self.target_object._make_router_dict(self.router)
self.assertEqual({'network_id': self.ext_net_id,
- 'enable_snat': True},
+ 'enable_snat': True,
+ 'external_fixed_ips': []},
router_dict[l3.EXTERNAL_GW_INFO])
def test_make_router_dict_with_ext_gw_snat_disabled(self):
self.router.enable_snat = False
router_dict = self.target_object._make_router_dict(self.router)
self.assertEqual({'network_id': self.ext_net_id,
- 'enable_snat': False},
+ 'enable_snat': False,
+ 'external_fixed_ips': []},
router_dict[l3.EXTERNAL_GW_INFO])
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'),
('external_gateway_info',
{'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(
name=name, admin_state_up=True, tenant_id=tenant_id,
external_gateway_info=input_value) as router:
diff --git a/neutron/tests/unit/test_l3_plugin.py b/neutron/tests/unit/test_l3_plugin.py
index ecb1ead448..6b82d1759c 100644
--- a/neutron/tests/unit/test_l3_plugin.py
+++ b/neutron/tests/unit/test_l3_plugin.py
@@ -1102,11 +1102,17 @@ class L3NatTestCaseBase(L3NatTestCaseMixin):
'remove', tenant_router['router']['id'],
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:
self._add_external_gateway_to_router(
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):
with self.router() as r: