Merge "Implement additional driver mode for Generic driver"

This commit is contained in:
Jenkins 2015-02-02 22:13:29 +00:00 committed by Gerrit Code Review
commit 77e3087ad0
8 changed files with 446 additions and 95 deletions

View File

@ -20,6 +20,7 @@ import sys
from novaclient import exceptions as nova_exception
from novaclient import service_catalog
from novaclient import utils
from novaclient.v1_1 import client as nova_client
from novaclient.v1_1.contrib import assisted_volume_snapshots
from novaclient.v1_1 import servers as nova_servers
@ -27,6 +28,7 @@ from oslo_config import cfg
from manila.db import base
from manila import exception
from manila.i18n import _
from manila.openstack.common import log as logging
@ -181,6 +183,15 @@ class API(base.Base):
novaclient(context).servers.get(instance_id)
)
def server_get_by_name_or_id(self, context, instance_name_or_id):
try:
server = utils.find_resource(
novaclient(context).servers, instance_name_or_id)
except nova_exception.CommandError as e:
msg = _("Failed to get Nova VM. %s") % e
raise exception.ManilaException(msg)
return _untranslate_server_summary_view(server)
def server_list(self, context, search_opts=None, all_tenants=False):
if search_opts is None:
search_opts = {}

View File

@ -109,7 +109,9 @@ _global_opt_lists = [
manila.share.drivers.huawei.huawei_nas.huawei_opts,
manila.share.drivers.ibm.gpfs.gpfs_share_opts,
manila.share.drivers.netapp.cluster_mode.NETAPP_NAS_OPTS,
manila.share.drivers.service_instance.server_opts,
manila.share.drivers.service_instance.common_opts,
manila.share.drivers.service_instance.no_share_servers_handling_mode_opts,
manila.share.drivers.service_instance.share_servers_handling_mode_opts,
manila.share.drivers.zfssa.zfssashare.ZFSSA_OPTS,
manila.share.manager.share_manager_opts,
manila.volume._volume_opts,

View File

@ -85,22 +85,35 @@ CONF.register_opts(share_opts)
def ensure_server(f):
def wrap(self, *args, **kwargs):
server = kwargs.get('share_server')
context = args[0]
if not server:
# For now generic driver does not support flat networking.
# When we implement flat networking in generic driver
# we will not need share server to be passed and
# will change this logic.
raise exception.ManilaException(_('Share server not found.'))
server = kwargs.get('share_server')
if not self.driver_handles_share_servers:
if not server:
server = self.service_instance_manager.get_common_server()
kwargs['share_server'] = server
else:
raise exception.ManilaException(
_("Share server handling is not available. "
"But 'share_server' was provided. '%s'. "
"Share network should not be used.") % server['id'])
elif not server:
raise exception.ManilaException(
_("Share server handling is enabled. But 'share_server' "
"is not provided. Make sure you used 'share_network'."))
if not server.get('backend_details'):
raise exception.ManilaException(_('Share server backend '
'details missing.'))
raise exception.ManilaException(
_("Share server '%s' does not have backend details.") %
server['id'])
if not self.service_instance_manager.ensure_service_instance(
context, server['backend_details']):
raise exception.ServiceInstanceUnavailable()
return f(self, *args, **kwargs)
return wrap
@ -109,11 +122,11 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
def __init__(self, db, *args, **kwargs):
"""Do initialization."""
super(GenericShareDriver, self).__init__(True, *args, **kwargs)
super(GenericShareDriver, self).__init__(
[False, True], *args, **kwargs)
self.admin_context = context.get_admin_context()
self.db = db
self.configuration.append_config_values(share_opts)
self.configuration.append_config_values(service_instance.server_opts)
self._helpers = {}
self.backend_name = self.configuration.safe_get(
'share_backend_name') or "Cinder_Volumes"
@ -479,6 +492,8 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
def delete_share(self, context, share, share_server=None):
"""Deletes share."""
if not self.driver_handles_share_servers:
share_server = self.service_instance_manager.get_common_server()
if self._is_share_server_active(context, share_server):
self._get_helper(share).remove_export(
share_server['backend_details'], share['name'])
@ -490,7 +505,6 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
# with any reason that caused absence of Nova instances.
self._deallocate_container(self.admin_context, share)
@ensure_server
def create_snapshot(self, context, snapshot, share_server=None):
"""Creates a snapshot."""
volume = self._get_volume(self.admin_context, snapshot['share_id'])
@ -515,7 +529,6 @@ class GenericShareDriver(driver.ExecuteMixin, driver.ShareDriver):
'created in %ss. Giving up') %
self.configuration.max_time_to_create_volume)
@ensure_server
def delete_snapshot(self, context, snapshot, share_server=None):
"""Deletes a snapshot."""
volume_snapshot = self._get_volume_snapshot(self.admin_context,

View File

@ -1,4 +1,5 @@
# Copyright (c) 2014 NetApp, Inc.
# Copyright (c) 2015 Mirantis, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -25,7 +26,7 @@ from oslo_config import cfg
from oslo_utils import importutils
import six
from manila.common import constants
from manila.common import constants as const
from manila import compute
from manila import context
from manila import exception
@ -39,7 +40,7 @@ from manila import utils
LOG = logging.getLogger(__name__)
server_opts = [
share_servers_handling_mode_opts = [
cfg.StrOpt('service_image_name',
default='manila-service-image',
help="Name of image in glance, that will be used to create "
@ -47,11 +48,6 @@ server_opts = [
cfg.StrOpt('service_instance_name_template',
default='manila_service_instance_%s',
help="Name of service instance."),
cfg.StrOpt('service_instance_user',
help="User in service instance."),
cfg.StrOpt('service_instance_password',
default=None,
help="Password to service instance user."),
cfg.StrOpt('manila_service_keypair_name',
default='manila-service',
help="Name of keypair that will be created and used "
@ -59,12 +55,6 @@ server_opts = [
cfg.StrOpt('path_to_public_key',
default='~/.ssh/id_rsa.pub',
help="Path to hosts public key."),
cfg.StrOpt('path_to_private_key',
default='~/.ssh/id_rsa',
help="Path to hosts private key."),
cfg.IntOpt('max_time_to_build_instance',
default=300,
help="Maximum time to wait for creating service instance."),
cfg.StrOpt('service_instance_security_group',
default="manila-service",
help="Name of security group, that will be used for "
@ -93,8 +83,48 @@ server_opts = [
help='Attach share server directly to share network.'),
]
no_share_servers_handling_mode_opts = [
cfg.StrOpt(
"service_instance_name_or_id",
help="Name or ID of service instance in Nova to use for share "
"exports. Used only when share servers handling is disabled."),
cfg.StrOpt(
"service_net_name_or_ip",
help="Can be either name of network that is used by service "
"instance within Nova to get IP address or IP address itself "
"for managing shares there. "
"Used only when share servers handling is disabled."),
cfg.StrOpt(
"tenant_net_name_or_ip",
help="Can be either name of network that is used by service "
"instance within Nova to get IP address or IP address itself "
"for exporting shares. "
"Used only when share servers handling is disabled."),
]
common_opts = [
cfg.StrOpt(
"service_instance_user",
help="User in service instance that will be used for authentication."),
cfg.StrOpt(
"service_instance_password",
default=None,
secret=True,
help="Password for service instance user."),
cfg.StrOpt(
"path_to_private_key",
default="~/.ssh/id_rsa",
help="Path to host's private key."),
cfg.IntOpt(
"max_time_to_build_instance",
default=300,
help="Maximum time in seconds to wait for creating service instance."),
]
CONF = cfg.CONF
CONF.register_opts(server_opts)
CONF.register_opts(common_opts)
CONF.register_opts(no_share_servers_handling_mode_opts)
CONF.register_opts(share_servers_handling_mode_opts)
lock = threading.Lock()
@ -126,20 +156,45 @@ class ServiceInstanceManager(object):
value = CONF.get(key)
return value
def __init__(self, db, *args, **kwargs):
def __init__(self, db, driver_config):
"""Do initialization."""
super(ServiceInstanceManager, self).__init__()
self.driver_config = None
if "driver_config" in kwargs:
self.driver_config = kwargs["driver_config"]
self.db = db
self.driver_config = driver_config
self.driver_config.append_config_values(common_opts)
if self.get_config_option("driver_handles_share_servers"):
self.driver_config.append_config_values(
share_servers_handling_mode_opts)
else:
self.driver_config.append_config_values(
no_share_servers_handling_mode_opts)
if not self.get_config_option("service_instance_user"):
raise exception.ServiceInstanceException(_('Service instance user '
'is not specified'))
raise exception.ServiceInstanceException(
_('Service instance user is not specified.'))
self.admin_context = context.get_admin_context()
self._execute = utils.execute
self.compute_api = compute.API()
self.neutron_api = neutron.API()
self.db = db
self.path_to_private_key = self.get_config_option(
"path_to_private_key")
self.max_time_to_build_instance = self.get_config_option(
"max_time_to_build_instance")
if self.get_config_option("driver_handles_share_servers"):
self.neutron_api = neutron.API()
self.path_to_public_key = self.get_config_option(
"path_to_public_key")
self.connect_share_server_to_tenant_network = (
self.get_config_option(
'connect_share_server_to_tenant_network'))
self._get_service_tenant_id()
self.service_network_id = self._get_service_network()
self.vif_driver = importutils.import_class(
self.get_config_option("interface_driver"))()
self._setup_connectivity_with_service_instances()
def _get_service_tenant_id(self):
attempts = 5
while attempts:
try:
@ -152,17 +207,57 @@ class ServiceInstanceManager(object):
else:
raise exception.ServiceInstanceException(_('Can not receive '
'service tenant id.'))
self.service_network_id = self._get_service_network()
self.vif_driver = importutils.import_class(
self.get_config_option("interface_driver"))()
self._setup_connectivity_with_service_instances()
self.max_time_to_build_instance = self.get_config_option(
"max_time_to_build_instance")
self.path_to_private_key = self.get_config_option(
"path_to_private_key")
self.path_to_public_key = self.get_config_option("path_to_public_key")
self.connect_share_server_to_tenant_network = self.get_config_option(
'connect_share_server_to_tenant_network')
def get_common_server(self):
data = {
'public_address': None,
'private_address': None,
'service_net_name_or_ip': self.get_config_option(
'service_net_name_or_ip'),
'tenant_net_name_or_ip': self.get_config_option(
'tenant_net_name_or_ip'),
}
data['instance'] = self.compute_api.server_get_by_name_or_id(
self.admin_context,
self.get_config_option('service_instance_name_or_id'))
if netaddr.valid_ipv4(data['service_net_name_or_ip']):
data['private_address'] = [data['service_net_name_or_ip']]
else:
data['private_address'] = self._get_addresses_by_network_name(
data['service_net_name_or_ip'], data['instance'])
if netaddr.valid_ipv4(data['tenant_net_name_or_ip']):
data['public_address'] = [data['tenant_net_name_or_ip']]
else:
data['public_address'] = self._get_addresses_by_network_name(
data['tenant_net_name_or_ip'], data['instance'])
if not (data['public_address'] and data['private_address']):
raise exception.ManilaException(
"Can not find one of net addresses for service instance. "
"Instance: %(instance)s, "
"private_address: %(private_address)s, "
"public_address: %(public_address)s." % data)
share_server = {
'username': self.get_config_option('service_instance_user'),
'password': self.get_config_option('service_instance_password'),
'pk_path': self.path_to_private_key,
'ip': data['private_address'][0], # for handling
'public_address': data['public_address'][0], # for exports
'instance_id': data['instance']['id'],
}
return {'backend_details': share_server}
def _get_addresses_by_network_name(self, net_name, server):
net_ips = []
if 'networks' in server and net_name in server['networks']:
net_ips = server['networks'][net_name]
elif 'addresses' in server and net_name in server['addresses']:
net_ips = [addr['addr'] for addr in server['addresses'][net_name]]
return net_ips
@utils.synchronized("service_instance_get_service_network", external=True)
def _get_service_network(self):
@ -193,11 +288,7 @@ class ServiceInstanceManager(object):
def _get_server_ip(self, server):
"""Returns service vms ip address."""
net_name = self.get_config_option("service_network_name")
net_ips = []
if 'networks' in server and net_name in server['networks']:
net_ips = server['networks'][net_name]
elif 'addresses' in server and net_name in server['addresses']:
net_ips = [addr['addr'] for addr in server['addresses'][net_name]]
net_ips = self._get_addresses_by_network_name(net_name, server)
if not net_ips:
msg = _("Failed to get service instance ip address. "
"Service network name is '%(net_name)s' "
@ -234,7 +325,7 @@ class ServiceInstanceManager(object):
LOG.debug("Creating security group with name '%s'.", name)
sg = self.compute_api.security_group_create(
context, name, description)
for protocol, ports in constants.SERVICE_INSTANCE_SECGROUP_DATA:
for protocol, ports in const.SERVICE_INSTANCE_SECGROUP_DATA:
self.compute_api.security_group_rule_create(
context,
parent_group_id=sg.id,

View File

@ -14,6 +14,7 @@
import mock
from novaclient import exceptions as nova_exception
from novaclient import utils
from novaclient.v1_1 import servers as nova_servers
from manila.compute import nova
@ -87,7 +88,17 @@ class NovaApiTestCase(test.TestCase):
def test_server_get(self):
instance_id = 'instance_id1'
result = self.api.server_get(self.ctx, instance_id)
self.assertEqual(result['id'], instance_id)
self.assertEqual(instance_id, result['id'])
def test_server_get_by_name_or_id(self):
instance_id = 'instance_id1'
server = {'id': instance_id, 'fake_key': 'fake_value'}
self.stubs.Set(utils, 'find_resource', mock.Mock(return_value=server))
result = self.api.server_get_by_name_or_id(self.ctx, instance_id)
self.assertEqual(instance_id, result['id'])
utils.find_resource.assert_called_once_with(mock.ANY, instance_id)
def test_server_get_failed(self):
nova.novaclient.side_effect = nova_exception.NotFound(404)

View File

@ -89,6 +89,9 @@ class API(object):
def server_get(self, *args, **kwargs):
pass
def server_get_by_name_or_id(self, *args, **kwargs):
pass
def keypair_list(self, *args, **kwargs):
pass

View File

@ -1,4 +1,5 @@
# Copyright (c) 2014 NetApp, Inc.
# Copyright (c) 2015 Mirantis, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@ -624,6 +625,27 @@ class GenericShareDriverTestCase(test.TestCase):
self._helper_nfs.create_export.assert_called_once_with(
self.server['backend_details'], self.share['name'])
def test_delete_share_no_share_servers_handling(self):
self.stubs.Set(self._driver, '_deallocate_container', mock.Mock())
self.stubs.Set(
self._driver.service_instance_manager,
'get_common_server', mock.Mock(return_value=self.server))
self.stubs.Set(
self._driver.service_instance_manager,
'ensure_service_instance', mock.Mock(return_value=False))
CONF.set_default('driver_handles_share_servers', False)
self._driver.delete_share(self._context, self.share)
self._driver.service_instance_manager.get_common_server.\
assert_called_once_with()
self._driver._deallocate_container.assert_called_once_with(
self._driver.admin_context, self.share)
self._driver.service_instance_manager.ensure_service_instance.\
assert_called_once_with(
self._context, self.server['backend_details'])
def test_delete_share(self):
self.stubs.Set(self._driver, '_unmount_device', mock.Mock())
self.stubs.Set(self._driver, '_detach_volume', mock.Mock())
@ -641,6 +663,9 @@ class GenericShareDriverTestCase(test.TestCase):
self.server['backend_details'])
self._driver._deallocate_container.assert_called_once_with(
self._driver.admin_context, self.share)
self._driver.service_instance_manager.ensure_service_instance.\
assert_called_once_with(
self._context, self.server['backend_details'])
def test_delete_share_without_share_server(self):
self.stubs.Set(self._driver, '_unmount_device', mock.Mock())
@ -684,17 +709,20 @@ class GenericShareDriverTestCase(test.TestCase):
self.stubs.Set(self._driver, '_detach_volume', mock.Mock())
self.stubs.Set(self._driver, '_deallocate_container', mock.Mock())
with mock.patch.object(self._driver.service_instance_manager,
'ensure_service_instance',
mock.Mock(return_value=False)):
self._driver.delete_share(
self._context, self.share, share_server=self.server)
self.stubs.Set(
self._driver.service_instance_manager,
'ensure_service_instance', mock.Mock(return_value=False))
self._driver.delete_share(
self._context, self.share, share_server=self.server)
self.assertFalse(self._helper_nfs.remove_export.called)
self.assertFalse(self._driver._unmount_device.called)
self.assertFalse(self._driver._detach_volume.called)
self._driver._deallocate_container.assert_called_once_with(
self._driver.admin_context, self.share)
self.assertFalse(self._helper_nfs.remove_export.called)
self.assertFalse(self._driver._unmount_device.called)
self.assertFalse(self._driver._detach_volume.called)
self._driver._deallocate_container.assert_called_once_with(
self._driver.admin_context, self.share)
self._driver.service_instance_manager.ensure_service_instance.\
assert_called_once_with(
self._context, self.server['backend_details'])
def test_create_snapshot(self):
fake_vol = fake_volume.FakeVolume()
@ -787,7 +815,7 @@ class GenericShareDriverTestCase(test.TestCase):
self.assertRaises(exception.InvalidShare,
self._driver._get_helper, share)
def test_setup_network(self):
def test__setup_server(self):
sim = self._driver.instance_manager
net_info = {'server_id': 'fake',
'neutron_net_id': 'fake-net-id',
@ -799,7 +827,7 @@ class GenericShareDriverTestCase(test.TestCase):
'fake-net-id',
'fake-subnet-id')
def test_setup_network_revert(self):
def test__setup_server_revert(self):
def raise_exception(*args, **kwargs):
raise exception.ServiceInstanceException
@ -814,7 +842,7 @@ class GenericShareDriverTestCase(test.TestCase):
self._driver.setup_server,
net_info)
def test_teardown_network(self):
def test__teardown_server(self):
server_details = {
'instance_id': 'fake_instance_id',
'subnet_id': 'fake_subnet_id',
@ -929,6 +957,70 @@ class GenericShareDriverTestCase(test.TestCase):
self.assertEqual('Open Source', result['vendor_name'])
@generic.ensure_server
def fake(driver_instance, context, share_server=None):
return share_server
@ddt.ddt
class GenericDriverEnsureServerTestCase(test.TestCase):
def setUp(self):
super(GenericDriverEnsureServerTestCase, self).setUp()
self._context = context.get_admin_context()
self.server = {'id': 'fake_id', 'backend_details': {'foo': 'bar'}}
self.dhss_false = type(
'Fake', (object,), {'driver_handles_share_servers': False})
self.dhss_true = type(
'Fake', (object,), {'driver_handles_share_servers': True})
def test_share_servers_are_not_handled_server_not_provided(self):
self.dhss_false.service_instance_manager = mock.Mock()
self.dhss_false.service_instance_manager.get_common_server = (
mock.Mock(return_value=self.server))
self.dhss_false.service_instance_manager.ensure_service_instance = (
mock.Mock(return_value=True))
actual = fake(self.dhss_false, self._context)
self.assertEqual(self.server, actual)
self.dhss_false.service_instance_manager.\
get_common_server.assert_called_once_with()
self.dhss_false.service_instance_manager.ensure_service_instance.\
assert_called_once_with(
self._context, self.server['backend_details'])
@ddt.data({'id': 'without_details'},
{'id': 'with_details', 'backend_details': {'foo': 'bar'}})
def test_share_servers_are_not_handled_server_provided(self, server):
self.assertRaises(
exception.ManilaException,
fake, self.dhss_false, self._context, share_server=server)
def test_share_servers_are_handled_server_provided(self):
self.dhss_true.service_instance_manager = mock.Mock()
self.dhss_true.service_instance_manager.ensure_service_instance = (
mock.Mock(return_value=True))
actual = fake(self.dhss_true, self._context, share_server=self.server)
self.assertEqual(self.server, actual)
self.dhss_true.service_instance_manager.ensure_service_instance.\
assert_called_once_with(
self._context, self.server['backend_details'])
def test_share_servers_are_handled_invalid_server_provided(self):
server = {'id': 'without_details'}
self.assertRaises(
exception.ManilaException,
fake, self.dhss_true, self._context, share_server=server)
def test_share_servers_are_handled_server_not_provided(self):
self.assertRaises(
exception.ManilaException, fake, self.dhss_true, self._context)
class NFSHelperTestCase(test.TestCase):
"""Test case for NFS helper of generic driver."""

View File

@ -18,12 +18,15 @@
import copy
import os
import ddt
import mock
from oslo_config import cfg
from oslo_utils import importutils
import six
from manila import context
from manila import exception
from manila.share import configuration
from manila.share.drivers import service_instance
from manila import test
from manila.tests import fake_compute
@ -34,23 +37,60 @@ from manila import utils
CONF = cfg.CONF
def fake_get_config_option(key):
if key == 'driver_handles_share_servers':
return True
elif key == 'service_instance_password':
return None
elif key == 'service_instance_user':
return 'fake_user'
elif key == 'service_network_name':
return 'fake_service_network_name'
elif key == 'service_instance_flavor_id':
return 100
elif key == 'service_instance_name_template':
return 'fake_manila_service_instance_%s'
elif key == 'service_image_name':
return 'fake_service_image_name'
elif key == 'manila_service_keypair_name':
return 'fake_manila_service_keypair_name'
elif key == 'path_to_private_key':
return 'fake_path_to_private_key'
elif key == 'path_to_public_key':
return 'fake_path_to_public_key'
elif key == 'max_time_to_build_instance':
return 500
elif key == 'connect_share_server_to_tenant_network':
return False
elif key == 'service_network_cidr':
return '99.254.0.0/16'
elif key == 'service_network_division_mask':
return 25
else:
return mock.Mock()
@ddt.ddt
class ServiceInstanceManagerTestCase(test.TestCase):
"""Tests InstanceManager."""
def setUp(self):
super(ServiceInstanceManagerTestCase, self).setUp()
self._context = context.get_admin_context()
self.config = configuration.Configuration(None)
self.config.safe_get = mock.Mock(side_effect=fake_get_config_option)
self._helper_cifs = mock.Mock()
self._helper_nfs = mock.Mock()
self._db = mock.Mock()
self.stubs.Set(service_instance.neutron, 'API', fake_network.API)
self.stubs.Set(service_instance.compute, 'API', fake_compute.API)
self.stubs.Set(importutils, 'import_class', mock.Mock())
with mock.patch.object(service_instance.ServiceInstanceManager,
'_setup_connectivity_with_service_instances',
mock.Mock()):
self._manager = service_instance.ServiceInstanceManager(self._db,
{})
self._manager = service_instance.ServiceInstanceManager(
self._db, self.config)
self._manager.service_tenant_id = 'service tenant id'
self._manager.service_network_id = 'service network id'
self._manager.admin_context = self._context
@ -70,12 +110,12 @@ class ServiceInstanceManagerTestCase(test.TestCase):
def test_get_service_network_net_exists(self):
net1 = copy.copy(fake_network.API.network)
net2 = copy.copy(fake_network.API.network)
net1['name'] = CONF.service_network_name
net1['name'] = self._manager.get_config_option('service_network_name')
net1['id'] = 'fake service network id'
self.stubs.Set(self._manager.neutron_api, 'get_all_tenant_networks',
mock.Mock(return_value=[net1, net2]))
result = self._manager._get_service_network()
self.assertEqual(result, net1['id'])
self.assertEqual(net1['id'], result)
def test_get_service_network_net_does_not_exists(self):
net = fake_network.FakeNetwork()
@ -84,10 +124,11 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.stubs.Set(self._manager.neutron_api, 'network_create',
mock.Mock(return_value=net))
result = self._manager._get_service_network()
self.assertEqual(result, net['id'])
self.assertEqual(net['id'], result)
def test_get_service_network_ambiguos(self):
net = fake_network.FakeNetwork(name=CONF.service_network_name)
net = fake_network.FakeNetwork(
name=self._manager.get_config_option('service_network_name'))
self.stubs.Set(self._manager.neutron_api, 'get_all_tenant_networks',
mock.Mock(return_value=[net, net]))
self.assertRaises(exception.ManilaException,
@ -96,14 +137,14 @@ class ServiceInstanceManagerTestCase(test.TestCase):
def test_get_service_instance_name(self):
result = self._manager._get_service_instance_name(
'fake_share_network_id')
self.assertEqual(result, CONF.service_instance_name_template %
'fake_share_network_id')
self.assertEqual(
'fake_manila_service_instance_None_fake_share_network_id', result)
def test_get_server_ip_found_in_networks_section(self):
ip = '10.0.0.1'
fake_server = {
'networks': {
CONF.service_network_name: [ip],
self._manager.get_config_option('service_network_name'): [ip],
}
}
result = self._manager._get_server_ip(fake_server)
@ -113,7 +154,7 @@ class ServiceInstanceManagerTestCase(test.TestCase):
ip = '10.0.0.1'
fake_server = {
'addresses': {
CONF.service_network_name: [
self._manager.get_config_option('service_network_name'): [
{'addr': ip, 'version': 4, }
],
}
@ -311,8 +352,9 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.assertFalse(result)
def test_get_key_create_new(self):
fake_keypair = fake_compute.FakeKeypair(
name=CONF.manila_service_keypair_name)
keypair_name = self._manager.get_config_option(
'manila_service_keypair_name')
fake_keypair = fake_compute.FakeKeypair(name=keypair_name)
self.stubs.Set(self._manager.compute_api, 'keypair_list',
mock.Mock(return_value=[]))
self.stubs.Set(self._manager.compute_api, 'keypair_import',
@ -320,17 +362,20 @@ class ServiceInstanceManagerTestCase(test.TestCase):
result = self._manager._get_key(self._context)
self.assertEqual(result,
(fake_keypair.name,
os.path.expanduser(CONF.path_to_private_key)))
self.assertEqual(
(fake_keypair.name,
os.path.expanduser(self._manager.get_config_option(
'path_to_private_key'))),
result)
self._manager.compute_api.keypair_list.assert_called_once_with(
self._context)
self._manager.compute_api.keypair_import.assert_called_once_with(
self._context, 'manila-service', '')
self._context, keypair_name, '')
def test_get_key_exists(self):
fake_keypair = fake_compute.FakeKeypair(
name=CONF.manila_service_keypair_name,
name=self._manager.get_config_option(
'manila_service_keypair_name'),
public_key='fake_public_key')
self.stubs.Set(self._manager.compute_api, 'keypair_list',
mock.Mock(return_value=[fake_keypair]))
@ -344,13 +389,16 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self._manager.compute_api.keypair_list.assert_called_once_with(
self._context)
self.assertFalse(self._manager.compute_api.keypair_import.called)
self.assertEqual(result,
(fake_keypair.name,
os.path.expanduser(CONF.path_to_private_key)))
self.assertEqual(
(fake_keypair.name,
os.path.expanduser(self._manager.get_config_option(
'path_to_private_key'))),
result)
def test_get_key_exists_recreate(self):
fake_keypair = fake_compute.FakeKeypair(
name=CONF.manila_service_keypair_name,
name=self._manager.get_config_option(
'manila_service_keypair_name'),
public_key='fake_public_key1')
self.stubs.Set(self._manager.compute_api, 'keypair_list',
mock.Mock(return_value=[fake_keypair]))
@ -369,9 +417,11 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self._context, fake_keypair.id)
self._manager.compute_api.keypair_import.assert_called_once_with(
self._context, fake_keypair.name, 'fake_public_key2')
self.assertEqual(result,
(fake_keypair.name,
os.path.expanduser(CONF.path_to_private_key)))
self.assertEqual(
(fake_keypair.name,
os.path.expanduser(self._manager.get_config_option(
'path_to_private_key'))),
result)
def test_get_key_keypath_to_public_not_set(self):
self._manager.path_to_public_key = None
@ -414,14 +464,15 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self.assertEqual(result, (None, None))
def test_get_service_image(self):
fake_image1 = fake_compute.FakeImage(name=CONF.service_image_name)
fake_image1 = fake_compute.FakeImage(
name=self._manager.get_config_option('service_image_name'))
fake_image2 = fake_compute.FakeImage(name='another-image')
self.stubs.Set(self._manager.compute_api, 'image_list',
mock.Mock(return_value=[fake_image1, fake_image2]))
result = self._manager._get_service_image(self._context)
self.assertEqual(result, fake_image1.id)
self.assertEqual(fake_image1.id, result)
def test_get_service_image_not_found(self):
self.stubs.Set(self._manager.compute_api, 'image_list',
@ -834,8 +885,9 @@ class ServiceInstanceManagerTestCase(test.TestCase):
def test_get_cidr_for_subnet(self):
serv_cidr = service_instance.netaddr.IPNetwork(
CONF.service_network_cidr)
fake_division_mask = CONF.service_network_division_mask
self._manager.get_config_option('service_network_cidr'))
fake_division_mask = self._manager.get_config_option(
'service_network_division_mask')
cidrs = serv_cidr.subnet(fake_division_mask)
cidr1 = six.text_type(next(cidrs))
cidr2 = six.text_type(next(cidrs))
@ -936,3 +988,79 @@ class ServiceInstanceManagerTestCase(test.TestCase):
self._manager.neutron_api.update_subnet.assert_has_calls([
mock.call(subnet_id, ''),
])
@ddt.data(
{'s': 'fake_net_s', 't': 'fake_net_t'},
{'s': 'fake_net_s', 't': '12.34.56.78'},
{'s': '98.76.54.123', 't': 'fake_net_t'},
{'s': '98.76.54.123', 't': '12.34.56.78'})
@ddt.unpack
def test_get_common_server_valid_cases(self, s, t):
self._get_common_server(s, t, True)
@ddt.data(
{'s': 'fake_net_s', 't': 'fake'},
{'s': 'fake', 't': 'fake_net_t'},
{'s': 'fake', 't': 'fake'},
{'s': '98.76.54.123', 't': '12.12.12.1212'},
{'s': '12.12.12.1212', 't': '12.34.56.78'},
{'s': '12.12.12.1212', 't': '12.12.12.1212'})
@ddt.unpack
def test_get_common_server_invalid_cases(self, s, t):
self._get_common_server(s, t, False)
def _get_common_server(self, s, t, is_valid=True):
fake_instance_id = 'fake_instance_id'
fake_user = 'fake_user'
fake_pass = 'fake_pass'
fake_net_s = 'fake_net_s'
fake_addr_s = '98.76.54.123'
fake_net_t = 'fake_net_t'
fake_addr_t = '12.34.56.78'
fake_server = {
'id': fake_instance_id,
'networks': {fake_net_s: [fake_addr_s], fake_net_t: [fake_addr_t]},
'addresses': {fake_net_s: {'addr': fake_addr_s},
fake_net_t: {'addr': fake_addr_t}},
}
expected = {
'backend_details': {
'username': fake_user,
'password': fake_pass,
'pk_path': self._manager.path_to_private_key,
'ip': fake_addr_s,
'public_address': fake_addr_t,
'instance_id': fake_instance_id,
}
}
def fake_get_config_option(attr):
if attr == 'service_net_name_or_ip':
return s
elif attr == 'tenant_net_name_or_ip':
return t
elif attr == 'service_instance_name_or_id':
return fake_instance_id
elif attr == 'service_instance_user':
return fake_user
elif attr == 'service_instance_password':
return fake_pass
else:
raise exception.ManilaException("Wrong test data provided.")
self.mock_object(
self._manager.compute_api, 'server_get_by_name_or_id',
mock.Mock(return_value=fake_server))
self.mock_object(
self._manager, 'get_config_option',
mock.Mock(side_effect=fake_get_config_option))
if is_valid:
actual = self._manager.get_common_server()
self.assertEqual(expected, actual)
else:
self.assertRaises(
exception.ManilaException,
self._manager.get_common_server)
self.assertTrue(
self._manager.compute_api.server_get_by_name_or_id.called)