Updated generic_driver and service_instance with activation
Generic driver changes to activation/deactivation of share_networks requires changes to service instance. Also it requires changes to tempest plugin, that should use activation of share networks before creation of shares. Partially-implements bp share-network-activation-api Closes-Bug: #1294577 Closes-Bug: #1273758 Change-Id: Ide3b9a51038b532bee464e256f6e830fb93001f7
This commit is contained in:
parent
85f02a9556
commit
69c063997c
|
@ -278,6 +278,14 @@ class BaseSharesTest(test.BaseTestCase):
|
|||
client = cls.shares_client
|
||||
if description is None:
|
||||
description = "Tempest's share"
|
||||
if (share_network_id or client.share_network_id):
|
||||
share_network_id = share_network_id or client.share_network_id
|
||||
__, body = client.get_share_network(share_network_id)
|
||||
if body["status"].lower() == "inactive":
|
||||
resp, __ = client.activate_share_network(share_network_id)
|
||||
assert (int(resp["status"]) in test.HTTP_SUCCESS)
|
||||
client.wait_for_share_network_status(share_network_id,
|
||||
"active")
|
||||
r, s = client.create_share(share_protocol=share_protocol, size=size,
|
||||
name=name, snapshot_id=snapshot_id,
|
||||
description=description,
|
||||
|
@ -391,6 +399,11 @@ class BaseSharesTest(test.BaseTestCase):
|
|||
client.delete_snapshot(res_id)
|
||||
client.wait_for_resource_deletion(snapshot_id=res_id)
|
||||
elif res["type"] is "share_network":
|
||||
__, body = client.get_share_network(res_id)
|
||||
if body["status"].lower() == "active":
|
||||
client.deactivate_share_network(res_id)
|
||||
client.wait_for_share_network_status(res_id,
|
||||
"inactive")
|
||||
client.delete_share_network(res_id)
|
||||
client.wait_for_resource_deletion(sn_id=res_id)
|
||||
elif res["type"] is "security_service":
|
||||
|
|
|
@ -42,3 +42,11 @@ class NoAvailableNetwork(base.TempestException):
|
|||
|
||||
class InvalidResource(base.TempestException):
|
||||
message = "Provided invalid resource: %(message)s"
|
||||
|
||||
|
||||
class ShareNetworkActivationFailed(base.TempestException):
|
||||
message = "Share-network with id %(sn_id) failed to activate"
|
||||
|
||||
|
||||
class ShareNetworkDeactivationFailed(base.TempestException):
|
||||
message = "Share-network with id %(sn_id) failed to deactivate"
|
||||
|
|
|
@ -450,6 +450,47 @@ class SharesClient(rest_client.RestClient):
|
|||
def delete_share_network(self, sn_id):
|
||||
return self.delete("share-networks/%s" % sn_id)
|
||||
|
||||
def action_with_share_network(self, sn_id, action="activate"):
|
||||
"""Activates or deactivates share networks.
|
||||
|
||||
param: sn_id: id of share-network
|
||||
param: action: available values are "activate" and "deactivate"
|
||||
returns: tuple with resp and body of response
|
||||
"""
|
||||
|
||||
body = json.dumps({action: {}})
|
||||
uri = "share-networks/%s/action" % sn_id
|
||||
resp, body = self.post(uri, body=body)
|
||||
return resp, self._parse_resp(body)
|
||||
|
||||
def activate_share_network(self, sn_id):
|
||||
return self.action_with_share_network(sn_id, "activate")
|
||||
|
||||
def deactivate_share_network(self, sn_id):
|
||||
return self.action_with_share_network(sn_id, "deactivate")
|
||||
|
||||
def wait_for_share_network_status(self, sn_id, status="active"):
|
||||
"""Waits for a Share network to reach a given status."""
|
||||
__, body = self.get_share_network(sn_id)
|
||||
sn_name = body['name']
|
||||
sn_status = body['status'].lower()
|
||||
start = int(time.time())
|
||||
|
||||
while sn_status != status:
|
||||
time.sleep(self.build_interval)
|
||||
__, body = self.get_share_network(sn_id)
|
||||
sn_status = body['status'].lower()
|
||||
if 'error' in sn_status:
|
||||
# Error can be set only on attempt to activate
|
||||
raise share_exceptions.\
|
||||
ShareNetworkActivationFailed(sn_id=sn_id)
|
||||
|
||||
if int(time.time()) - start >= self.build_timeout:
|
||||
message = ('Share-network %s failed to reach %s status within '
|
||||
'the required time (%s s).' %
|
||||
(sn_name, status, self.build_timeout))
|
||||
raise exceptions.TimeoutException(message)
|
||||
|
||||
###############
|
||||
|
||||
def _map_security_service_and_share_network(self, sn_id, ss_id,
|
||||
|
|
|
@ -208,8 +208,9 @@ class ShareController(wsgi.Controller):
|
|||
except exception.ShareNetworkNotFound as e:
|
||||
msg = "%s" % e
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
if share_network['status'] == constants.STATUS_ERROR:
|
||||
msg = _("Share network is in 'ERROR' state.")
|
||||
if share_network['status'] != constants.STATUS_ACTIVE:
|
||||
msg = _("Share network '%s' is not in 'ACTIVE' state.")
|
||||
msg = msg % share_network["id"]
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
else:
|
||||
kwargs['share_network_id'] = share_network_id
|
||||
|
|
|
@ -20,5 +20,7 @@ STATUS_DELETED = 'DELETED'
|
|||
STATUS_ERROR = 'ERROR'
|
||||
STATUS_ACTIVE = 'ACTIVE'
|
||||
STATUS_INACTIVE = 'INACTIVE'
|
||||
STATUS_ACTIVATING = 'ACTIVATING'
|
||||
STATUS_DEACTIVATING = 'DEACTIVATING'
|
||||
|
||||
SECURITY_SERVICES_ALLOWED_TYPES = ['active_directory', 'ldap', 'kerberos']
|
||||
|
|
|
@ -13,12 +13,20 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import time
|
||||
|
||||
from oslo.config import cfg
|
||||
|
||||
from manila.common import constants
|
||||
from manila.db import base as db_base
|
||||
from manila import exception
|
||||
from manila import network as manila_network
|
||||
from manila.network.neutron import api as neutron_api
|
||||
from manila.network.neutron import constants as neutron_constants
|
||||
from manila.openstack.common import log as logging
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
|
||||
|
@ -53,10 +61,7 @@ class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
|
|||
for _ in range(0, allocation_count):
|
||||
self._create_port(context, share_network, device_owner)
|
||||
|
||||
return self.db.share_network_update(
|
||||
context,
|
||||
share_network['id'],
|
||||
{'status': constants.STATUS_ACTIVE})
|
||||
return self.db.share_network_get(context, share_network['id'])
|
||||
|
||||
def deallocate_network(self, context, share_network):
|
||||
"""Deallocate neutron network resources for the given network info:
|
||||
|
@ -72,30 +77,20 @@ class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
|
|||
for port in ports:
|
||||
self._delete_port(context, port)
|
||||
|
||||
self.db.share_network_update(context,
|
||||
share_network['id'],
|
||||
{'status': constants.STATUS_INACTIVE})
|
||||
|
||||
def _create_port(self, context, share_network, device_owner):
|
||||
try:
|
||||
port = self.neutron_api.create_port(
|
||||
share_network['project_id'],
|
||||
network_id=share_network['neutron_net_id'],
|
||||
subnet_id=share_network['neutron_subnet_id'],
|
||||
device_owner='manila:' + device_owner)
|
||||
except exception.NetworkException:
|
||||
self.db.share_network_update(context,
|
||||
share_network['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
raise
|
||||
else:
|
||||
port_dict = {'id': port['id'],
|
||||
'share_network_id': share_network['id'],
|
||||
'ip_address': port['fixed_ips'][0]['ip_address'],
|
||||
'mac_address': port['mac_address'],
|
||||
'status': constants.STATUS_ACTIVE}
|
||||
self.db.network_allocation_create(context, port_dict)
|
||||
return port_dict
|
||||
port = self.neutron_api.create_port(share_network['project_id'],
|
||||
network_id=share_network['neutron_net_id'],
|
||||
subnet_id=share_network['neutron_subnet_id'],
|
||||
device_owner='manila:' + device_owner)
|
||||
port_dict = {
|
||||
'id': port['id'],
|
||||
'share_network_id': share_network['id'],
|
||||
'ip_address': port['fixed_ips'][0]['ip_address'],
|
||||
'mac_address': port['mac_address'],
|
||||
'status': constants.STATUS_ACTIVE,
|
||||
}
|
||||
self.db.network_allocation_create(context, port_dict)
|
||||
return port_dict
|
||||
|
||||
def _delete_port(self, context, port):
|
||||
try:
|
||||
|
@ -104,9 +99,6 @@ class NeutronNetworkPlugin(manila_network.NetworkBaseAPI, db_base.Base):
|
|||
self.db.network_allocation_update(context,
|
||||
port['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
self.db.share_network_update(context,
|
||||
port['share_network_id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
raise
|
||||
else:
|
||||
self.db.network_allocation_delete(context, port['id'])
|
||||
|
|
|
@ -23,6 +23,7 @@ import time
|
|||
|
||||
from oslo.config import cfg
|
||||
|
||||
from manila.common import constants
|
||||
from manila import compute
|
||||
from manila import context
|
||||
from manila import exception
|
||||
|
@ -99,7 +100,9 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
self.service_instance_manager = service_instance.\
|
||||
ServiceInstanceManager(self.db, self._helpers)
|
||||
self.get_service_instance = self.service_instance_manager.\
|
||||
get_service_instance
|
||||
get_service_instance
|
||||
self.delete_service_instance = self.service_instance_manager.\
|
||||
delete_service_instance
|
||||
self.share_networks_locks = self.service_instance_manager.\
|
||||
share_networks_locks
|
||||
self.share_networks_servers = self.service_instance_manager.\
|
||||
|
@ -350,11 +353,12 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
if not share['share_network_id']:
|
||||
return
|
||||
server = self.get_service_instance(self.admin_context,
|
||||
share_network_id=share['share_network_id'],
|
||||
create=False)
|
||||
share_network_id=share['share_network_id'],
|
||||
return_inactive=True)
|
||||
if server:
|
||||
self._get_helper(share).remove_export(server, share['name'])
|
||||
self._unmount_device(context, share, server)
|
||||
if server['status'] == 'ACTIVE':
|
||||
self._get_helper(share).remove_export(server, share['name'])
|
||||
self._unmount_device(context, share, server)
|
||||
self._detach_volume(context, share, server)
|
||||
self._deallocate_container(context, share)
|
||||
|
||||
|
@ -405,7 +409,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
def ensure_share(self, context, share):
|
||||
"""Ensure that storage are mounted and exported."""
|
||||
server = self.get_service_instance(context,
|
||||
share_network_id=share['share_network_id'])
|
||||
share_network_id=share['share_network_id'], create=True)
|
||||
volume = self._get_volume(context, share['id'])
|
||||
volume = self._attach_volume(context, share, server, volume)
|
||||
self._mount_device(context, share, server, volume)
|
||||
|
@ -428,8 +432,7 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
if not share['share_network_id']:
|
||||
return
|
||||
server = self.get_service_instance(self.admin_context,
|
||||
share_network_id=share['share_network_id'],
|
||||
create=False)
|
||||
share_network_id=share['share_network_id'])
|
||||
if server:
|
||||
self._get_helper(share).deny_access(server, share['name'],
|
||||
access['access_type'],
|
||||
|
@ -444,10 +447,28 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
|
|||
raise exception.InvalidShare(reason='Wrong share type')
|
||||
|
||||
def get_network_allocations_number(self):
|
||||
"""Get number of network interfaces to be created."""
|
||||
# NOTE(vponomaryov): Generic driver does not need allocations, because
|
||||
# Nova will handle it. It is valid for all multitenant drivers, that
|
||||
# use service instance provided by Nova.
|
||||
return 0
|
||||
|
||||
def setup_network(self, network_info):
|
||||
pass
|
||||
def setup_network(self, share_network, metadata=None):
|
||||
sn_id = share_network["id"]
|
||||
msg = _("Creating share infrastructure for share network '%s'.")
|
||||
LOG.debug(msg % sn_id)
|
||||
self.get_service_instance(context=self.admin_context,
|
||||
share_network_id=sn_id,
|
||||
create=True)
|
||||
|
||||
def teardown_network(self, share_network):
|
||||
sn_id = share_network["id"]
|
||||
msg = _("Removing share infrastructure for share network '%s'.")
|
||||
LOG.debug(msg % sn_id)
|
||||
try:
|
||||
self.delete_service_instance(self.admin_context, sn_id)
|
||||
except Exception as e:
|
||||
LOG.debug(e)
|
||||
|
||||
|
||||
class NASHelperBase(object):
|
||||
|
|
|
@ -115,7 +115,14 @@ def _ssh_exec(server, command):
|
|||
|
||||
|
||||
class ServiceInstanceManager(object):
|
||||
"""Manages nova instances for various share drivers."""
|
||||
"""Manages nova instances for various share drivers.
|
||||
|
||||
This class provides two external methods:
|
||||
1. get_service_instance: creates or discovers service instance and network
|
||||
infrastructure for provided share network.
|
||||
2. delete_service_instance: removes service instance and network
|
||||
infrastructure.
|
||||
"""
|
||||
|
||||
def __init__(self, db, _helpers, *args, **kwargs):
|
||||
"""Do initialization."""
|
||||
|
@ -199,8 +206,6 @@ class ServiceInstanceManager(object):
|
|||
|
||||
def _delete_server(self, context, server):
|
||||
"""Deletes the server."""
|
||||
if not server:
|
||||
return
|
||||
self.compute_api.server_delete(context, server['id'])
|
||||
t = time.time()
|
||||
while time.time() - t < CONF.max_time_to_build_instance:
|
||||
|
@ -216,43 +221,62 @@ class ServiceInstanceManager(object):
|
|||
CONF.max_time_to_build_instance)
|
||||
|
||||
@synchronized
|
||||
def get_service_instance(self, context, share_network_id, create=True):
|
||||
"""Finds or creates and sets up service vm."""
|
||||
def get_service_instance(self, context, share_network_id, create=False,
|
||||
return_inactive=False):
|
||||
"""Finds or creates and sets up service vm.
|
||||
|
||||
:param context: defines context, that should be used
|
||||
:param share_network_id: it provides network data for service VM
|
||||
:param create: allow create service VM or not
|
||||
:param return_inactive: allows to return not active VM, without
|
||||
raise of exception
|
||||
:returns: dict with data for service VM
|
||||
:raises: exception.ServiceInstanceException
|
||||
"""
|
||||
server = self.share_networks_servers.get(share_network_id, {})
|
||||
old_server_ip = server.get('ip', None)
|
||||
if self._ensure_server(context, server, update=True):
|
||||
return server
|
||||
else:
|
||||
self._delete_server(context, server)
|
||||
server = {}
|
||||
service_instance_name = self._get_service_instance_name(
|
||||
share_network_id)
|
||||
search_opts = {'name': service_instance_name}
|
||||
servers = self.compute_api.server_list(context, search_opts, True)
|
||||
if len(servers) == 1:
|
||||
server = servers[0]
|
||||
server = self._discover_service_instance(context, share_network_id)
|
||||
old_server_ip = None
|
||||
is_active = False
|
||||
if server:
|
||||
server['ip'] = self._get_server_ip(server)
|
||||
old_server_ip = server['ip']
|
||||
if not self._ensure_server(context, server):
|
||||
is_active = self._ensure_server(context, server)
|
||||
if not is_active and create:
|
||||
if server:
|
||||
self._delete_server(context, server)
|
||||
server.clear()
|
||||
elif len(servers) > 1:
|
||||
raise exception.ServiceInstanceException(
|
||||
_('Error. Ambiguous service instances.'))
|
||||
if not server and create:
|
||||
server = self._create_service_instance(context,
|
||||
service_instance_name,
|
||||
share_network_id,
|
||||
old_server_ip)
|
||||
if server:
|
||||
is_active = True
|
||||
|
||||
self.share_networks_servers[share_network_id] = server
|
||||
if is_active:
|
||||
server['share_network_id'] = share_network_id
|
||||
server['ip'] = self._get_server_ip(server)
|
||||
server['ssh_pool'] = self._get_ssh_pool(server)
|
||||
server['ssh'] = server['ssh_pool'].create()
|
||||
for helper in self._helpers.values():
|
||||
helper.init_helper(server)
|
||||
elif not return_inactive:
|
||||
msg = _('Service instance for share network %s is not active or '
|
||||
'does not exist') % share_network_id
|
||||
raise exception.ServiceInstanceException(msg)
|
||||
|
||||
self.share_networks_servers[share_network_id] = server
|
||||
return server
|
||||
|
||||
def _discover_service_instance(self, context, share_network_id):
|
||||
server = {}
|
||||
instance_name = self._get_service_instance_name(share_network_id)
|
||||
search_opts = {'name': instance_name}
|
||||
servers = self.compute_api.server_list(context, search_opts, True)
|
||||
if len(servers) == 1:
|
||||
return servers[0]
|
||||
elif len(servers) > 1:
|
||||
raise exception.ServiceInstanceException(
|
||||
_('Error. Ambiguous service instances.'))
|
||||
return server
|
||||
|
||||
def _get_ssh_pool(self, server):
|
||||
|
@ -308,10 +332,11 @@ class ServiceInstanceManager(object):
|
|||
raise exception.ServiceInstanceException(
|
||||
_('Ambiguous image name.'))
|
||||
|
||||
def _create_service_instance(self, context, instance_name,
|
||||
share_network_id, old_server_ip):
|
||||
def _create_service_instance(self, context, share_network_id,
|
||||
old_server_ip):
|
||||
"""Creates service vm and sets up networking for it."""
|
||||
service_image_id = self._get_service_image(context)
|
||||
instance_name = self._get_service_instance_name(share_network_id)
|
||||
|
||||
with lock:
|
||||
key_name = self._get_key(context)
|
||||
|
@ -546,21 +571,29 @@ class ServiceInstanceManager(object):
|
|||
else:
|
||||
raise exception.ServiceInstanceException(_('No available cidrs.'))
|
||||
|
||||
def delete_share_infrastructure(self, context, share_network_id):
|
||||
def delete_service_instance(self, context, share_network_id):
|
||||
"""Removes share infrastructure.
|
||||
|
||||
Deletes service vm and subnet, associated to share network.
|
||||
"""
|
||||
server = self.get_service_instance(context,
|
||||
share_network_id=share_network_id,
|
||||
create=False)
|
||||
server = self._discover_service_instance(context, share_network_id)
|
||||
if server:
|
||||
self._delete_server(context, server)
|
||||
subnet_id = self._get_service_subnet(share_network_id)
|
||||
if subnet_id:
|
||||
subnet = self._get_service_subnet(share_network_id)
|
||||
if subnet:
|
||||
subnet_id = subnet['id']
|
||||
router = self._get_private_router(share_network_id)
|
||||
port = self._get_service_port()
|
||||
self.neutron_api.router_remove_interface(router['id'], subnet_id)
|
||||
try:
|
||||
self.neutron_api.router_remove_interface(router['id'],
|
||||
subnet_id)
|
||||
except exception.NetworkException as e:
|
||||
if e.kwargs['code'] != 404:
|
||||
raise
|
||||
LOG.debug(_('Subnet %(subnet_id)s is not attached to the '
|
||||
'router %(router_id)s.') %
|
||||
{'subnet_id': subnet_id,
|
||||
'router_id': router['id']})
|
||||
self._remove_fixed_ip_from_service_port(port, subnet_id)
|
||||
self.neutron_api.delete_subnet(subnet_id)
|
||||
self._setup_connectivity_with_service_instances()
|
||||
|
|
|
@ -110,10 +110,6 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
if share_network_id:
|
||||
share_network = self.db.share_network_get(context,
|
||||
share_network_id)
|
||||
if share_network['status'] == constants.STATUS_INACTIVE:
|
||||
share_network = self._activate_share_network(
|
||||
context,
|
||||
share_network)
|
||||
else:
|
||||
share_network = {}
|
||||
|
||||
|
@ -272,7 +268,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
|
||||
def deactivate_network(self, context, share_network_id):
|
||||
share_network = self.db.share_network_get(context, share_network_id)
|
||||
self.driver.teardown_network(share_network)
|
||||
self._deactivate_network(context, share_network)
|
||||
self.network_api.deallocate_network(context, share_network)
|
||||
|
||||
def _activate_share_network(self, context, share_network, metadata=None):
|
||||
|
@ -282,11 +278,29 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||
context,
|
||||
share_network,
|
||||
count=allocation_number)
|
||||
try:
|
||||
self.driver.setup_network(share_network, metadata=metadata)
|
||||
except exception.ManilaException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.network_api.deallocate_network(context,
|
||||
share_network)
|
||||
else:
|
||||
return share_network
|
||||
try:
|
||||
self.db.share_network_update(context, share_network['id'],
|
||||
{'status': constants.STATUS_ACTIVATING})
|
||||
self.driver.setup_network(share_network, metadata=metadata)
|
||||
self.db.share_network_update(context, share_network['id'],
|
||||
{'status': constants.STATUS_ACTIVE})
|
||||
except exception.ManilaException:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.db.share_network_update(context, share_network['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
self.network_api.deallocate_network(context, share_network)
|
||||
else:
|
||||
return share_network
|
||||
|
||||
def _deactivate_network(self, context, share_network):
|
||||
self.db.share_network_update(context, share_network['id'],
|
||||
{'status': constants.STATUS_DEACTIVATING})
|
||||
try:
|
||||
self.driver.teardown_network(share_network)
|
||||
except Exception as e:
|
||||
with excutils.save_and_reraise_exception():
|
||||
self.db.share_network_update(context, share_network['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
else:
|
||||
self.db.share_network_update(context, share_network['id'],
|
||||
{'status': constants.STATUS_INACTIVE})
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
# Copyright 2014 Mirantis Inc.
|
||||
#
|
||||
# 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 mock
|
||||
|
||||
from manila.openstack.common import log as logging
|
||||
from manila.tests import fake_compute
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FakeServiceInstanceManager(object):
|
||||
|
||||
def __init__(self):
|
||||
self.db = mock.Mock()
|
||||
self._helpers = {
|
||||
'CIFS': mock.Mock(),
|
||||
'NFS': mock.Mock(),
|
||||
}
|
||||
self.share_networks_locks = {}
|
||||
self.share_networks_servers = {}
|
||||
self.fake_server = fake_compute.FakeServer()
|
||||
self.service_instance_name_template = 'manila_fake_service_instance-%s'
|
||||
|
||||
def get_service_instance(self, context, share_network_id, create=True):
|
||||
return self.fake_server
|
||||
|
||||
def _create_service_instance(self, context, instance_name,
|
||||
share_network_id, old_server_ip):
|
||||
return self.fake_server
|
||||
|
||||
def _delete_server(self, context, server):
|
||||
pass
|
||||
|
||||
def _get_service_instance_name(self, share_network_id):
|
||||
return self.service_instance_name_template % share_network_id
|
|
@ -73,7 +73,7 @@ class NeutronNetworkPluginTest(unittest.TestCase):
|
|||
|
||||
@mock.patch.object(db_api, 'network_allocation_create',
|
||||
mock.Mock(return_values=fake_network_allocation))
|
||||
@mock.patch.object(db_api, 'share_network_update',
|
||||
@mock.patch.object(db_api, 'share_network_get',
|
||||
mock.Mock(return_value=fake_share_network))
|
||||
def test_allocate_network_one_allocation(self):
|
||||
has_provider_nw_ext = mock.patch.object(self.plugin,
|
||||
|
@ -105,10 +105,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
|
|||
db_api.network_allocation_create.assert_called_once_with(
|
||||
self.fake_context,
|
||||
fake_network_allocation)
|
||||
db_api.share_network_update.assert_called_once_with(
|
||||
self.fake_context,
|
||||
fake_share_network['id'],
|
||||
{'status': constants.STATUS_ACTIVE})
|
||||
|
||||
has_provider_nw_ext.stop()
|
||||
save_nw_data.stop()
|
||||
|
@ -116,7 +112,7 @@ class NeutronNetworkPluginTest(unittest.TestCase):
|
|||
|
||||
@mock.patch.object(db_api, 'network_allocation_create',
|
||||
mock.Mock(return_values=fake_network_allocation))
|
||||
@mock.patch.object(db_api, 'share_network_update',
|
||||
@mock.patch.object(db_api, 'share_network_get',
|
||||
mock.Mock(return_value=fake_share_network))
|
||||
def test_allocate_network_two_allocation(self):
|
||||
has_provider_nw_ext = mock.patch.object(self.plugin,
|
||||
|
@ -152,10 +148,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
|
|||
self.plugin.neutron_api.create_port.assert_has_calls(
|
||||
neutron_api_calls)
|
||||
db_api.network_allocation_create.assert_has_calls(db_api_calls)
|
||||
db_api.share_network_update.assert_called_once_with(
|
||||
self.fake_context,
|
||||
fake_share_network['id'],
|
||||
{'status': constants.STATUS_ACTIVE})
|
||||
|
||||
has_provider_nw_ext.stop()
|
||||
save_nw_data.stop()
|
||||
|
@ -179,10 +171,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
|
|||
self.plugin.allocate_network,
|
||||
self.fake_context,
|
||||
fake_share_network)
|
||||
db_api.share_network_update.assert_called_once_with(
|
||||
self.fake_context,
|
||||
fake_share_network['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
|
||||
has_provider_nw_ext.stop()
|
||||
save_nw_data.stop()
|
||||
|
@ -223,11 +211,6 @@ class NeutronNetworkPluginTest(unittest.TestCase):
|
|||
self.fake_context,
|
||||
fake_network_allocation['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
db_api.share_network_update.assert_called_once_with(
|
||||
self.fake_context,
|
||||
share_nw['id'],
|
||||
{'status': constants.STATUS_ERROR})
|
||||
|
||||
delete_port.stop()
|
||||
|
||||
@mock.patch.object(db_api, 'share_network_update', mock.Mock())
|
||||
|
|
|
@ -137,7 +137,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
mock.Mock(return_value=mock.Mock()))
|
||||
|
||||
result = self._manager.get_service_instance(self._context,
|
||||
share_network_id='fake_share_network_id')
|
||||
share_network_id='fake_share_network_id',
|
||||
create=True)
|
||||
|
||||
self._manager._ensure_server.assert_called_once()
|
||||
self._manager._get_ssh_pool.assert_called_once_with(fake_server)
|
||||
|
@ -186,7 +187,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
mock.Mock(return_value=mock.Mock()))
|
||||
|
||||
result = self._manager.get_service_instance(self._context,
|
||||
share_network_id='fake_share_network_id')
|
||||
share_network_id='fake_share_network_id',
|
||||
create=True)
|
||||
|
||||
self._manager._ensure_server.assert_has_calls(
|
||||
[mock.call(self._context, old_fake_server, update=True)])
|
||||
|
@ -356,6 +358,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
def test_create_service_instance(self):
|
||||
fake_server = fake_compute.FakeServer()
|
||||
fake_port = fake_network.FakePort()
|
||||
fake_instance_name = 'fake_instance_name'
|
||||
sn_id = 'fake_sn_id'
|
||||
self.stubs.Set(self._manager, '_get_service_image',
|
||||
mock.Mock(return_value='fake_image_id'))
|
||||
self.stubs.Set(self._manager, '_get_key',
|
||||
|
@ -370,9 +374,10 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self.stubs.Set(self._manager, '_get_server_ip',
|
||||
mock.Mock(return_value='fake_ip'))
|
||||
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
|
||||
|
||||
self.stubs.Set(self._manager, '_get_service_instance_name',
|
||||
mock.Mock(return_value=fake_instance_name))
|
||||
result = self._manager._create_service_instance(self._context,
|
||||
'instance_name', self.share, None)
|
||||
sn_id, None)
|
||||
|
||||
self._manager._get_service_image.assert_called_once()
|
||||
self._manager._get_key.assert_called_once()
|
||||
|
@ -380,7 +385,7 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self._manager._setup_connectivity_with_service_instances.\
|
||||
assert_called_once()
|
||||
self._manager.compute_api.server_create.assert_called_once_with(
|
||||
self._context, 'instance_name', 'fake_image_id',
|
||||
self._context, fake_instance_name, 'fake_image_id',
|
||||
CONF.service_instance_flavor_id, 'fake_key_name', None, None,
|
||||
nics=[{'port-id': fake_port['id']}])
|
||||
service_instance.socket.socket.assert_called_once()
|
||||
|
@ -405,8 +410,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
|
||||
|
||||
self.assertRaises(exception.ManilaException,
|
||||
self._manager._create_service_instance, self._context,
|
||||
'instance_name', self.share, None)
|
||||
self._manager._create_service_instance,
|
||||
self._context, self.share, None)
|
||||
|
||||
self._manager.compute_api.server_create.assert_called_once()
|
||||
self.assertFalse(self._manager.compute_api.server_get.called)
|
||||
|
@ -432,8 +437,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self.stubs.Set(service_instance.socket, 'socket', mock.Mock())
|
||||
|
||||
self.assertRaises(exception.ManilaException,
|
||||
self._manager._create_service_instance,
|
||||
self._context, 'instance_name', self.share, None)
|
||||
self._manager._create_service_instance,
|
||||
self._context, self.share, None)
|
||||
|
||||
self._manager.neutron_api.delete_port.\
|
||||
assert_called_once_with(fake_port['id'])
|
||||
|
@ -447,8 +452,8 @@ class ServiceInstanceManagerTestCase(test.TestCase):
|
|||
self.stubs.Set(self._manager, '_get_key',
|
||||
mock.Mock(return_value=None))
|
||||
self.assertRaises(exception.ManilaException,
|
||||
self._manager._create_service_instance, self._context,
|
||||
'instance_name', self.share, None)
|
||||
self._manager._create_service_instance,
|
||||
self._context, self.share, None)
|
||||
|
||||
def test_setup_network_for_instance(self):
|
||||
fake_service_net = fake_network.FakeNetwork(subnets=[])
|
||||
|
|
|
@ -37,6 +37,12 @@ class FakeShareDriver(object):
|
|||
def __init__(self, db, **kwargs):
|
||||
self.db = db
|
||||
|
||||
def share_network_update(*args, **kwargs):
|
||||
pass
|
||||
|
||||
self.db.share_network_update = mock.Mock(
|
||||
side_effect=share_network_update)
|
||||
|
||||
def create_snapshot(self, context, snapshot):
|
||||
pass
|
||||
|
||||
|
@ -366,17 +372,19 @@ class ShareTestCase(test.TestCase):
|
|||
metadata=test_meta)
|
||||
|
||||
def test_setup_share_network(self):
|
||||
network_info = {'fake': 'fake'}
|
||||
share_network = {'id': 'fake_sn_id', 'share_network': 'share_network'}
|
||||
allocation_number = 555
|
||||
self.share.driver.get_network_allocations_number = mock.Mock(
|
||||
return_value=555)
|
||||
return_value=allocation_number)
|
||||
self.share.network_api.allocate_network = mock.Mock(
|
||||
return_value={'network_info': 'network_info'})
|
||||
return_value=share_network)
|
||||
self.share.driver.setup_network = mock.Mock()
|
||||
self.share._activate_share_network(self.context, network_info)
|
||||
self.share._activate_share_network(context=self.context,
|
||||
share_network=share_network)
|
||||
self.share.network_api.allocate_network.assert_called_once_with(
|
||||
self.context, network_info, count=555)
|
||||
self.context, share_network, count=allocation_number)
|
||||
self.share.driver.setup_network.assert_called_once_with(
|
||||
{'network_info': 'network_info'}, metadata=None)
|
||||
share_network, metadata=None)
|
||||
|
||||
def test_setup_share_network_error(self):
|
||||
network_info = {'fake': 'fake', 'id': 'fakeid'}
|
||||
|
@ -403,8 +411,7 @@ class ShareTestCase(test.TestCase):
|
|||
nw_api_deallocate_nw.stop()
|
||||
|
||||
def test_activate_network(self):
|
||||
share_network_id = 'fake network id'
|
||||
share_network = {}
|
||||
share_network = {'id': 'fake network id'}
|
||||
db_share_nw_get = mock.patch.object(self.share.db,
|
||||
'share_network_get').start()
|
||||
db_share_nw_get.return_value = share_network
|
||||
|
@ -418,9 +425,9 @@ class ShareTestCase(test.TestCase):
|
|||
|
||||
with mock.patch.object(self.share.driver, 'setup_network',
|
||||
mock.Mock()):
|
||||
self.share.activate_network(self.context, share_network_id)
|
||||
self.share.activate_network(self.context, share_network['id'])
|
||||
db_share_nw_get.assert_called_once_with(self.context,
|
||||
share_network_id)
|
||||
share_network['id'])
|
||||
drv_get_alloc_cnt.assert_any_call()
|
||||
nw_api_allocate_nw.assert_called_once_with(self.context,
|
||||
share_network,
|
||||
|
@ -434,8 +441,7 @@ class ShareTestCase(test.TestCase):
|
|||
nw_api_allocate_nw.stop()
|
||||
|
||||
def test_deactivate_network(self):
|
||||
share_network_id = 'fake network id'
|
||||
share_network = {}
|
||||
share_network = {'id': 'fake network id'}
|
||||
db_share_nw_get = mock.patch.object(self.share.db,
|
||||
'share_network_get').start()
|
||||
db_share_nw_get.return_value = share_network
|
||||
|
@ -444,9 +450,9 @@ class ShareTestCase(test.TestCase):
|
|||
|
||||
with mock.patch.object(self.share.driver, 'teardown_network',
|
||||
mock.Mock()):
|
||||
self.share.deactivate_network(self.context, share_network_id)
|
||||
self.share.deactivate_network(self.context, share_network['id'])
|
||||
db_share_nw_get.assert_called_once_with(self.context,
|
||||
share_network_id)
|
||||
share_network['id'])
|
||||
nw_api_deallocate_nw.assert_called_once_with(self.context,
|
||||
share_network)
|
||||
self.share.driver.teardown_network.assert_called_once_with(
|
||||
|
|
|
@ -28,6 +28,7 @@ from manila.share.drivers import generic
|
|||
from manila import test
|
||||
from manila.tests.db import fakes as db_fakes
|
||||
from manila.tests import fake_compute
|
||||
from manila.tests import fake_service_instance
|
||||
from manila.tests import fake_utils
|
||||
from manila.tests import fake_volume
|
||||
from manila import volume
|
||||
|
@ -97,7 +98,16 @@ class GenericShareDriverTestCase(test.TestCase):
|
|||
self._driver.get_service_instance = mock.Mock()
|
||||
self._driver.share_networks_servers = {}
|
||||
self._driver.admin_context = self._context
|
||||
self._driver.instance_manager = mock.Mock()
|
||||
|
||||
self.fake_sn = {"id": "fake_sn_id"}
|
||||
fsim = fake_service_instance.FakeServiceInstanceManager()
|
||||
sim = mock.Mock(return_value=fsim)
|
||||
self._driver.instance_manager = sim
|
||||
self._driver.service_instance_manager = sim
|
||||
self.fake_server = sim._create_service_instance(
|
||||
context="fake", instance_name="fake",
|
||||
share_network_id=self.fake_sn["id"], old_server_ip="fake")
|
||||
|
||||
self.stubs.Set(generic, '_ssh_exec', mock.Mock())
|
||||
self.stubs.Set(generic, 'synchronized', mock.Mock(side_effect=
|
||||
lambda f: f))
|
||||
|
@ -550,6 +560,28 @@ class GenericShareDriverTestCase(test.TestCase):
|
|||
access['access_type'],
|
||||
access['access_to'])
|
||||
|
||||
def test_setup_network(self):
|
||||
sim = self._driver.instance_manager
|
||||
self._driver.setup_network(self.fake_sn)
|
||||
sim.get_service_instance.assert_called_once()
|
||||
|
||||
def test_setup_network_revert(self):
|
||||
|
||||
def raise_exception(*args, **kwargs):
|
||||
raise exception.ServiceInstanceException
|
||||
|
||||
self.stubs.Set(self._driver, 'get_service_instance',
|
||||
mock.Mock(side_effect=raise_exception))
|
||||
self.assertRaises(exception.ServiceInstanceException,
|
||||
self._driver.setup_network,
|
||||
self.fake_sn)
|
||||
|
||||
def test_teardown_network(self):
|
||||
sim = self._driver.instance_manager
|
||||
self._driver.service_instance_manager = sim
|
||||
self._driver.teardown_network(self.fake_sn)
|
||||
sim.delete_service_instance.assert_called_once()
|
||||
|
||||
|
||||
class NFSHelperTestCase(test.TestCase):
|
||||
"""Test case for NFS helper of generic driver."""
|
||||
|
|
Loading…
Reference in New Issue