From e4b02708a7b24036200654d7dac8f5b4b91247cb Mon Sep 17 00:00:00 2001 From: yuanyu Date: Tue, 11 Jan 2022 10:39:09 +0800 Subject: [PATCH] 3par add host mapping view --- .../drivers/hpe/hpe_3par/component_handler.py | 241 ++++ delfin/drivers/hpe/hpe_3par/consts.py | 36 + delfin/drivers/hpe/hpe_3par/hpe_3parstor.py | 18 + delfin/drivers/hpe/hpe_3par/rest_handler.py | 7 + delfin/drivers/hpe/hpe_3par/ssh_handler.py | 102 ++ .../drivers/hpe/hpe_3par/test_hpe_3parstor.py | 1183 +++++++++++++++++ 6 files changed, 1587 insertions(+) diff --git a/delfin/drivers/hpe/hpe_3par/component_handler.py b/delfin/drivers/hpe/hpe_3par/component_handler.py index 9c7e86ea1..643e4e812 100644 --- a/delfin/drivers/hpe/hpe_3par/component_handler.py +++ b/delfin/drivers/hpe/hpe_3par/component_handler.py @@ -417,3 +417,244 @@ def parse_speed(self, speed_value): err_msg = "analyse speed error: %s" % (six.text_type(err)) LOG.error(err_msg) return speed + + def list_storage_host_initiators(self, storage_id): + initiators = self.ssh_handler.list_storage_host_initiators() + initiators_list = [] + for initiator in (initiators or []): + if initiator: + wwn = initiator.get('wwn/iscsi_name', '').replace('-', '') + if wwn: + port = initiator.get('port', '').replace('-', '') + ip_addr = initiator.get('ip_addr') + type = constants.PortType.FC + if ip_addr and ip_addr != 'n/a': + type = constants.PortType.ISCSI + name = wwn + if port: + name = '%s_%s' % (wwn, port) + initiator_model = { + "name": name, + "storage_id": storage_id, + "native_storage_host_initiator_id": name, + "wwn": wwn, + "type": type, + "status": constants.InitiatorStatus.ONLINE, + "native_storage_host_id": initiator.get('id', + '').replace( + '-', ''), + } + initiators_list.append(initiator_model) + return initiators_list + + def list_storage_hosts(self, storage_id): + host_datas = self.rest_handler.list_storage_host() + host_list = [] + if host_datas: + hosts = host_datas.get('members') + for host in (hosts or []): + if host and host.get('name'): + descriptors = host.get('descriptors') + comment = None + os = '' + ip_addr = None + if descriptors: + comment = descriptors.get('comment') + os = descriptors.get('os', '') + ip_addr = descriptors.get('IPAddr') + host_model = { + "name": host.get('name'), + "description": comment, + "storage_id": storage_id, + "native_storage_host_id": host.get('id'), + "os_type": consts.HOST_OS_MAP.get(os, 'Unknown'), + "status": constants.HostStatus.NORMAL, + "ip_address": ip_addr + } + host_list.append(host_model) + return host_list + + def list_storage_host_groups(self, storage_id): + host_groups = self.ssh_handler.list_storage_host_groups() + host_group_list = [] + result = {} + if host_groups: + hosts_map = self.ssh_handler.get_resources_ids( + self.ssh_handler.HPE3PAR_COMMAND_SHOWHOST_D, + consts.HOST_OR_VV_PATTERN) + for host_group in host_groups: + host_members = host_group.get('members') + host_ids = [] + if hosts_map: + for host_name in (host_members or []): + host_id = hosts_map.get(host_name) + if host_id: + host_ids.append(host_id) + host_group_model = { + "name": host_group.get('name'), + "description": host_group.get('comment'), + "storage_id": storage_id, + "native_storage_host_group_id": host_group.get('id'), + "storage_hosts": ','.join(host_ids) + } + host_group_list.append(host_group_model) + storage_host_grp_relation_list = [] + for storage_host_group in host_group_list: + storage_hosts = storage_host_group.pop('storage_hosts', None) + if not storage_hosts: + continue + storage_hosts = storage_hosts.split(',') + + for storage_host in storage_hosts: + storage_host_group_relation = { + 'storage_id': storage_id, + 'native_storage_host_group_id': storage_host_group.get( + 'native_storage_host_group_id'), + 'native_storage_host_id': storage_host + } + storage_host_grp_relation_list \ + .append(storage_host_group_relation) + + result = { + 'storage_host_groups': host_group_list, + 'storage_host_grp_host_rels': storage_host_grp_relation_list + } + return result + + def list_port_groups(self, storage_id): + views = self.ssh_handler.list_masking_views() + port_groups_list = [] + port_list = [] + for view in (views or []): + port = view.get('port', '').replace('-', '') + if port: + if port in port_list: + continue + port_list.append(port) + port_group_model = { + "name": "port_group_" + port, + "description": "port_group_" + port, + "storage_id": storage_id, + "native_port_group_id": "port_group_" + port, + "ports": port + } + port_groups_list.append(port_group_model) + port_group_relation_list = [] + for port_group in port_groups_list: + ports = port_group.pop('ports', None) + if not ports: + continue + ports = ports.split(',') + + for port in ports: + port_group_relation = { + 'storage_id': storage_id, + 'native_port_group_id': + port_group.get('native_port_group_id'), + 'native_port_id': port + } + port_group_relation_list.append(port_group_relation) + result = { + 'port_groups': port_groups_list, + 'port_grp_port_rels': port_group_relation_list + } + return result + + def list_volume_groups(self, storage_id): + volume_groups = self.ssh_handler.list_volume_groups() + volume_group_list = [] + result = {} + if volume_groups: + volumes_map = self.ssh_handler.get_resources_ids( + self.ssh_handler.HPE3PAR_COMMAND_SHOWVV, + consts.HOST_OR_VV_PATTERN) + for volume_group in volume_groups: + volume_members = volume_group.get('members') + volume_ids = [] + if volumes_map: + for volume_name in (volume_members or []): + volume_id = volumes_map.get(volume_name) + if volume_id: + volume_ids.append(volume_id) + volume_group_model = { + "name": volume_group.get('name'), + "description": volume_group.get('comment'), + "storage_id": storage_id, + "native_volume_group_id": volume_group.get('id'), + "volumes": ','.join(volume_ids) + } + volume_group_list.append(volume_group_model) + volume_group_relation_list = [] + for volume_group in volume_group_list: + volumes = volume_group.pop('volumes', None) + if not volumes: + continue + volumes = volumes.split(',') + + for volume in volumes: + volume_group_relation = { + 'storage_id': storage_id, + 'native_volume_group_id': + volume_group.get('native_volume_group_id'), + 'native_volume_id': volume} + volume_group_relation_list.append(volume_group_relation) + + result = { + 'volume_groups': volume_group_list, + 'vol_grp_vol_rels': volume_group_relation_list + } + return result + + def list_masking_views(self, storage_id): + views = self.ssh_handler.list_masking_views() + views_list = [] + if views: + hosts_map = self.ssh_handler.get_resources_ids( + self.ssh_handler.HPE3PAR_COMMAND_SHOWHOST_D, + consts.HOST_OR_VV_PATTERN) + hosts_group_map = self.ssh_handler.get_resources_ids( + self.ssh_handler.HPE3PAR_COMMAND_SHOWHOSTSET_D, + consts.HOST_OR_VV_PATTERN) + volumes_map = self.ssh_handler.get_resources_ids( + self.ssh_handler.HPE3PAR_COMMAND_SHOWVV, + consts.HOST_OR_VV_PATTERN) + volumes_group_map = self.ssh_handler.get_resources_ids( + self.ssh_handler.HPE3PAR_COMMAND_SHOWVVSET_D, + consts.HOST_OR_VV_PATTERN) + for view in views: + vv_name = view.get('vvname') + host_name = view.get('hostname') + if vv_name and host_name: + port = view.get('port', '').replace('-', '') + id = view.get('lun') + wwn = view.get('host_wwn/iscsi_name', '').replace('-', '') + native_port_group_id = None + if port: + id = '%s_%s' % (view.get('lun'), port) + native_port_group_id = 'port_group_%s' % port + if wwn: + id = '%s_%s' % (id, wwn) + view_model = { + 'native_masking_view_id': id, + "name": view.get('lun'), + 'native_port_group_id': native_port_group_id, + "storage_id": storage_id + } + if 'set:' in vv_name: + vv_set_id = volumes_group_map.get( + vv_name.replace('set:', '')) + view_model['native_volume_group_id'] = vv_set_id + else: + vv_id = volumes_map.get(vv_name) + view_model['native_volume_id'] = vv_id + if 'set:' in host_name: + host_set_id = hosts_group_map.get( + host_name.replace('set:', '')) + view_model[ + 'native_storage_host_group_id'] = host_set_id + else: + host_id = hosts_map.get(host_name) + view_model['native_storage_host_id'] = host_id + + views_list.append(view_model) + return views_list diff --git a/delfin/drivers/hpe/hpe_3par/consts.py b/delfin/drivers/hpe/hpe_3par/consts.py index 57d61c8db..63167bb78 100644 --- a/delfin/drivers/hpe/hpe_3par/consts.py +++ b/delfin/drivers/hpe/hpe_3par/consts.py @@ -655,6 +655,11 @@ "ShareDir\\s+State" VFS_PATTERN = "^\\s*VFS\\s+FPG\\s+IPAddr\\s+State" IPV4_PATTERN = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$" + +HOST_OR_VV_SET_PATTERN = "^\\s*Id\\s+Name\\s+Members\\s+Comment" +HOST_OR_VV_PATTERN = "^\\s*Id\\s+Name\\s+" +VLUN_PATTERN = "^\\s*Lun\\s+VVName\\s+HostName" + CONTROLLER_STATUS_MAP = { 'OK': constants.ControllerStatus.NORMAL, 'NORMAL': constants.ControllerStatus.NORMAL, @@ -705,3 +710,34 @@ 1: "control", 2: "data" } +HOST_OS_MAP = { + 'AIX': constants.HostOSTypes.AIX, + 'Citrix Xen Server 5.x/6.x': constants.HostOSTypes.XEN_SERVER, + 'Citrix Xen Server 7.x': constants.HostOSTypes.XEN_SERVER, + 'HP-UX': constants.HostOSTypes.HP_UX, + 'HP-UX (11i v1,11i v2)': constants.HostOSTypes.HP_UX, + 'HP-UX (11i v3)': constants.HostOSTypes.HP_UX, + 'OpenVMS': constants.HostOSTypes.OPEN_VMS, + 'Oracle VM x86': constants.HostOSTypes.ORACLE_VM, + 'Solaris 11': constants.HostOSTypes.SOLARIS, + 'Solaris 9/10': constants.HostOSTypes.SOLARIS, + 'VMware (ESXi)': constants.HostOSTypes.VMWARE_ESX, + 'ESXI6.0': constants.HostOSTypes.VMWARE_ESX, + 'ESX 4.x/5.x': constants.HostOSTypes.VMWARE_ESX, + 'Windows 2003': constants.HostOSTypes.WINDOWS, + 'Windows 2008/2008 R2': constants.HostOSTypes.WINDOWS, + 'Windows 2012': constants.HostOSTypes.WINDOWS_SERVER_2012, + 'Windows 2012 / WS2012 R2': constants.HostOSTypes.WINDOWS_SERVER_2012, + 'Windows Server 2016': constants.HostOSTypes.WINDOWS, + 'Red Hat Enterprise Linux': constants.HostOSTypes.LINUX, + 'OE Linux UEK (5.x, 6.x)': constants.HostOSTypes.LINUX, + 'OE Linux UEK 7.x': constants.HostOSTypes.LINUX, + 'RHE Linux (5.x, 6.x)': constants.HostOSTypes.LINUX, + 'RHE Linux (Pre RHEL 5)': constants.HostOSTypes.LINUX, + 'RHE Linux 7.x': constants.HostOSTypes.LINUX, + 'SuSE (10.x, 11.x)': constants.HostOSTypes.LINUX, + 'SuSE': constants.HostOSTypes.LINUX, + 'SuSE 12.x': constants.HostOSTypes.LINUX, + 'SuSE Linux (Pre SLES 10)': constants.HostOSTypes.LINUX, + 'SuSE Virtualization': constants.HostOSTypes.LINUX +} diff --git a/delfin/drivers/hpe/hpe_3par/hpe_3parstor.py b/delfin/drivers/hpe/hpe_3par/hpe_3parstor.py index c655ccefb..911408fdd 100644 --- a/delfin/drivers/hpe/hpe_3par/hpe_3parstor.py +++ b/delfin/drivers/hpe/hpe_3par/hpe_3parstor.py @@ -104,3 +104,21 @@ def list_qtrees(self, context): def list_shares(self, context): pass + + def list_storage_host_initiators(self, context): + return self.comhandler.list_storage_host_initiators(self.storage_id) + + def list_storage_hosts(self, context): + return self.comhandler.list_storage_hosts(self.storage_id) + + def list_storage_host_groups(self, context): + return self.comhandler.list_storage_host_groups(self.storage_id) + + def list_port_groups(self, context): + return self.comhandler.list_port_groups(self.storage_id) + + def list_volume_groups(self, context): + return self.comhandler.list_volume_groups(self.storage_id) + + def list_masking_views(self, context): + return self.comhandler.list_masking_views(self.storage_id) diff --git a/delfin/drivers/hpe/hpe_3par/rest_handler.py b/delfin/drivers/hpe/hpe_3par/rest_handler.py index af135bfad..0fde1bf84 100644 --- a/delfin/drivers/hpe/hpe_3par/rest_handler.py +++ b/delfin/drivers/hpe/hpe_3par/rest_handler.py @@ -38,6 +38,8 @@ class RestHandler(object): REST_ALERTS_URL = '/api/v1/eventlog?query="category EQ 2"' + REST_HOSTS_URL = '/api/v1/hosts' + REST_AUTH_KEY = 'X-HP3PAR-WSAPI-SessionKey' session_lock = None @@ -196,3 +198,8 @@ def get_all_volumes(self): rejson = self.get_resinfo_call(RestHandler.REST_VOLUMES_URL, method='GET') return rejson + + def list_storage_host(self): + rejson = self.get_resinfo_call(RestHandler.REST_HOSTS_URL, + method='GET') + return rejson diff --git a/delfin/drivers/hpe/hpe_3par/ssh_handler.py b/delfin/drivers/hpe/hpe_3par/ssh_handler.py index f9155caac..7f6cbd84e 100644 --- a/delfin/drivers/hpe/hpe_3par/ssh_handler.py +++ b/delfin/drivers/hpe/hpe_3par/ssh_handler.py @@ -48,6 +48,11 @@ class SSHHandler(object): HPE3PAR_COMMAND_SHOWPORT_RCIP = 'showport -rcip' HPE3PAR_COMMAND_SHOWPORT_FCOE = 'showport -fcoe' HPE3PAR_COMMAND_SHOWPORT_FS = 'showport -fs' + HPE3PAR_COMMAND_SHOWHOSTSET_D = 'showhostset -d' + HPE3PAR_COMMAND_SHOWVVSET_D = 'showvvset -d' + HPE3PAR_COMMAND_SHOWHOST_D = 'showhost -d' + HPE3PAR_COMMAND_SHOWVV = 'showvv' + HPE3PAR_COMMAND_SHOWVLUN_T = 'showvlun -a' def __init__(self, **kwargs): self.kwargs = kwargs @@ -288,6 +293,23 @@ def parse_datas_to_list(self, resource_info, pattern_str, para_map=None): str_info, obj_list, titles) + elif para_map and para_map.get('command', '') \ + == 'parse_set_groups_table': + if '---------------------------------' in str_line: + break + obj_list = self.parse_set_groups_table(cols_size, + titles_size, + str_info, + obj_list) + elif para_map and para_map.get('command', '') \ + == 'parse_view_table': + if '---------------------------------' in str_line: + break + obj_list = self.parse_view_table(cols_size, + titles_size, + str_info, + obj_list, + titles) else: if cols_size == titles_size: obj_model = {} @@ -414,3 +436,83 @@ def exec_command(self, command): LOG.error("command %s failed: %s" % (command, re)) raise exception.StorageBackendException(re) return re + + def list_storage_host_groups(self): + para_map = { + 'command': 'parse_set_groups_table' + } + return self.get_resources_info( + SSHHandler.HPE3PAR_COMMAND_SHOWHOSTSET_D, + self.parse_datas_to_list, + pattern_str=consts.HOST_OR_VV_SET_PATTERN, + para_map=para_map) + + def list_volume_groups(self): + para_map = { + 'command': 'parse_set_groups_table' + } + return self.get_resources_info( + SSHHandler.HPE3PAR_COMMAND_SHOWVVSET_D, + self.parse_datas_to_list, + pattern_str=consts.HOST_OR_VV_SET_PATTERN, + para_map=para_map) + + def parse_set_groups_table(self, cols_size, titles_size, str_info, + obj_list): + if cols_size >= titles_size: + members = [] + value = str_info[2].replace('-', '') + if value: + members = [value] + obj_model = { + 'id': str_info[0], + 'name': str_info[1], + 'members': members, + 'comment': (" ".join(str_info[3:])).replace('-', ''), + } + obj_list.append(obj_model) + elif obj_list and cols_size == 1: + value = str_info[0].replace('-', '') + if value: + obj_model = obj_list[-1] + if obj_model and obj_model.get('members'): + obj_model.get('members').append(value) + return obj_list + + def parse_view_table(self, cols_size, titles_size, str_info, obj_list, + titles): + if cols_size >= titles_size: + obj_model = {} + for i in range(titles_size): + key = titles[i].lower().replace('-', '') + obj_model[key] = str_info[i] + if obj_model: + obj_list.append(obj_model) + return obj_list + + def get_resources_ids(self, command, pattern_str, para_map=None): + if not para_map: + para_map = { + 'key_position': 1, + 'value_position': 0 + } + return self.get_resources_info(command, + self.parse_datas_to_map, + pattern_str=pattern_str, + para_map=para_map, throw_excep=False) + + def list_storage_host_initiators(self): + return self.get_resources_info( + SSHHandler.HPE3PAR_COMMAND_SHOWHOST_D, + self.parse_datas_to_list, + pattern_str=consts.HOST_OR_VV_PATTERN) + + def list_masking_views(self): + para_map = { + 'command': 'parse_view_table' + } + return self.get_resources_info( + SSHHandler.HPE3PAR_COMMAND_SHOWVLUN_T, + self.parse_datas_to_list, + pattern_str=consts.VLUN_PATTERN, + para_map=para_map) diff --git a/delfin/tests/unit/drivers/hpe/hpe_3par/test_hpe_3parstor.py b/delfin/tests/unit/drivers/hpe/hpe_3par/test_hpe_3parstor.py index e70629adb..f24cd9d5f 100644 --- a/delfin/tests/unit/drivers/hpe/hpe_3par/test_hpe_3parstor.py +++ b/delfin/tests/unit/drivers/hpe/hpe_3par/test_hpe_3parstor.py @@ -146,6 +146,1095 @@ def __init__(self): 108 """ +HOST_GROUP_DATAS = """ + Id Name Members Comment +194 HostSet_VMware Host_ESXi6.5_125 -- +229 HostSet_Suse11_Oracle Host_Suse11_8.44.75.122 -- +257 HostGroup_ESX6.0 ESX6.0_8.44.75.145 -- + ESX6.0_8.44.75.146 +264 HostSet_Win2016_WSFC RH2288V5_Win2016_node2 -- + RH2288V5_Win2016_node1 +266 HostSet_Win2012_WSFC RH2285_Win2012_wsfc1 -- + Rh2285_Win2012_wsfc2 +268 HostSet_AIX Host_AIX_51.10.192.20 -- +270 HostSet_Suse11 Host_Suse11_8.44.75.123 -- +274 Suse11sp4_150 litng138.150 -- +----------------------------------------------------------- + 32 total 28 +""" +HOST_ID_DATAS = """ + Id Name Persona -WWN/iSCSI_Name- Port IP_addr + 175 Host_ESXi6.5_125 Generic 2408244427906812 --- n/a + 54 Doradov3_lm Generic 2418244427906812 --- n/a + 57 AIX_wenbin AIX-legacy 10000000C9E74BCC --- n/a + 65 SKY-ESXI60 Generic 2100001B321BE0FF --- n/a + 65 SKY-ESXI60 Generic 2101001B323BE0FF --- n/a + 67 zouming Generic 2012E4A8B6B0A1CC --- n/a + 67 zouming Generic 2002E4A8B6B0A1CC --- n/a + 68 powerpath Generic 21000024FF36D406 --- n/a + 68 powerpath Generic 21000024FF36D407 --- n/a + 69 power_v3 Generic 20809CE37435D845 --- n/a + 69 power_v3 Generic 20909CE37435D845 --- n/a + 89 vplex_meta_important Generic 5000144280292012 0:1:2 n/a + 89 vplex_meta_important Generic 5000144280292010 0:1:2 n/a + 89 vplex_meta_important Generic 5000144290292012 1:1:2 n/a + 89 vplex_meta_important Generic 500014429029E910 1:1:2 n/a + 89 vplex_meta_important Generic 500014429029E912 1:1:2 n/a + 89 vplex_meta_important Generic 500014428029E912 1:1:2 n/a + 89 vplex_meta_important Generic 500014428029E910 1:1:2 n/a + 89 vplex_meta_important Generic 5000144290292010 1:1:2 n/a + 89 vplex_meta_important Generic 5000144290292012 0:1:2 n/a + 89 vplex_meta_important Generic 5000144290292010 0:1:2 n/a + 89 vplex_meta_important Generic 500014429029E912 0:1:2 n/a + 89 vplex_meta_important Generic 500014429029E910 0:1:2 n/a + 89 vplex_meta_important Generic 5000144280292012 1:1:2 n/a + 89 vplex_meta_important Generic 5000144280292010 1:1:2 n/a + 89 vplex_meta_important Generic 500014428029E912 0:1:2 n/a + 89 vplex_meta_important Generic 500014428029E910 0:1:2 n/a + 91 Dorado5000_51.45 Generic 200080D4A58EA53A --- n/a + 91 Dorado5000_51.45 Generic 201080D4A58EA53A --- n/a + 98 AIX6.1_LN AIX-legacy 10000000C9781C57 --- n/a + 98 AIX6.1_LN AIX-legacy 10000000C9781853 --- n/a +115 huhuihost Generic 2100000E1E1A9B30 --- n/a +121 Dorado5000V3_F3 Generic 201880D4A58EA53A --- n/a +160 host002 Generic 21000024FF41DCF8 --- n/a + -- -- -- 21000024FF41DCF7 1:0:2 n/a + -- -- -- 21000024FF41DCF6 1:0:2 n/a + -- -- -- 21000024FF0CC6CA 0:1:2 n/a + -- -- -- 21000024FF0CC6CA 1:1:2 n/a + -- -- -- 21000024FF0CBF47 0:1:2 n/a + -- -- -- 21000024FF0CBF47 1:1:2 n/a +""" +VOLUME_GROUP_DATAS = """ +Id Name Members Comment + 91 wcj_2 wcj_2.0 -- + wcj_2.1 + wcj_2.2 + wcj_2.3 +110 HP-Esxi-LUNSet -- -- +124 zhangjun -- -- +126 wcj_1 wcj_1.1 -- +127 wcj_3 wcj_3.0 -- + wcj_3.1 +128 IBM_SVC -- -- +129 zyz_3parF200_ zyz_3parF200.0 -- + zyz_3parF200.1 + zyz_3parF200.2 + zyz_3parF200.3 +130 zyz zyz_2 -- +131 tx -- -- +132 tx9 -- -- +133 wcj_hp_1 -- -- +136 AIX_YG_WYK_LUN AIX_YG_WYK_LUN.0 -- + AIX_YG_WYK_LUN.1 + AIX_YG_WYK_LUN.2 + AIX_YG_WYK_LUN.3 +140 st11 -- -- +146 Solaris_lun_group Solaris_LUN1_13G -- + solaris_LUN_2_33G +147 wcj_vplex wcj_vplex.0 -- +----------------------------------------------------------- + 32 total 28 +""" +VOLUME_ID_DATAS = """ + Id Name Prov Type CopyOf BsId Rd -Detailed_State- Adm Snp Usr VSize +4836 wcj_2.0 tpvv base --- 4836 RW normal 256 512 512 5120 +4798 zyz_2 tpvv base --- 4836 RW normal 256 512 512 5120 +4797 wcj_3.1 tpvv base --- 4836 RW normal 256 512 512 5120 +666 yytest_vv_001 tpvv base --- 4836 RW normal 256 512 512 5120 +------------------------------------------------------------------------ + 409 total 51072 158720 3279488 18186240 +""" +HOST_DATAS = [ + { + "total": 38, + "members": [ + { + "id": 54, + "name": "Doradov3_lm", + "descriptors": { + "location": "U9-3-B17R_B7", + "IPAddr": "100.157.61.100", + "os": "ESXI6.0", + "model": "RH2288H V3" + }, + "FCPaths": [ + { + "wwn": "2408244427906812", + "hostSpeed": 0 + }, + { + "wwn": "2418244427906812", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 57, + "name": "AIX_wenbin", + "FCPaths": [ + { + "wwn": "10000000C9E74BCC", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 5, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 65, + "name": "SKY-ESXI60", + "descriptors": { + "location": "U9-3-B17R_B7", + "IPAddr": "100.157.61.100", + "os": "ESXI6.0", + "model": "RH2288H V3" + }, + "FCPaths": [ + { + "wwn": "2100001B321BE0FF", + "hostSpeed": 0 + }, + { + "wwn": "2101001B323BE0FF", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 67, + "name": "zouming", + "FCPaths": [ + { + "wwn": "2012E4A8B6B0A1CC", + "hostSpeed": 0 + }, + { + "wwn": "2002E4A8B6B0A1CC", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 68, + "name": "powerpath", + "FCPaths": [ + { + "wwn": "21000024FF36D406", + "hostSpeed": 0 + }, + { + "wwn": "21000024FF36D407", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 69, + "name": "power_v3", + "FCPaths": [ + { + "wwn": "20809CE37435D845", + "hostSpeed": 0 + }, + { + "wwn": "20909CE37435D845", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 89, + "name": "vplex_meta_important", + "FCPaths": [ + { + "wwn": "5000144280292012", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144280292010", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144290292012", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014429029E910", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014429029E912", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014428029E912", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014428029E910", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144290292010", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144290292012", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144290292010", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014429029E912", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014429029E910", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144280292012", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "5000144280292010", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014428029E912", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "500014428029E910", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 91, + "name": "Dorado5000_51.45", + "FCPaths": [ + { + "wwn": "200080D4A58EA53A", + "hostSpeed": 0 + }, + { + "wwn": "201080D4A58EA53A", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 98, + "name": "AIX6.1_LN", + "descriptors": { + "os": "AIX" + }, + "FCPaths": [ + { + "wwn": "10000000C9781C57", + "hostSpeed": 0 + }, + { + "wwn": "10000000C9781853", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 5, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 115, + "name": "huhuihost", + "descriptors": { + "os": "SuSE" + }, + "FCPaths": [ + { + "wwn": "2100000E1E1A9B30", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 121, + "name": "Dorado5000V3_F3", + "descriptors": { + "os": "Red Hat Enterprise Linux" + }, + "FCPaths": [ + { + "wwn": "201880D4A58EA53A", + "hostSpeed": 0 + }, + { + "wwn": "200380D4A58EA53A", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 122, + "name": "DYP_RHEL", + "descriptors": { + "IPAddr": "100.157.18.22", + "os": "Red Hat Enterprise Linux" + }, + "FCPaths": [ + { + "wwn": "10000090FA76D446", + "hostSpeed": 0 + }, + { + "wwn": "10000090FA76D447", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 123, + "name": "DYP_Dorado6000", + "FCPaths": [ + { + "wwn": "2618346AC212FB94", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 124, + "name": "tool_rhel6.8", + "FCPaths": [ + { + "wwn": "21000024FF543687", + "hostSpeed": 0 + }, + { + "wwn": "21000024FF543686", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 125, + "name": "OceanStor6800", + "FCPaths": [ + { + "wwn": "2430E0979656725A", + "hostSpeed": 0 + }, + { + "wwn": "2208E0979656725A", + "hostSpeed": 0 + }, + { + "wwn": "2218E0979656725A", + "hostSpeed": 0 + }, + { + "wwn": "2428E0979656725A", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 126, + "name": "fyc_test", + "FCPaths": [ + { + "wwn": "21000024FF41DE7E", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 127, + "name": "huhui", + "descriptors": { + "os": "SuSE" + }, + "FCPaths": [ + { + "wwn": "500601610864241E", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 132, + "name": "ESX8.44.161.152", + "descriptors": { + "os": "ESX 4.x/5.x" + }, + "FCPaths": [ + { + "wwn": "21000024FF2F3266", + "hostSpeed": 0 + }, + { + "wwn": "21000024FF2F3267", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 8, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 133, + "name": "ESX89PT_suse_8.44.190.111", + "descriptors": { + "os": "SuSE" + }, + "FCPaths": [ + { + "wwn": "21000024FF36F1ED", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 134, + "name": "SVC", + "descriptors": { + "os": "Exanet" + }, + "FCPaths": [ + { + "wwn": "500507680110EF7C", + "hostSpeed": 0 + }, + { + "wwn": "500507680120EF7C", + "hostSpeed": 0 + }, + { + "wwn": "500507680120EF3E", + "hostSpeed": 0 + }, + { + "wwn": "500507680110EF3E", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 3, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 135, + "name": "NSS_8.44.162.50", + "descriptors": { + "os": "Red Hat Enterprise Linux" + }, + "FCPaths": [ + { + "wwn": "21000024FF0DC381", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 137, + "name": "D185_8.44.143.201", + "descriptors": { + "os": "Red Hat Enterprise Linux" + }, + "FCPaths": [ + { + "wwn": "29A11603042D0306", + "hostSpeed": 0 + }, + { + "wwn": "28D01603042D0306", + "hostSpeed": 0 + }, + { + "wwn": "2903010203040509", + "hostSpeed": 0 + }, + { + "wwn": "2802010203040509", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 139, + "name": "Dorado3000V6", + "FCPaths": [ + { + "wwn": "2019CC64A68314D3", + "hostSpeed": 0 + }, + { + "wwn": "2009CC64A68314D3", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 141, + "name": "8.44.143.27T2", + "FCPaths": [ + { + "wwn": "10000090FA50C4DF", + "hostSpeed": 0 + }, + { + "wwn": "10000090FA50C4DE", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 142, + "name": "8.44.143.27T1", + "FCPaths": [], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 144, + "name": "C61_51.10.58.190", + "descriptors": { + "os": "Red Hat Enterprise Linux" + }, + "FCPaths": [ + { + "wwn": "2210112224901223", + "hostSpeed": 0 + }, + { + "wwn": "2200112224901223", + "hostSpeed": 0 + }, + { + "wwn": "2230112224901223", + "hostSpeed": 0 + }, + { + "wwn": "2220112224901223", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 145, + "name": "8.44.43.19", + "FCPaths": [ + { + "wwn": "21000024FF754606", + "hostSpeed": 0 + }, + { + "wwn": "21000024FF1A99E1", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 146, + "name": "ZTY_win2012", + "descriptors": { + "os": "Windows 2012" + }, + "FCPaths": [ + { + "wwn": "21000024FF40272B", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "21000024FF40272A", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 2, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 147, + "name": "DoradoV6_183", + "FCPaths": [ + { + "wwn": "240B121314151617", + "hostSpeed": 0 + }, + { + "wwn": "2409121314151617", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 148, + "name": "rhev_125", + "descriptors": { + "os": "Windows 2012" + }, + "FCPaths": [ + { + "wwn": "21000024FF4BC1B7", + "hostSpeed": 0 + }, + { + "wwn": "21000024FF4BC1B6", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 2, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 150, + "name": "windows2012_68", + "descriptors": { + "os": "Windows 2012" + }, + "FCPaths": [ + { + "wwn": "2101001B32B0667A", + "hostSpeed": 0 + }, + { + "wwn": "2100001B3290667A", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 2, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 151, + "name": "Dorado5000V6_80", + "FCPaths": [ + { + "wwn": "2001183D5E0F5131", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "2011183D5E0F5131", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 152, + "name": "windows2012_60", + "descriptors": { + "os": "Windows 2012" + }, + "FCPaths": [ + { + "wwn": "21000024FF53B4BC", + "hostSpeed": 0 + }, + { + "wwn": "21000024FF53B4BD", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 2, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 153, + "name": "aix_8.44.134.204", + "descriptors": { + "os": "AIX" + }, + "FCPaths": [ + { + "wwn": "10000000C975804C", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "10000000C9765E79", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 5, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 154, + "name": "Dorado5500_V6_109", + "descriptors": { + "IPAddr": "8.44.133.82", + "os": "Windows 2012" + }, + "FCPaths": [ + { + "wwn": "221818022D189653", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "220818022D189653", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 2, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 155, + "name": "aix134.205", + "descriptors": { + "IPAddr": "8.44.134.205", + "os": "AIX" + }, + "FCPaths": [ + { + "wwn": "20000000C9781C81", + "hostSpeed": 0 + }, + { + "wwn": "10000000C9781C0C", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 5, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "id": 158, + "name": "hsv6", + "FCPaths": [ + { + "wwn": "28130A2B304438A8", + "hostSpeed": 0 + }, + { + "wwn": "28120A2B304438A8", + "hostSpeed": 0 + }, + { + "wwn": "28F20A2B304438A8", + "hostSpeed": 0 + }, + { + "wwn": "28F30A2B304438A8", + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "persona": 1, + "initiatorChapEnabled": False, + "targetChapEnabled": False + }, + { + "FCPaths": [ + { + "wwn": "21000024FF41DCF7", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "21000024FF41DCF6", + "portPos": { + "node": 1, + "slot": 0, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "21000024FF0CC6CA", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "21000024FF0CC6CA", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "21000024FF0CBF47", + "portPos": { + "node": 0, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + }, + { + "wwn": "21000024FF0CBF47", + "portPos": { + "node": 1, + "slot": 1, + "cardPort": 2 + }, + "hostSpeed": 0 + } + ], + "iSCSIPaths": [], + "initiatorChapEnabled": False, + "targetChapEnabled": False + } + ] + } +] +VIEW_DATAS = """ + Lun VVName HostName -Host_WWN/iSCSI_Name- Port Type + 2 yytest_vv_001 host002 ---------------- 0:2:1 host + 0 set:vvset001 set:hostset111 ---------------- 1:2:1 host set +-------------------------------------------------------------------- + 2 total +""" + CONTROLLER_RESULT = [ { 'name': '1307327-0', @@ -195,6 +1284,56 @@ def __init__(self): 'ipv6': None, 'ipv6_mask': None }] +HOST_GROUP_RESULT = [ + { + 'name': 'HostSet_VMware', + 'description': '', + 'storage_id': '12345', + 'native_storage_host_group_id': '194' + }] +VOLUME_GROUP_RESULT = [ + { + 'name': 'wcj_2', + 'description': '', + 'storage_id': '12345', + 'native_volume_group_id': '91' + }] +PORT_GROUP_RESULT = [ + { + 'name': 'port_group_0:2:1', + 'description': 'port_group_0:2:1', + 'storage_id': '12345', + 'native_port_group_id': 'port_group_0:2:1' + }] +HOST_RESULT = [ + { + 'name': 'Doradov3_lm', + 'description': None, + 'storage_id': '12345', + 'native_storage_host_id': 54, + 'os_type': 'VMware ESX', + 'status': 'normal', + 'ip_address': '100.157.61.100' + }] +INITIATOR_RESULT = [ + { + 'name': '2408244427906812', + 'storage_id': '12345', + 'native_storage_host_initiator_id': '2408244427906812', + 'wwn': '2408244427906812', + 'type': 'fc', + 'status': 'online', + 'native_storage_host_id': '175' + }] +VIEW_RESULT = [ + { + 'native_masking_view_id': '2_0:2:1', + 'name': '2', + 'native_port_group_id': 'port_group_0:2:1', + 'storage_id': '12345', + 'native_volume_id': '666', + 'native_storage_host_id': '160' + }] def create_driver(): @@ -605,3 +1744,47 @@ def test_get_ports(self): PORT_RCIP_DATAS, PORT_RCIP_DATAS]) ports = driver.list_ports(context) self.assertDictEqual(ports[0], PORT_RESULT[0]) + + def test_get_storage_host_groups(self): + driver = create_driver() + SSHPool.do_exec = mock.Mock(side_effect=[HOST_GROUP_DATAS, + HOST_ID_DATAS]) + host_groups = driver.list_storage_host_groups(context) + self.assertDictEqual(host_groups.get('storage_host_groups')[0], + HOST_GROUP_RESULT[0]) + + def test_get_volume_groups(self): + driver = create_driver() + SSHPool.do_exec = mock.Mock(side_effect=[VOLUME_GROUP_DATAS, + VOLUME_ID_DATAS]) + volume_groups = driver.list_volume_groups(context) + self.assertDictEqual(volume_groups.get('volume_groups')[0], + VOLUME_GROUP_RESULT[0]) + + def test_storage_hosts(self): + driver = create_driver() + with mock.patch.object(RestHandler, 'get_resinfo_call', + side_effect=HOST_DATAS): + storage_hosts = driver.list_storage_hosts(context) + self.assertDictEqual(storage_hosts[0], HOST_RESULT[0]) + + def test_get_storage_host_initiators(self): + driver = create_driver() + SSHPool.do_exec = mock.Mock(side_effect=[HOST_ID_DATAS]) + initiators = driver.list_storage_host_initiators(context) + self.assertDictEqual(initiators[0], INITIATOR_RESULT[0]) + + def test_get_masking_views(self): + driver = create_driver() + SSHPool.do_exec = mock.Mock( + side_effect=[VIEW_DATAS, HOST_ID_DATAS, HOST_GROUP_DATAS, + VOLUME_ID_DATAS, VOLUME_GROUP_DATAS]) + views = driver.list_masking_views(context) + self.assertDictEqual(views[0], VIEW_RESULT[0]) + + def test_get_port_groups(self): + driver = create_driver() + SSHPool.do_exec = mock.Mock(side_effect=[VIEW_DATAS]) + port_groups = driver.list_port_groups(context) + self.assertDictEqual(port_groups.get('port_groups')[0], + PORT_GROUP_RESULT[0])