Merge "Enable Manila multi-SVM driver on NetApp cDOT 8.3"

This commit is contained in:
Jenkins 2015-07-12 09:19:54 +00:00 committed by Gerrit Code Review
commit 1d00bfdfd2
8 changed files with 532 additions and 82 deletions

View File

@ -42,6 +42,7 @@ EVOLNOTCLONE = '13170'
EVOL_NOT_MOUNTED = '14716'
ESIS_CLONE_NOT_LICENSED = '14956'
EOBJECTNOTFOUND = '15661'
E_VIFMGR_PORT_ALREADY_ASSIGNED_TO_BROADCAST_DOMAIN = '18605'
class NaServer(object):

View File

@ -47,6 +47,10 @@ class NetAppBaseClient(object):
minor = res.get_child_content('minor-version')
return major, minor
def _init_features(self):
"""Set up the repository of available Data ONTAP features."""
self.features = Features()
def check_is_naelement(self, elem):
"""Checks if object is instance of NaElement."""
if not isinstance(elem, netapp_api.NaElement):
@ -74,3 +78,19 @@ class NetAppBaseClient(object):
def send_ems_log_message(self, message_dict):
"""Sends a message to the Data ONTAP EMS log."""
raise NotImplementedError()
class Features(object):
def __init__(self):
self.defined_features = set()
def add_feature(self, name, supported=True):
if not isinstance(supported, bool):
raise TypeError("Feature value must be a bool type.")
self.defined_features.add(name)
setattr(self, name, supported)
def __getattr__(self, name):
# NOTE(cknight): Needed to keep pylint happy.
raise AttributeError

View File

@ -32,6 +32,8 @@ from manila.share.drivers.netapp import utils as na_utils
LOG = log.getLogger(__name__)
DELETED_PREFIX = 'deleted_manila_'
DEFAULT_IPSPACE = 'Default'
DEFAULT_BROADCAST_DOMAIN = 'OpenStack'
class NetAppCmodeClient(client_base.NetAppBaseClient):
@ -46,6 +48,19 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
(major, minor) = self.get_ontapi_version(cached=False)
self.connection.set_api_version(major, minor)
self._init_features()
def _init_features(self):
"""Initialize cDOT feature support map."""
super(NetAppCmodeClient, self)._init_features()
ontapi_version = self.get_ontapi_version(cached=True)
ontapi_1_30 = ontapi_version >= (1, 30)
self.features.add_feature('BROADCAST_DOMAINS', supported=ontapi_1_30)
self.features.add_feature('IPSPACES', supported=ontapi_1_30)
self.features.add_feature('SUBNETS', supported=ontapi_1_30)
def _invoke_vserver_api(self, na_element, vserver):
server = copy.copy(self.connection)
server.set_vserver(vserver)
@ -265,7 +280,7 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
},
},
'desired-attributes': {
'node-details-info': {
'net-port-info': {
'port': None,
'node': None,
'operational-speed': None,
@ -350,6 +365,9 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
self._create_vlan(node, port, vlan)
home_port_name = '%(port)s-%(tag)s' % {'port': port, 'tag': vlan}
if self.features.BROADCAST_DOMAINS:
self._ensure_broadcast_domain_for_port(node, home_port_name)
interface_name = (lif_name_template %
{'node': node, 'net_allocation_id': allocation_id})
@ -393,6 +411,104 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
msg_args = {'vlan': vlan, 'port': port, 'err_msg': e.message}
raise exception.NetAppException(msg % msg_args)
@na_utils.trace
def _ensure_broadcast_domain_for_port(self, node, port,
domain=DEFAULT_BROADCAST_DOMAIN,
ipspace=DEFAULT_IPSPACE):
"""Ensure a port is in a broadcast domain. Create one if necessary."""
if self._get_broadcast_domain_for_port(node, port):
return
if not self._broadcast_domain_exists(domain, ipspace):
self._create_broadcast_domain(domain, ipspace)
self._add_port_to_broadcast_domain(node, port, domain, ipspace)
@na_utils.trace
def _get_broadcast_domain_for_port(self, node, port):
"""Get broadcast domain for a specific port."""
api_args = {
'query': {
'net-port-info': {
'node': node,
'port': port,
},
},
'desired-attributes': {
'net-port-info': {
'broadcast-domain': None,
},
},
}
result = self.send_request('net-port-get-iter', api_args)
net_port_info_list = result.get_child_by_name(
'attributes-list') or netapp_api.NaElement('none')
port_info = net_port_info_list.get_children()
if not port_info:
msg = _('Could not find port %(port)s on node %(node)s.')
msg_args = {'port': port, 'node': node}
raise exception.NetAppException(msg % msg_args)
return port_info[0].get_child_content('broadcast-domain')
@na_utils.trace
def _broadcast_domain_exists(self, domain, ipspace):
"""Check if a broadcast domain exists."""
api_args = {
'query': {
'net-port-broadcast-domain-info': {
'ipspace': ipspace,
'broadcast-domain': domain,
},
},
'desired-attributes': {
'net-port-broadcast-domain-info': None,
},
}
result = self.send_request('net-port-broadcast-domain-get-iter',
api_args)
return self._has_records(result)
@na_utils.trace
def _create_broadcast_domain(self, domain, ipspace, mtu=1500):
"""Create a broadcast domain."""
api_args = {
'ipspace': ipspace,
'broadcast-domain': domain,
'mtu': mtu,
}
self.send_request('net-port-broadcast-domain-create', api_args)
@na_utils.trace
def _add_port_to_broadcast_domain(self, node, port, domain, ipspace):
qualified_port_name = ':'.join([node, port])
try:
api_args = {
'ipspace': ipspace,
'broadcast-domain': domain,
'ports': {
'net-qualified-port-name': qualified_port_name,
}
}
self.send_request('net-port-broadcast-domain-add-ports', api_args)
except netapp_api.NaApiError as e:
if e.code == (netapp_api.
E_VIFMGR_PORT_ALREADY_ASSIGNED_TO_BROADCAST_DOMAIN):
LOG.debug('Port %(port)s already exists in broadcast domain '
'%(domain)s', {'port': port, 'domain': domain})
else:
msg = _('Failed to add port %(port)s to broadcast domain '
'%(domain)s. %(err_msg)s')
msg_args = {
'port': qualified_port_name,
'domain': domain,
'err_msg': e.message,
}
raise exception.NetAppException(msg % msg_args)
@na_utils.trace
def network_interface_exists(self, vserver_name, node, port, ip, netmask,
vlan):
@ -595,12 +711,14 @@ class NetAppCmodeClient(client_base.NetAppBaseClient):
def setup_security_services(self, security_services, vserver_client,
vserver_name):
api_args = {
'name-mapping-switch': {
'nmswitch': 'ldap,file',
},
'name-server-switch': {
'nsswitch': 'ldap,file',
},
'name-mapping-switch': [
{'nmswitch': 'ldap'},
{'nmswitch': 'file'}
],
'name-server-switch': [
{'nsswitch': 'ldap'},
{'nsswitch': 'file'}
],
'vserver-name': vserver_name,
}
self.send_request('vserver-modify', api_args)

View File

@ -42,8 +42,6 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
@na_utils.trace
def check_for_setup_error(self):
self._check_data_ontap_version()
if self._have_cluster_creds:
if self.configuration.netapp_vserver:
msg = _LW('Vserver is specified in the configuration. This is '
@ -65,17 +63,6 @@ class NetAppCmodeMultiSVMFileStorageLibrary(
super(NetAppCmodeMultiSVMFileStorageLibrary, self).\
check_for_setup_error()
def _check_data_ontap_version(self):
# Temporary check to indicate that the Kilo multi-SVM driver does not
# support cDOT 8.3 or higher.
ontapi_version = self._client.get_ontapi_version()
if ontapi_version >= (1, 30):
msg = _('Clustered Data ONTAP 8.3.0 or higher is not '
'supported by this version of the driver when the '
'configuration option driver_handles_share_servers '
'is set to True.')
raise exception.NetAppException(msg)
@na_utils.trace
def _get_vserver(self, share_server=None):

View File

@ -60,6 +60,9 @@ NETMASK = '255.255.255.0'
NET_ALLOCATION_ID = 'fake_allocation_id'
LIF_NAME_TEMPLATE = 'os_%(net_allocation_id)s'
LIF_NAME = LIF_NAME_TEMPLATE % {'net_allocation_id': NET_ALLOCATION_ID}
IPSPACE = 'fake_ipspace'
BROADCAST_DOMAIN = 'fake_domain'
MTU = 9000
EMS_MESSAGE = {
'computer-name': 'fake_host',
@ -431,6 +434,43 @@ SORTED_PORTS_ALL_SPEEDS = (
{'node': NODE_NAME, 'port': 'port7'},
)
NET_PORT_GET_ITER_BROADCAST_DOMAIN_RESPONSE = etree.XML("""
<results status="passed">
<attributes-list>
<net-port-info>
<broadcast-domain>%(domain)s</broadcast-domain>
<node>%(node)s</node>
<port>%(port)s</port>
</net-port-info>
</attributes-list>
<num-records>1</num-records>
</results>
""" % {'domain': BROADCAST_DOMAIN, 'node': NODE_NAME, 'port': PORT})
NET_PORT_GET_ITER_BROADCAST_DOMAIN_MISSING_RESPONSE = etree.XML("""
<results status="passed">
<attributes-list>
<net-port-info>
<node>%(node)s</node>
<port>%(port)s</port>
</net-port-info>
</attributes-list>
<num-records>1</num-records>
</results>
""" % {'node': NODE_NAME, 'port': PORT})
NET_PORT_BROADCAST_DOMAIN_GET_ITER_RESPONSE = etree.XML("""
<results status="passed">
<attributes-list>
<net-port-broadcast-domain-info>
<broadcast-domain>%(domain)s</broadcast-domain>
<ipspace>%(ipspace)s</ipspace>
</net-port-broadcast-domain-info>
</attributes-list>
<num-records>1</num-records>
</results>
""" % {'domain': BROADCAST_DOMAIN, 'ipspace': IPSPACE})
NET_INTERFACE_GET_ITER_RESPONSE = etree.XML("""
<results status="passed">
<attributes-list>

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import ddt
import mock
from oslo_log import log
@ -56,6 +57,12 @@ class NetAppBaseClientTestCase(test.TestCase):
self.assertEqual(1, major)
self.assertEqual(20, minor)
def test_init_features(self):
self.client._init_features()
self.assertSetEqual(set(), self.client.features.defined_features)
def test_check_is_naelement(self):
element = netapp_api.NaElement('name')
@ -122,3 +129,38 @@ class NetAppBaseClientTestCase(test.TestCase):
self.assertRaises(NotImplementedError,
self.client.send_ems_log_message,
{})
@ddt.ddt
class FeaturesTestCase(test.TestCase):
def setUp(self):
super(FeaturesTestCase, self).setUp()
self.features = client_base.Features()
def test_init(self):
self.assertSetEqual(set(), self.features.defined_features)
def test_add_feature_default(self):
self.features.add_feature('FEATURE_1')
self.assertTrue(self.features.FEATURE_1)
self.assertIn('FEATURE_1', self.features.defined_features)
@ddt.data(True, False)
def test_add_feature(self, value):
self.features.add_feature('FEATURE_2', value)
self.assertEqual(value, self.features.FEATURE_2)
self.assertIn('FEATURE_2', self.features.defined_features)
@ddt.data('True', 'False', 0, 1, 1.0, None, [], {}, (True,))
def test_add_feature_type_error(self, value):
self.assertRaises(TypeError,
self.features.add_feature,
'FEATURE_3',
value)
self.assertNotIn('FEATURE_3', self.features.defined_features)
def test_get_attr_missing(self):
self.assertRaises(AttributeError, getattr, self.features, 'FEATURE_4')

View File

@ -63,6 +63,31 @@ class NetAppClientCmodeTestCase(test.TestCase):
def _mock_api_error(self, code='fake'):
return mock.Mock(side_effect=netapp_api.NaApiError(code=code))
def test_init_features_ontapi_1_21(self):
self.mock_object(client_base.NetAppBaseClient,
'get_ontapi_version',
mock.Mock(return_value=(1, 21)))
self.client._init_features()
self.assertFalse(self.client.features.BROADCAST_DOMAINS)
self.assertFalse(self.client.features.IPSPACES)
self.assertFalse(self.client.features.SUBNETS)
@ddt.data((1, 30), (1, 40), (2, 0))
def test_init_features_ontapi_1_30(self, ontapi_version):
self.mock_object(client_base.NetAppBaseClient,
'get_ontapi_version',
mock.Mock(return_value=ontapi_version))
self.client._init_features()
self.assertTrue(self.client.features.BROADCAST_DOMAINS)
self.assertTrue(self.client.features.IPSPACES)
self.assertTrue(self.client.features.SUBNETS)
def test_invoke_vserver_api(self):
self.client._invoke_vserver_api('fake-api', 'fake_vserver')
@ -487,7 +512,7 @@ class NetAppClientCmodeTestCase(test.TestCase):
},
},
'desired-attributes': {
'node-details-info': {
'net-port-info': {
'port': None,
'node': None,
'operational-speed': None,
@ -559,8 +584,14 @@ class NetAppClientCmodeTestCase(test.TestCase):
self.assertListEqual([], result)
def test_create_network_interface(self):
@ddt.data((True, True), (True, False), (False, True), (False, False))
@ddt.unpack
def test_create_network_interface(self, broadcast_domains_supported,
use_vlans):
self.client.features.add_feature('BROADCAST_DOMAINS',
broadcast_domains_supported)
self.mock_object(self.client, '_ensure_broadcast_domain_for_port')
self.mock_object(self.client, '_create_vlan')
self.mock_object(self.client, 'send_request')
@ -572,50 +603,32 @@ class NetAppClientCmodeTestCase(test.TestCase):
{'data-protocol': 'cifs'}
],
'home-node': fake.NODE_NAME,
'home-port': fake.VLAN_PORT,
'home-port': fake.VLAN_PORT if use_vlans else fake.PORT,
'netmask': fake.NETMASK,
'interface-name': fake.LIF_NAME,
'role': 'data',
'vserver': fake.VSERVER_NAME,
}
self.client.create_network_interface(fake.IP_ADDRESS, fake.NETMASK,
fake.VLAN, fake.NODE_NAME,
fake.PORT, fake.VSERVER_NAME,
fake.NET_ALLOCATION_ID,
fake.LIF_NAME_TEMPLATE)
self.client._create_vlan.assert_called_with(fake.NODE_NAME, fake.PORT,
fake.VLAN)
self.client.send_request.assert_has_calls([
mock.call('net-interface-create', lif_create_args)])
def test_create_network_interface_no_vlan(self):
self.mock_object(self.client, '_create_vlan')
self.mock_object(self.client, 'send_request')
lif_create_args = {
'address': fake.IP_ADDRESS,
'administrative-status': 'up',
'data-protocols': [
{'data-protocol': 'nfs'},
{'data-protocol': 'cifs'}
],
'home-node': fake.NODE_NAME,
'home-port': fake.PORT,
'netmask': fake.NETMASK,
'interface-name': fake.LIF_NAME,
'role': 'data',
'vserver': fake.VSERVER_NAME,
}
self.client.create_network_interface(fake.IP_ADDRESS, fake.NETMASK,
None, fake.NODE_NAME,
fake.PORT, fake.VSERVER_NAME,
fake.VLAN if use_vlans else None,
fake.NODE_NAME, fake.PORT,
fake.VSERVER_NAME,
fake.NET_ALLOCATION_ID,
fake.LIF_NAME_TEMPLATE)
if use_vlans:
self.client._create_vlan.assert_called_with(
fake.NODE_NAME, fake.PORT, fake.VLAN)
else:
self.assertFalse(self.client._create_vlan.called)
if broadcast_domains_supported:
self.client._ensure_broadcast_domain_for_port.assert_called_with(
fake.NODE_NAME, fake.VLAN_PORT if use_vlans else fake.PORT)
else:
self.assertFalse(
self.client._ensure_broadcast_domain_for_port.called)
self.client.send_request.assert_has_calls([
mock.call('net-interface-create', lif_create_args)])
@ -665,6 +678,229 @@ class NetAppClientCmodeTestCase(test.TestCase):
fake.PORT,
fake.VLAN)
def test_ensure_broadcast_domain_for_port_has_domain(self):
self.mock_object(self.client,
'_get_broadcast_domain_for_port',
mock.Mock(return_value=fake.BROADCAST_DOMAIN))
self.mock_object(self.client, '_broadcast_domain_exists')
self.mock_object(self.client, '_create_broadcast_domain')
self.mock_object(self.client, '_add_port_to_broadcast_domain')
self.client._ensure_broadcast_domain_for_port(fake.NODE_NAME,
fake.PORT)
self.client._get_broadcast_domain_for_port.assert_has_calls([
mock.call(fake.NODE_NAME, fake.PORT)])
self.assertFalse(self.client._broadcast_domain_exists.called)
self.assertFalse(self.client._create_broadcast_domain.called)
self.assertFalse(self.client._add_port_to_broadcast_domain.called)
def test_ensure_broadcast_domain_for_port_domain_not_found(self):
self.mock_object(self.client,
'_get_broadcast_domain_for_port',
mock.Mock(return_value=None))
self.mock_object(self.client,
'_broadcast_domain_exists',
mock.Mock(return_value=False))
self.mock_object(self.client, '_create_broadcast_domain')
self.mock_object(self.client, '_add_port_to_broadcast_domain')
self.client._ensure_broadcast_domain_for_port(
fake.NODE_NAME, fake.PORT, domain=fake.BROADCAST_DOMAIN,
ipspace=fake.IPSPACE)
self.client._get_broadcast_domain_for_port.assert_has_calls([
mock.call(fake.NODE_NAME, fake.PORT)])
self.client._broadcast_domain_exists.assert_has_calls([
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE)])
self.client._create_broadcast_domain.assert_has_calls([
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE)])
self.client._add_port_to_broadcast_domain.assert_has_calls([
mock.call(fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
fake.IPSPACE)])
def test_ensure_broadcast_domain_for_port_domain_found(self):
self.mock_object(self.client,
'_get_broadcast_domain_for_port',
mock.Mock(return_value=None))
self.mock_object(self.client,
'_broadcast_domain_exists',
mock.Mock(return_value=True))
self.mock_object(self.client, '_create_broadcast_domain')
self.mock_object(self.client, '_add_port_to_broadcast_domain')
self.client._ensure_broadcast_domain_for_port(
fake.NODE_NAME, fake.PORT, domain=fake.BROADCAST_DOMAIN,
ipspace=fake.IPSPACE)
self.client._get_broadcast_domain_for_port.assert_has_calls([
mock.call(fake.NODE_NAME, fake.PORT)])
self.client._broadcast_domain_exists.assert_has_calls([
mock.call(fake.BROADCAST_DOMAIN, fake.IPSPACE)])
self.assertFalse(self.client._create_broadcast_domain.called)
self.client._add_port_to_broadcast_domain.assert_has_calls([
mock.call(fake.NODE_NAME, fake.PORT, fake.BROADCAST_DOMAIN,
fake.IPSPACE)])
def test_get_broadcast_domain_for_port(self):
api_response = netapp_api.NaElement(
fake.NET_PORT_GET_ITER_BROADCAST_DOMAIN_RESPONSE)
self.mock_object(self.client,
'send_request',
mock.Mock(return_value=api_response))
net_port_get_iter_args = {
'query': {
'net-port-info': {
'node': fake.NODE_NAME,
'port': fake.PORT,
},
},
'desired-attributes': {
'net-port-info': {
'broadcast-domain': None,
},
},
}
result = self.client._get_broadcast_domain_for_port(fake.NODE_NAME,
fake.PORT)
self.client.send_request.assert_has_calls([
mock.call('net-port-get-iter', net_port_get_iter_args)])
self.assertEqual(fake.BROADCAST_DOMAIN, result)
def test_get_broadcast_domain_for_port_port_not_found(self):
api_response = netapp_api.NaElement(
fake.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
'send_request',
mock.Mock(return_value=api_response))
self.assertRaises(exception.NetAppException,
self.client._get_broadcast_domain_for_port,
fake.NODE_NAME,
fake.PORT)
def test_get_broadcast_domain_for_port_domain_not_found(self):
api_response = netapp_api.NaElement(
fake.NET_PORT_GET_ITER_BROADCAST_DOMAIN_MISSING_RESPONSE)
self.mock_object(self.client,
'send_request',
mock.Mock(return_value=api_response))
result = self.client._get_broadcast_domain_for_port(fake.NODE_NAME,
fake.PORT)
self.assertIsNone(result)
def test_broadcast_domain_exists(self):
api_response = netapp_api.NaElement(
fake.NET_PORT_BROADCAST_DOMAIN_GET_ITER_RESPONSE)
self.mock_object(self.client,
'send_request',
mock.Mock(return_value=api_response))
result = self.client._broadcast_domain_exists(fake.BROADCAST_DOMAIN,
fake.IPSPACE)
net_port_broadcast_domain_get_iter_args = {
'query': {
'net-port-broadcast-domain-info': {
'ipspace': fake.IPSPACE,
'broadcast-domain': fake.BROADCAST_DOMAIN,
},
},
'desired-attributes': {
'net-port-broadcast-domain-info': None,
},
}
self.client.send_request.assert_has_calls([
mock.call('net-port-broadcast-domain-get-iter',
net_port_broadcast_domain_get_iter_args)])
self.assertTrue(result)
def test_broadcast_domain_exists_not_found(self):
api_response = netapp_api.NaElement(
fake.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
'send_request',
mock.Mock(return_value=api_response))
result = self.client._broadcast_domain_exists(fake.BROADCAST_DOMAIN,
fake.IPSPACE)
self.assertFalse(result)
def test_create_broadcast_domain(self):
self.mock_object(self.client, 'send_request')
result = self.client._create_broadcast_domain(fake.BROADCAST_DOMAIN,
fake.IPSPACE,
mtu=fake.MTU)
net_port_broadcast_domain_create_args = {
'ipspace': fake.IPSPACE,
'broadcast-domain': fake.BROADCAST_DOMAIN,
'mtu': fake.MTU,
}
self.assertIsNone(result)
self.client.send_request.assert_has_calls([
mock.call('net-port-broadcast-domain-create',
net_port_broadcast_domain_create_args)])
def test_add_port_to_broadcast_domain(self):
self.mock_object(self.client, 'send_request')
add_port_to_broadcast_domain_args = {
'ipspace': fake.IPSPACE,
'broadcast-domain': fake.BROADCAST_DOMAIN,
'ports': {
'net-qualified-port-name': ':'.join([fake.NODE_NAME,
fake.VLAN_PORT])
}
}
result = self.client._add_port_to_broadcast_domain(
fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
fake.IPSPACE)
self.assertIsNone(result)
self.client.send_request.assert_has_calls([
mock.call('net-port-broadcast-domain-add-ports',
add_port_to_broadcast_domain_args)])
def test_add_port_to_broadcast_domain_already_present(self):
self.mock_object(self.client, 'send_request', self._mock_api_error(
code=netapp_api.
E_VIFMGR_PORT_ALREADY_ASSIGNED_TO_BROADCAST_DOMAIN))
result = self.client._add_port_to_broadcast_domain(
fake.NODE_NAME, fake.VLAN_PORT, fake.BROADCAST_DOMAIN,
fake.IPSPACE)
self.assertIsNone(result)
def test_add_port_to_broadcast_domain_api_error(self):
self.mock_object(self.client, 'send_request', self._mock_api_error())
self.assertRaises(exception.NetAppException,
self.client._add_port_to_broadcast_domain,
fake.NODE_NAME,
fake.VLAN_PORT,
fake.BROADCAST_DOMAIN,
fake.IPSPACE)
def test_network_interface_exists(self):
api_response = netapp_api.NaElement(
@ -1029,11 +1265,16 @@ class NetAppClientCmodeTestCase(test.TestCase):
fake.VSERVER_NAME)
vserver_modify_args = {
'name-mapping-switch': {'nmswitch': 'ldap,file'},
'name-server-switch': {'nsswitch': 'ldap,file'},
'name-mapping-switch': [
{'nmswitch': 'ldap'},
{'nmswitch': 'file'},
],
'name-server-switch': [
{'nsswitch': 'ldap'},
{'nsswitch': 'file'},
],
'vserver-name': fake.VSERVER_NAME
}
self.client.send_request.assert_has_calls([
mock.call('vserver-modify', vserver_modify_args)])
self.vserver_client.configure_ldap.assert_has_calls([
@ -1049,11 +1290,16 @@ class NetAppClientCmodeTestCase(test.TestCase):
fake.VSERVER_NAME)
vserver_modify_args = {
'name-mapping-switch': {'nmswitch': 'ldap,file'},
'name-server-switch': {'nsswitch': 'ldap,file'},
'name-mapping-switch': [
{'nmswitch': 'ldap'},
{'nmswitch': 'file'},
],
'name-server-switch': [
{'nsswitch': 'ldap'},
{'nsswitch': 'file'},
],
'vserver-name': fake.VSERVER_NAME
}
self.client.send_request.assert_has_calls([
mock.call('vserver-modify', vserver_modify_args)])
self.vserver_client.configure_active_directory.assert_has_calls([
@ -1070,11 +1316,16 @@ class NetAppClientCmodeTestCase(test.TestCase):
fake.VSERVER_NAME)
vserver_modify_args = {
'name-mapping-switch': {'nmswitch': 'ldap,file'},
'name-server-switch': {'nsswitch': 'ldap,file'},
'name-mapping-switch': [
{'nmswitch': 'ldap'},
{'nmswitch': 'file'},
],
'name-server-switch': [
{'nsswitch': 'ldap'},
{'nsswitch': 'file'},
],
'vserver-name': fake.VSERVER_NAME
}
self.client.send_request.assert_has_calls([
mock.call('vserver-modify', vserver_modify_args)])
self.client.create_kerberos_realm.assert_has_calls([
@ -1093,11 +1344,16 @@ class NetAppClientCmodeTestCase(test.TestCase):
fake.VSERVER_NAME)
vserver_modify_args = {
'name-mapping-switch': {'nmswitch': 'ldap,file'},
'name-server-switch': {'nsswitch': 'ldap,file'},
'name-mapping-switch': [
{'nmswitch': 'ldap'},
{'nmswitch': 'file'},
],
'name-server-switch': [
{'nsswitch': 'ldap'},
{'nsswitch': 'file'},
],
'vserver-name': fake.VSERVER_NAME
}
self.client.send_request.assert_has_calls([
mock.call('vserver-modify', vserver_modify_args)])

View File

@ -65,14 +65,11 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.mock_object(self.library,
'_find_matching_aggregates',
mock.Mock(return_value=fake.AGGREGATES))
mock_check_data_ontap_version = self.mock_object(
self.library, '_check_data_ontap_version')
mock_super = self.mock_object(lib_base.NetAppCmodeFileStorageLibrary,
'check_for_setup_error')
self.library.check_for_setup_error()
self.assertTrue(mock_check_data_ontap_version.called)
self.assertTrue(self.library._find_matching_aggregates.called)
mock_super.assert_called_once_with()
@ -107,17 +104,6 @@ class NetAppFileStorageLibraryTestCase(test.TestCase):
self.library.check_for_setup_error)
self.assertTrue(self.library._find_matching_aggregates.called)
@ddt.data((1, 20), (1, 21))
def test_check_data_ontap_version(self, version):
self.library._client.get_ontapi_version.return_value = version
self.assertIsNone(self.library._check_data_ontap_version())
@ddt.data((1, 30), (1, 31), (1, 40), (2, 0))
def test_check_data_ontap_version_too_new(self, version):
self.library._client.get_ontapi_version.return_value = version
self.assertRaises(exception.NetAppException,
self.library._check_data_ontap_version)
def test_get_vserver_no_share_server(self):
self.assertRaises(exception.InvalidInput,