Shared filesystem management project for OpenStack.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

397 lines
17 KiB

# Copyright (c) 2014 NetApp, 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 hashlib
import mock
from manila import context
from manila.share import configuration
from manila.share.drivers.netapp import api as naapi
from manila.share.drivers.netapp import cluster_mode as driver
from manila import test
class NetAppClusteredDrvTestCase(test.TestCase):
"""Tests for NetApp cmode driver.
"""
def setUp(self):
super(NetAppClusteredDrvTestCase, self).setUp()
self._context = context.get_admin_context()
self._db = mock.Mock()
driver.driver.NetAppApiClient = mock.Mock()
self.driver = driver.NetAppClusteredShareDriver(
self._db, configuration=configuration.Configuration(None))
self.driver._client = mock.Mock()
self.driver._client.send_request = mock.Mock()
self._vserver_client = mock.Mock()
self._vserver_client.send_request = mock.Mock()
driver.driver.NetAppApiClient = mock.Mock(
return_value=self._vserver_client)
self.share = {'id': 'fake_uuid',
'project_id': 'fake_tenant_id',
'name': 'fake_name',
'size': 1,
'share_proto': 'fake',
'share_network_id': 'fake_net_id',
'network_info': {
'network_allocations': [
{'ip_address': 'ip'}
]
}
}
self.snapshot = {'id': 'fake_snapshot_uuid',
'project_id': 'fake_tenant_id',
'share_id': 'fake_share_id',
'share': self.share
}
self.security_service = {'id': 'fake_id',
'domain': 'FAKE',
'server': 'fake_server',
'sid': 'fake_sid',
'password': 'fake_password'}
self.helper = mock.Mock()
self.driver._helpers = {'FAKE': self.helper}
self.driver._licenses = ['fake']
def test_create_vserver(self):
res = naapi.NaElement('fake')
res.add_new_child('aggregate-name', 'aggr')
self.driver.configuration.netapp_root_volume_aggregate = 'root'
fake_aggrs = mock.Mock()
fake_aggrs.get_child_by_name.return_value = fake_aggrs
fake_aggrs.get_children.return_value = [res]
self.driver._client.send_request = mock.Mock(return_value=fake_aggrs)
vserver_create_args = {
'vserver-name': 'os_fake_net_id',
'root-volume-security-style': 'unix',
'root-volume-aggregate': 'root',
'root-volume': 'root',
'name-server-switch': {
'nsswitch': 'file'
}
}
vserver_modify_args = {
'aggr-list': [
{'aggr-name': 'aggr'}
],
'vserver-name': 'os_fake_net_id'}
self.driver._create_vserver('os_fake_net_id')
self.driver._client.send_request.assert_has_calls([
mock.call('vserver-create', vserver_create_args),
mock.call('aggr-get-iter'),
mock.call('vserver-modify', vserver_modify_args),
]
)
def test_get_network_allocations_number(self):
res = mock.Mock()
res.get_child_content.return_value = '5'
self.driver._client.send_request = mock.Mock(return_value=res)
self.assertEqual(self.driver.get_network_allocations_number(), 5)
def test_delete_vserver(self):
self.driver._delete_vserver('fake', self._vserver_client)
self._vserver_client.send_request.assert_has_calls([
mock.call('volume-offline', {'name': 'root'}),
mock.call('volume-destroy', {'name': 'root'})
])
self.driver._client.send_request.assert_called_once_with(
'vserver-destroy', {'vserver-name': 'fake'})
def test_create_net_iface(self):
self.driver._create_net_iface('1.1.1.1', '255.255.255.0', '200',
'node', 'port', 'vserver-name', 'all_id')
vlan_args = {
'vlan-info': {
'parent-interface': 'port',
'node': 'node',
'vlanid': '200'}
}
interface_args = {
'address': '1.1.1.1',
'administrative-status': 'up',
'data-protocols': [
{'data-protocol': 'nfs'},
{'data-protocol': 'cifs'}
],
'home-node': 'node',
'home-port': 'port-200',
'netmask': '255.255.255.0',
'interface-name': 'os_all_id',
'role': 'data',
'vserver': 'vserver-name',
}
self.driver._client.send_request.assert_has_calls([
mock.call('net-vlan-create', vlan_args),
mock.call('net-interface-create', interface_args),
])
def test_enable_nfs(self):
self.driver._enable_nfs(self._vserver_client)
export_args = {
'client-match': '0.0.0.0/0',
'policy-name': 'default',
'ro-rule': {
'security-flavor': 'any'
},
'rw-rule': {
'security-flavor': 'any'
}
}
self._vserver_client.send_request.assert_has_calls(
[mock.call('nfs-enable'),
mock.call('nfs-service-modify', {'is-nfsv40-enabled': 'true'}),
mock.call('export-rule-create', export_args)]
)
def test_configure_ldap(self):
conf_name = hashlib.md5('fake_id').hexdigest()
client_args = {
'ldap-client-config': conf_name,
'servers': {
'ip-address': 'fake_server'
},
'tcp-port': '389',
'schema': 'RFC-2307',
'bind-password': 'fake_password'
}
config_args = {'client-config': conf_name,
'client-enabled': 'true'}
self.driver._configure_ldap(self.security_service,
self._vserver_client)
self._vserver_client.send_request.assert_has_calls([
mock.call('ldap-client-create', client_args),
mock.call('ldap-config-create', config_args)])
def test_configure_kerberos(self):
kerberos_args = {'admin-server-ip': 'fake_server',
'admin-server-port': '749',
'clock-skew': '5',
'comment': '',
'config-name': 'fake_id',
'kdc-ip': 'fake_server',
'kdc-port': '88',
'kdc-vendor': 'other',
'password-server-ip': 'fake_server',
'password-server-port': '464',
'realm': 'FAKE'}
spn = 'nfs/fake-vserver.FAKE@FAKE'
kerberos_modify_args = {'admin-password': 'fake_password',
'admin-user-name': 'fake_sid',
'interface-name': 'fake_lif',
'is-kerberos-enabled': 'true',
'service-principal-name': spn
}
self.driver._get_lifs = mock.Mock(return_value=['fake_lif'])
self.driver._configure_dns = mock.Mock(return_value=['fake_lif'])
self.driver._configure_kerberos('fake_vserver', self.security_service,
self._vserver_client)
self.driver._client.send_request.assert_called_once_with(
'kerberos-realm-create', kerberos_args)
self._vserver_client.send_request.assert_called_once_with(
'kerberos-config-modify', kerberos_modify_args)
def test_configure_active_directory(self):
self.driver._configure_dns = mock.Mock()
self.driver._configure_active_directory(self.security_service,
self._vserver_client)
args = {'admin-username': 'fake_sid',
'admin-password': 'fake_password',
'force-account-overwrite': 'true',
'cifs-server': 'fake_server',
'domain': 'FAKE'}
self._vserver_client.send_request.assert_called_with(
'cifs-server-create', args)
def test_allocate_container(self):
root = naapi.NaElement('root')
attributes = naapi.NaElement('attributes')
vserver_info = naapi.NaElement('vserver-info')
vserver_aggr_info_list = naapi.NaElement('vserver-aggr-info-list')
for i in range(1, 4):
vserver_aggr_info_list.add_node_with_children('aggr-attributes',
**{'aggr-name': 'fake%s' % i,
'aggr-availsize': '%s' % i})
vserver_info.add_child_elem(vserver_aggr_info_list)
attributes.add_child_elem(vserver_info)
root.add_child_elem(attributes)
root.add_new_child('attributes', None)
self._vserver_client.send_request = mock.Mock(return_value=root)
self.driver._allocate_container(self.share, 'vserver',
self._vserver_client)
args = {'containing-aggr-name': 'fake3',
'size': '1g',
'volume': 'share_fake_uuid',
'junction-path': '/share_fake_uuid'
}
self._vserver_client.send_request.assert_called_with(
'volume-create', args)
def test_allocate_container_from_snapshot(self):
self.driver._allocate_container_from_snapshot(self.share,
self.snapshot,
'vserver',
self._vserver_client)
args = {'volume': 'share_fake_uuid',
'parent-volume': 'share_fake_share_id',
'parent-snapshot': 'share_snapshot_fake_snapshot_uuid',
'junction-path': '/share_fake_uuid'}
self._vserver_client.send_request.assert_called_with(
'volume-clone-create', args)
def test_deallocate_container(self):
self.driver._deallocate_container(self.share, self._vserver_client)
self._vserver_client.send_request.assert_has_calls([
mock.call('volume-unmount',
{'volume-name': 'share_fake_uuid'}),
mock.call('volume-offline',
{'name': 'share_fake_uuid'}),
mock.call('volume-destroy',
{'name': 'share_fake_uuid'})
])
def test_create_export(self):
self.helper.create_share = mock.Mock(return_value="fake-location")
export_location = self.driver._create_export(
self.share, 'vserver', self._vserver_client)
self.helper.create_share.assert_called_once_with(
"share_%s" % self.share['id'], 'ip')
self.assertEqual(export_location, "fake-location")
def test_create_snapshot(self):
self.driver.create_snapshot(self._context, self.snapshot)
self._vserver_client.send_request.assert_called_once_with(
'snapshot-create',
{'volume': 'share_fake_share_id',
'snapshot': 'share_snapshot_fake_snapshot_uuid'})
def test_delete_share(self):
resp = mock.Mock()
resp.get_child_content.return_value = 1
self._vserver_client.send_request = mock.Mock(return_value=resp)
self.driver.delete_share(self._context, self.share)
self.helper.delete_share.assert_called_once_with(self.share)
def test_allow_access(self):
access = "1.2.3.4"
self.driver.allow_access(self._context, self.share, access)
self.helper.allow_access.assert_called_ince_with(self._context,
self.share, access)
def test_deny_access(self):
access = "1.2.3.4"
self.driver.deny_access(self._context, self.share, access)
self.helper.deny_access.assert_called_ince_with(self._context,
self.share, access)
class NetAppNFSHelperTestCase(test.TestCase):
"""Tests for NetApp 7mode driver.
"""
def setUp(self):
super(NetAppNFSHelperTestCase, self).setUp()
self._context = context.get_admin_context()
self._db = mock.Mock()
self.client = mock.Mock()
self.share = {'id': 'fake_uuid',
'tenant_id': 'fake_tenant_id',
'name': 'fake_name',
'size': 1,
'export_location': 'location:/path',
'share_proto': 'fake'}
self.helper = driver.NetAppClusteredNFSHelper()
self.helper._client = mock.Mock()
self.helper._client.send_request = mock.Mock()
def test_create_share(self):
location = self.helper.create_share('share_name',
'fake-vserver-location')
self.helper._client.send_request.assert_called_once_with(
'nfs-exportfs-append-rules-2', mock.ANY)
self.assertEqual(location, 'fake-vserver-location:/share_name')
def test_delete_share(self):
self.helper.delete_share(self.share)
self.helper._client.send_request.assert_called_once_with(
'nfs-exportfs-delete-rules', mock.ANY)
def test_allow_access(self):
access = {'access_to': '1.2.3.4',
'access_type': 'ip'}
root = naapi.NaElement('root')
rules = naapi.NaElement('rules')
root.add_child_elem(rules)
self.helper._client.send_request = mock.Mock(return_value=root)
self.helper.allow_access(self._context, self.share, access)
self.helper._client.send_request.assert_has_calls([
mock.call('nfs-exportfs-list-rules-2', mock.ANY),
mock.call('nfs-exportfs-append-rules-2', mock.ANY)
])
def test_deny_access(self):
access = {'access_to': '1.2.3.4',
'access_type': 'ip'}
root = naapi.NaElement('root')
rules = naapi.NaElement('rules')
root.add_child_elem(rules)
self.helper._client.send_request = mock.Mock(return_value=root)
self.helper.allow_access(self._context, self.share, access)
self.helper._client.send_request.assert_has_calls([
mock.call('nfs-exportfs-list-rules-2', mock.ANY),
mock.call('nfs-exportfs-append-rules-2', mock.ANY)
])
class NetAppCIFSHelperTestCase(test.TestCase):
"""Tests for NetApp 7mode driver.
"""
def setUp(self):
super(NetAppCIFSHelperTestCase, self).setUp()
self._context = context.get_admin_context()
self._db = mock.Mock()
self.share = {'id': 'fake_uuid',
'tenant_id': 'fake_tenant_id',
'name': 'fake_name',
'size': 1,
'export_location': 'location:/path',
'share_proto': 'fake'}
self.helper = driver.NetAppClusteredCIFSHelper()
self.helper._client = mock.Mock()
self.helper._client.send_request = mock.Mock()
def test_create_share(self):
self.helper.create_share('fake_name', '1.1.1.1')
self.helper._client.send_request.assert_has_calls([
mock.call('cifs-share-create', {'path': '/fake_name',
'share-name': 'fake_name'}),
mock.call('cifs-share-access-control-delete',
{'user-or-group': 'Everyone', 'share': 'fake_name'})
])
def test_delete_share(self):
self.share['export_location'] = "nfs://host/fake_name"
self.helper.delete_share(self.share)
self.helper._client.send_request.assert_called_with(
'cifs-share-delete', {'share-name': 'fake_name'})
def test_allow_access(self):
self.helper._allow_access_for('fake_name', 'fake_share')
self.helper._client.send_request.assert_called_with(
'cifs-share-access-control-create', {'permission': 'full_control',
'share': 'fake_share',
'user-or-group': 'fake_name'})