From d98222a654973f1acc7ab6d82e52e67590ed31ec Mon Sep 17 00:00:00 2001 From: Jay Xu Date: Mon, 18 Apr 2016 04:07:27 -0400 Subject: [PATCH] Add gateway in network_info and share network API Get gateway information from network plugin and put it into network_info. It is required by EMC Unity storage to create a interface. APIImpact DocImpact Change-Id: I8614b8686af7fa5764b49e8e3cb4a4855dc3a5f4 Implements: blueprint add-gateway-info --- manila/api/openstack/api_version_request.py | 3 +- .../openstack/rest_api_version_history.rst | 4 + manila/api/v1/share_networks.py | 13 ++- manila/api/views/share_networks.py | 20 +++- ...dd_gateway_to_network_allocations_table.py | 40 +++++++ manila/db/sqlalchemy/models.py | 2 + .../network/neutron/neutron_network_plugin.py | 2 + manila/network/nova_network_plugin.py | 2 + manila/network/standalone_network_plugin.py | 2 + manila/tests/api/views/test_share_networks.py | 21 ++-- .../alembic/migrations_data_checks.py | 107 ++++++++++++++++++ .../network/neutron/test_neutron_plugin.py | 16 ++- .../tests/network/test_nova_network_plugin.py | 15 ++- .../network/test_standalone_network_plugin.py | 14 ++- manila_tempest_tests/config.py | 2 +- .../services/share/v2/json/shares_client.py | 21 ++++ .../tests/api/test_share_networks.py | 8 +- .../add_gateway_into_db-1f3cd3f392ae81cf.yaml | 4 + 18 files changed, 263 insertions(+), 33 deletions(-) create mode 100644 manila/db/migrations/alembic/versions/fdfb668d19e1_add_gateway_to_network_allocations_table.py mode change 100644 => 100755 manila_tempest_tests/services/share/v2/json/shares_client.py mode change 100644 => 100755 manila_tempest_tests/tests/api/test_share_networks.py create mode 100644 releasenotes/notes/add_gateway_into_db-1f3cd3f392ae81cf.yaml diff --git a/manila/api/openstack/api_version_request.py b/manila/api/openstack/api_version_request.py index eed7e734bc..7d09e06211 100644 --- a/manila/api/openstack/api_version_request.py +++ b/manila/api/openstack/api_version_request.py @@ -68,13 +68,14 @@ REST_API_VERSION_HISTORY = """ * 2.16 - Add user_id in share show/create/manage API. * 2.17 - Added project_id and user_id fields to the JSON response of snapshot show/create/manage API. + * 2.18 - Add gateway to the JSON response of share network show API. """ # The minimum and maximum versions of the API supported # The default api version request is defined to be the # the minimum version of the API supported. _MIN_API_VERSION = "2.0" -_MAX_API_VERSION = "2.17" +_MAX_API_VERSION = "2.18" DEFAULT_API_VERSION = _MIN_API_VERSION diff --git a/manila/api/openstack/rest_api_version_history.rst b/manila/api/openstack/rest_api_version_history.rst index e10a14dca8..5192b74a9f 100644 --- a/manila/api/openstack/rest_api_version_history.rst +++ b/manila/api/openstack/rest_api_version_history.rst @@ -114,3 +114,7 @@ user documentation. 2.17 ---- Added user_id and project_id in snapshot show/create/manage APIs. + +2.18 +---- + Add gateway in share network show API. diff --git a/manila/api/v1/share_networks.py b/manila/api/v1/share_networks.py index cde19a5bb2..906cdf854e 100644 --- a/manila/api/v1/share_networks.py +++ b/manila/api/v1/share_networks.py @@ -59,7 +59,7 @@ class ShareNetworkController(wsgi.Controller): except exception.ShareNetworkNotFound as e: raise exc.HTTPNotFound(explanation=six.text_type(e)) - return self._view_builder.build_share_network(share_network) + return self._view_builder.build_share_network(req, share_network) def delete(self, req, id): """Delete specified share network.""" @@ -172,7 +172,8 @@ class ShareNetworkController(wsgi.Controller): if network[key] == value] limited_list = common.limited(networks, req) - return self._view_builder.build_share_networks(limited_list, is_detail) + return self._view_builder.build_share_networks( + req, limited_list, is_detail) def index(self, req): """Returns a summary list of share networks.""" @@ -236,7 +237,7 @@ class ShareNetworkController(wsgi.Controller): msg = "Could not save supplied data due to database error" raise exc.HTTPBadRequest(explanation=msg) - return self._view_builder.build_share_network(share_network) + return self._view_builder.build_share_network(req, share_network) def create(self, req, body): """Creates a new share network.""" @@ -279,7 +280,7 @@ class ShareNetworkController(wsgi.Controller): raise exc.HTTPBadRequest(explanation=msg) QUOTAS.commit(context, reservations) - return self._view_builder.build_share_network(share_network) + return self._view_builder.build_share_network(req, share_network) def action(self, req, id, body): _actions = { @@ -324,7 +325,7 @@ class ShareNetworkController(wsgi.Controller): except exception.ShareNetworkSecurityServiceAssociationError as e: raise exc.HTTPBadRequest(explanation=six.text_type(e)) - return self._view_builder.build_share_network(share_network) + return self._view_builder.build_share_network(req, share_network) def _remove_security_service(self, req, id, data): """Dissociate share network from a given security service.""" @@ -347,7 +348,7 @@ class ShareNetworkController(wsgi.Controller): except exception.ShareNetworkSecurityServiceDissociationError as e: raise exc.HTTPBadRequest(explanation=six.text_type(e)) - return self._view_builder.build_share_network(share_network) + return self._view_builder.build_share_network(req, share_network) def create_resource(): diff --git a/manila/api/views/share_networks.py b/manila/api/views/share_networks.py index cf8fbef29c..d47182f51a 100644 --- a/manila/api/views/share_networks.py +++ b/manila/api/views/share_networks.py @@ -20,18 +20,22 @@ class ViewBuilder(common.ViewBuilder): """Model a server API response as a python dictionary.""" _collection_name = 'share_networks' + _detail_version_modifiers = ["add_gateway"] - def build_share_network(self, share_network): + def build_share_network(self, request, share_network): """View of a share network.""" - return {'share_network': self._build_share_network_view(share_network)} + return {'share_network': self._build_share_network_view( + request, share_network)} - def build_share_networks(self, share_networks, is_detail=True): + def build_share_networks(self, request, share_networks, is_detail=True): return {'share_networks': - [self._build_share_network_view(share_network, is_detail) + [self._build_share_network_view( + request, share_network, is_detail) for share_network in share_networks]} - def _build_share_network_view(self, share_network, is_detail=True): + def _build_share_network_view(self, request, share_network, + is_detail=True): sn = { 'id': share_network.get('id'), 'name': share_network.get('name'), @@ -50,4 +54,10 @@ class ViewBuilder(common.ViewBuilder): 'ip_version': share_network.get('ip_version'), 'description': share_network.get('description'), }) + + self.update_versioned_resource_dict(request, sn, share_network) return sn + + @common.ViewBuilder.versioned_method("2.18") + def add_gateway(self, context, network_dict, network): + network_dict['gateway'] = network.get('gateway') diff --git a/manila/db/migrations/alembic/versions/fdfb668d19e1_add_gateway_to_network_allocations_table.py b/manila/db/migrations/alembic/versions/fdfb668d19e1_add_gateway_to_network_allocations_table.py new file mode 100644 index 0000000000..1342ed3dab --- /dev/null +++ b/manila/db/migrations/alembic/versions/fdfb668d19e1_add_gateway_to_network_allocations_table.py @@ -0,0 +1,40 @@ +# 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. + +"""add_gateway_to_network_allocations_table + +Revision ID: fdfb668d19e1 +Revises: 221a83cfd85b +Create Date: 2016-04-19 10:07:16.224806 + +""" + +# revision identifiers, used by Alembic. +revision = 'fdfb668d19e1' +down_revision = '221a83cfd85b' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column( + 'network_allocations', + sa.Column('gateway', sa.String(64), nullable=True)) + op.add_column( + 'share_networks', + sa.Column('gateway', sa.String(64), nullable=True)) + + +def downgrade(): + op.drop_column('network_allocations', 'gateway') + op.drop_column('share_networks', 'gateway') diff --git a/manila/db/sqlalchemy/models.py b/manila/db/sqlalchemy/models.py index 0e92764701..39d8d0e840 100644 --- a/manila/db/sqlalchemy/models.py +++ b/manila/db/sqlalchemy/models.py @@ -754,6 +754,7 @@ class ShareNetwork(BASE, ManilaBase): network_type = Column(String(32), nullable=True) segmentation_id = Column(Integer, nullable=True) cidr = Column(String(64), nullable=True) + gateway = Column(String(64), nullable=True) ip_version = Column(Integer, nullable=True) name = Column(String(255), nullable=True) description = Column(String(255), nullable=True) @@ -862,6 +863,7 @@ class NetworkAllocation(BASE, ManilaBase): ip_address = Column(String(64), nullable=True) ip_version = Column(Integer, nullable=True) cidr = Column(String(64), nullable=True) + gateway = Column(String(64), nullable=True) network_type = Column(String(32), nullable=True) segmentation_id = Column(Integer, nullable=True) mac_address = Column(String(32), nullable=True) diff --git a/manila/network/neutron/neutron_network_plugin.py b/manila/network/neutron/neutron_network_plugin.py index e7bc011160..706a59c3a7 100644 --- a/manila/network/neutron/neutron_network_plugin.py +++ b/manila/network/neutron/neutron_network_plugin.py @@ -123,6 +123,7 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI): 'id': port['id'], 'share_server_id': share_server['id'], 'ip_address': port['fixed_ips'][0]['ip_address'], + 'gateway': share_network['gateway'], 'mac_address': port['mac_address'], 'status': constants.STATUS_ACTIVE, 'label': self.label, @@ -167,6 +168,7 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI): subnet_values = { 'cidr': subnet_info['cidr'], + 'gateway': subnet_info['gateway_ip'], 'ip_version': subnet_info['ip_version'] } share_network.update(subnet_values) diff --git a/manila/network/nova_network_plugin.py b/manila/network/nova_network_plugin.py index 8905d320f5..c106e62331 100644 --- a/manila/network/nova_network_plugin.py +++ b/manila/network/nova_network_plugin.py @@ -88,6 +88,7 @@ class NovaNetworkPlugin(network.NetworkBaseAPI): 'status': constants.STATUS_ACTIVE, 'label': self.label, 'cidr': share_network['cidr'], + 'gateway': share_network['gateway'], 'ip_version': share_network['ip_version'], 'segmentation_id': share_network['segmentation_id'], 'network_type': share_network['network_type'], @@ -150,6 +151,7 @@ class NovaNetworkPlugin(network.NetworkBaseAPI): """Update 'share-network' with plugin specific data.""" data = { 'cidr': (nova_net['cidr'] or nova_net['cidr_v6']), + 'gateway': (nova_net['gateway'] or nova_net['gateway_v6']), 'ip_version': (4 if nova_net['cidr'] else 6), 'segmentation_id': nova_net['vlan'], 'network_type': ('vlan' if nova_net['vlan'] else 'flat'), diff --git a/manila/network/standalone_network_plugin.py b/manila/network/standalone_network_plugin.py index 9bb976cf14..ea44af9972 100644 --- a/manila/network/standalone_network_plugin.py +++ b/manila/network/standalone_network_plugin.py @@ -249,6 +249,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI): 'network_type': self.network_type, 'segmentation_id': self.segmentation_id, 'cidr': six.text_type(self.net.cidr), + 'gateway': six.text_type(self.gateway), 'ip_version': self.ip_version, } share_network.update(data) @@ -281,6 +282,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI): 'network_type': share_network['network_type'], 'segmentation_id': share_network['segmentation_id'], 'cidr': share_network['cidr'], + 'gateway': share_network['gateway'], 'ip_version': share_network['ip_version'], } allocations.append( diff --git a/manila/tests/api/views/test_share_networks.py b/manila/tests/api/views/test_share_networks.py index 171d8d0c36..3d2f3d2358 100644 --- a/manila/tests/api/views/test_share_networks.py +++ b/manila/tests/api/views/test_share_networks.py @@ -17,6 +17,7 @@ import ddt from manila.api.views import share_networks from manila import test +from manila.tests.api import fakes @ddt.ddt @@ -25,6 +26,7 @@ class ViewBuilderTestCase(test.TestCase): def setUp(self): super(ViewBuilderTestCase, self).setUp() self.builder = share_networks.ViewBuilder() + self.req = fakes.HTTPRequest.blank('/share-networks', version="2.18") def test__collection_name(self): self.assertEqual('share_networks', self.builder._collection_name) @@ -33,14 +35,14 @@ class ViewBuilderTestCase(test.TestCase): {'id': 'fake_sn_id', 'name': 'fake_sn_name'}, {'id': 'fake_sn_id', 'name': 'fake_sn_name', 'fake_extra_key': 'foo'}, ) - def test_build_share_network(self, sn): + def test_build_share_network_v_2_18(self, sn): expected_keys = ( 'id', 'name', 'project_id', 'created_at', 'updated_at', 'neutron_net_id', 'neutron_subnet_id', 'nova_net_id', 'network_type', 'segmentation_id', 'cidr', 'ip_version', - 'description') + 'gateway', 'description') - result = self.builder.build_share_network(sn) + result = self.builder.build_share_network(self.req, sn) self.assertEqual(1, len(result)) self.assertIn('share_network', result) @@ -64,10 +66,11 @@ class ViewBuilderTestCase(test.TestCase): segmentation_id='fake_segmentation_id', cidr='fake_cidr', ip_version='fake_ip_version', + gateway='fake_gateway', description='fake_description'), dict(id='fake_id2', name='fake_name2')], ) - def test_build_share_networks_with_details(self, share_networks): + def test_build_share_networks_with_details_v_2_18(self, share_networks): expected = [] for share_network in share_networks: expected.append(dict( @@ -83,10 +86,12 @@ class ViewBuilderTestCase(test.TestCase): segmentation_id=share_network.get('segmentation_id'), cidr=share_network.get('cidr'), ip_version=share_network.get('ip_version'), + gateway=share_network.get('gateway'), description=share_network.get('description'))) expected = {'share_networks': expected} - result = self.builder.build_share_networks(share_networks, True) + result = self.builder.build_share_networks( + self.req, share_networks, True) self.assertEqual(expected, result) @@ -97,13 +102,15 @@ class ViewBuilderTestCase(test.TestCase): [{'id': 'id1', 'name': 'name1'}, {'id': 'id2', 'name': 'name2', 'fake': 'I should not be returned'}], ) - def test_build_share_networks_without_details(self, share_networks): + def test_build_share_networks_without_details_v_2_18(self, + share_networks): expected = [] for share_network in share_networks: expected.append(dict( id=share_network.get('id'), name=share_network.get('name'))) expected = {'share_networks': expected} - result = self.builder.build_share_networks(share_networks, False) + result = self.builder.build_share_networks( + self.req, share_networks, False) self.assertEqual(expected, result) diff --git a/manila/tests/db/migrations/alembic/migrations_data_checks.py b/manila/tests/db/migrations/alembic/migrations_data_checks.py index 87e2813aff..46d2f992e9 100644 --- a/manila/tests/db/migrations/alembic/migrations_data_checks.py +++ b/manila/tests/db/migrations/alembic/migrations_data_checks.py @@ -655,3 +655,110 @@ class ShareNetwoksFieldLengthChecks(BaseMigrationChecks): self._check_length_for_table_columns('security_services', engine, ('project_id',), 36) + + +@map_to_migration('fdfb668d19e1') +class NewGatewayColumnChecks(BaseMigrationChecks): + na_table_name = 'network_allocations' + sn_table_name = 'share_networks' + na_ids = ['network_allocation_id_fake_%d' % i for i in (1, 2, 3)] + sn_ids = ['share_network_id_fake_%d' % i for i in (1, 2)] + + def setup_upgrade_data(self, engine): + user_id = 'user_id' + project_id = 'project_id' + share_server_id = 'share_server_id_foo' + + # Create share network + share_network_data = { + 'id': self.sn_ids[0], + 'user_id': user_id, + 'project_id': project_id, + } + sn_table = utils.load_table(self.sn_table_name, engine) + engine.execute(sn_table.insert(share_network_data)) + + # Create share server + share_server_data = { + 'id': share_server_id, + 'share_network_id': share_network_data['id'], + 'host': 'fake_host', + 'status': 'active', + } + ss_table = utils.load_table('share_servers', engine) + engine.execute(ss_table.insert(share_server_data)) + + # Create network allocations + network_allocations = [ + { + 'id': self.na_ids[0], + 'share_server_id': share_server_id, + 'ip_address': '1.1.1.1', + }, + { + 'id': self.na_ids[1], + 'share_server_id': share_server_id, + 'ip_address': '2.2.2.2', + }, + ] + na_table = utils.load_table(self.na_table_name, engine) + engine.execute(na_table.insert(network_allocations)) + + def check_upgrade(self, engine, data): + na_table = utils.load_table(self.na_table_name, engine) + for na in engine.execute(na_table.select()): + self.test_case.assertTrue(hasattr(na, 'gateway')) + + # Create network allocation + network_allocations = [ + { + 'id': self.na_ids[2], + 'share_server_id': na.share_server_id, + 'ip_address': '3.3.3.3', + 'gateway': '3.3.3.1', + 'network_type': 'vlan', + 'segmentation_id': 1005, + 'ip_version': 4, + 'cidr': '240.0.0.0/16', + }, + ] + engine.execute(na_table.insert(network_allocations)) + + # Select network allocations with gateway info + for na in engine.execute( + na_table.select().where(na_table.c.gateway == '3.3.3.1')): + self.test_case.assertTrue(hasattr(na, 'gateway')) + self.test_case.assertEqual(network_allocations[0]['gateway'], + getattr(na, 'gateway')) + + sn_table = utils.load_table(self.sn_table_name, engine) + for sn in engine.execute(sn_table.select()): + self.test_case.assertTrue(hasattr(sn, 'gateway')) + + # Create share network + share_networks = [ + { + 'id': self.sn_ids[1], + 'user_id': sn.user_id, + 'project_id': sn.project_id, + 'gateway': '1.1.1.1', + 'name': 'name_foo', + }, + ] + engine.execute(sn_table.insert(share_networks)) + + # Select share network + for sn in engine.execute( + sn_table.select().where(sn_table.c.name == 'name_foo')): + self.test_case.assertTrue(hasattr(sn, 'gateway')) + self.test_case.assertEqual(share_networks[0]['gateway'], + getattr(sn, 'gateway')) + + def check_downgrade(self, engine): + for table_name, ids in ((self.na_table_name, self.na_ids), + (self.sn_table_name, self.sn_ids)): + table = utils.load_table(table_name, engine) + db_result = engine.execute(table.select()) + self.test_case.assertTrue(db_result.rowcount >= len(ids)) + for record in db_result: + self.test_case.assertFalse(hasattr(record, 'gateway')) diff --git a/manila/tests/network/neutron/test_neutron_plugin.py b/manila/tests/network/neutron/test_neutron_plugin.py index 55b38d31e2..7790186a0e 100644 --- a/manila/tests/network/neutron/test_neutron_plugin.py +++ b/manila/tests/network/neutron/test_neutron_plugin.py @@ -61,6 +61,7 @@ fake_share_network = { 'segmentation_id': 1234, 'ip_version': 4, 'cidr': 'fake_cidr', + 'gateway': 'fake_gateway', } fake_share_server = { @@ -82,6 +83,7 @@ fake_network_allocation = { 'segmentation_id': fake_share_network['segmentation_id'], 'ip_version': fake_share_network['ip_version'], 'cidr': fake_share_network['cidr'], + 'gateway': fake_share_network['gateway'], } @@ -270,8 +272,16 @@ class NeutronNetworkPluginTest(test.TestCase): @mock.patch.object(db_api, 'share_network_update', mock.Mock()) def test_save_neutron_subnet_data(self): - neutron_subnet_info = {'cidr': '10.0.0.0/24', - 'ip_version': 4} + neutron_subnet_info = { + 'cidr': '10.0.0.0/24', + 'ip_version': 4, + 'gateway_ip': '10.0.0.1', + } + subnet_value = { + 'cidr': '10.0.0.0/24', + 'ip_version': 4, + 'gateway': '10.0.0.1', + } with mock.patch.object(self.plugin.neutron_api, 'get_subnet', @@ -284,7 +294,7 @@ class NeutronNetworkPluginTest(test.TestCase): self.plugin.db.share_network_update.assert_called_once_with( self.fake_context, fake_share_network['id'], - neutron_subnet_info) + subnet_value) def test_has_network_provider_extension_true(self): extensions = {neutron_constants.PROVIDER_NW_EXT: {}} diff --git a/manila/tests/network/test_nova_network_plugin.py b/manila/tests/network/test_nova_network_plugin.py index c92838622e..13fff85d8a 100644 --- a/manila/tests/network/test_nova_network_plugin.py +++ b/manila/tests/network/test_nova_network_plugin.py @@ -90,8 +90,9 @@ class NovaNetworkPluginTest(test.TestCase): self.instance.admin_context, expected_ip_address) self.instance.db.share_network_update.assert_called_once_with( self.fake_context, share_network['id'], - dict(cidr=nova_net['cidr'], ip_version=4, - segmentation_id=nova_net['vlan'], network_type=net_type)) + dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'], + ip_version=4, segmentation_id=nova_net['vlan'], + network_type=net_type)) self.instance.db.network_allocations_get_by_ip_address.\ assert_has_calls([ mock.call(self.fake_context, '20.0.0.7'), @@ -149,8 +150,9 @@ class NovaNetworkPluginTest(test.TestCase): mock.call(self.instance.admin_context, expected_ip_address2)]) self.instance.db.share_network_update.assert_called_once_with( self.fake_context, self.share_network['id'], - dict(cidr=nova_net['cidr'], ip_version=4, - segmentation_id=nova_net['vlan'], network_type=net_type)) + dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'], + ip_version=4, segmentation_id=nova_net['vlan'], + network_type=net_type)) self.instance.db.network_allocations_get_by_ip_address.\ assert_has_calls([ mock.call(self.fake_context, '20.0.0.2'), @@ -186,8 +188,9 @@ class NovaNetworkPluginTest(test.TestCase): self.instance.admin_context, self.share_network['nova_net_id']) self.instance.db.share_network_update.assert_called_once_with( self.fake_context, self.share_network['id'], - dict(cidr=nova_net['cidr'], ip_version=4, - segmentation_id=nova_net['vlan'], network_type='vlan')) + dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'], + ip_version=4, segmentation_id=nova_net['vlan'], + network_type='vlan')) self.assertEqual( 248, self.instance.db.network_allocations_get_by_ip_address.call_count) diff --git a/manila/tests/network/test_standalone_network_plugin.py b/manila/tests/network/test_standalone_network_plugin.py index 2d76807a81..5a740f2d8b 100644 --- a/manila/tests/network/test_standalone_network_plugin.py +++ b/manila/tests/network/test_standalone_network_plugin.py @@ -309,7 +309,9 @@ class StandaloneNetworkPluginTest(test.TestCase): instance.db.share_network_update.assert_called_once_with( fake_context, fake_share_network['id'], dict(network_type=None, segmentation_id=None, - cidr=six.text_type(instance.net.cidr), ip_version=4)) + cidr=six.text_type(instance.net.cidr), + gateway=six.text_type(instance.gateway), + ip_version=4)) def test_allocate_network_zero_addresses_ipv6(self): data = { @@ -330,7 +332,9 @@ class StandaloneNetworkPluginTest(test.TestCase): instance.db.share_network_update.assert_called_once_with( fake_context, fake_share_network['id'], dict(network_type=None, segmentation_id=None, - cidr=six.text_type(instance.net.cidr), ip_version=6)) + cidr=six.text_type(instance.net.cidr), + gateway=six.text_type(instance.gateway), + ip_version=6)) def test_allocate_network_one_ip_address_ipv4_no_usages_exist(self): data = { @@ -357,6 +361,7 @@ class StandaloneNetworkPluginTest(test.TestCase): 'network_type': 'vlan', 'segmentation_id': 1003, 'cidr': '10.0.0.0/24', + 'gateway': '10.0.0.1', 'ip_version': 4, } instance.db.share_network_update.assert_called_once_with( @@ -401,6 +406,7 @@ class StandaloneNetworkPluginTest(test.TestCase): 'network_type': None, 'segmentation_id': None, 'cidr': six.text_type(instance.net.cidr), + 'gateway': six.text_type(instance.gateway), 'ip_version': 4, } instance.db.share_network_update.assert_called_once_with( @@ -444,6 +450,8 @@ class StandaloneNetworkPluginTest(test.TestCase): instance.db.share_network_update.assert_called_once_with( fake_context, fake_share_network['id'], dict(network_type=None, segmentation_id=None, - cidr=six.text_type(instance.net.cidr), ip_version=4)) + cidr=six.text_type(instance.net.cidr), + gateway=six.text_type(instance.gateway), + ip_version=4)) instance.db.network_allocations_get_by_ip_address.assert_has_calls( [mock.call(fake_context, '10.0.0.2')]) diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py index e2b98a3c60..7a7ee6f211 100644 --- a/manila_tempest_tests/config.py +++ b/manila_tempest_tests/config.py @@ -34,7 +34,7 @@ ShareGroup = [ help="The minimum api microversion is configured to be the " "value of the minimum microversion supported by Manila."), cfg.StrOpt("max_api_microversion", - default="2.17", + default="2.18", help="The maximum api microversion is configured to be the " "value of the latest microversion supported by Manila."), cfg.StrOpt("region", diff --git a/manila_tempest_tests/services/share/v2/json/shares_client.py b/manila_tempest_tests/services/share/v2/json/shares_client.py old mode 100644 new mode 100755 index ab33002a65..3995161504 --- a/manila_tempest_tests/services/share/v2/json/shares_client.py +++ b/manila_tempest_tests/services/share/v2/json/shares_client.py @@ -1210,3 +1210,24 @@ class SharesV2Client(shares_client.SharesClient): version=version) self.expected_success(202, resp.status) return self._parse_resp(body) + + def list_share_networks(self, detailed=False, params=None, + version=LATEST_MICROVERSION): + """Get list of share networks w/o filters.""" + uri = 'share-networks/detail' if detailed else 'share-networks' + uri += '?%s' % urlparse.urlencode(params) if params else '' + resp, body = self.get(uri, version=version) + self.expected_success(200, resp.status) + return self._parse_resp(body) + + def list_share_networks_with_detail(self, params=None, + version=LATEST_MICROVERSION): + """Get detailed list of share networks w/o filters.""" + return self.list_share_networks( + detailed=True, params=params, version=version) + + def get_share_network(self, share_network_id, version=LATEST_MICROVERSION): + resp, body = self.get("share-networks/%s" % share_network_id, + version=version) + self.expected_success(200, resp.status) + return self._parse_resp(body) diff --git a/manila_tempest_tests/tests/api/test_share_networks.py b/manila_tempest_tests/tests/api/test_share_networks.py old mode 100644 new mode 100755 index ef8bb01f85..b9d2d8cfaf --- a/manila_tempest_tests/tests/api/test_share_networks.py +++ b/manila_tempest_tests/tests/api/test_share_networks.py @@ -19,6 +19,7 @@ from tempest import test import testtools from manila_tempest_tests.tests.api import base +from manila_tempest_tests import utils CONF = config.CONF @@ -37,7 +38,7 @@ class ShareNetworkListMixin(object): @test.attr(type=[base.TAG_POSITIVE, base.TAG_API]) def test_list_share_networks_with_detail(self): - listed = self.shares_client.list_share_networks_with_detail() + listed = self.shares_v2_client.list_share_networks_with_detail() any(self.sn_with_ldap_ss["id"] in sn["id"] for sn in listed) # verify keys @@ -47,6 +48,11 @@ class ShareNetworkListMixin(object): "neutron_net_id", "neutron_subnet_id", "created_at", "updated_at", "segmentation_id", ] + + # In v2.18 and beyond, we expect gateway. + if utils.is_microversion_supported('2.18'): + keys.append('gateway') + [self.assertIn(key, sn.keys()) for sn in listed for key in keys] @test.attr(type=[base.TAG_POSITIVE, base.TAG_API]) diff --git a/releasenotes/notes/add_gateway_into_db-1f3cd3f392ae81cf.yaml b/releasenotes/notes/add_gateway_into_db-1f3cd3f392ae81cf.yaml new file mode 100644 index 0000000000..48adfc4ff6 --- /dev/null +++ b/releasenotes/notes/add_gateway_into_db-1f3cd3f392ae81cf.yaml @@ -0,0 +1,4 @@ +--- +features: + - Store network gateway value in DB. + - Gateway is added to the JSON response of the /share-networks API.