Merge "Add gateway in network_info and share network API"
This commit is contained in:
commit
fdc1158562
@ -68,13 +68,14 @@ REST_API_VERSION_HISTORY = """
|
|||||||
* 2.16 - Add user_id in share show/create/manage API.
|
* 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
|
* 2.17 - Added project_id and user_id fields to the JSON response of
|
||||||
snapshot show/create/manage API.
|
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 minimum and maximum versions of the API supported
|
||||||
# The default api version request is defined to be the
|
# The default api version request is defined to be the
|
||||||
# the minimum version of the API supported.
|
# the minimum version of the API supported.
|
||||||
_MIN_API_VERSION = "2.0"
|
_MIN_API_VERSION = "2.0"
|
||||||
_MAX_API_VERSION = "2.17"
|
_MAX_API_VERSION = "2.18"
|
||||||
DEFAULT_API_VERSION = _MIN_API_VERSION
|
DEFAULT_API_VERSION = _MIN_API_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,3 +114,7 @@ user documentation.
|
|||||||
2.17
|
2.17
|
||||||
----
|
----
|
||||||
Added user_id and project_id in snapshot show/create/manage APIs.
|
Added user_id and project_id in snapshot show/create/manage APIs.
|
||||||
|
|
||||||
|
2.18
|
||||||
|
----
|
||||||
|
Add gateway in share network show API.
|
||||||
|
@ -59,7 +59,7 @@ class ShareNetworkController(wsgi.Controller):
|
|||||||
except exception.ShareNetworkNotFound as e:
|
except exception.ShareNetworkNotFound as e:
|
||||||
raise exc.HTTPNotFound(explanation=six.text_type(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):
|
def delete(self, req, id):
|
||||||
"""Delete specified share network."""
|
"""Delete specified share network."""
|
||||||
@ -172,7 +172,8 @@ class ShareNetworkController(wsgi.Controller):
|
|||||||
if network[key] == value]
|
if network[key] == value]
|
||||||
|
|
||||||
limited_list = common.limited(networks, req)
|
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):
|
def index(self, req):
|
||||||
"""Returns a summary list of share networks."""
|
"""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"
|
msg = "Could not save supplied data due to database error"
|
||||||
raise exc.HTTPBadRequest(explanation=msg)
|
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):
|
def create(self, req, body):
|
||||||
"""Creates a new share network."""
|
"""Creates a new share network."""
|
||||||
@ -279,7 +280,7 @@ class ShareNetworkController(wsgi.Controller):
|
|||||||
raise exc.HTTPBadRequest(explanation=msg)
|
raise exc.HTTPBadRequest(explanation=msg)
|
||||||
|
|
||||||
QUOTAS.commit(context, reservations)
|
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):
|
def action(self, req, id, body):
|
||||||
_actions = {
|
_actions = {
|
||||||
@ -324,7 +325,7 @@ class ShareNetworkController(wsgi.Controller):
|
|||||||
except exception.ShareNetworkSecurityServiceAssociationError as e:
|
except exception.ShareNetworkSecurityServiceAssociationError as e:
|
||||||
raise exc.HTTPBadRequest(explanation=six.text_type(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):
|
def _remove_security_service(self, req, id, data):
|
||||||
"""Dissociate share network from a given security service."""
|
"""Dissociate share network from a given security service."""
|
||||||
@ -347,7 +348,7 @@ class ShareNetworkController(wsgi.Controller):
|
|||||||
except exception.ShareNetworkSecurityServiceDissociationError as e:
|
except exception.ShareNetworkSecurityServiceDissociationError as e:
|
||||||
raise exc.HTTPBadRequest(explanation=six.text_type(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():
|
def create_resource():
|
||||||
|
@ -20,18 +20,22 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
"""Model a server API response as a python dictionary."""
|
"""Model a server API response as a python dictionary."""
|
||||||
|
|
||||||
_collection_name = 'share_networks'
|
_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."""
|
"""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':
|
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]}
|
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 = {
|
sn = {
|
||||||
'id': share_network.get('id'),
|
'id': share_network.get('id'),
|
||||||
'name': share_network.get('name'),
|
'name': share_network.get('name'),
|
||||||
@ -50,4 +54,10 @@ class ViewBuilder(common.ViewBuilder):
|
|||||||
'ip_version': share_network.get('ip_version'),
|
'ip_version': share_network.get('ip_version'),
|
||||||
'description': share_network.get('description'),
|
'description': share_network.get('description'),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
self.update_versioned_resource_dict(request, sn, share_network)
|
||||||
return sn
|
return sn
|
||||||
|
|
||||||
|
@common.ViewBuilder.versioned_method("2.18")
|
||||||
|
def add_gateway(self, context, network_dict, network):
|
||||||
|
network_dict['gateway'] = network.get('gateway')
|
||||||
|
@ -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')
|
@ -754,6 +754,7 @@ class ShareNetwork(BASE, ManilaBase):
|
|||||||
network_type = Column(String(32), nullable=True)
|
network_type = Column(String(32), nullable=True)
|
||||||
segmentation_id = Column(Integer, nullable=True)
|
segmentation_id = Column(Integer, nullable=True)
|
||||||
cidr = Column(String(64), nullable=True)
|
cidr = Column(String(64), nullable=True)
|
||||||
|
gateway = Column(String(64), nullable=True)
|
||||||
ip_version = Column(Integer, nullable=True)
|
ip_version = Column(Integer, nullable=True)
|
||||||
name = Column(String(255), nullable=True)
|
name = Column(String(255), nullable=True)
|
||||||
description = 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_address = Column(String(64), nullable=True)
|
||||||
ip_version = Column(Integer, nullable=True)
|
ip_version = Column(Integer, nullable=True)
|
||||||
cidr = Column(String(64), nullable=True)
|
cidr = Column(String(64), nullable=True)
|
||||||
|
gateway = Column(String(64), nullable=True)
|
||||||
network_type = Column(String(32), nullable=True)
|
network_type = Column(String(32), nullable=True)
|
||||||
segmentation_id = Column(Integer, nullable=True)
|
segmentation_id = Column(Integer, nullable=True)
|
||||||
mac_address = Column(String(32), nullable=True)
|
mac_address = Column(String(32), nullable=True)
|
||||||
|
@ -123,6 +123,7 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
|||||||
'id': port['id'],
|
'id': port['id'],
|
||||||
'share_server_id': share_server['id'],
|
'share_server_id': share_server['id'],
|
||||||
'ip_address': port['fixed_ips'][0]['ip_address'],
|
'ip_address': port['fixed_ips'][0]['ip_address'],
|
||||||
|
'gateway': share_network['gateway'],
|
||||||
'mac_address': port['mac_address'],
|
'mac_address': port['mac_address'],
|
||||||
'status': constants.STATUS_ACTIVE,
|
'status': constants.STATUS_ACTIVE,
|
||||||
'label': self.label,
|
'label': self.label,
|
||||||
@ -167,6 +168,7 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
|||||||
|
|
||||||
subnet_values = {
|
subnet_values = {
|
||||||
'cidr': subnet_info['cidr'],
|
'cidr': subnet_info['cidr'],
|
||||||
|
'gateway': subnet_info['gateway_ip'],
|
||||||
'ip_version': subnet_info['ip_version']
|
'ip_version': subnet_info['ip_version']
|
||||||
}
|
}
|
||||||
share_network.update(subnet_values)
|
share_network.update(subnet_values)
|
||||||
|
@ -88,6 +88,7 @@ class NovaNetworkPlugin(network.NetworkBaseAPI):
|
|||||||
'status': constants.STATUS_ACTIVE,
|
'status': constants.STATUS_ACTIVE,
|
||||||
'label': self.label,
|
'label': self.label,
|
||||||
'cidr': share_network['cidr'],
|
'cidr': share_network['cidr'],
|
||||||
|
'gateway': share_network['gateway'],
|
||||||
'ip_version': share_network['ip_version'],
|
'ip_version': share_network['ip_version'],
|
||||||
'segmentation_id': share_network['segmentation_id'],
|
'segmentation_id': share_network['segmentation_id'],
|
||||||
'network_type': share_network['network_type'],
|
'network_type': share_network['network_type'],
|
||||||
@ -150,6 +151,7 @@ class NovaNetworkPlugin(network.NetworkBaseAPI):
|
|||||||
"""Update 'share-network' with plugin specific data."""
|
"""Update 'share-network' with plugin specific data."""
|
||||||
data = {
|
data = {
|
||||||
'cidr': (nova_net['cidr'] or nova_net['cidr_v6']),
|
'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),
|
'ip_version': (4 if nova_net['cidr'] else 6),
|
||||||
'segmentation_id': nova_net['vlan'],
|
'segmentation_id': nova_net['vlan'],
|
||||||
'network_type': ('vlan' if nova_net['vlan'] else 'flat'),
|
'network_type': ('vlan' if nova_net['vlan'] else 'flat'),
|
||||||
|
@ -249,6 +249,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
|
|||||||
'network_type': self.network_type,
|
'network_type': self.network_type,
|
||||||
'segmentation_id': self.segmentation_id,
|
'segmentation_id': self.segmentation_id,
|
||||||
'cidr': six.text_type(self.net.cidr),
|
'cidr': six.text_type(self.net.cidr),
|
||||||
|
'gateway': six.text_type(self.gateway),
|
||||||
'ip_version': self.ip_version,
|
'ip_version': self.ip_version,
|
||||||
}
|
}
|
||||||
share_network.update(data)
|
share_network.update(data)
|
||||||
@ -281,6 +282,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
|
|||||||
'network_type': share_network['network_type'],
|
'network_type': share_network['network_type'],
|
||||||
'segmentation_id': share_network['segmentation_id'],
|
'segmentation_id': share_network['segmentation_id'],
|
||||||
'cidr': share_network['cidr'],
|
'cidr': share_network['cidr'],
|
||||||
|
'gateway': share_network['gateway'],
|
||||||
'ip_version': share_network['ip_version'],
|
'ip_version': share_network['ip_version'],
|
||||||
}
|
}
|
||||||
allocations.append(
|
allocations.append(
|
||||||
|
@ -17,6 +17,7 @@ import ddt
|
|||||||
|
|
||||||
from manila.api.views import share_networks
|
from manila.api.views import share_networks
|
||||||
from manila import test
|
from manila import test
|
||||||
|
from manila.tests.api import fakes
|
||||||
|
|
||||||
|
|
||||||
@ddt.ddt
|
@ddt.ddt
|
||||||
@ -25,6 +26,7 @@ class ViewBuilderTestCase(test.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(ViewBuilderTestCase, self).setUp()
|
super(ViewBuilderTestCase, self).setUp()
|
||||||
self.builder = share_networks.ViewBuilder()
|
self.builder = share_networks.ViewBuilder()
|
||||||
|
self.req = fakes.HTTPRequest.blank('/share-networks', version="2.18")
|
||||||
|
|
||||||
def test__collection_name(self):
|
def test__collection_name(self):
|
||||||
self.assertEqual('share_networks', self.builder._collection_name)
|
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'},
|
||||||
{'id': 'fake_sn_id', 'name': 'fake_sn_name', 'fake_extra_key': 'foo'},
|
{'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 = (
|
expected_keys = (
|
||||||
'id', 'name', 'project_id', 'created_at', 'updated_at',
|
'id', 'name', 'project_id', 'created_at', 'updated_at',
|
||||||
'neutron_net_id', 'neutron_subnet_id', 'nova_net_id',
|
'neutron_net_id', 'neutron_subnet_id', 'nova_net_id',
|
||||||
'network_type', 'segmentation_id', 'cidr', 'ip_version',
|
'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.assertEqual(1, len(result))
|
||||||
self.assertIn('share_network', result)
|
self.assertIn('share_network', result)
|
||||||
@ -64,10 +66,11 @@ class ViewBuilderTestCase(test.TestCase):
|
|||||||
segmentation_id='fake_segmentation_id',
|
segmentation_id='fake_segmentation_id',
|
||||||
cidr='fake_cidr',
|
cidr='fake_cidr',
|
||||||
ip_version='fake_ip_version',
|
ip_version='fake_ip_version',
|
||||||
|
gateway='fake_gateway',
|
||||||
description='fake_description'),
|
description='fake_description'),
|
||||||
dict(id='fake_id2', name='fake_name2')],
|
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 = []
|
expected = []
|
||||||
for share_network in share_networks:
|
for share_network in share_networks:
|
||||||
expected.append(dict(
|
expected.append(dict(
|
||||||
@ -83,10 +86,12 @@ class ViewBuilderTestCase(test.TestCase):
|
|||||||
segmentation_id=share_network.get('segmentation_id'),
|
segmentation_id=share_network.get('segmentation_id'),
|
||||||
cidr=share_network.get('cidr'),
|
cidr=share_network.get('cidr'),
|
||||||
ip_version=share_network.get('ip_version'),
|
ip_version=share_network.get('ip_version'),
|
||||||
|
gateway=share_network.get('gateway'),
|
||||||
description=share_network.get('description')))
|
description=share_network.get('description')))
|
||||||
expected = {'share_networks': expected}
|
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)
|
self.assertEqual(expected, result)
|
||||||
|
|
||||||
@ -97,13 +102,15 @@ class ViewBuilderTestCase(test.TestCase):
|
|||||||
[{'id': 'id1', 'name': 'name1'},
|
[{'id': 'id1', 'name': 'name1'},
|
||||||
{'id': 'id2', 'name': 'name2', 'fake': 'I should not be returned'}],
|
{'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 = []
|
expected = []
|
||||||
for share_network in share_networks:
|
for share_network in share_networks:
|
||||||
expected.append(dict(
|
expected.append(dict(
|
||||||
id=share_network.get('id'), name=share_network.get('name')))
|
id=share_network.get('id'), name=share_network.get('name')))
|
||||||
expected = {'share_networks': expected}
|
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)
|
self.assertEqual(expected, result)
|
||||||
|
@ -655,3 +655,110 @@ class ShareNetwoksFieldLengthChecks(BaseMigrationChecks):
|
|||||||
|
|
||||||
self._check_length_for_table_columns('security_services', engine,
|
self._check_length_for_table_columns('security_services', engine,
|
||||||
('project_id',), 36)
|
('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'))
|
||||||
|
@ -61,6 +61,7 @@ fake_share_network = {
|
|||||||
'segmentation_id': 1234,
|
'segmentation_id': 1234,
|
||||||
'ip_version': 4,
|
'ip_version': 4,
|
||||||
'cidr': 'fake_cidr',
|
'cidr': 'fake_cidr',
|
||||||
|
'gateway': 'fake_gateway',
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_share_server = {
|
fake_share_server = {
|
||||||
@ -82,6 +83,7 @@ fake_network_allocation = {
|
|||||||
'segmentation_id': fake_share_network['segmentation_id'],
|
'segmentation_id': fake_share_network['segmentation_id'],
|
||||||
'ip_version': fake_share_network['ip_version'],
|
'ip_version': fake_share_network['ip_version'],
|
||||||
'cidr': fake_share_network['cidr'],
|
'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())
|
@mock.patch.object(db_api, 'share_network_update', mock.Mock())
|
||||||
def test_save_neutron_subnet_data(self):
|
def test_save_neutron_subnet_data(self):
|
||||||
neutron_subnet_info = {'cidr': '10.0.0.0/24',
|
neutron_subnet_info = {
|
||||||
'ip_version': 4}
|
'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,
|
with mock.patch.object(self.plugin.neutron_api,
|
||||||
'get_subnet',
|
'get_subnet',
|
||||||
@ -284,7 +294,7 @@ class NeutronNetworkPluginTest(test.TestCase):
|
|||||||
self.plugin.db.share_network_update.assert_called_once_with(
|
self.plugin.db.share_network_update.assert_called_once_with(
|
||||||
self.fake_context,
|
self.fake_context,
|
||||||
fake_share_network['id'],
|
fake_share_network['id'],
|
||||||
neutron_subnet_info)
|
subnet_value)
|
||||||
|
|
||||||
def test_has_network_provider_extension_true(self):
|
def test_has_network_provider_extension_true(self):
|
||||||
extensions = {neutron_constants.PROVIDER_NW_EXT: {}}
|
extensions = {neutron_constants.PROVIDER_NW_EXT: {}}
|
||||||
|
@ -90,8 +90,9 @@ class NovaNetworkPluginTest(test.TestCase):
|
|||||||
self.instance.admin_context, expected_ip_address)
|
self.instance.admin_context, expected_ip_address)
|
||||||
self.instance.db.share_network_update.assert_called_once_with(
|
self.instance.db.share_network_update.assert_called_once_with(
|
||||||
self.fake_context, share_network['id'],
|
self.fake_context, share_network['id'],
|
||||||
dict(cidr=nova_net['cidr'], ip_version=4,
|
dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'],
|
||||||
segmentation_id=nova_net['vlan'], network_type=net_type))
|
ip_version=4, segmentation_id=nova_net['vlan'],
|
||||||
|
network_type=net_type))
|
||||||
self.instance.db.network_allocations_get_by_ip_address.\
|
self.instance.db.network_allocations_get_by_ip_address.\
|
||||||
assert_has_calls([
|
assert_has_calls([
|
||||||
mock.call(self.fake_context, '20.0.0.7'),
|
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)])
|
mock.call(self.instance.admin_context, expected_ip_address2)])
|
||||||
self.instance.db.share_network_update.assert_called_once_with(
|
self.instance.db.share_network_update.assert_called_once_with(
|
||||||
self.fake_context, self.share_network['id'],
|
self.fake_context, self.share_network['id'],
|
||||||
dict(cidr=nova_net['cidr'], ip_version=4,
|
dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'],
|
||||||
segmentation_id=nova_net['vlan'], network_type=net_type))
|
ip_version=4, segmentation_id=nova_net['vlan'],
|
||||||
|
network_type=net_type))
|
||||||
self.instance.db.network_allocations_get_by_ip_address.\
|
self.instance.db.network_allocations_get_by_ip_address.\
|
||||||
assert_has_calls([
|
assert_has_calls([
|
||||||
mock.call(self.fake_context, '20.0.0.2'),
|
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.admin_context, self.share_network['nova_net_id'])
|
||||||
self.instance.db.share_network_update.assert_called_once_with(
|
self.instance.db.share_network_update.assert_called_once_with(
|
||||||
self.fake_context, self.share_network['id'],
|
self.fake_context, self.share_network['id'],
|
||||||
dict(cidr=nova_net['cidr'], ip_version=4,
|
dict(cidr=nova_net['cidr'], gateway=nova_net['gateway'],
|
||||||
segmentation_id=nova_net['vlan'], network_type='vlan'))
|
ip_version=4, segmentation_id=nova_net['vlan'],
|
||||||
|
network_type='vlan'))
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
248,
|
248,
|
||||||
self.instance.db.network_allocations_get_by_ip_address.call_count)
|
self.instance.db.network_allocations_get_by_ip_address.call_count)
|
||||||
|
@ -309,7 +309,9 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
|||||||
instance.db.share_network_update.assert_called_once_with(
|
instance.db.share_network_update.assert_called_once_with(
|
||||||
fake_context, fake_share_network['id'],
|
fake_context, fake_share_network['id'],
|
||||||
dict(network_type=None, segmentation_id=None,
|
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):
|
def test_allocate_network_zero_addresses_ipv6(self):
|
||||||
data = {
|
data = {
|
||||||
@ -330,7 +332,9 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
|||||||
instance.db.share_network_update.assert_called_once_with(
|
instance.db.share_network_update.assert_called_once_with(
|
||||||
fake_context, fake_share_network['id'],
|
fake_context, fake_share_network['id'],
|
||||||
dict(network_type=None, segmentation_id=None,
|
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):
|
def test_allocate_network_one_ip_address_ipv4_no_usages_exist(self):
|
||||||
data = {
|
data = {
|
||||||
@ -357,6 +361,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
|||||||
'network_type': 'vlan',
|
'network_type': 'vlan',
|
||||||
'segmentation_id': 1003,
|
'segmentation_id': 1003,
|
||||||
'cidr': '10.0.0.0/24',
|
'cidr': '10.0.0.0/24',
|
||||||
|
'gateway': '10.0.0.1',
|
||||||
'ip_version': 4,
|
'ip_version': 4,
|
||||||
}
|
}
|
||||||
instance.db.share_network_update.assert_called_once_with(
|
instance.db.share_network_update.assert_called_once_with(
|
||||||
@ -401,6 +406,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
|||||||
'network_type': None,
|
'network_type': None,
|
||||||
'segmentation_id': None,
|
'segmentation_id': None,
|
||||||
'cidr': six.text_type(instance.net.cidr),
|
'cidr': six.text_type(instance.net.cidr),
|
||||||
|
'gateway': six.text_type(instance.gateway),
|
||||||
'ip_version': 4,
|
'ip_version': 4,
|
||||||
}
|
}
|
||||||
instance.db.share_network_update.assert_called_once_with(
|
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(
|
instance.db.share_network_update.assert_called_once_with(
|
||||||
fake_context, fake_share_network['id'],
|
fake_context, fake_share_network['id'],
|
||||||
dict(network_type=None, segmentation_id=None,
|
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(
|
instance.db.network_allocations_get_by_ip_address.assert_has_calls(
|
||||||
[mock.call(fake_context, '10.0.0.2')])
|
[mock.call(fake_context, '10.0.0.2')])
|
||||||
|
@ -34,7 +34,7 @@ ShareGroup = [
|
|||||||
help="The minimum api microversion is configured to be the "
|
help="The minimum api microversion is configured to be the "
|
||||||
"value of the minimum microversion supported by Manila."),
|
"value of the minimum microversion supported by Manila."),
|
||||||
cfg.StrOpt("max_api_microversion",
|
cfg.StrOpt("max_api_microversion",
|
||||||
default="2.17",
|
default="2.18",
|
||||||
help="The maximum api microversion is configured to be the "
|
help="The maximum api microversion is configured to be the "
|
||||||
"value of the latest microversion supported by Manila."),
|
"value of the latest microversion supported by Manila."),
|
||||||
cfg.StrOpt("region",
|
cfg.StrOpt("region",
|
||||||
|
21
manila_tempest_tests/services/share/v2/json/shares_client.py
Normal file → Executable file
21
manila_tempest_tests/services/share/v2/json/shares_client.py
Normal file → Executable file
@ -1210,3 +1210,24 @@ class SharesV2Client(shares_client.SharesClient):
|
|||||||
version=version)
|
version=version)
|
||||||
self.expected_success(202, resp.status)
|
self.expected_success(202, resp.status)
|
||||||
return self._parse_resp(body)
|
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)
|
||||||
|
8
manila_tempest_tests/tests/api/test_share_networks.py
Normal file → Executable file
8
manila_tempest_tests/tests/api/test_share_networks.py
Normal file → Executable file
@ -19,6 +19,7 @@ from tempest import test
|
|||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from manila_tempest_tests.tests.api import base
|
from manila_tempest_tests.tests.api import base
|
||||||
|
from manila_tempest_tests import utils
|
||||||
|
|
||||||
CONF = config.CONF
|
CONF = config.CONF
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ class ShareNetworkListMixin(object):
|
|||||||
|
|
||||||
@test.attr(type=[base.TAG_POSITIVE, base.TAG_API])
|
@test.attr(type=[base.TAG_POSITIVE, base.TAG_API])
|
||||||
def test_list_share_networks_with_detail(self):
|
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)
|
any(self.sn_with_ldap_ss["id"] in sn["id"] for sn in listed)
|
||||||
|
|
||||||
# verify keys
|
# verify keys
|
||||||
@ -47,6 +48,11 @@ class ShareNetworkListMixin(object):
|
|||||||
"neutron_net_id", "neutron_subnet_id",
|
"neutron_net_id", "neutron_subnet_id",
|
||||||
"created_at", "updated_at", "segmentation_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]
|
[self.assertIn(key, sn.keys()) for sn in listed for key in keys]
|
||||||
|
|
||||||
@test.attr(type=[base.TAG_POSITIVE, base.TAG_API])
|
@test.attr(type=[base.TAG_POSITIVE, base.TAG_API])
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- Store network gateway value in DB.
|
||||||
|
- Gateway is added to the JSON response of the /share-networks API.
|
Loading…
Reference in New Issue
Block a user