Add port_details to Floating IP
If the floating IP is associated with a port, this attribute will contain detailed information of the associated port. This allows users to retrieve the floating IPs with information of its associated port (if any) in one API call. Other related patches: * neutron-lib: https://review.openstack.org/#/c/534882/ * osc: https://review.openstack.org/#/c/533809/ * sdk: https://review.openstack.org/#/c/533811/ * tempest-plugin: https://review.openstack.org/#/c/561710/ APIImpact the API reference needs to be updated Change-Id: I31e940d2986278d2fbee6fdfea4ff15f7c07ebaa Partial-Bug: #1723026
This commit is contained in:
parent
f2dced777a
commit
c760d4f26f
42
neutron/db/l3_fip_port_details.py
Normal file
42
neutron/db/l3_fip_port_details.py
Normal file
@ -0,0 +1,42 @@
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from neutron_lib.api.definitions import l3 as l3_apidef
|
||||
|
||||
from neutron.db import _resource_extend as resource_extend
|
||||
|
||||
|
||||
def _make_port_details_dict(port):
|
||||
return {'name': port['name'],
|
||||
'network_id': port['network_id'],
|
||||
'mac_address': port['mac_address'],
|
||||
'admin_state_up': port['admin_state_up'],
|
||||
'status': port['status'],
|
||||
'device_id': port['device_id'],
|
||||
'device_owner': port['device_owner']}
|
||||
|
||||
|
||||
@resource_extend.has_resource_extenders
|
||||
class Fip_port_details_db_mixin(object):
|
||||
"""Mixin class to enable floating IP's port_details attributes."""
|
||||
|
||||
@staticmethod
|
||||
@resource_extend.extends([l3_apidef.FLOATINGIPS])
|
||||
def _extend_fip_dict_device_id(fip_res, fip_db):
|
||||
if fip_db.fixed_port:
|
||||
fip_res['port_details'] = _make_port_details_dict(
|
||||
fip_db.fixed_port)
|
||||
else:
|
||||
fip_res['port_details'] = None
|
||||
return fip_res
|
@ -90,6 +90,9 @@ class FloatingIP(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
cascade='all,delete-orphan'),
|
||||
foreign_keys='FloatingIP.floating_port_id')
|
||||
fixed_port_id = sa.Column(sa.String(36), sa.ForeignKey('ports.id'))
|
||||
fixed_port = orm.relationship(models_v2.Port,
|
||||
foreign_keys='FloatingIP.fixed_port_id',
|
||||
lazy='joined')
|
||||
fixed_ip_address = sa.Column(sa.String(64))
|
||||
router_id = sa.Column(sa.String(36), sa.ForeignKey('routers.id'))
|
||||
# Additional attribute for keeping track of the router where the floating
|
||||
|
43
neutron/extensions/_fip_port_details_lib.py
Normal file
43
neutron/extensions/_fip_port_details_lib.py
Normal file
@ -0,0 +1,43 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
TODO(hongbin): This module should be deleted once neutron-lib containing
|
||||
https://review.openstack.org/#/c/534882/ change is released.
|
||||
"""
|
||||
|
||||
from neutron_lib.api.definitions import l3
|
||||
from neutron_lib import constants
|
||||
|
||||
|
||||
PORT_DETAILS = 'port_details'
|
||||
|
||||
ALIAS = 'fip-port-details'
|
||||
IS_SHIM_EXTENSION = False
|
||||
IS_STANDARD_ATTR_EXTENSION = False
|
||||
NAME = 'Floating IP Port Details Extension'
|
||||
DESCRIPTION = 'Add port_details attribute to Floating IP resource'
|
||||
UPDATED_TIMESTAMP = '2018-04-09T10:00:00-00:00'
|
||||
RESOURCE_ATTRIBUTE_MAP = {
|
||||
l3.FLOATINGIPS: {
|
||||
PORT_DETAILS: {
|
||||
'allow_post': False, 'allow_put': False,
|
||||
'default': constants.ATTR_NOT_SPECIFIED,
|
||||
'is_visible': True
|
||||
}
|
||||
}
|
||||
}
|
||||
SUB_RESOURCE_ATTRIBUTE_MAP = {}
|
||||
ACTION_MAP = {}
|
||||
REQUIRED_EXTENSIONS = [l3.ALIAS]
|
||||
OPTIONAL_EXTENSIONS = []
|
||||
ACTION_STATUS = {}
|
21
neutron/extensions/fip_port_details.py
Normal file
21
neutron/extensions/fip_port_details.py
Normal file
@ -0,0 +1,21 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutron_lib.api import extensions
|
||||
|
||||
from neutron.extensions import _fip_port_details_lib as apidef
|
||||
|
||||
|
||||
class Fip_port_details(extensions.APIExtensionDescriptor):
|
||||
"""Extension class adding port_details to Floating IP."""
|
||||
|
||||
api_definition = apidef
|
@ -32,6 +32,7 @@ from neutron.db import dns_db
|
||||
from neutron.db import extraroute_db
|
||||
from neutron.db import l3_dvr_ha_scheduler_db
|
||||
from neutron.db import l3_dvrscheduler_db
|
||||
from neutron.db import l3_fip_port_details
|
||||
from neutron.db import l3_fip_qos
|
||||
from neutron.db import l3_gwmode_db
|
||||
from neutron.db import l3_hamode_db
|
||||
@ -67,7 +68,8 @@ class L3RouterPlugin(service_base.ServicePluginBase,
|
||||
l3_gwmode_db.L3_NAT_db_mixin,
|
||||
l3_dvr_ha_scheduler_db.L3_DVR_HA_scheduler_db_mixin,
|
||||
dns_db.DNSDbMixin,
|
||||
l3_fip_qos.FloatingQoSDbMixin):
|
||||
l3_fip_qos.FloatingQoSDbMixin,
|
||||
l3_fip_port_details.Fip_port_details_db_mixin):
|
||||
|
||||
"""Implementation of the Neutron L3 Router Service Plugin.
|
||||
|
||||
@ -81,7 +83,8 @@ class L3RouterPlugin(service_base.ServicePluginBase,
|
||||
_supported_extension_aliases = ["dvr", "router", "ext-gw-mode",
|
||||
"extraroute", "l3_agent_scheduler",
|
||||
"l3-ha", "router_availability_zone",
|
||||
"l3-flavors", "qos-fip"]
|
||||
"l3-flavors", "qos-fip",
|
||||
"fip-port-details"]
|
||||
|
||||
__native_pagination_support = True
|
||||
__native_sorting_support = True
|
||||
|
@ -14,6 +14,7 @@ NETWORK_API_EXTENSIONS+=",ext-gw-mode"
|
||||
NETWORK_API_EXTENSIONS+=",external-net"
|
||||
NETWORK_API_EXTENSIONS+=",extra_dhcp_opt"
|
||||
NETWORK_API_EXTENSIONS+=",extraroute"
|
||||
NETWORK_API_EXTENSIONS+=",fip-port-details"
|
||||
NETWORK_API_EXTENSIONS+=",flavors"
|
||||
NETWORK_API_EXTENSIONS+=",ip-substring-filtering"
|
||||
NETWORK_API_EXTENSIONS+=",l3-flavors"
|
||||
|
136
neutron/tests/unit/extensions/test_fip_port_details.py
Normal file
136
neutron/tests/unit/extensions/test_fip_port_details.py
Normal file
@ -0,0 +1,136 @@
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from neutron.db import l3_fip_port_details
|
||||
from neutron.extensions import _fip_port_details_lib as apiref
|
||||
from neutron.extensions import l3
|
||||
from neutron.tests.unit.extensions import test_l3
|
||||
|
||||
|
||||
class FloatingIPPortDetailsTestExtensionManager(object):
|
||||
|
||||
def get_resources(self):
|
||||
return l3.L3.get_resources()
|
||||
|
||||
def get_actions(self):
|
||||
return []
|
||||
|
||||
def get_request_extensions(self):
|
||||
return []
|
||||
|
||||
|
||||
class TestFloatingIPPortDetailsIntPlugin(
|
||||
test_l3.TestL3NatIntPlugin,
|
||||
l3_fip_port_details.Fip_port_details_db_mixin):
|
||||
supported_extension_aliases = ["external-net", "router",
|
||||
apiref.ALIAS]
|
||||
|
||||
|
||||
class TestFloatingIPPortDetailsL3NatServicePlugin(
|
||||
test_l3.TestL3NatServicePlugin,
|
||||
l3_fip_port_details.Fip_port_details_db_mixin):
|
||||
supported_extension_aliases = ["router", apiref.ALIAS]
|
||||
|
||||
|
||||
class FloatingIPPortDetailsDBTestCaseBase(test_l3.L3NatTestCaseMixin):
|
||||
|
||||
def _assert_port_details(self, port, port_details):
|
||||
port['name'] = port_details['name']
|
||||
port['network_id'] = port_details['network_id']
|
||||
port['mac_address'] = port_details['mac_address']
|
||||
port['admin_state_up'] = port_details['admin_state_up']
|
||||
port['status'] = port_details['status']
|
||||
port['device_id'] = port_details['device_id']
|
||||
port['device_owner'] = port_details['device_owner']
|
||||
|
||||
def test_floatingip_create_with_port_details(self):
|
||||
with self.port() as p:
|
||||
with self.floatingip_with_assoc(port_id=p['port']['id']) as fip:
|
||||
body = self._show('floatingips', fip['floatingip']['id'])
|
||||
self.assertEqual(body['floatingip']['id'],
|
||||
fip['floatingip']['id'])
|
||||
self.assertEqual(body['floatingip']['port_id'],
|
||||
fip['floatingip']['port_id'])
|
||||
self._assert_port_details(
|
||||
p['port'], body['floatingip']['port_details'])
|
||||
|
||||
def test_floatingip_update_with_port_details(self):
|
||||
with self.port() as p:
|
||||
private_sub = {'subnet': {'id':
|
||||
p['port']['fixed_ips'][0]['subnet_id']}}
|
||||
with self.floatingip_no_assoc(private_sub) as fip:
|
||||
body = self._show('floatingips', fip['floatingip']['id'])
|
||||
self.assertIsNone(body['floatingip']['port_id'])
|
||||
self.assertIsNone(body['floatingip']['port_details'])
|
||||
|
||||
port_id = p['port']['id']
|
||||
body = self._update('floatingips', fip['floatingip']['id'],
|
||||
{'floatingip': {'port_id': port_id}})
|
||||
self.assertEqual(port_id, body['floatingip']['port_id'])
|
||||
self._assert_port_details(
|
||||
p['port'], body['floatingip']['port_details'])
|
||||
|
||||
def test_floatingip_list_with_port_details(self):
|
||||
with self.port() as p:
|
||||
with self.floatingip_with_assoc(port_id=p['port']['id']) as fip:
|
||||
body = self._list('floatingips')
|
||||
self.assertEqual(body['floatingips'][0]['id'],
|
||||
fip['floatingip']['id'])
|
||||
self.assertEqual(body['floatingips'][0]['port_id'],
|
||||
fip['floatingip']['port_id'])
|
||||
self._assert_port_details(
|
||||
p['port'], body['floatingips'][0]['port_details'])
|
||||
|
||||
|
||||
class FloatingIPPortDetailsDBIntTestCase(test_l3.L3BaseForIntTests,
|
||||
FloatingIPPortDetailsDBTestCaseBase):
|
||||
|
||||
def setUp(self, plugin=None):
|
||||
if not plugin:
|
||||
plugin = ('neutron.tests.unit.extensions.test_fip_port_details.'
|
||||
'TestFloatingIPPortDetailsIntPlugin')
|
||||
# for these tests we need to enable overlapping ips
|
||||
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||
cfg.CONF.set_default('max_routes', 3)
|
||||
ext_mgr = FloatingIPPortDetailsTestExtensionManager()
|
||||
super(test_l3.L3BaseForIntTests, self).setUp(
|
||||
plugin=plugin,
|
||||
ext_mgr=ext_mgr)
|
||||
|
||||
self.setup_notification_driver()
|
||||
|
||||
|
||||
class FloatingIPPortDetailsDBSepTestCase(test_l3.L3BaseForSepTests,
|
||||
FloatingIPPortDetailsDBTestCaseBase):
|
||||
|
||||
def setUp(self):
|
||||
# the plugin without L3 support
|
||||
plugin = 'neutron.tests.unit.extensions.test_l3.TestNoL3NatPlugin'
|
||||
# the L3 service plugin
|
||||
l3_plugin = ('neutron.tests.unit.extensions.test_fip_port_details.'
|
||||
'TestFloatingIPPortDetailsL3NatServicePlugin')
|
||||
service_plugins = {'l3_plugin_name': l3_plugin}
|
||||
|
||||
# for these tests we need to enable overlapping ips
|
||||
cfg.CONF.set_default('allow_overlapping_ips', True)
|
||||
cfg.CONF.set_default('max_routes', 3)
|
||||
ext_mgr = FloatingIPPortDetailsTestExtensionManager()
|
||||
super(test_l3.L3BaseForSepTests, self).setUp(
|
||||
plugin=plugin,
|
||||
ext_mgr=ext_mgr,
|
||||
service_plugins=service_plugins)
|
||||
|
||||
self.setup_notification_driver()
|
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add attribute ``port_details`` to floating IP. The value of this attribute
|
||||
contains information of the associated port.
|
||||
|
Loading…
Reference in New Issue
Block a user