manila/manila/tests/share/drivers/dell_emc/common/enas/fakes.py

1740 lines
61 KiB
Python

# Copyright (c) 2015 EMC Corporation.
# 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 mock
from oslo_utils import units
from manila.common import constants as const
from manila.share import configuration as conf
from manila.share.drivers.dell_emc.common.enas import utils
from manila.tests import fake_share
def query(func):
def inner(*args, **kwargs):
return (
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
'<RequestPacket xmlns="http://www.emc.com/schemas/celerra/'
'xml_api"><Request><Query>'
+ func(*args, **kwargs)
+ '</Query></Request></RequestPacket>'
)
return inner
def start_task(func):
def inner(*args, **kwargs):
return (
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
'<RequestPacket xmlns="http://www.emc.com/schemas/celerra/'
'xml_api"><Request><StartTask timeout="300">'
+ func(*args, **kwargs)
+ '</StartTask></Request></RequestPacket>')
return inner
def response(func):
def inner(*args, **kwargs):
return (
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
'<ResponsePacket xmlns="http://www.emc.com/schemas/celerra/'
'xml_api"><Response>'
+ func(*args, **kwargs)
+ '</Response></ResponsePacket>'
).encode()
return inner
class FakeData(object):
# Share information
share_id = '7cf7c200_d3af_4e05_b87e_9167c95df4f9'
host = 'HostA@BackendB#fake_pool_name'
share_name = share_id
share_size = 10
new_size = 20
src_share_name = '7cf7c200_d3af_4e05_b87e_9167c95df4f0'
# Snapshot information
snapshot_name = 'de4c9050-e2f9-4ce1-ade4-5ed0c9f26451'
src_snap_name = 'de4c9050-e2f9-4ce1-ade4-5ed0c9f26452'
snapshot_id = 'fake_snap_id'
snapshot_size = 10 * units.Ki
# Share network information
share_network_id = 'c5b3a865-56d0-4d88-abe5-879965e099c9'
cidr = '192.168.1.0/24'
cidr_v6 = 'fdf8:f53b:82e1::/64'
segmentation_id = 100
network_allocations_id1 = '132dbb10-9a36-46f2-8d89-3d909830c356'
network_allocations_id2 = '7eabdeed-bad2-46ea-bd0f-a33884c869e0'
network_allocations_id3 = '98c9e490-a842-4e59-b59a-a6042069d35b'
network_allocations_id4 = '6319a917-ab95-4b65-a498-773ae33c5550'
network_allocations_ip1 = '192.168.1.1'
network_allocations_ip2 = '192.168.1.2'
network_allocations_ip3 = 'fdf8:f53b:82e1::1'
network_allocations_ip4 = 'fdf8:f53b:82e1::2'
network_allocations_ip_version1 = 4
network_allocations_ip_version2 = 4
network_allocations_ip_version3 = 6
network_allocations_ip_version4 = 6
domain_name = 'fake_domain'
domain_user = 'administrator'
domain_password = 'password'
dns_ip_address = '192.168.1.200'
dns_ipv6_address = 'fdf8:f53b:82e1::f'
# Share server information
share_server_id = '56aafd02-4d44-43d7-b784-57fc88167224'
# Filesystem information
filesystem_name = share_name
filesystem_id = 'fake_filesystem_id'
filesystem_size = 10 * units.Ki
filesystem_new_size = 20 * units.Ki
# Mountpoint information
path = '/' + share_name
# Mover information
mover_name = 'server_2'
mover_id = 'fake_mover_id'
interface_name1 = network_allocations_id1[-12:]
interface_name2 = network_allocations_id2[-12:]
interface_name3 = network_allocations_id3[-12:]
interface_name4 = network_allocations_id4[-12:]
long_interface_name = network_allocations_id1
net_mask = '255.255.255.0'
net_mask_v6 = 64
device_name = 'cge-1-0'
interconnect_id = '2001'
# VDM information
vdm_name = share_server_id
vdm_id = 'fake_vdm_id'
# Pool information
pool_name = 'fake_pool_name'
pool_id = 'fake_pool_id'
pool_used_size = 20480
pool_total_size = 511999
# NFS share access information
rw_hosts = ['192.168.1.1', '192.168.1.2']
ro_hosts = ['192.168.1.3', '192.168.1.4']
nfs_host_ip = '192.168.1.5'
rw_hosts_ipv6 = ['fdf8:f53b:82e1::1', 'fdf8:f53b:82e1::2']
ro_hosts_ipv6 = ['fdf8:f53b:82e1::3', 'fdf8:f53b:82e1::4']
nfs_host_ipv6 = 'fdf8:f53b:82e1::5'
fake_output = ''
fake_error_msg = 'fake error message'
emc_share_backend = 'vnx'
powermax_share_backend = 'powermax'
emc_nas_server = '192.168.1.20'
emc_nas_login = 'fakename'
emc_nas_password = 'fakepassword'
share_backend_name = 'EMC_NAS_Storage'
cifs_access = """
1478607389: SMB:11: Unix user 'Guest' UID=32769
1478607389: SMB:10: FindUserUid:Access_Password 'Guest',1=0x8001 T=0
1478607389: SHARE: 6: ALLOWED:fullcontrol:S-1-5-15-3399d125-6dcdf5f4
1478607389: SMB:11: Unix user 'Administrator' UID=32768
1478607389: SMB:10: FindUserUid:Access_Password 'Administrator',
1478607389: SHARE: 6: ALLOWED:fullcontrol:S-1-5-15-3399d125
"""
class StorageObjectTestData(object):
def __init__(self):
self.share_name = FakeData.share_name
self.filesystem_name = FakeData.filesystem_name
self.filesystem_id = FakeData.filesystem_id
self.filesystem_size = 10 * units.Ki
self.filesystem_new_size = 20 * units.Ki
self.path = FakeData.path
self.snapshot_name = FakeData.snapshot_name
self.snapshot_id = FakeData.snapshot_id
self.snapshot_size = 10 * units.Ki
self.src_snap_name = FakeData.src_snap_name
self.src_fileystems_name = FakeData.src_share_name
self.mover_name = FakeData.mover_name
self.mover_id = FakeData.mover_id
self.vdm_name = FakeData.vdm_name
self.vdm_id = FakeData.vdm_id
self.pool_name = FakeData.pool_name
self.pool_id = FakeData.pool_id
self.pool_used_size = FakeData.pool_used_size
self.pool_total_size = FakeData.pool_total_size
self.interface_name1 = FakeData.interface_name1
self.interface_name2 = FakeData.interface_name2
self.interface_name3 = FakeData.interface_name3
self.interface_name4 = FakeData.interface_name4
self.long_interface_name = FakeData.long_interface_name
self.ip_address1 = FakeData.network_allocations_ip1
self.ip_address2 = FakeData.network_allocations_ip2
self.ip_address3 = FakeData.network_allocations_ip3
self.ip_address4 = FakeData.network_allocations_ip4
self.net_mask = FakeData.net_mask
self.net_mask_v6 = FakeData.net_mask_v6
self.vlan_id = FakeData.segmentation_id
self.cifs_server_name = FakeData.vdm_name
self.domain_name = FakeData.domain_name
self.domain_user = FakeData.domain_user
self.domain_password = FakeData.domain_password
self.dns_ip_address = FakeData.dns_ip_address
self.device_name = FakeData.device_name
self.interconnect_id = FakeData.interconnect_id
self.rw_hosts = FakeData.rw_hosts
self.ro_hosts = FakeData.ro_hosts
self.nfs_host_ip = FakeData.nfs_host_ip
self.rw_hosts_ipv6 = FakeData.rw_hosts_ipv6
self.ro_hosts_ipv6 = FakeData.ro_hosts_ipv6
self.nfs_host_ipv6 = FakeData.nfs_host_ipv6
self.fake_output = FakeData.fake_output
@response
def resp_get_error(self):
return (
'<QueryStatus maxSeverity="error">'
'<Problem messageCode="18522112101" facility="Generic" '
'component="API" message="Fake message." severity="error">'
'<Description>Fake description.</Description>'
'<Action>Fake action.</Action>'
'<Diagnostics>Fake diagnostics.</Diagnostics>'
'</Problem>'
'<Problem messageCode="18522112101" facility="Generic" '
'component="API" message="Fake message." severity="error">'
'<Description>Fake description.</Description>'
'<Action>Fake action.</Action>'
'<Diagnostics>Fake diagnostics.</Diagnostics>'
'</Problem>'
'</QueryStatus> '
)
@response
def resp_get_without_value(self):
return (
'<QueryStatus maxSeverity="ok"/>'
)
@response
def resp_task_succeed(self):
return (
'<TaskResponse taskId="123">'
'<Status maxSeverity="ok"/>'
'</TaskResponse>'
)
@response
def resp_task_error(self):
return (
'<TaskResponse taskId="123">'
'<Status maxSeverity="error"/>'
'</TaskResponse>'
)
@response
def resp_invalid_mover_id(self):
return (
'<Fault maxSeverity="error">'
'<Problem messageCode="14227341323" facility="Prevalidator" '
'component="API" message="Mover with id=100 not found." '
'severity="error">'
'<Description>The Mover ID supplied with the request is invalid.'
'</Description>'
'<Action>Refer to the XML API v2 schema/documentation and correct '
'your user program logic.</Action>'
'<Diagnostics> Exception tag: 14fb692e556 Exception '
'message: com.emc.nas.ccmd.common.MessageInstanceImpl@5004000d '
'</Diagnostics>'
'</Problem>'
'</Fault> '
)
@response
def resp_need_retry(self):
return ('<TaskResponse taskId="915525">'
'<Status maxSeverity = "error">'
'<Problem messageCode = "13421840537" component = "fake"'
' message = "unable to acquire lock(s), try later"'
' severity = "error" >'
'<Description> fake desp. </Description>'
'<Action>fake action </Action>'
'</Problem></Status></TaskResponse>')
@start_task
def req_fake_start_task(self):
return '<StartFake name="foo"></StartFake>'
class FileSystemTestData(StorageObjectTestData):
def __init__(self):
super(FileSystemTestData, self).__init__()
@start_task
def req_create_on_vdm(self):
return (
'<NewFileSystem name="%(name)s">'
'<Vdm vdm="%(id)s"/>'
'<StoragePool mayContainSlices="true" pool="%(pool_id)s" '
'size="%(size)s"/>'
'</NewFileSystem>'
% {'name': self.filesystem_name,
'id': self.vdm_id,
'pool_id': self.pool_id,
'size': self.filesystem_size}
)
@start_task
def req_create_on_mover(self):
return (
'<NewFileSystem name="%(name)s">'
'<Mover mover="%(id)s"/>'
'<StoragePool mayContainSlices="true" pool="%(pool_id)s" '
'size="%(size)s"/>'
'</NewFileSystem>'
% {'name': self.filesystem_name,
'id': self.mover_id,
'pool_id': self.pool_id,
'size': self.filesystem_size}
)
@response
def resp_create_but_already_exist(self):
return (
' <TaskResponse taskId="31362">'
'<Status maxSeverity="error">'
'<Problem messageCode="13691191325" component="APL" '
'message="A file system with the name fake_filesystem '
'already exists." severity="error">'
'<Description></Description>'
'<Action></Action>'
'</Problem>'
'</Status>'
'</TaskResponse> '
)
@start_task
def req_delete(self):
return (
'<DeleteFileSystem fileSystem="%(id)s"/>' %
{'id': self.filesystem_id}
)
@response
def resp_delete_but_failed(self):
return (
'<Fault maxSeverity="error">'
'<Problem messageCode="14227341326" facility="Prevalidator" '
'component="API" message="File system with id=77777 not found." '
'severity="error">'
'<Description>The file system ID supplied with the request is '
'invalid.</Description>'
'<Action>Refer to the XML API v2 schema/documentation and correct '
'your user program logic.</Action>'
'<Diagnostics> Exception tag: 14fb6b6a7b8 Exception '
'message: com.emc.nas.ccmd.common.MessageInstanceImpl@5004000e '
'</Diagnostics>'
'</Problem>'
'</Fault> '
)
@start_task
def req_extend(self):
return (
'<ExtendFileSystem fileSystem="%(id)s">'
'<StoragePool pool="%(pool_id)s" size="%(size)d"/>'
'</ExtendFileSystem>' %
{'id': self.filesystem_id,
'pool_id': self.pool_id,
'size': self.filesystem_new_size - self.filesystem_size}
)
@response
def resp_extend_but_error(self):
return (
'<Fault maxSeverity="error">'
'<Problem messageCode="14227341325" facility="Prevalidator" '
'component="API" message="Fake message.">'
'<Description>Fake description.</Description>'
'<Action>Fake action.</Action>'
'<Diagnostics> Fake diagnostics.</Diagnostics>'
'</Problem>'
'</Fault> '
)
@query
def req_get(self):
return (
'<FileSystemQueryParams>'
'<AspectSelection fileSystemCapacityInfos="true" '
'fileSystems="true"/>'
'<Alias name="%(name)s"/>'
'</FileSystemQueryParams>' %
{'name': self.filesystem_name}
)
@response
def resp_get_succeed(self):
return (
'<QueryStatus maxSeverity="ok"/>'
'<FileSystem name="%(name)s" type="uxfs" volume="107" '
'storagePools="%(pool_id)s" storages="1" containsSlices="true" '
'internalUse="false" dataServicePolicies="Thin=No,Compressed=No,'
'Mirrored=No,Tiering policy=Auto-Tier/Highest Available Tier" '
'fileSystem="%(id)s">'
'<ProductionFileSystemData cwormState="off"/>'
'</FileSystem>'
'<FileSystemCapacityInfo volumeSize="%(size)s" '
'fileSystem="%(id)s"/>' %
{'name': self.filesystem_name,
'id': self.filesystem_id,
'size': self.filesystem_size,
'pool_id': self.pool_id}
)
@response
def resp_get_but_miss_property(self):
return (
'<QueryStatus maxSeverity="ok"/>'
'<FileSystem name="%(name)s" type="uxfs" volume="107" '
'storagePools="%(pool_id)s" storages="1" containsSlices="true" '
'internalUse="false" '
'fileSystem="%(id)s">'
'<ProductionFileSystemData cwormState="off"/>'
'</FileSystem>'
'<FileSystemCapacityInfo volumeSize="%(size)s" '
'fileSystem="%(id)s"/>' %
{'name': self.filesystem_name,
'id': self.filesystem_id,
'size': self.filesystem_size,
'pool_id': self.pool_id}
)
@response
def resp_get_but_not_found(self):
return (
'<QueryStatus maxSeverity="warning">'
'<Problem messageCode="18522112101" facility="Generic" '
'component="API" message="The query may be incomplete or '
'requested object not found." severity="warning">'
'<Description>The query may be incomplete because some of the '
'Celerra components are unavailable or do not exist. Another '
'reason may be application error. </Description>'
'<Action>If the entire Celerra is functioning correctly, '
'check your client application logic. </Action>'
'<Diagnostics>File system not found.</Diagnostics>'
'</Problem>'
'<Problem messageCode="18522112101" facility="Generic" '
'component="API" message="The query may be incomplete or '
'requested object not found." severity="warning">'
'<Description>The query may be incomplete because some of the '
'Celerra components are unavailable or do not exist. Another '
'reason may be application error.</Description>'
'<Action>If the entire Celerra is functioning correctly, '
'check your client application logic.</Action>'
'<Diagnostics>Migration file system not found.</Diagnostics>'
'</Problem>'
'</QueryStatus> '
)
def cmd_create_from_ckpt(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_fs',
'-name', self.filesystem_name,
'-type', 'uxfs',
'-create',
'samesize=' + self.src_fileystems_name,
'pool=' + self.pool_name,
'storage=SINGLE',
'worm=off',
'-thin', 'no',
'-option', 'slice=y',
]
def cmd_copy_ckpt(self):
session_name = self.filesystem_name + ':' + self.src_snap_name
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_copy',
'-name', session_name[0:63],
'-source', '-ckpt', self.src_snap_name,
'-destination', '-fs', self.filesystem_name,
'-interconnect', "id=" + self.interconnect_id,
'-overwrite_destination',
'-full_copy',
]
output_copy_ckpt = "OK"
error_copy_ckpt = "ERROR"
def cmd_nas_fs_info(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_fs',
'-info', self.filesystem_name,
]
def output_info(self):
return (
"""output = id = 515
name = %(share_name)s
acl = 0
in_use = True
type = uxfs
worm = off
volume = v993
deduplication = Off
thin_storage = True
tiering_policy = Auto-Tier/Optimize Pool
compressed= False
mirrored = False
ckpts = %(ckpt)s
stor_devs = FNM00124500890-004B
disks = d7
disk=d7 fakeinfo""" %
{'share_name': self.filesystem_name,
'ckpt': self.snapshot_name})
def cmd_delete(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_fs',
'-delete', self.snapshot_name,
'-Force',
]
class SnapshotTestData(StorageObjectTestData):
def __init__(self):
super(SnapshotTestData, self).__init__()
@start_task
def req_create(self):
return (
'<NewCheckpoint checkpointOf="%(fsid)s" '
'name="%(name)s"><SpaceAllocationMethod>'
'<StoragePool pool="%(pool_id)s"/></SpaceAllocationMethod>'
'</NewCheckpoint>'
% {'fsid': self.filesystem_id,
'name': self.snapshot_name,
'pool_id': self.pool_id}
)
@start_task
def req_create_with_size(self):
return (
'<NewCheckpoint checkpointOf="%(fsid)s" '
'name="%(name)s"><SpaceAllocationMethod>'
'<StoragePool pool="%(pool_id)s" size="%(size)s"/>'
'</SpaceAllocationMethod>'
'</NewCheckpoint>'
% {'fsid': self.filesystem_id,
'name': self.snapshot_name,
'pool_id': self.pool_id,
'size': self.snapshot_size}
)
@response
def resp_create_but_already_exist(self):
return (
'<Status maxSeverity="error">'
'<Problem messageCode="13690535947" component="APL" '
'message="snap_0 is already in use." severity="error">'
'<Description></Description>'
'<Action></Action>'
'</Problem>'
'</Status>'
)
@query
def req_get(self):
return (
'<CheckpointQueryParams><Alias name="%(name)s"/>'
'</CheckpointQueryParams>'
% {'name': self.snapshot_name}
)
@response
def resp_get_succeed(self):
return (
'<QueryStatus maxSeverity="ok"/>'
'<Checkpoint checkpointOf="%(fs_id)s" name="%(name)s_replica1"'
' state="active" time="1405428355" fileSystemSize="0"'
' checkpoint="%(snap_id)s"/>'
% {'name': self.snapshot_name,
'fs_id': self.filesystem_id,
'snap_id': self.snapshot_id}
)
@start_task
def req_delete(self):
return (
'<DeleteCheckpoint checkpoint="%(id)s"/>' %
{'id': self.snapshot_id}
)
class MountPointTestData(StorageObjectTestData):
def __init__(self):
super(MountPointTestData, self).__init__()
@start_task
def req_create(self, mover_id, is_vdm=True):
return (
'<NewMount path="%(path)s" fileSystem="%(fs_id)s">'
'<MoverOrVdm mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s"/>'
'</NewMount>' %
{'path': self.path,
'fs_id': self.filesystem_id,
'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false'}
)
@response
def resp_create_but_already_exist(self):
return (
'<TaskResponse taskId="31428">'
'<Status maxSeverity="error">'
'<Problem messageCode="13690601492" component="APL" '
'message="Mount already exists" severity="error">'
'<Description></Description> <Action></Action>'
'</Problem>'
'</Status>'
'</TaskResponse> ')
@start_task
def req_delete(self, mover_id, is_vdm=True):
return (
'<DeleteMount path="%(path)s" mover="%(mover_id)s" '
'moverIdIsVdm="%(is_vdm)s"/>' %
{'path': self.path,
'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false'}
)
@response
def resp_delete_but_nonexistent(self):
return (
'<TaskResponse taskId="31401">'
'<Status maxSeverity="error"> <Problem messageCode="13690601492" '
'component="APL" message="/fake_filesystem : No such path or '
'invalid operation." severity="error">'
'<Description></Description> <Action></Action>'
'</Problem>'
'</Status>'
'</TaskResponse> '
)
@query
def req_get(self, mover_id, is_vdm=True):
return (
'<MountQueryParams><MoverOrVdm mover="%(mover_id)s" '
'moverIdIsVdm="%(is_vdm)s"/></MountQueryParams>' %
{'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false'}
)
@response
def resp_get_succeed(self, mover_id, is_vdm=True):
return (
'<QueryStatus maxSeverity="ok"/>'
'<Mount fileSystem="%(fsID)s" disabled="false"'
' ntCredential="false" path="%(path)s" mover="%(mover_id)s"'
' moverIdIsVdm="%(is_vdm)s">'
'<NfsOptions ro="false" virusScan="true"'
' prefetch="true" uncached="false"/>'
'<CifsOptions cifsSyncwrite="false" notify="true"'
' triggerLevel="512" notifyOnAccess="false"'
' notifyOnWrite="false" oplock="true" accessPolicy="NATIVE"'
' lockingPolicy="nolock"/></Mount>'
% {'path': self.path,
'fsID': self.filesystem_id,
'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false'}
)
def cmd_server_mount(self, mode):
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_mount', self.vdm_name,
'-option', mode,
self.filesystem_name,
self.path,
]
def cmd_server_umount(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_umount', self.vdm_name,
'-perm', self.snapshot_name,
]
class VDMTestData(StorageObjectTestData):
def __init__(self):
super(VDMTestData, self).__init__()
@start_task
def req_create(self):
return (
'<NewVdm mover="%(mover_id)s" name="%(vdm_name)s"/>' %
{'mover_id': self.mover_id, 'vdm_name': self.vdm_name}
)
@response
def resp_create_but_already_exist(self):
return (
'<TaskResponse taskId="32551">'
'<Status maxSeverity="error">'
'<Problem messageCode="13421840550" component="CS_CORE" '
'message="VDM_01 : an entry with this name already exists" '
'severity="error">'
'<Description>Duplicate name specified</Description>'
'<Action>Specify a unqiue name</Action>'
'</Problem>'
'<Problem messageCode="13421840550" component="CS_CORE" '
'message="VDM_01 : an entry with this name already exists" '
'severity="error">'
'<Description>Duplicate name specified</Description>'
'<Action>Specify a unqiue name</Action>'
'</Problem>'
'</Status>'
'</TaskResponse> '
)
@query
def req_get(self):
return '<VdmQueryParams/>'
@response
def resp_get_succeed(self, name=None, interface1=None, interface2=None):
if name is None:
name = self.vdm_name
if interface1 is None:
interface1 = self.interface_name1
if interface2 is None:
interface2 = self.interface_name2
return (
'<QueryStatus maxSeverity="ok"/>'
'<Vdm name="%(vdm_name)s" state="loaded" mover="%(mover_id)s" '
'rootFileSystem="396" vdm="%(vdm_id)s">'
'<Status maxSeverity="ok"/>'
'<Interfaces> <li>%(interface1)s</li> <li>%(interface2)s</li>'
'</Interfaces> </Vdm>' %
{'vdm_name': name,
'vdm_id': self.vdm_id,
'mover_id': self.mover_id,
'interface1': interface1,
'interface2': interface2}
)
@response
def resp_get_but_not_found(self):
return (
'<QueryStatus maxSeverity="ok"/>'
)
@start_task
def req_delete(self):
return '<DeleteVdm vdm="%(vdmid)s"/>' % {'vdmid': self.vdm_id}
def cmd_attach_nfs_interface(self, interface=None):
if interface is None:
interface = self.interface_name2
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_server',
'-vdm', self.vdm_name,
'-attach', interface,
]
def cmd_detach_nfs_interface(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_server',
'-vdm', self.vdm_name,
'-detach', self.interface_name2,
]
def cmd_get_interfaces(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_server',
'-i',
'-vdm', self.vdm_name,
]
def output_get_interfaces_vdm(self,
cifs_interface=FakeData.interface_name1,
nfs_interface=FakeData.interface_name2):
return (
"""id = %(vdmid)s
name = %(name)s
acl = 0
type = vdm
server = server_2
rootfs = root_fs_vdm_vdm-fakeid
I18N mode = UNICODE
mountedfs =
member_of =
status :
defined = enabled
actual = loaded, active
Interfaces to services mapping:
interface=%(nfs_if_name)s :vdm
interface=%(cifs_if_name)s :cifs""" %
{'vdmid': self.vdm_id,
'name': self.vdm_name,
'nfs_if_name': nfs_interface,
'cifs_if_name': cifs_interface}
)
def output_get_interfaces_nfs(self,
cifs_interface=FakeData.interface_name1,
nfs_interface=FakeData.interface_name2):
return (
"""id = %(vdmid)s
name = %(name)s
acl = 0
type = vdm
server = server_2
rootfs = root_fs_vdm_vdm-fakeid
I18N mode = UNICODE
mountedfs =
member_of =
status :
defined = enabled
actual = loaded, active
Interfaces to services mapping:
interface=%(nfs_if_name)s :nfs
interface=%(cifs_if_name)s :cifs""" %
{'vdmid': self.vdm_id,
'name': self.vdm_name,
'nfs_if_name': nfs_interface,
'cifs_if_name': cifs_interface}
)
class PoolTestData(StorageObjectTestData):
def __init__(self):
super(PoolTestData, self).__init__()
@query
def req_get(self):
return (
'<StoragePoolQueryParams/>'
)
@response
def resp_get_succeed(self, name=None, id=None):
if not name:
name = self.pool_name
if not id:
id = self.pool_id
return (
'<QueryStatus maxSeverity="ok"/>'
'<StoragePool movers="1 2" memberVolumes="98" storageSystems="1" '
'name="fake" '
'description="Mapped Pool Pool_2 on APM00152904560" '
'mayContainSlicesDefault="true" diskType="Capacity" '
'size="511999" usedSize="20480" autoSize="511999" '
'virtualProvisioning="false" isHomogeneous="true" '
'dataServicePolicies="Thin=No,Compressed=No,Mirrored=No,Tiering '
'policy=Auto-Tier/Highest Available Tier" templatePool="59" '
'stripeCount="5" stripeSize="256" pool="9">'
'<SystemStoragePoolData dynamic="true" greedy="true" '
'potentialAdditionalSize="0" isBackendPool="true"/>'
'</StoragePool>'
'<StoragePool movers="1 2" memberVolumes="98" storageSystems="1" '
'name="%(name)s" '
'description="Mapped Pool Pool_2 on APM00152904560" '
'mayContainSlicesDefault="true" diskType="Capacity" '
'size="411999" usedSize="%(pool_used_size)s" '
'autoSize="%(pool_total_size)s" virtualProvisioning="false" '
'isHomogeneous="true" '
'dataServicePolicies="Thin=No,Compressed=No,Mirrored=No,Tiering '
'policy=Auto-Tier/Highest Available Tier" templatePool="59" '
'stripeCount="5" stripeSize="256" pool="%(id)s">'
'<SystemStoragePoolData dynamic="true" greedy="true" '
'potentialAdditionalSize="0" isBackendPool="true"/>'
'</StoragePool>' %
{'name': name,
'id': id,
'pool_used_size': self.pool_used_size,
'pool_total_size': self.pool_total_size}
)
class MoverTestData(StorageObjectTestData):
def __init__(self):
super(MoverTestData, self).__init__()
@query
def req_get_ref(self):
return (
'<MoverQueryParams>'
'<AspectSelection movers="true"/>'
'</MoverQueryParams>'
)
@response
def resp_get_ref_succeed(self, name=None):
if not name:
name = self.mover_name
return (
'<QueryStatus maxSeverity="info">'
'<Problem messageCode="18522112101" facility="Generic" '
'component="API" message="The query may be incomplete or '
'requested object not found." severity="warning">'
'<Description>The query may be incomplete because some of the '
'Celerra components are unavailable or do not exist. Another '
'reason may be application error.</Description>'
'<Action>If the entire Celerra is functioning correctly, '
'check your client application logic.</Action>'
'<Diagnostics>Standby Data Mover server_2.faulted.server_3 is '
'out of service.</Diagnostics>'
'</Problem>'
'</QueryStatus>'
'<Mover name="%(name)s" host="1" role="primary" standbys="2" '
'i18NMode="UNICODE" failoverPolicy="auto" '
'ntpServers="192.168.1.82" mover="%(id)s"/>'
'<Mover name="server_3" host="2" role="standby" standbyFors="1" '
'i18NMode="ASCII" failoverPolicy="none" mover="2"/>' %
{'name': name, 'id': self.mover_id}
)
@query
def req_get(self):
return (
'<MoverQueryParams mover="%(id)s">'
'<AspectSelection moverInterfaces="true" moverStatuses="true" '
'movers="true" moverNisDomains="true" moverNetworkDevices="true" '
'moverDnsDomains="true" moverRoutes="true" '
'moverDeduplicationSettings="true"/>'
'</MoverQueryParams>' %
{'id': self.mover_id}
)
@response
def resp_get_succeed(self, name=None):
if not name:
name = self.mover_name
return (
'<QueryStatus maxSeverity="ok"/><Mover name="%(name)s" '
'host="1" role="primary" i18NMode="UNICODE" failoverPolicy="none"'
' ntpServers="192.168.1.82" mover="%(id)s"/>'
'<MoverStatus version="T8.1.3.34944" csTime="1406795150" '
'clock="140681" timezone="GMT-5" uptime="85096" '
'mover="%(id)s"><Status maxSeverity="ok"/>'
'</MoverStatus>'
'<MoverDnsDomain servers="192.168.1.82" protocol="udp" '
'mover="%(id)s" name="win2012.openstack"/>'
'<MoverInterface name="%(long_interface_name)s" device="mge0" '
'ipVersion="IPv4" netMask="255.255.255.0" '
'broadcastAddr="128.221.252.255" '
'macAddr="0:60:16:53:cc:87" mtu="1500" up="true" vlanid="0" '
'mover="%(id)s" ipAddress="128.221.252.1"/>'
'<MoverInterface name="%(interface_name1)s" device="cge-2-0" '
'ipVersion="IPv4" netMask="255.255.255.0" '
'broadcastAddr="128.221.252.255" macAddr="0:60:16:53:cc:87" '
'mtu="1500" up="true" vlanid="0" mover="%(id)s" '
'ipAddress="128.221.252.2"/>'
'<MoverInterface name="%(interface_name2)s" device="cge-2-1" '
'ipVersion="IPv4" netMask="255.255.255.0" '
'broadcastAddr="128.221.252.255" macAddr="0:60:16:53:cc:87" '
'mtu="1500" up="true" vlanid="0" mover="%(id)s" '
'ipAddress="128.221.252.3"/>'
'<MoverRoute destination="0.0.0.0" interface="192.168.1.178" '
'ipVersion="IPv4" netMask="0.0.0.0" '
'gateway="192.168.1.217" mover="%(id)s"/>'
'<LogicalNetworkDevice speed="auto" interfaces="192.168.1.136" '
'type="physical-ethernet" mover="%(id)s" name="cge-2-0"/>'
% {'id': self.mover_id,
'name': name,
'long_interface_name': self.long_interface_name[:31],
'interface_name1': self.interface_name1,
'interface_name2': self.interface_name2}
)
@start_task
def req_create_interface(self,
if_name=FakeData.interface_name1,
ip=FakeData.network_allocations_ip1):
return (
'<NewMoverInterface name="%(if_name)s" vlanid="%(vlan)s" '
'netMask="%(net_mask)s" device="%(device_name)s" '
'mover="%(mover_id)s" ipAddress="%(ip)s"/>'
% {'if_name': if_name,
'vlan': self.vlan_id,
'ip': ip,
'mover_id': self.mover_id,
'device_name': self.device_name,
'net_mask': self.net_mask}
)
@start_task
def req_create_interface_with_ipv6(self,
if_name=FakeData.interface_name3,
ip=FakeData.network_allocations_ip3):
return (
'<NewMoverInterface name="%(if_name)s" vlanid="%(vlan)s" '
'ipVersion="IPv6" netMask="%(net_mask)s" '
'device="%(device_name)s" '
'mover="%(mover_id)s" ipAddress="%(ip)s"/>'
% {'if_name': if_name,
'vlan': self.vlan_id,
'ip': ip,
'mover_id': self.mover_id,
'device_name': self.device_name,
'net_mask': self.net_mask_v6}
)
@response
def resp_create_interface_but_name_already_exist(self):
return (
'<Status maxSeverity="error">'
'<Problem messageCode="13421840550" component="CS_CORE" '
'message="%(interface_name)s : an entry with this name already '
'exists" severity="error">'
'<Description>Duplicate name specified</Description>'
'<Action>Specify a unqiue name</Action>'
'</Problem>'
'</Status>' % {'interface_name': self.interface_name1}
)
@response
def resp_create_interface_but_ip_already_exist(self):
return (
'<Status maxSeverity="error">'
'<Problem messageCode="13691781136" component="CS_CORE" '
'message="Interface %(ip)s already exists." severity="error">'
'<Description></Description><Action></Action>'
'</Problem>'
'</Status>' % {'ip': self.ip_address1}
)
@response
def resp_create_interface_with_conflicted_vlan_id(self):
return (
'<Status maxSeverity="error">'
'<Problem messageCode="13421850371" component="CS_CORE" '
'message="160: Invalid VLAN change. Other interfaces on this '
'subnet are in a different VLAN." severity="error">'
'<Description>The operation cannot complete because other '
'interfaces on the same subnet are in a different VLAN. '
'The Data Mover requires all interfaces in the same subnet '
'to be in the same VLAN.</Description>'
'<Action>Specify a VLAN to match other interfaces in the same '
'subnet. To move multiple interfaces to a different VLAN, '
'first set the VLAN id on each interface to 0, '
'and then set their VLAN id\'s to the new VLAN number.</Action>'
'</Problem>'
'</Status>'
)
@start_task
def req_delete_interface(self, ip=FakeData.network_allocations_ip1):
return (
'<DeleteMoverInterface mover="%(mover_id)s" '
'ipAddress="%(ip)s"/>' %
{'ip': ip,
'mover_id': self.mover_id, }
)
@response
def resp_delete_interface_but_nonexistent(self):
return (
'<Status maxSeverity="error">'
'<Problem messageCode="13691781134" component="APL" '
'message="Device 192.168.237.100 does not exist." '
'severity="error">'
'<Description></Description>'
'<Action></Action>'
'</Problem>'
'</Status>'
)
def cmd_get_interconnect_id(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/nas_cel',
'-interconnect', '-l',
]
def output_get_interconnect_id(self):
return (
'id name source_server destination_system destination_server\n'
'%(id)s loopback %(src_server)s nas149 %(dest_server)s\n' %
{'id': self.interconnect_id,
'src_server': self.mover_name,
'dest_server': self.mover_name}
)
def cmd_get_physical_devices(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_sysconfig',
self.mover_name, '-pci',
]
def output_get_physical_devices(self):
return (
'server_2 : PCI DEVICES:\n'
'On Board:\n'
' PMC QE8 Fibre Channel Controller\n'
' 0: fcp-0-0 IRQ: 20 addr: 5006016047a00245\n'
' 0: fcp-0-1 IRQ: 21 addr: 5006016147a00245\n'
' 0: fcp-0-2 IRQ: 22 addr: 5006016247a00245\n'
' 0: fcp-0-3 IRQ: 23 addr: 5006016347a00245\n'
' Broadcom Gigabit Ethernet Controller\n'
' 0: cge-1-0 IRQ: 24\n'
' speed=auto duplex=auto txflowctl=disable rxflowctl=disable\n'
' Link: Up\n'
' 0: cge-1-1 IRQ: 25\n'
' speed=auto duplex=auto txflowctl=disable rxflowctl=disable\n'
' Link: Down\n'
' 0: cge-1-2 IRQ: 26\n'
' speed=auto duplex=auto txflowctl=disable rxflowctl=disable\n'
' Link: Down\n'
' 0: cge-1-3 IRQ: 27\n'
' speed=auto duplex=auto txflowctl=disable rxflowctl=disable\n'
' Link: Up\n'
'Slot: 4\n'
' PLX PCI-Express Switch Controller\n'
' 1: PLX PEX8648 IRQ: 10\n'
)
class DNSDomainTestData(StorageObjectTestData):
def __init__(self):
super(DNSDomainTestData, self).__init__()
@start_task
def req_create(self, ip_addr=None):
if ip_addr is None:
ip_addr = self.dns_ip_address
return (
'<NewMoverDnsDomain mover="%(mover_id)s" protocol="udp" '
'name="%(domain_name)s" servers="%(server_ips)s"/>' %
{'mover_id': self.mover_id,
'domain_name': self.domain_name,
'server_ips': ip_addr}
)
@start_task
def req_delete(self):
return (
'<DeleteMoverDnsDomain mover="%(mover_id)s" '
'name="%(domain_name)s"/>' %
{'mover_id': self.mover_id,
'domain_name': self.domain_name}
)
class CIFSServerTestData(StorageObjectTestData):
def __init__(self):
super(CIFSServerTestData, self).__init__()
@start_task
def req_create(self, mover_id, is_vdm=True, ip_addr=None):
if ip_addr is None:
ip_addr = self.ip_address1
return (
'<NewW2KCifsServer interfaces="%(ip)s" compName="%(comp_name)s" '
'name="%(name)s" domain="%(domain)s">'
'<MoverOrVdm mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s"/>'
'<Aliases><li>%(alias)s</li></Aliases>'
'<JoinDomain userName="%(domain_user)s" '
'password="%(domain_password)s"/>'
'</NewW2KCifsServer>'
% {'ip': ip_addr,
'comp_name': self.cifs_server_name,
'name': self.cifs_server_name[-14:],
'mover_id': mover_id,
'alias': self.cifs_server_name[-12:],
'domain_user': self.domain_user,
'domain_password': self.domain_password,
'domain': self.domain_name,
'is_vdm': 'true' if is_vdm else 'false'}
)
@query
def req_get(self, mover_id, is_vdm=True):
return (
'<CifsServerQueryParams>'
'<MoverOrVdm mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s"/>'
'</CifsServerQueryParams>' %
{'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false'}
)
@response
def resp_get_succeed(self, mover_id, is_vdm, join_domain,
cifs_server_name=None,
ip_addr=None):
if cifs_server_name is None:
cifs_server_name = self.cifs_server_name
if ip_addr is None:
ip_addr = self.ip_address1
return (
'<QueryStatus maxSeverity="ok"/>'
'<CifsServer interfaces="%(ip)s" type="W2K" '
'localUsers="false" name="%(cifsserver)s" '
'mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s"><Aliases>'
'<li>%(alias)s</li></Aliases><W2KServerData domain='
'"%(domain)s" compName="%(comp_name)s" '
'domainJoined="%(join_domain)s"/></CifsServer>'
% {'mover_id': mover_id,
'cifsserver': self.cifs_server_name[-14:],
'ip': ip_addr,
'is_vdm': 'true' if is_vdm else 'false',
'alias': self.cifs_server_name[-12:],
'domain': self.domain_name,
'join_domain': 'true' if join_domain else 'false',
'comp_name': cifs_server_name}
)
@response
def resp_get_without_interface(self, mover_id, is_vdm, join_domain):
return (
'<QueryStatus maxSeverity="ok"/>'
'<CifsServer interfaces="" type="W2K" localUsers="false" '
'name="%(cifsserver)s" mover="%(mover_id)s" '
'moverIdIsVdm="%(is_vdm)s">'
'<Aliases><li>%(alias)s</li></Aliases>'
'<W2KServerData domain="%(domain)s" compName="%(comp_name)s" '
'domainJoined="%(join_domain)s"/></CifsServer>'
% {'mover_id': mover_id,
'cifsserver': self.cifs_server_name[-14:],
'is_vdm': 'true' if is_vdm else 'false',
'alias': self.cifs_server_name[-12:],
'domain': self.domain_name,
'join_domain': 'true' if join_domain else 'false',
'comp_name': self.cifs_server_name}
)
@start_task
def req_modify(self, mover_id, is_vdm=True, join_domain=False):
return (
'<ModifyW2KCifsServer mover="%(mover_id)s" '
'moverIdIsVdm="%(is_vdm)s" name="%(cifsserver)s">'
'<DomainSetting userName="%(username)s" password="%(pw)s" '
'joinDomain="%(join_domain)s"/>'
'</ModifyW2KCifsServer>'
% {'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false',
'join_domain': 'true' if join_domain else 'false',
'cifsserver': self.cifs_server_name[-14:],
'username': self.domain_user,
'pw': self.domain_password}
)
@response
def resp_modify_but_already_join_domain(self):
return (
'<Status maxSeverity="error"> '
'<Problem messageCode="13157007726" component="DART" '
'message="Fake message." severity="error">'
'<Description>Fake description</Description>'
'<Action>Fake action.</Action>'
'</Problem>'
'</Status> '
)
@response
def resp_modify_but_unjoin_domain(self):
return (
'<Status maxSeverity="error"> '
'<Problem messageCode="13157007723" component="DART" '
'message="Fake message." severity="error">'
'<Description>Fake description</Description>'
'<Action>Fake action.</Action>'
'</Problem>'
'</Status> '
)
@start_task
def req_delete(self, mover_id, is_vdm=True):
return (
'<DeleteCifsServer mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s" '
'name="%(cifsserver)s"/>'
% {'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false',
'cifsserver': self.cifs_server_name[-14:]}
)
class CIFSShareTestData(StorageObjectTestData):
def __init__(self):
super(CIFSShareTestData, self).__init__()
@start_task
def req_create(self, mover_id, is_vdm=True):
return (
'<NewCifsShare path="%(path)s" name="%(share_name)s">'
'<MoverOrVdm mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s"/>'
'<CifsServers><li>%(cifsserver)s</li></CifsServers>'
'</NewCifsShare>' %
{'path': '/' + self.share_name,
'share_name': self.share_name,
'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false',
'cifsserver': self.cifs_server_name[-14:]}
)
@start_task
def req_delete(self, mover_id, is_vdm=True):
return (
'<DeleteCifsShare mover="%(mover_id)s" moverIdIsVdm="%(is_vdm)s" '
'name="%(share_name)s">'
'<CifsServers><li>%(cifsserver)s</li></CifsServers>'
'</DeleteCifsShare>' %
{'share_name': self.share_name,
'mover_id': mover_id,
'is_vdm': 'true' if is_vdm else 'false',
'cifsserver': self.cifs_server_name[-12:]}
)
@query
def req_get(self):
return '<CifsShareQueryParams name="%s"/>' % self.share_name
@response
def resp_get_succeed(self, mover_id, is_vdm=True):
return (
'<QueryStatus maxSeverity="ok"/>'
'<CifsShare path="%(path)s" fileSystem="%(fsid)s" name="%(name)s" '
'mover="%(moverid)s" moverIdIsVdm="%(is_vdm)s">'
'<CifsServers><li>%(alias)s</li>'
'</CifsServers>'
'</CifsShare>' %
{'path': self.path,
'fsid': self.filesystem_id,
'name': self.share_name,
'moverid': mover_id,
'is_vdm': 'true' if is_vdm else 'false',
'alias': self.cifs_server_name[-12:]}
)
def cmd_disable_access(self):
cmd_str = 'sharesd %s set noaccess' % self.share_name
return [
'env', 'NAS_DB=/nas',
'/nas/bin/.server_config', self.vdm_name,
'-v', '%s' % cmd_str,
]
def cmd_change_access(self, access_level=const.ACCESS_LEVEL_RW,
action='grant', user=None):
if user is None:
user = self.domain_user
account = user + '@' + self.domain_name
if access_level == const.ACCESS_LEVEL_RW:
str_access = 'fullcontrol'
else:
str_access = 'read'
allow_str = (
'sharesd %(share_name)s %(action)s %(account)s=%(access)s'
% {'share_name': self.share_name,
'action': action,
'account': account,
'access': str_access}
)
return [
'env', 'NAS_DB=/nas',
'/nas/bin/.server_config', self.vdm_name,
'-v', '%s' % allow_str,
]
def cmd_get_access(self):
get_str = 'sharesd %s dump' % self.share_name
return [
'env', 'NAS_DB=/nas',
'/nas/bin/.server_config', self.vdm_name,
'-v', '%s' % get_str,
]
def output_allow_access(self):
return (
"Command succeeded: :3 sharesd %(share)s grant "
"%(user)s@%(domain)s=fullcontrol"
% {'share': self.share_name,
'user': self.domain_user,
'domain': self.domain_name}
)
def output_allow_access_but_duplicate_ace(self):
return (
'%(vdm_name)s : commands processed: 1'
'output is complete'
'1443422844: SMB: 6: ACE for %(domain)s\\%(user)s '
'unchanged'
'1443422844: ADMIN: 3: '
'Command failed: :23 '
'sharesd %(share)s grant %(user)s@%(domain)s=read'
'Error 4020: %(vdm_name)s : failed to complete command"'
% {'share': self.share_name,
'user': self.domain_user,
'domain': self.domain_name,
'vdm_name': self.vdm_name}
)
def output_deny_access_but_no_ace(self):
return (
'%(vdm_name)s : commands processed: 1'
'output is complete'
'1443515516: SMB: 6: No ACE found for %(domain)s\\%(user)s '
'1443515516: ADMIN: 3: '
'Command failed: :26 '
'sharesd %(share)s revoke %(user)s@%(domain)s=read'
'Error 4020: %(vdm_name)s : failed to complete command"'
% {'share': self.share_name,
'user': self.domain_user,
'domain': self.domain_name,
'vdm_name': self.vdm_name}
)
def output_deny_access_but_no_user_found(self):
return (
'%(vdm_name)s : commands processed: 1'
'output is complete'
'1443520322: SMB: 6: Cannot get mapping for %(domain)s\\%(user)s '
'1443520322: ADMIN: 3: '
'Command failed: :26 '
'sharesd %(share)s revoke %(user)s@%(domain)s=read'
'Error 4020: %(vdm_name)s : failed to complete command"'
% {'share': self.share_name,
'user': self.domain_user,
'domain': self.domain_name,
'vdm_name': self.vdm_name}
)
class NFSShareTestData(StorageObjectTestData):
def __init__(self):
super(NFSShareTestData, self).__init__()
def cmd_create(self):
default_access = 'access=-0.0.0.0/0.0.0.0'
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_export', self.vdm_name,
'-option', default_access,
self.path,
]
def output_create(self):
return "%s : done" % self.vdm_name
def cmd_get(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_export', self.vdm_name,
'-P', 'nfs',
'-list', self.path,
]
def output_get_succeed(self, rw_hosts, ro_hosts):
rw_hosts = [utils.convert_ipv6_format_if_needed(ip_addr) for ip_addr in
rw_hosts]
ro_hosts = [utils.convert_ipv6_format_if_needed(ip_addr) for ip_addr in
ro_hosts]
if rw_hosts and ro_hosts:
return (
'%(mover_name)s :\nexport "%(path)s" '
'access=%(host)s:-0.0.0.0/0.0.0.0 root=%(host)s '
'rw=%(rw_host)s ro=%(ro_host)s\n'
% {'mover_name': self.vdm_name,
'path': self.path,
'host': ":".join(rw_hosts + ro_hosts),
'rw_host': ":".join(rw_hosts),
'ro_host': ":".join(ro_hosts)}
)
elif rw_hosts:
return (
'%(mover_name)s :\nexport "%(path)s" '
'access=%(host)s:-0.0.0.0/0.0.0.0 root=%(host)s '
'rw=%(rw_host)s\n'
% {'mover_name': self.vdm_name,
'host': ":".join(rw_hosts),
'path': self.path,
'rw_host': ":".join(rw_hosts)}
)
elif ro_hosts:
return (
'%(mover_name)s :\nexport "%(path)s" '
'access=%(host)s:-0.0.0.0/0.0.0.0 root=%(host)s '
'ro=%(ro_host)s\n'
% {'mover_name': self.vdm_name,
'host': ":".join(ro_hosts),
'path': self.path,
'ro_host': ":".join(ro_hosts)}
)
else:
return (
'%(mover_name)s :\nexport "%(path)s" '
'access=-0.0.0.0/0.0.0.0\n'
% {'mover_name': self.vdm_name,
'path': self.path}
)
def output_get_but_not_found(self):
return (
'%(mover_name)s : \nError 2: %(mover_name)s : '
'No such file or directory \n' % {'mover_name': self.vdm_name}
)
def cmd_delete(self):
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_export', self.vdm_name,
'-unexport',
'-perm',
self.path,
]
def output_delete_succeed(self):
return "%s : done" % self.vdm_name
def output_delete_but_locked(self):
return ("Error 2201: %s : unable to acquire lock(s), try later"
% self.vdm_name)
def cmd_set_access(self, rw_hosts, ro_hosts):
rw_hosts = [utils.convert_ipv6_format_if_needed(ip_addr) for ip_addr in
rw_hosts]
ro_hosts = [utils.convert_ipv6_format_if_needed(ip_addr) for ip_addr in
ro_hosts]
access_str = ("access=%(access_hosts)s:-0.0.0.0/0.0.0.0,"
"root=%(root_hosts)s,rw=%(rw_hosts)s,ro=%(ro_hosts)s" %
{'rw_hosts': ":".join(rw_hosts),
'ro_hosts': ":".join(ro_hosts),
'root_hosts': ":".join(rw_hosts + ro_hosts),
'access_hosts': ":".join(rw_hosts + ro_hosts)})
return [
'env', 'NAS_DB=/nas', '/nas/bin/server_export', self.vdm_name,
'-ignore',
'-option', access_str,
self.path,
]
def output_set_access_success(self):
return "%s : done" % self.vdm_name
class FakeEMCShareDriver(object):
def __init__(self, enas_type='vnx'):
self.configuration = conf.Configuration(None)
self.configuration.append_config_values = mock.Mock(return_value=0)
self.configuration.emc_share_backend = FakeData.emc_share_backend
self.configuration.vnx_server_container = FakeData.mover_name
if enas_type == 'powermax':
self.configuration.emc_share_backend = (
FakeData.powermax_share_backend)
self.configuration.vmax_server_container = FakeData.mover_name
self.configuration.emc_nas_server = FakeData.emc_nas_server
self.configuration.emc_nas_login = FakeData.emc_nas_login
self.configuration.emc_nas_password = FakeData.emc_nas_password
self.configuration.share_backend_name = FakeData.share_backend_name
CIFS_SHARE = fake_share.fake_share(
id=FakeData.share_id,
name=FakeData.share_name,
size=FakeData.share_size,
share_network_id=FakeData.share_network_id,
share_server_id=FakeData.share_server_id,
host=FakeData.host,
share_proto='CIFS')
NFS_SHARE = fake_share.fake_share(
id=FakeData.share_id,
name=FakeData.share_name,
size=FakeData.share_size,
share_network_id=FakeData.share_network_id,
share_server_id=FakeData.share_server_id,
host=FakeData.host,
share_proto='NFS')
CIFS_RW_ACCESS = fake_share.fake_access(
access_type='user',
access_to=FakeData.domain_user,
access_level='rw')
CIFS_RO_ACCESS = fake_share.fake_access(
access_type='user',
access_to=FakeData.domain_user,
access_level='ro')
NFS_RW_ACCESS = fake_share.fake_access(
access_type='ip',
access_to=FakeData.nfs_host_ip,
access_level='rw')
NFS_RW_ACCESS_IPV6 = fake_share.fake_access(
access_type='ip',
access_to=FakeData.nfs_host_ipv6,
access_level='rw')
NFS_RO_ACCESS = fake_share.fake_access(
access_type='ip',
access_to=FakeData.nfs_host_ip,
access_level='ro')
NFS_RO_ACCESS_IPV6 = fake_share.fake_access(
access_type='ip',
access_to=FakeData.nfs_host_ipv6,
access_level='ro')
SHARE_SERVER = {
'id': FakeData.share_server_id,
'share_network': {
'name': 'fake_share_network',
'id': FakeData.share_network_id
},
'share_network_id': FakeData.share_network_id,
'backend_details': {
'share_server_name': FakeData.vdm_name,
'cifs_if': FakeData.network_allocations_ip1,
'nfs_if': FakeData.network_allocations_ip2,
}
}
SHARE_SERVER_IPV6 = {
'id': FakeData.share_server_id,
'share_network': {
'name': 'fake_share_network',
'id': FakeData.share_network_id
},
'share_network_id': FakeData.share_network_id,
'backend_details': {
'share_server_name': FakeData.vdm_name,
'cifs_if': FakeData.network_allocations_ip3,
'nfs_if': FakeData.network_allocations_ip4,
}
}
SERVER_DETAIL = {
'share_server_name': FakeData.vdm_name,
'cifs_if': FakeData.network_allocations_ip1,
'nfs_if': FakeData.network_allocations_ip2,
}
SERVER_DETAIL_IPV6 = {
'share_server_name': FakeData.vdm_name,
'cifs_if': FakeData.network_allocations_ip3,
'nfs_if': FakeData.network_allocations_ip4,
}
SECURITY_SERVICE = [
{
'type': 'active_directory',
'domain': FakeData.domain_name,
'dns_ip': FakeData.dns_ip_address,
'user': FakeData.domain_user,
'password': FakeData.domain_password
},
]
SECURITY_SERVICE_IPV6 = [
{
'type': 'active_directory',
'domain': FakeData.domain_name,
'dns_ip': FakeData.dns_ipv6_address,
'user': FakeData.domain_user,
'password': FakeData.domain_password
},
]
NETWORK_INFO = {
'server_id': FakeData.share_server_id,
'cidr': FakeData.cidr,
'security_services': [
{'type': 'active_directory',
'domain': FakeData.domain_name,
'dns_ip': FakeData.dns_ip_address,
'user': FakeData.domain_user,
'password': FakeData.domain_password},
],
'segmentation_id': FakeData.segmentation_id,
'network_type': 'vlan',
'network_allocations': [
{'id': FakeData.network_allocations_id1,
'ip_address': FakeData.network_allocations_ip1,
'ip_version': FakeData.network_allocations_ip_version1},
{'id': FakeData.network_allocations_id2,
'ip_address': FakeData.network_allocations_ip2,
'ip_version': FakeData.network_allocations_ip_version2}
]
}
NETWORK_INFO_IPV6 = {
'server_id': FakeData.share_server_id,
'cidr': FakeData.cidr_v6,
'security_services': [
{'type': 'active_directory',
'domain': FakeData.domain_name,
'dns_ip': FakeData.dns_ipv6_address,
'user': FakeData.domain_user,
'password': FakeData.domain_password},
],
'segmentation_id': FakeData.segmentation_id,
'network_type': 'vlan',
'network_allocations': [
{'id': FakeData.network_allocations_id3,
'ip_address': FakeData.network_allocations_ip3,
'ip_version': FakeData.network_allocations_ip_version3},
{'id': FakeData.network_allocations_id4,
'ip_address': FakeData.network_allocations_ip4,
'ip_version': FakeData.network_allocations_ip_version4}
]
}
STATS = dict(
share_backend_name='VNX',
vendor_name='EMC',
storage_protocol='NFS_CIFS',
driver_version='2.0.0,')
STATS_VMAX = dict(
share_backend_name='VMAX',
vendor_name='EMC',
storage_protocol='NFS_CIFS',
driver_version='2.0.0,')