Merge "Add admin network for DHSS=True share drivers"
This commit is contained in:
commit
29cbef0532
@ -710,6 +710,9 @@ def share_network_remove_security_service(context, id, security_service_id):
|
||||
security_service_id)
|
||||
|
||||
|
||||
##################
|
||||
|
||||
|
||||
def network_allocation_create(context, values):
|
||||
"""Create a network allocation DB record."""
|
||||
return IMPL.network_allocation_create(context, values)
|
||||
@ -726,11 +729,10 @@ def network_allocation_update(context, id, values):
|
||||
|
||||
|
||||
def network_allocations_get_for_share_server(context, share_server_id,
|
||||
session=None):
|
||||
"""Get network allocation for share server."""
|
||||
return IMPL.network_allocations_get_for_share_server(context,
|
||||
share_server_id,
|
||||
session=session)
|
||||
session=None, label=None):
|
||||
"""Get network allocations for share server."""
|
||||
return IMPL.network_allocations_get_for_share_server(
|
||||
context, share_server_id, label=label, session=session)
|
||||
|
||||
|
||||
def network_allocations_get_by_ip_address(context, ip_address):
|
||||
|
@ -0,0 +1,59 @@
|
||||
# Copyright 2015 Mirantis Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 more network info attributes to 'network_allocations' table.
|
||||
|
||||
Revision ID: 5155c7077f99
|
||||
Revises: 293fac1130ca
|
||||
Create Date: 2015-12-22 12:05:24.297049
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '5155c7077f99'
|
||||
down_revision = '293fac1130ca'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
default_label_value = 'user'
|
||||
op.add_column(
|
||||
'network_allocations',
|
||||
sa.Column('label',
|
||||
sa.String(255),
|
||||
default=default_label_value,
|
||||
server_default=default_label_value,
|
||||
nullable=True),
|
||||
)
|
||||
op.add_column(
|
||||
'network_allocations',
|
||||
sa.Column('network_type', sa.String(32), nullable=True))
|
||||
op.add_column(
|
||||
'network_allocations',
|
||||
sa.Column('segmentation_id', sa.Integer, nullable=True))
|
||||
op.add_column(
|
||||
'network_allocations',
|
||||
sa.Column('ip_version', sa.Integer, nullable=True))
|
||||
op.add_column(
|
||||
'network_allocations',
|
||||
sa.Column('cidr', sa.String(64), nullable=True))
|
||||
|
||||
|
||||
def downgrade():
|
||||
for col_name in ('label', 'network_type', 'segmentation_id', 'ip_version',
|
||||
'cidr'):
|
||||
op.drop_column('network_allocations', col_name)
|
@ -2942,11 +2942,26 @@ def network_allocations_get_by_ip_address(context, ip_address):
|
||||
|
||||
@require_context
|
||||
def network_allocations_get_for_share_server(context, share_server_id,
|
||||
session=None):
|
||||
session=None, label=None):
|
||||
if session is None:
|
||||
session = get_session()
|
||||
result = model_query(context, models.NetworkAllocation, session=session).\
|
||||
filter_by(share_server_id=share_server_id).all()
|
||||
|
||||
query = model_query(
|
||||
context, models.NetworkAllocation, session=session,
|
||||
).filter_by(
|
||||
share_server_id=share_server_id,
|
||||
)
|
||||
if label:
|
||||
if label != 'admin':
|
||||
query = query.filter(or_(
|
||||
# NOTE(vponomaryov): we treat None as alias for 'user'.
|
||||
models.NetworkAllocation.label == None, # noqa
|
||||
models.NetworkAllocation.label == label,
|
||||
))
|
||||
else:
|
||||
query = query.filter(models.NetworkAllocation.label == label)
|
||||
|
||||
result = query.all()
|
||||
return result
|
||||
|
||||
|
||||
|
@ -807,7 +807,12 @@ class NetworkAllocation(BASE, ManilaBase):
|
||||
__tablename__ = 'network_allocations'
|
||||
id = Column(String(36), primary_key=True, nullable=False)
|
||||
deleted = Column(String(36), default='False')
|
||||
label = Column(String(255), nullable=True)
|
||||
ip_address = Column(String(64), nullable=True)
|
||||
ip_version = Column(Integer, nullable=True)
|
||||
cidr = 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)
|
||||
share_server_id = Column(String(36), ForeignKey('share_servers.id'),
|
||||
nullable=False)
|
||||
|
@ -17,8 +17,11 @@ import abc
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import importutils
|
||||
import six
|
||||
|
||||
from manila.db import base as db_base
|
||||
from manila import exception
|
||||
from manila.i18n import _
|
||||
|
||||
network_opts = [
|
||||
cfg.StrOpt(
|
||||
@ -32,7 +35,7 @@ network_opts = [
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def API(config_group_name=None):
|
||||
def API(config_group_name=None, label='user'):
|
||||
"""Selects class and config group of network plugin.
|
||||
|
||||
:param config_group_name: name of config group to be used for
|
||||
@ -45,22 +48,28 @@ def API(config_group_name=None):
|
||||
else:
|
||||
network_api_class = CONF.network_api_class
|
||||
cls = importutils.import_class(network_api_class)
|
||||
return cls(config_group_name=config_group_name)
|
||||
return cls(config_group_name=config_group_name, label=label)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class NetworkBaseAPI(db_base.Base):
|
||||
"""User network plugin for setting up main net interfaces."""
|
||||
|
||||
def __init__(self, db_driver=None):
|
||||
super(NetworkBaseAPI, self).__init__(db_driver=db_driver)
|
||||
|
||||
def _verify_share_network(self, share_server_id, share_network):
|
||||
if share_network is None:
|
||||
msg = _("'Share network' is not provided for setting up "
|
||||
"network interfaces for 'Share server' "
|
||||
"'%s'.") % share_server_id
|
||||
raise exception.NetworkBadConfigurationException(reason=msg)
|
||||
|
||||
@abc.abstractmethod
|
||||
def allocate_network(self, context, network_id, subnet_id, **kwargs):
|
||||
def allocate_network(self, context, share_server, share_network=None,
|
||||
**kwargs):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def deallocate_network(self, context, share_server_id):
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_provider_info(self, context, network_id, subnet_id):
|
||||
pass
|
||||
|
@ -50,6 +50,11 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
||||
self._neutron_api = None
|
||||
self._neutron_api_args = args
|
||||
self._neutron_api_kwargs = kwargs
|
||||
self._label = kwargs.pop('label', 'user')
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self._label
|
||||
|
||||
@property
|
||||
@utils.synchronized("instantiate_neutron_api")
|
||||
@ -59,7 +64,8 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
||||
**self._neutron_api_kwargs)
|
||||
return self._neutron_api
|
||||
|
||||
def allocate_network(self, context, share_server, share_network, **kwargs):
|
||||
def allocate_network(self, context, share_server, share_network=None,
|
||||
**kwargs):
|
||||
"""Allocate network resources using given network information.
|
||||
|
||||
Create neutron ports for a given neutron network and subnet,
|
||||
@ -77,6 +83,7 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
||||
msg = "%s extension required" % neutron_constants.PROVIDER_NW_EXT
|
||||
raise exception.NetworkBadConfigurationException(reason=msg)
|
||||
|
||||
self._verify_share_network(share_server['id'], share_network)
|
||||
self._save_neutron_network_data(context, share_network)
|
||||
self._save_neutron_subnet_data(context, share_network)
|
||||
|
||||
@ -118,6 +125,11 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
||||
'ip_address': port['fixed_ips'][0]['ip_address'],
|
||||
'mac_address': port['mac_address'],
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': self.label,
|
||||
'network_type': share_network['network_type'],
|
||||
'segmentation_id': share_network['segmentation_id'],
|
||||
'ip_version': share_network['ip_version'],
|
||||
'cidr': share_network['cidr'],
|
||||
}
|
||||
return self.db.network_allocation_create(context, port_dict)
|
||||
|
||||
@ -143,10 +155,11 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
||||
'network_type': net_info['provider:network_type'],
|
||||
'segmentation_id': net_info['provider:segmentation_id']
|
||||
}
|
||||
share_network.update(provider_nw_dict)
|
||||
|
||||
self.db.share_network_update(context,
|
||||
share_network['id'],
|
||||
provider_nw_dict)
|
||||
if self.label != 'admin':
|
||||
self.db.share_network_update(
|
||||
context, share_network['id'], provider_nw_dict)
|
||||
|
||||
def _save_neutron_subnet_data(self, context, share_network):
|
||||
subnet_info = self.neutron_api.get_subnet(
|
||||
@ -156,10 +169,11 @@ class NeutronNetworkPlugin(network.NetworkBaseAPI):
|
||||
'cidr': subnet_info['cidr'],
|
||||
'ip_version': subnet_info['ip_version']
|
||||
}
|
||||
share_network.update(subnet_values)
|
||||
|
||||
self.db.share_network_update(context,
|
||||
share_network['id'],
|
||||
subnet_values)
|
||||
if self.label != 'admin':
|
||||
self.db.share_network_update(
|
||||
context, share_network['id'], subnet_values)
|
||||
|
||||
|
||||
class NeutronSingleNetworkPlugin(NeutronNetworkPlugin):
|
||||
@ -173,9 +187,17 @@ class NeutronSingleNetworkPlugin(NeutronNetworkPlugin):
|
||||
self.subnet = self.neutron_api.configuration.neutron_subnet_id
|
||||
self._verify_net_and_subnet()
|
||||
|
||||
def allocate_network(self, context, share_server, share_network, **kwargs):
|
||||
share_network = self._update_share_network_net_data(
|
||||
context, share_network)
|
||||
def allocate_network(self, context, share_server, share_network=None,
|
||||
**kwargs):
|
||||
if self.label != 'admin':
|
||||
share_network = self._update_share_network_net_data(
|
||||
context, share_network)
|
||||
else:
|
||||
share_network = {
|
||||
'project_id': self.neutron_api.admin_project_id,
|
||||
'neutron_net_id': self.net,
|
||||
'neutron_subnet_id': self.subnet,
|
||||
}
|
||||
super(NeutronSingleNetworkPlugin, self).allocate_network(
|
||||
context, share_server, share_network, **kwargs)
|
||||
|
||||
|
@ -44,12 +44,17 @@ class NovaNetworkPlugin(network.NetworkBaseAPI):
|
||||
This plugin uses Nova networks provided within 'share-network' entities.
|
||||
"""
|
||||
|
||||
def __init__(self, config_group_name=None, db_driver=None):
|
||||
def __init__(self, config_group_name=None, db_driver=None, label=None):
|
||||
super(NovaNetworkPlugin, self).__init__(db_driver=db_driver)
|
||||
self.config_group_name = config_group_name or 'DEFAULT'
|
||||
self._label = label or 'user'
|
||||
self.admin_context = manila.context.get_admin_context()
|
||||
self.nova_api = nova.API()
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self._label
|
||||
|
||||
@utils.synchronized(
|
||||
"allocate_network_for_nova_network_plugin", external=True)
|
||||
def allocate_network(self, context, share_server, share_network, **kwargs):
|
||||
@ -73,14 +78,20 @@ class NovaNetworkPlugin(network.NetworkBaseAPI):
|
||||
# because several required attrs of network are available
|
||||
# only for admins.
|
||||
nova_net = self.nova_api.network_get(self.admin_context, nova_net_id)
|
||||
self._save_network_info(context, nova_net, share_network['id'])
|
||||
self._save_network_info(context, nova_net, share_network)
|
||||
ip_addresses = self._get_available_ips(
|
||||
context, nova_net, allocation_count)
|
||||
for ip_address in ip_addresses:
|
||||
data = dict(
|
||||
share_server_id=share_server['id'],
|
||||
ip_address=ip_address,
|
||||
status=constants.STATUS_ACTIVE)
|
||||
data = {
|
||||
'share_server_id': share_server['id'],
|
||||
'ip_address': ip_address,
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': self.label,
|
||||
'cidr': share_network['cidr'],
|
||||
'ip_version': share_network['ip_version'],
|
||||
'segmentation_id': share_network['segmentation_id'],
|
||||
'network_type': share_network['network_type'],
|
||||
}
|
||||
self.nova_api.fixed_ip_reserve(self.admin_context, ip_address)
|
||||
allocations.append(
|
||||
self.db.network_allocation_create(context, data))
|
||||
@ -135,14 +146,17 @@ class NovaNetworkPlugin(network.NetworkBaseAPI):
|
||||
LOG.error(msg)
|
||||
raise exception.NetworkBadConfigurationException(reason=msg)
|
||||
|
||||
def _save_network_info(self, context, nova_net, share_network_id):
|
||||
def _save_network_info(self, context, nova_net, share_network):
|
||||
"""Update 'share-network' with plugin specific data."""
|
||||
data = dict(
|
||||
cidr=(nova_net['cidr'] or nova_net['cidr_v6']),
|
||||
ip_version=(4 if nova_net['cidr'] else 6),
|
||||
segmentation_id=nova_net['vlan'],
|
||||
network_type=('vlan' if nova_net['vlan'] else 'flat'))
|
||||
self.db.share_network_update(context, share_network_id, data)
|
||||
data = {
|
||||
'cidr': (nova_net['cidr'] or nova_net['cidr_v6']),
|
||||
'ip_version': (4 if nova_net['cidr'] else 6),
|
||||
'segmentation_id': nova_net['vlan'],
|
||||
'network_type': ('vlan' if nova_net['vlan'] else 'flat'),
|
||||
}
|
||||
share_network.update(data)
|
||||
if self.label != 'admin':
|
||||
self.db.share_network_update(context, share_network['id'], data)
|
||||
|
||||
def deallocate_network(self, context, share_server_id):
|
||||
"""Deallocate network resources for share server."""
|
||||
@ -177,8 +191,11 @@ class NovaSingleNetworkPlugin(NovaNetworkPlugin):
|
||||
@utils.synchronized(
|
||||
"allocate_network_for_nova_network_plugin", external=True)
|
||||
def allocate_network(self, context, share_server, share_network, **kwargs):
|
||||
share_network = self._update_share_network_net_data(
|
||||
context, share_network)
|
||||
if self.label != 'admin':
|
||||
share_network = self._update_share_network_net_data(
|
||||
context, share_network)
|
||||
else:
|
||||
share_network = {'nova_net_id': self.net_id}
|
||||
return self._allocate_network(
|
||||
context, share_server, share_network, **kwargs)
|
||||
|
||||
|
@ -43,7 +43,7 @@ standalone_network_plugin_opts = [
|
||||
"share servers. Optional.",
|
||||
choices=['flat', 'vlan', 'vxlan', 'gre'],
|
||||
deprecated_group='DEFAULT'),
|
||||
cfg.StrOpt(
|
||||
cfg.IntOpt(
|
||||
'standalone_network_plugin_segmentation_id',
|
||||
help="Set it if network has segmentation (VLAN, VXLAN, etc...). "
|
||||
"It will be assigned to share-network and share drivers will be "
|
||||
@ -82,7 +82,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
|
||||
from some network.
|
||||
"""
|
||||
|
||||
def __init__(self, config_group_name=None, db_driver=None):
|
||||
def __init__(self, config_group_name=None, db_driver=None, label='user'):
|
||||
super(StandaloneNetworkPlugin, self).__init__(db_driver=db_driver)
|
||||
self.config_group_name = config_group_name or 'DEFAULT'
|
||||
CONF.register_opts(
|
||||
@ -90,6 +90,7 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
|
||||
group=self.config_group_name)
|
||||
self.configuration = getattr(CONF, self.config_group_name, CONF)
|
||||
self._set_persistent_network_data()
|
||||
self._label = label
|
||||
LOG.debug(
|
||||
"\nStandalone network plugin data for config group "
|
||||
"'%(config_group)s': \n"
|
||||
@ -112,6 +113,10 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
|
||||
ip_ranges=self.allowed_ip_ranges,
|
||||
reserved=self.reserved_addresses))
|
||||
|
||||
@property
|
||||
def label(self):
|
||||
return self._label
|
||||
|
||||
def _set_persistent_network_data(self):
|
||||
"""Sets persistent data for whole plugin."""
|
||||
self.network_type = (
|
||||
@ -240,30 +245,44 @@ class StandaloneNetworkPlugin(network.NetworkBaseAPI):
|
||||
|
||||
def _save_network_info(self, context, share_network):
|
||||
"""Update share-network with plugin specific data."""
|
||||
data = dict(
|
||||
network_type=self.network_type,
|
||||
segmentation_id=self.segmentation_id,
|
||||
cidr=six.text_type(self.net.cidr),
|
||||
ip_version=self.ip_version)
|
||||
self.db.share_network_update(context, share_network['id'], data)
|
||||
data = {
|
||||
'network_type': self.network_type,
|
||||
'segmentation_id': self.segmentation_id,
|
||||
'cidr': six.text_type(self.net.cidr),
|
||||
'ip_version': self.ip_version,
|
||||
}
|
||||
share_network.update(data)
|
||||
if self.label != 'admin':
|
||||
self.db.share_network_update(context, share_network['id'], data)
|
||||
|
||||
@utils.synchronized(
|
||||
"allocate_network_for_standalone_network_plugin", external=True)
|
||||
def allocate_network(self, context, share_server, share_network, **kwargs):
|
||||
def allocate_network(self, context, share_server, share_network=None,
|
||||
**kwargs):
|
||||
"""Allocate network resources using one dedicated network.
|
||||
|
||||
This one has interprocess lock to avoid concurrency in creation of
|
||||
share servers with same IP addresses using different share-networks.
|
||||
"""
|
||||
allocation_count = kwargs.get('count', 1)
|
||||
if self.label != 'admin':
|
||||
self._verify_share_network(share_server['id'], share_network)
|
||||
else:
|
||||
share_network = share_network or {}
|
||||
self._save_network_info(context, share_network)
|
||||
allocations = []
|
||||
ip_addresses = self._get_available_ips(context, allocation_count)
|
||||
for ip_address in ip_addresses:
|
||||
data = dict(
|
||||
share_server_id=share_server['id'],
|
||||
ip_address=ip_address,
|
||||
status=constants.STATUS_ACTIVE)
|
||||
data = {
|
||||
'share_server_id': share_server['id'],
|
||||
'ip_address': ip_address,
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': self.label,
|
||||
'network_type': share_network['network_type'],
|
||||
'segmentation_id': share_network['segmentation_id'],
|
||||
'cidr': share_network['cidr'],
|
||||
'ip_version': share_network['ip_version'],
|
||||
}
|
||||
allocations.append(
|
||||
self.db.network_allocation_create(context, data))
|
||||
return allocations
|
||||
|
@ -111,6 +111,12 @@ share_opts = [
|
||||
default=True,
|
||||
help="Specify whether read only access mode is supported in this"
|
||||
"backend."),
|
||||
cfg.StrOpt(
|
||||
"admin_network_config_group",
|
||||
help="If share driver requires to setup admin network for share, then "
|
||||
"define network plugin config options in some separate config "
|
||||
"group and set its name here. Used only with another "
|
||||
"option 'driver_handles_share_servers' set to 'True'."),
|
||||
]
|
||||
|
||||
ssh_opts = [
|
||||
@ -232,14 +238,25 @@ class ShareDriver(object):
|
||||
self.configuration.append_config_values(share_opts)
|
||||
network_config_group = (self.configuration.network_config_group or
|
||||
self.configuration.config_group)
|
||||
admin_network_config_group = (
|
||||
self.configuration.admin_network_config_group)
|
||||
else:
|
||||
network_config_group = None
|
||||
admin_network_config_group = (
|
||||
CONF.admin_network_config_group)
|
||||
|
||||
self._verify_share_server_handling(driver_handles_share_servers)
|
||||
if self.driver_handles_share_servers:
|
||||
# Enable common network
|
||||
self.network_api = network.API(
|
||||
config_group_name=network_config_group)
|
||||
|
||||
# Enable admin network
|
||||
if admin_network_config_group:
|
||||
self._admin_network_api = network.API(
|
||||
config_group_name=admin_network_config_group,
|
||||
label='admin')
|
||||
|
||||
if hasattr(self, 'init_execute_mixin'):
|
||||
# Instance with 'ExecuteMixin'
|
||||
self.init_execute_mixin(*args, **kwargs) # pylint: disable=E1101
|
||||
@ -247,6 +264,11 @@ class ShareDriver(object):
|
||||
# Instance with 'GaneshaMixin'
|
||||
self.init_ganesha_mixin(*args, **kwargs) # pylint: disable=E1101
|
||||
|
||||
@property
|
||||
def admin_network_api(self):
|
||||
if hasattr(self, '_admin_network_api'):
|
||||
return self._admin_network_api
|
||||
|
||||
@property
|
||||
def driver_handles_share_servers(self):
|
||||
if self.configuration:
|
||||
@ -675,6 +697,9 @@ class ShareDriver(object):
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_admin_network_allocations_number(self):
|
||||
return 0
|
||||
|
||||
def allocate_network(self, context, share_server, share_network,
|
||||
count=None, **kwargs):
|
||||
"""Allocate network resources using given network information."""
|
||||
@ -685,6 +710,19 @@ class ShareDriver(object):
|
||||
self.network_api.allocate_network(
|
||||
context, share_server, share_network, **kwargs)
|
||||
|
||||
def allocate_admin_network(self, context, share_server, count=None,
|
||||
**kwargs):
|
||||
"""Allocate admin network resources using given network information."""
|
||||
if count is None:
|
||||
count = self.get_admin_network_allocations_number()
|
||||
if count and not self.admin_network_api:
|
||||
msg = _("Admin network plugin is not set up.")
|
||||
raise exception.NetworkBadConfigurationException(reason=msg)
|
||||
elif count:
|
||||
kwargs.update(count=count)
|
||||
self.admin_network_api.allocate_network(
|
||||
context, share_server, **kwargs)
|
||||
|
||||
def deallocate_network(self, context, share_server_id):
|
||||
"""Deallocate network resources for the given share server."""
|
||||
if self.get_network_allocations_number():
|
||||
|
@ -1561,7 +1561,14 @@ class ShareManager(manager.SchedulerDependentManager):
|
||||
# Network info is used by driver for setting up share server
|
||||
# and getting server info on share creation.
|
||||
network_allocations = self.db.network_allocations_get_for_share_server(
|
||||
context, share_server['id'])
|
||||
context, share_server['id'], label='user')
|
||||
admin_network_allocations = (
|
||||
self.db.network_allocations_get_for_share_server(
|
||||
context, share_server['id'], label='admin'))
|
||||
# NOTE(vponomaryov): following network_info fields are deprecated:
|
||||
# 'segmentation_id', 'cidr' and 'network_type'.
|
||||
# And they should be used from network allocations directly.
|
||||
# They should be removed right after no one uses them.
|
||||
network_info = {
|
||||
'server_id': share_server['id'],
|
||||
'segmentation_id': share_network['segmentation_id'],
|
||||
@ -1571,6 +1578,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
||||
'nova_net_id': share_network['nova_net_id'],
|
||||
'security_services': share_network['security_services'],
|
||||
'network_allocations': network_allocations,
|
||||
'admin_network_allocations': admin_network_allocations,
|
||||
'backend_details': share_server.get('backend_details'),
|
||||
'network_type': share_network['network_type'],
|
||||
}
|
||||
@ -1581,6 +1589,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
||||
share_network = self.db.share_network_get(
|
||||
context, share_server['share_network_id'])
|
||||
self.driver.allocate_network(context, share_server, share_network)
|
||||
self.driver.allocate_admin_network(context, share_server)
|
||||
|
||||
# Get share_network again in case it was updated.
|
||||
share_network = self.db.share_network_get(
|
||||
|
@ -470,3 +470,85 @@ class ShareReplicationMigrationChecks(BaseMigrationChecks):
|
||||
self.valid_share_ids)
|
||||
self.test_case.assertFalse(
|
||||
hasattr(share_instance, 'replica_state'))
|
||||
|
||||
|
||||
@map_to_migration('5155c7077f99')
|
||||
class NetworkAllocationsNewLabelColumnChecks(BaseMigrationChecks):
|
||||
table_name = 'network_allocations'
|
||||
ids = ['fake_network_allocation_id_%d' % i for i in (1, 2, 3)]
|
||||
|
||||
def setup_upgrade_data(self, engine):
|
||||
user_id = 'user_id'
|
||||
project_id = 'project_id'
|
||||
share_server_id = 'foo_share_server_id'
|
||||
|
||||
# Create share network
|
||||
share_network_data = {
|
||||
'id': 'foo_share_network_id',
|
||||
'user_id': user_id,
|
||||
'project_id': project_id,
|
||||
}
|
||||
sn_table = utils.load_table('share_networks', 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.ids[0],
|
||||
'share_server_id': share_server_id,
|
||||
'ip_address': '1.1.1.1'},
|
||||
{'id': self.ids[1],
|
||||
'share_server_id': share_server_id,
|
||||
'ip_address': '2.2.2.2'},
|
||||
]
|
||||
na_table = utils.load_table(self.table_name, engine)
|
||||
for network_allocation in network_allocations:
|
||||
engine.execute(na_table.insert(network_allocation))
|
||||
|
||||
def check_upgrade(self, engine, data):
|
||||
na_table = utils.load_table(self.table_name, engine)
|
||||
for na in engine.execute(na_table.select()):
|
||||
self.test_case.assertTrue(hasattr(na, 'label'))
|
||||
self.test_case.assertEqual(na.label, 'user')
|
||||
|
||||
# Create admin network allocation
|
||||
network_allocations = [
|
||||
{'id': self.ids[2],
|
||||
'share_server_id': na.share_server_id,
|
||||
'ip_address': '3.3.3.3',
|
||||
'label': 'admin',
|
||||
'network_type': 'vlan',
|
||||
'segmentation_id': 1005,
|
||||
'ip_version': 4,
|
||||
'cidr': '240.0.0.0/16'},
|
||||
]
|
||||
engine.execute(na_table.insert(network_allocations))
|
||||
|
||||
# Select admin network allocations
|
||||
for na in engine.execute(
|
||||
na_table.select().where(na_table.c.label == 'admin')):
|
||||
self.test_case.assertTrue(hasattr(na, 'label'))
|
||||
self.test_case.assertEqual('admin', na.label)
|
||||
for col_name in ('network_type', 'segmentation_id', 'ip_version',
|
||||
'cidr'):
|
||||
self.test_case.assertTrue(hasattr(na, col_name))
|
||||
self.test_case.assertEqual(
|
||||
network_allocations[0][col_name], getattr(na, col_name))
|
||||
|
||||
def check_downgrade(self, engine):
|
||||
na_table = utils.load_table(self.table_name, engine)
|
||||
db_result = engine.execute(na_table.select())
|
||||
self.test_case.assertTrue(db_result.rowcount >= len(self.ids))
|
||||
for na in db_result:
|
||||
for col_name in ('label', 'network_type', 'segmentation_id',
|
||||
'ip_version', 'cidr'):
|
||||
self.test_case.assertFalse(hasattr(na, col_name))
|
||||
|
@ -1967,3 +1967,99 @@ class AvailabilityZonesDatabaseAPITestCase(test.TestCase):
|
||||
|
||||
self.assertEqual(1, len(actual_result))
|
||||
self.assertEqual('test2', actual_result[0]['name'])
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class NetworkAllocationsDatabaseAPITestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(NetworkAllocationsDatabaseAPITestCase, self).setUp()
|
||||
self.user_id = 'user_id'
|
||||
self.project_id = 'project_id'
|
||||
self.share_server_id = 'foo_share_server_id'
|
||||
self.ctxt = context.RequestContext(
|
||||
user_id=self.user_id, project_id=self.project_id, is_admin=True)
|
||||
self.user_network_allocations = [
|
||||
{'share_server_id': self.share_server_id,
|
||||
'ip_address': '1.1.1.1',
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': None},
|
||||
{'share_server_id': self.share_server_id,
|
||||
'ip_address': '2.2.2.2',
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': 'user'},
|
||||
]
|
||||
self.admin_network_allocations = [
|
||||
{'share_server_id': self.share_server_id,
|
||||
'ip_address': '3.3.3.3',
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': 'admin'},
|
||||
{'share_server_id': self.share_server_id,
|
||||
'ip_address': '4.4.4.4',
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': 'admin'},
|
||||
]
|
||||
|
||||
def _setup_network_allocations_get_for_share_server(self):
|
||||
# Create share network
|
||||
share_network_data = {
|
||||
'id': 'foo_share_network_id',
|
||||
'user_id': self.user_id,
|
||||
'project_id': self.project_id,
|
||||
}
|
||||
db_api.share_network_create(self.ctxt, share_network_data)
|
||||
|
||||
# Create share server
|
||||
share_server_data = {
|
||||
'id': self.share_server_id,
|
||||
'share_network_id': share_network_data['id'],
|
||||
'host': 'fake_host',
|
||||
'status': 'active',
|
||||
}
|
||||
db_api.share_server_create(self.ctxt, share_server_data)
|
||||
|
||||
# Create user network allocations
|
||||
for user_network_allocation in self.user_network_allocations:
|
||||
db_api.network_allocation_create(
|
||||
self.ctxt, user_network_allocation)
|
||||
|
||||
# Create admin network allocations
|
||||
for admin_network_allocation in self.admin_network_allocations:
|
||||
db_api.network_allocation_create(
|
||||
self.ctxt, admin_network_allocation)
|
||||
|
||||
def test_get_only_user_network_allocations(self):
|
||||
self._setup_network_allocations_get_for_share_server()
|
||||
|
||||
result = db_api.network_allocations_get_for_share_server(
|
||||
self.ctxt, self.share_server_id, label='user')
|
||||
|
||||
self.assertEqual(
|
||||
len(self.user_network_allocations), len(result))
|
||||
for na in result:
|
||||
self.assertIn(na.label, (None, 'user'))
|
||||
|
||||
def test_get_only_admin_network_allocations(self):
|
||||
self._setup_network_allocations_get_for_share_server()
|
||||
|
||||
result = db_api.network_allocations_get_for_share_server(
|
||||
self.ctxt, self.share_server_id, label='admin')
|
||||
|
||||
self.assertEqual(
|
||||
len(self.admin_network_allocations), len(result))
|
||||
for na in result:
|
||||
self.assertEqual(na.label, 'admin')
|
||||
|
||||
def test_get_all_network_allocations(self):
|
||||
self._setup_network_allocations_get_for_share_server()
|
||||
|
||||
result = db_api.network_allocations_get_for_share_server(
|
||||
self.ctxt, self.share_server_id, label=None)
|
||||
|
||||
self.assertEqual(
|
||||
len(self.user_network_allocations +
|
||||
self.admin_network_allocations),
|
||||
len(result)
|
||||
)
|
||||
for na in result:
|
||||
self.assertIn(na.label, ('admin', 'user', None))
|
||||
|
@ -57,6 +57,10 @@ fake_share_network = {
|
||||
'name': 'fake name',
|
||||
'description': 'fake description',
|
||||
'security_services': [],
|
||||
'network_type': 'fake_network_type',
|
||||
'segmentation_id': 1234,
|
||||
'ip_version': 4,
|
||||
'cidr': 'fake_cidr',
|
||||
}
|
||||
|
||||
fake_share_server = {
|
||||
@ -73,6 +77,11 @@ fake_network_allocation = {
|
||||
'ip_address': fake_neutron_port['fixed_ips'][0]['ip_address'],
|
||||
'mac_address': fake_neutron_port['mac_address'],
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
'label': 'user',
|
||||
'network_type': fake_share_network['network_type'],
|
||||
'segmentation_id': fake_share_network['segmentation_id'],
|
||||
'ip_version': fake_share_network['ip_version'],
|
||||
'cidr': fake_share_network['cidr'],
|
||||
}
|
||||
|
||||
|
||||
|
@ -42,6 +42,8 @@ class NovaNetworkPluginTest(test.TestCase):
|
||||
self.fake_context, self.share_server, share_network, count=0)
|
||||
|
||||
self.assertEqual([], allocations)
|
||||
self.assertTrue(hasattr(self.instance, 'label'))
|
||||
self.assertEqual('user', self.instance.label)
|
||||
|
||||
@ddt.data('flat', 'vlan')
|
||||
def test_allocate_network_get_one(self, net_type):
|
||||
@ -226,12 +228,12 @@ class NovaSingleNetworkPluginTest(test.TestCase):
|
||||
self.context = context.RequestContext(
|
||||
user_id='fake user', project_id='fake project', is_admin=False)
|
||||
|
||||
def _get_instance(self):
|
||||
def _get_instance(self, label=None):
|
||||
nova_net_id = 'fake_nova_net_id'
|
||||
config_data = dict(
|
||||
DEFAULT=dict(nova_single_network_plugin_net_id=nova_net_id))
|
||||
with test_utils.create_temp_config_with_opts(config_data):
|
||||
return plugin.NovaSingleNetworkPlugin()
|
||||
return plugin.NovaSingleNetworkPlugin(label=label)
|
||||
|
||||
def test_init_valid(self):
|
||||
nova_net_id = 'fake_nova_net_id'
|
||||
@ -287,6 +289,24 @@ class NovaSingleNetworkPluginTest(test.TestCase):
|
||||
instance._allocate_network.assert_called_once_with(
|
||||
self.context, self.share_server, share_network, count=2)
|
||||
|
||||
def test_allocate_network_with_admin_label(self):
|
||||
instance = self._get_instance(label='admin')
|
||||
allocations = ['foo', 'bar']
|
||||
self.mock_object(instance.db, 'share_network_update')
|
||||
self.mock_object(
|
||||
instance, '_allocate_network', mock.Mock(return_value=allocations))
|
||||
fake_share_network = {'nova_net_id': 'fake_nova_net_id'}
|
||||
|
||||
result = instance.allocate_network(
|
||||
self.context, self.share_server, fake_share_network, count=2)
|
||||
|
||||
self.assertTrue(hasattr(instance, 'label'))
|
||||
self.assertEqual('admin', instance.label)
|
||||
self.assertEqual(allocations, result)
|
||||
instance.db.share_network_update.assert_has_calls([])
|
||||
instance._allocate_network.assert_called_once_with(
|
||||
self.context, self.share_server, fake_share_network, count=2)
|
||||
|
||||
def test_allocate_network_different_nova_net_id_is_set(self):
|
||||
instance = self._get_instance()
|
||||
share_network = dict(
|
||||
|
@ -67,7 +67,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
'standalone_network_plugin_gateway': '10.0.0.1',
|
||||
'standalone_network_plugin_mask': '255.255.0.0',
|
||||
'standalone_network_plugin_network_type': 'vlan',
|
||||
'standalone_network_plugin_segmentation_id': '1001',
|
||||
'standalone_network_plugin_segmentation_id': 1001,
|
||||
'standalone_network_plugin_allowed_ip_ranges': (
|
||||
'10.0.0.3-10.0.0.7,10.0.0.69-10.0.0.157,10.0.0.213'),
|
||||
'standalone_network_plugin_ip_version': 4,
|
||||
@ -86,7 +86,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
self.assertEqual('10.0.0.1', instance.gateway)
|
||||
self.assertEqual('255.255.0.0', instance.mask)
|
||||
self.assertEqual('vlan', instance.network_type)
|
||||
self.assertEqual('1001', instance.segmentation_id)
|
||||
self.assertEqual(1001, instance.segmentation_id)
|
||||
self.assertEqual(allowed_cidrs, instance.allowed_cidrs)
|
||||
self.assertEqual(
|
||||
['10.0.0.3-10.0.0.7', '10.0.0.69-10.0.0.157', '10.0.0.213'],
|
||||
@ -134,7 +134,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
'standalone_network_plugin_gateway': '2001:db8::0001',
|
||||
'standalone_network_plugin_mask': '88',
|
||||
'standalone_network_plugin_network_type': 'vlan',
|
||||
'standalone_network_plugin_segmentation_id': '3999',
|
||||
'standalone_network_plugin_segmentation_id': 3999,
|
||||
'standalone_network_plugin_allowed_ip_ranges': (
|
||||
'2001:db8::-2001:db8:0000:0000:0000:007f:ffff:ffff'),
|
||||
'standalone_network_plugin_ip_version': 6,
|
||||
@ -148,7 +148,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
self.assertEqual('2001:db8::0001', instance.gateway)
|
||||
self.assertEqual('88', instance.mask)
|
||||
self.assertEqual('vlan', instance.network_type)
|
||||
self.assertEqual('3999', instance.segmentation_id)
|
||||
self.assertEqual(3999, instance.segmentation_id)
|
||||
self.assertEqual(['2001:db8::/89'], instance.allowed_cidrs)
|
||||
self.assertEqual(
|
||||
['2001:db8::-2001:db8:0000:0000:0000:007f:ffff:ffff'],
|
||||
@ -166,7 +166,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
'standalone_network_plugin_gateway': '10.0.0.1',
|
||||
'standalone_network_plugin_mask': '255.255.0.0',
|
||||
'standalone_network_plugin_network_type': network_type,
|
||||
'standalone_network_plugin_segmentation_id': '1001',
|
||||
'standalone_network_plugin_segmentation_id': 1001,
|
||||
'standalone_network_plugin_ip_version': 4,
|
||||
},
|
||||
}
|
||||
@ -184,7 +184,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
'standalone_network_plugin_gateway': '10.0.0.1',
|
||||
'standalone_network_plugin_mask': '255.255.0.0',
|
||||
'standalone_network_plugin_network_type': fake_network_type,
|
||||
'standalone_network_plugin_segmentation_id': '1001',
|
||||
'standalone_network_plugin_segmentation_id': 1001,
|
||||
'standalone_network_plugin_ip_version': 4,
|
||||
},
|
||||
}
|
||||
@ -335,7 +335,7 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
data = {
|
||||
'DEFAULT': {
|
||||
'standalone_network_plugin_network_type': 'vlan',
|
||||
'standalone_network_plugin_segmentation_id': '1003',
|
||||
'standalone_network_plugin_segmentation_id': 1003,
|
||||
'standalone_network_plugin_gateway': '10.0.0.1',
|
||||
'standalone_network_plugin_mask': '24',
|
||||
},
|
||||
@ -352,16 +352,21 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
fake_context, fake_share_server, fake_share_network)
|
||||
|
||||
self.assertEqual(1, len(allocations))
|
||||
na_data = {
|
||||
'network_type': 'vlan',
|
||||
'segmentation_id': 1003,
|
||||
'cidr': '10.0.0.0/24',
|
||||
'ip_version': 4,
|
||||
}
|
||||
instance.db.share_network_update.assert_called_once_with(
|
||||
fake_context, fake_share_network['id'],
|
||||
dict(network_type='vlan', segmentation_id='1003',
|
||||
cidr=six.text_type(instance.net.cidr), ip_version=4))
|
||||
fake_context, fake_share_network['id'], na_data)
|
||||
instance.db.network_allocations_get_by_ip_address.assert_has_calls(
|
||||
[mock.call(fake_context, '10.0.0.2')])
|
||||
instance.db.network_allocation_create.assert_called_once_with(
|
||||
fake_context,
|
||||
dict(share_server_id=fake_share_server['id'],
|
||||
ip_address='10.0.0.2', status=constants.STATUS_ACTIVE))
|
||||
ip_address='10.0.0.2', status=constants.STATUS_ACTIVE,
|
||||
label='user', **na_data))
|
||||
|
||||
def test_allocate_network_two_ip_addresses_ipv4_two_usages_exist(self):
|
||||
ctxt = type('FakeCtxt', (object,), {'fake': ['10.0.0.2', '10.0.0.4']})
|
||||
@ -391,10 +396,14 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
ctxt, fake_share_server, fake_share_network, count=2)
|
||||
|
||||
self.assertEqual(2, len(allocations))
|
||||
na_data = {
|
||||
'network_type': None,
|
||||
'segmentation_id': None,
|
||||
'cidr': six.text_type(instance.net.cidr),
|
||||
'ip_version': 4,
|
||||
}
|
||||
instance.db.share_network_update.assert_called_once_with(
|
||||
ctxt, fake_share_network['id'],
|
||||
dict(network_type=None, segmentation_id=None,
|
||||
cidr=six.text_type(instance.net.cidr), ip_version=4))
|
||||
ctxt, fake_share_network['id'], dict(**na_data))
|
||||
instance.db.network_allocations_get_by_ip_address.assert_has_calls(
|
||||
[mock.call(ctxt, '10.0.0.2'), mock.call(ctxt, '10.0.0.3'),
|
||||
mock.call(ctxt, '10.0.0.4'), mock.call(ctxt, '10.0.0.5')])
|
||||
@ -402,11 +411,13 @@ class StandaloneNetworkPluginTest(test.TestCase):
|
||||
mock.call(
|
||||
ctxt,
|
||||
dict(share_server_id=fake_share_server['id'],
|
||||
ip_address='10.0.0.3', status=constants.STATUS_ACTIVE)),
|
||||
ip_address='10.0.0.3', status=constants.STATUS_ACTIVE,
|
||||
label='user', **na_data)),
|
||||
mock.call(
|
||||
ctxt,
|
||||
dict(share_server_id=fake_share_server['id'],
|
||||
ip_address='10.0.0.5', status=constants.STATUS_ACTIVE)),
|
||||
ip_address='10.0.0.5', status=constants.STATUS_ACTIVE,
|
||||
label='user', **na_data)),
|
||||
])
|
||||
|
||||
def test_allocate_network_no_available_ipv4_addresses(self):
|
||||
|
@ -49,6 +49,8 @@ class HPE3ParDriverTestCase(test.TestCase):
|
||||
self.conf.hpe3par_fstore_per_share = False
|
||||
self.conf.hpe3par_require_cifs_ip = False
|
||||
self.conf.network_config_group = 'test_network_config_group'
|
||||
self.conf.admin_network_config_group = (
|
||||
'test_admin_network_config_group')
|
||||
|
||||
def safe_get(attr):
|
||||
try:
|
||||
|
@ -712,6 +712,8 @@ class HuaweiShareDriverTestCase(test.TestCase):
|
||||
self.configuration = mock.Mock(spec=conf.Configuration)
|
||||
self.configuration.safe_get = mock.Mock(side_effect=_safe_get)
|
||||
self.configuration.network_config_group = 'fake_network_config_group'
|
||||
self.configuration.admin_network_config_group = (
|
||||
'fake_admin_network_config_group')
|
||||
self.configuration.share_backend_name = 'fake_share_backend_name'
|
||||
self.configuration.huawei_share_backend = 'V3'
|
||||
self.configuration.max_over_subscription_ratio = 1
|
||||
|
@ -89,6 +89,8 @@ class ZFSSAShareDriverTestCase(test.TestCase):
|
||||
self.configuration.zfssa_nas_quota_snap = 'true'
|
||||
self.configuration.zfssa_rest_timeout = 60
|
||||
self.configuration.network_config_group = 'fake_network_config_group'
|
||||
self.configuration.admin_network_config_group = (
|
||||
'fake_admin_network_config_group')
|
||||
self.configuration.driver_handles_share_servers = False
|
||||
|
||||
def test_create_share(self):
|
||||
|
@ -72,12 +72,15 @@ class ShareDriverTestCase(test.TestCase):
|
||||
self.assertTrue(share_driver.driver_handles_share_servers)
|
||||
|
||||
def _instantiate_share_driver(self, network_config_group,
|
||||
driver_handles_share_servers):
|
||||
driver_handles_share_servers,
|
||||
admin_network_config_group=None):
|
||||
self.mock_object(network, 'API')
|
||||
config = mock.Mock()
|
||||
config.append_config_values = mock.Mock()
|
||||
config.config_group = 'fake_config_group'
|
||||
config.network_config_group = network_config_group
|
||||
if admin_network_config_group:
|
||||
config.admin_network_config_group = admin_network_config_group
|
||||
config.safe_get = mock.Mock(return_value=driver_handles_share_servers)
|
||||
|
||||
share_driver = driver.ShareDriver([True, False], configuration=config)
|
||||
@ -85,14 +88,26 @@ class ShareDriverTestCase(test.TestCase):
|
||||
self.assertTrue(hasattr(share_driver, 'configuration'))
|
||||
config.append_config_values.assert_called_once_with(driver.share_opts)
|
||||
if driver_handles_share_servers:
|
||||
calls = []
|
||||
if network_config_group:
|
||||
network.API.assert_called_once_with(
|
||||
config_group_name=config.network_config_group)
|
||||
calls.append(mock.call(
|
||||
config_group_name=config.network_config_group))
|
||||
else:
|
||||
network.API.assert_called_once_with(
|
||||
config_group_name=config.config_group)
|
||||
calls.append(mock.call(
|
||||
config_group_name=config.config_group))
|
||||
if admin_network_config_group:
|
||||
calls.append(mock.call(
|
||||
config_group_name=config.admin_network_config_group,
|
||||
label='admin'))
|
||||
network.API.assert_has_calls(calls)
|
||||
self.assertTrue(hasattr(share_driver, 'network_api'))
|
||||
self.assertTrue(hasattr(share_driver, 'admin_network_api'))
|
||||
self.assertIsNotNone(share_driver.network_api)
|
||||
self.assertIsNotNone(share_driver.admin_network_api)
|
||||
else:
|
||||
self.assertFalse(hasattr(share_driver, 'network_api'))
|
||||
self.assertTrue(hasattr(share_driver, 'admin_network_api'))
|
||||
self.assertIsNone(share_driver.admin_network_api)
|
||||
self.assertFalse(network.API.called)
|
||||
return share_driver
|
||||
|
||||
@ -102,6 +117,11 @@ class ShareDriverTestCase(test.TestCase):
|
||||
def test_instantiate_share_driver_another_config_group(self):
|
||||
self._instantiate_share_driver("fake_network_config_group", True)
|
||||
|
||||
def test_instantiate_share_driver_with_admin_network(self):
|
||||
self._instantiate_share_driver(
|
||||
"fake_network_config_group", True,
|
||||
"fake_admin_network_config_group")
|
||||
|
||||
def test_instantiate_share_driver_no_configuration(self):
|
||||
self.mock_object(network, 'API')
|
||||
|
||||
@ -358,6 +378,87 @@ class ShareDriverTestCase(test.TestCase):
|
||||
|
||||
self.assertEqual(share_instances, result)
|
||||
|
||||
def test_get_admin_network_allocations_number(self):
|
||||
share_driver = self._instantiate_share_driver(None, True)
|
||||
|
||||
self.assertEqual(
|
||||
0, share_driver.get_admin_network_allocations_number())
|
||||
|
||||
def test_allocate_admin_network_count_None(self):
|
||||
share_driver = self._instantiate_share_driver(None, True)
|
||||
ctxt = 'fake_context'
|
||||
share_server = 'fake_share_server'
|
||||
mock_get_admin_network_allocations_number = self.mock_object(
|
||||
share_driver,
|
||||
'get_admin_network_allocations_number',
|
||||
mock.Mock(return_value=0))
|
||||
self.mock_object(
|
||||
share_driver.admin_network_api,
|
||||
'allocate_network',
|
||||
mock.Mock(side_effect=Exception('ShouldNotBeRaised')))
|
||||
|
||||
share_driver.allocate_admin_network(ctxt, share_server)
|
||||
|
||||
mock_get_admin_network_allocations_number.assert_called_once_with()
|
||||
self.assertFalse(
|
||||
share_driver.admin_network_api.allocate_network.called)
|
||||
|
||||
def test_allocate_admin_network_count_0(self):
|
||||
share_driver = self._instantiate_share_driver(None, True)
|
||||
ctxt = 'fake_context'
|
||||
share_server = 'fake_share_server'
|
||||
self.mock_object(
|
||||
share_driver,
|
||||
'get_admin_network_allocations_number',
|
||||
mock.Mock(return_value=0))
|
||||
self.mock_object(
|
||||
share_driver.admin_network_api,
|
||||
'allocate_network',
|
||||
mock.Mock(side_effect=Exception('ShouldNotBeRaised')))
|
||||
|
||||
share_driver.allocate_admin_network(ctxt, share_server, count=0)
|
||||
|
||||
self.assertFalse(
|
||||
share_driver.get_admin_network_allocations_number.called)
|
||||
self.assertFalse(
|
||||
share_driver.admin_network_api.allocate_network.called)
|
||||
|
||||
def test_allocate_admin_network_count_1_api_initialized(self):
|
||||
share_driver = self._instantiate_share_driver(None, True)
|
||||
ctxt = 'fake_context'
|
||||
share_server = 'fake_share_server'
|
||||
mock_get_admin_network_allocations_number = self.mock_object(
|
||||
share_driver,
|
||||
'get_admin_network_allocations_number',
|
||||
mock.Mock(return_value=1))
|
||||
self.mock_object(
|
||||
share_driver.admin_network_api,
|
||||
'allocate_network',
|
||||
mock.Mock())
|
||||
|
||||
share_driver.allocate_admin_network(ctxt, share_server)
|
||||
|
||||
mock_get_admin_network_allocations_number.assert_called_once_with()
|
||||
share_driver.admin_network_api.allocate_network.\
|
||||
assert_called_once_with(ctxt, share_server, count=1)
|
||||
|
||||
def test_allocate_admin_network_count_1_api_not_initialized(self):
|
||||
share_driver = self._instantiate_share_driver(None, True, None)
|
||||
ctxt = 'fake_context'
|
||||
share_server = 'fake_share_server'
|
||||
share_driver._admin_network_api = None
|
||||
mock_get_admin_network_allocations_number = self.mock_object(
|
||||
share_driver,
|
||||
'get_admin_network_allocations_number',
|
||||
mock.Mock(return_value=1))
|
||||
|
||||
self.assertRaises(
|
||||
exception.NetworkBadConfigurationException,
|
||||
share_driver.allocate_admin_network,
|
||||
ctxt, share_server,
|
||||
)
|
||||
mock_get_admin_network_allocations_number.assert_called_once_with()
|
||||
|
||||
def test_migrate_share(self):
|
||||
|
||||
driver.CONF.set_default('driver_handles_share_servers', False)
|
||||
|
@ -2311,10 +2311,15 @@ class ShareManagerTestCase(test.TestCase):
|
||||
self.assertEqual(1, mock_LOG.error.call_count)
|
||||
|
||||
def test__form_server_setup_info(self):
|
||||
fake_network_allocations = ['foo', 'bar']
|
||||
def fake_network_allocations_get_for_share_server(*args, **kwargs):
|
||||
if kwargs.get('label') != 'admin':
|
||||
return ['foo', 'bar']
|
||||
return ['admin-foo', 'admin-bar']
|
||||
|
||||
self.mock_object(
|
||||
self.share_manager.db, 'network_allocations_get_for_share_server',
|
||||
mock.Mock(return_value=fake_network_allocations))
|
||||
mock.Mock(
|
||||
side_effect=fake_network_allocations_get_for_share_server))
|
||||
fake_share_server = dict(
|
||||
id='fake_share_server_id', backend_details=dict(foo='bar'))
|
||||
fake_share_network = dict(
|
||||
@ -2333,7 +2338,10 @@ class ShareManagerTestCase(test.TestCase):
|
||||
neutron_subnet_id=fake_share_network['neutron_subnet_id'],
|
||||
nova_net_id=fake_share_network['nova_net_id'],
|
||||
security_services=fake_share_network['security_services'],
|
||||
network_allocations=fake_network_allocations,
|
||||
network_allocations=(
|
||||
fake_network_allocations_get_for_share_server()),
|
||||
admin_network_allocations=(
|
||||
fake_network_allocations_get_for_share_server(label='admin')),
|
||||
backend_details=fake_share_server['backend_details'],
|
||||
network_type=fake_share_network['network_type'])
|
||||
|
||||
@ -2342,7 +2350,10 @@ class ShareManagerTestCase(test.TestCase):
|
||||
|
||||
self.assertEqual(expected, network_info)
|
||||
self.share_manager.db.network_allocations_get_for_share_server.\
|
||||
assert_called_once_with(self.context, fake_share_server['id'])
|
||||
assert_has_calls([
|
||||
mock.call(self.context, fake_share_server['id'], label='user'),
|
||||
mock.call(self.context, fake_share_server['id'], label='admin')
|
||||
])
|
||||
|
||||
@ddt.data(
|
||||
{'network_info': {'network_type': 'vlan', 'segmentation_id': '100'}},
|
||||
|
130
manila/tests/test_network.py
Normal file
130
manila/tests/test_network.py
Normal file
@ -0,0 +1,130 @@
|
||||
# Copyright 2015 Mirantis Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
import ddt
|
||||
from oslo_config import cfg
|
||||
from oslo_utils import importutils
|
||||
|
||||
from manila import exception
|
||||
from manila import network
|
||||
from manila import test
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class APITestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(self.__class__, self).setUp()
|
||||
self.mock_object(importutils, 'import_class')
|
||||
|
||||
def test_init_api_with_default_config_group_name(self):
|
||||
network.API()
|
||||
|
||||
importutils.import_class.assert_called_once_with(
|
||||
CONF.network_api_class)
|
||||
importutils.import_class.return_value.assert_called_once_with(
|
||||
config_group_name=None, label='user')
|
||||
|
||||
def test_init_api_with_custom_config_group_name(self):
|
||||
group_name = 'FOO_GROUP_NAME'
|
||||
|
||||
network.API(config_group_name=group_name)
|
||||
|
||||
importutils.import_class.assert_called_once_with(
|
||||
getattr(CONF, group_name).network_api_class)
|
||||
importutils.import_class.return_value.assert_called_once_with(
|
||||
config_group_name=group_name, label='user')
|
||||
|
||||
def test_init_api_with_custom_config_group_name_and_label(self):
|
||||
group_name = 'FOO_GROUP_NAME'
|
||||
label = 'custom_label'
|
||||
|
||||
network.API(config_group_name=group_name, label=label)
|
||||
|
||||
importutils.import_class.assert_called_once_with(
|
||||
getattr(CONF, group_name).network_api_class)
|
||||
importutils.import_class.return_value.assert_called_once_with(
|
||||
config_group_name=group_name, label=label)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class NetworkBaseAPITestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(self.__class__, self).setUp()
|
||||
self.db_driver = 'fake_driver'
|
||||
self.mock_object(importutils, 'import_module')
|
||||
|
||||
def test_inherit_network_base_api_no_redefinitions(self):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
pass
|
||||
|
||||
self.assertRaises(TypeError, FakeNetworkAPI)
|
||||
|
||||
def test_inherit_network_base_api_deallocate_not_redefined(self):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
def allocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
self.assertRaises(TypeError, FakeNetworkAPI)
|
||||
|
||||
def test_inherit_network_base_api_allocate_not_redefined(self):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
def deallocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
self.assertRaises(TypeError, FakeNetworkAPI)
|
||||
|
||||
def test_inherit_network_base_api(self):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
def allocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def deallocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
result = FakeNetworkAPI()
|
||||
|
||||
self.assertTrue(hasattr(result, '_verify_share_network'))
|
||||
self.assertTrue(hasattr(result, 'allocate_network'))
|
||||
self.assertTrue(hasattr(result, 'deallocate_network'))
|
||||
|
||||
def test__verify_share_network_ok(self):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
def allocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def deallocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
result = FakeNetworkAPI()
|
||||
|
||||
result._verify_share_network('foo_id', {'id': 'bar_id'})
|
||||
|
||||
def test__verify_share_network_fail(self):
|
||||
class FakeNetworkAPI(network.NetworkBaseAPI):
|
||||
def allocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def deallocate_network(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
result = FakeNetworkAPI()
|
||||
|
||||
self.assertRaises(
|
||||
exception.NetworkBadConfigurationException,
|
||||
result._verify_share_network, 'foo_id', None)
|
Loading…
Reference in New Issue
Block a user