00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 """
00018 This module intend to provide independent methods for lsm.AccessGroup and
00019 volume masking/unmasking.
00020 """
00021
00022 from pywbem import CIMError, CIM_ERR_NOT_FOUND
00023
00024 from lsm import AccessGroup, md5, LsmError, ErrorNumber
00025
00026 from lsm.plugin.smispy.smis_common import SmisCommon
00027 from lsm.plugin.smispy import dmtf
00028 from lsm.plugin.smispy.utils import cim_path_to_path_str, path_str_to_cim_path
00029
00030 _CIM_INIT_PROS = ['StorageID', 'IDType']
00031
00032
00033 def _init_id_and_type_of(cim_inits):
00034 """
00035 Retrieve AccessGroup.init_ids and AccessGroup.init_type from
00036 a list of CIM_StorageHardwareID.
00037 """
00038 init_ids = []
00039 init_type = AccessGroup.INIT_TYPE_UNKNOWN
00040 init_types = []
00041 for cim_init in cim_inits:
00042 if cim_init['IDType'] == dmtf.ID_TYPE_WWPN:
00043 init_ids.append(init_id_of_cim_init(cim_init))
00044 init_types.append(AccessGroup.INIT_TYPE_WWPN)
00045 if cim_init['IDType'] == dmtf.ID_TYPE_ISCSI:
00046 init_ids.append(init_id_of_cim_init(cim_init))
00047 init_types.append(AccessGroup.INIT_TYPE_ISCSI_IQN)
00048
00049 continue
00050
00051 init_type_dict = {}
00052 for cur_init_type in init_types:
00053 init_type_dict[cur_init_type] = 1
00054
00055 if len(init_type_dict) == 1:
00056 init_type = init_types[0]
00057 elif len(init_type_dict) == 2:
00058 init_type = AccessGroup.INIT_TYPE_ISCSI_WWPN_MIXED
00059 return (init_ids, init_type)
00060
00061
00062 def cim_spc_pros():
00063 """
00064 Return the property of CIM_SCSIProtocolController required to generate
00065 lsm.AccessGroup
00066 'EMCAdapterRole' is for EMC VNX only.
00067 """
00068 return ['DeviceID', 'ElementName', 'StorageID', 'EMCAdapterRole',
00069 'SystemName']
00070
00071
00072 def cim_init_mg_pros():
00073 """
00074 Return the property of CIM_InitiatorMaskingGroup required to generate
00075 lsm.AccessGroup
00076 """
00077 return ['ElementName', 'InstanceID']
00078
00079
00080 def cim_init_of_cim_spc_path(smis_common, cim_spc_path):
00081 """
00082 Return a list of CIM_StorageHardwareID associated to cim_spc.
00083 Only contain ['StorageID', 'IDType'] property.
00084 Two ways to get StorageHardwareID from SCSIProtocolController:
00085 * Method A (defined in SNIA SMIS 1.6):
00086 CIM_SCSIProtocolController
00087 |
00088 | CIM_AssociatedPrivilege
00089 v
00090 CIM_StorageHardwareID
00091
00092 * Method B (defined in SNIA SMIS 1.3, 1.4, 1.5 and 1.6):
00093 CIM_SCSIProtocolController
00094 |
00095 | CIM_AuthorizedTarget
00096 v
00097 CIM_AuthorizedPrivilege
00098 |
00099 | CIM_AuthorizedSubject
00100 v
00101 CIM_StorageHardwareID
00102 """
00103 cim_inits = []
00104 if smis_common.profile_check(SmisCommon.SNIA_MASK_PROFILE,
00105 SmisCommon.SMIS_SPEC_VER_1_6,
00106 raise_error=False):
00107 try:
00108 cim_inits = smis_common.Associators(
00109 cim_spc_path,
00110 AssocClass='CIM_AssociatedPrivilege',
00111 ResultClass='CIM_StorageHardwareID',
00112 PropertyList=_CIM_INIT_PROS)
00113 except CIMError as cim_error:
00114 if cim_error[0] == CIM_ERR_NOT_FOUND:
00115 pass
00116 else:
00117 raise
00118
00119 if len(cim_inits) == 0:
00120 cim_aps_path = smis_common.AssociatorNames(
00121 cim_spc_path,
00122 AssocClass='CIM_AuthorizedTarget',
00123 ResultClass='CIM_AuthorizedPrivilege')
00124
00125 for cim_ap_path in cim_aps_path:
00126 cim_inits.extend(smis_common.Associators(
00127 cim_ap_path,
00128 AssocClass='CIM_AuthorizedSubject',
00129 ResultClass='CIM_StorageHardwareID',
00130 PropertyList=_CIM_INIT_PROS))
00131 return cim_inits
00132
00133
00134 def cim_spc_to_lsm_ag(smis_common, cim_spc, system_id):
00135 """
00136 Convert CIM_SCSIProtocolController to lsm.AccessGroup
00137 """
00138 ag_id = md5(cim_spc['DeviceID'])
00139 ag_name = cim_spc['ElementName']
00140 cim_inits = cim_init_of_cim_spc_path(smis_common, cim_spc.path)
00141 (init_ids, init_type) = _init_id_and_type_of(cim_inits)
00142 plugin_data = cim_path_to_path_str(cim_spc.path)
00143 return AccessGroup(
00144 ag_id, ag_name, init_ids, init_type, system_id, plugin_data)
00145
00146
00147 def cim_init_of_cim_init_mg_path(smis_common, cim_init_mg_path):
00148 """
00149 Use this association to get a list of CIM_StorageHardwareID:
00150 CIM_InitiatorMaskingGroup
00151 |
00152 | CIM_MemberOfCollection
00153 v
00154 CIM_StorageHardwareID
00155 Only contain ['StorageID', 'IDType'] property.
00156 """
00157 return smis_common.Associators(
00158 cim_init_mg_path,
00159 AssocClass='CIM_MemberOfCollection',
00160 ResultClass='CIM_StorageHardwareID',
00161 PropertyList=_CIM_INIT_PROS)
00162
00163
00164 def cim_init_mg_to_lsm_ag(smis_common, cim_init_mg, system_id):
00165 """
00166 Convert CIM_InitiatorMaskingGroup to lsm.AccessGroup
00167 """
00168 ag_name = cim_init_mg['ElementName']
00169 ag_id = md5(cim_init_mg['InstanceID'])
00170 cim_inits = cim_init_of_cim_init_mg_path(smis_common, cim_init_mg.path)
00171 (init_ids, init_type) = _init_id_and_type_of(cim_inits)
00172 plugin_data = cim_path_to_path_str(cim_init_mg.path)
00173 return AccessGroup(
00174 ag_id, ag_name, init_ids, init_type, system_id, plugin_data)
00175
00176
00177 def lsm_ag_to_cim_spc_path(smis_common, lsm_ag):
00178 """
00179 Convert lsm.AccessGroup to CIMInstanceName of CIM_SCSIProtocolController
00180 using lsm.AccessGroup.plugin_data.
00181 This method does not check whether plugin_data is cim_spc or cim_init_mg,
00182 caller should make sure that.
00183 """
00184 if not lsm_ag.plugin_data:
00185 raise LsmError(
00186 ErrorNumber.PLUGIN_BUG,
00187 "Got lsm.AccessGroup instance with empty plugin_data")
00188 if smis_common.system_list and \
00189 lsm_ag.system_id not in smis_common.system_list:
00190 raise LsmError(
00191 ErrorNumber.NOT_FOUND_SYSTEM,
00192 "System filtered in URI")
00193
00194 return path_str_to_cim_path(lsm_ag.plugin_data)
00195
00196
00197 def lsm_ag_to_cim_init_mg_path(smis_common, lsm_ag):
00198 """
00199 Convert lsm.AccessGroup to CIMInstanceName of CIM_InitiatorMaskingGroup
00200 using lsm.AccessGroup.plugin_data.
00201 This method does not check whether plugin_data is cim_spc or cim_init_mg,
00202 caller should make sure that.
00203 """
00204 return lsm_ag_to_cim_spc_path(smis_common, lsm_ag)
00205
00206
00207 def init_id_of_cim_init(cim_init):
00208 """
00209 Return CIM_StorageHardwareID['StorageID']
00210 """
00211 if 'StorageID' in cim_init:
00212 return cim_init['StorageID']
00213 raise LsmError(
00214 ErrorNumber.PLUGIN_BUG,
00215 "init_id_of_cim_init() got cim_init without 'StorageID' %s: %s" %
00216 (cim_init.path, cim_init.items()))
00217
00218
00219 def lsm_init_id_to_snia(lsm_init_id):
00220 """
00221 If lsm_init_id is a WWPN, convert it to SNIA format:
00222 [0-9A-F]{16}
00223 If not, return original directly.
00224 """
00225 val, init_type, init_id = AccessGroup.initiator_id_verify(lsm_init_id)
00226 if val and init_type == AccessGroup.INIT_TYPE_WWPN:
00227 return lsm_init_id.replace(':', '').upper()
00228 return lsm_init_id
00229
00230
00231 def cim_init_path_check_or_create(smis_common, system_id, init_id, init_type):
00232 """
00233 Check whether CIM_StorageHardwareID exists, if not, create new one.
00234 """
00235 cim_inits = smis_common.EnumerateInstances(
00236 'CIM_StorageHardwareID',
00237 PropertyList=_CIM_INIT_PROS)
00238
00239 if len(cim_inits):
00240 for cim_init in cim_inits:
00241 if init_id_of_cim_init(cim_init) == init_id:
00242 return cim_init.path
00243
00244
00245 dmtf_id_type = None
00246 if init_type == AccessGroup.INIT_TYPE_WWPN:
00247 dmtf_id_type = dmtf.ID_TYPE_WWPN
00248 elif init_type == AccessGroup.INIT_TYPE_ISCSI_IQN:
00249 dmtf_id_type = dmtf.ID_TYPE_ISCSI
00250 else:
00251 raise LsmError(
00252 ErrorNumber.PLUGIN_BUG,
00253 "cim_init_path_check_or_create(): Got invalid init_type: %d" %
00254 init_type)
00255
00256 cim_hwms = smis_common.cim_hwms_of_sys_id(system_id)
00257 in_params = {
00258 'StorageID': init_id,
00259 'IDType': dmtf_id_type,
00260 }
00261 return smis_common.invoke_method_wait(
00262 'CreateStorageHardwareID', cim_hwms.path, in_params,
00263 out_key='HardwareID', expect_class='CIM_StorageHardwareID')
00264
00265
00266 def cim_vols_masked_to_cim_spc_path(smis_common, cim_spc_path,
00267 property_list=None):
00268 """
00269 Use this association to find out masked volume for certain cim_spc:
00270 CIM_SCSIProtocolController
00271 |
00272 | CIM_ProtocolControllerForUnit
00273 v
00274 CIM_StorageVolume
00275 Return a list of CIMInstance
00276 """
00277 if property_list is None:
00278 property_list = []
00279
00280 return smis_common.Associators(
00281 cim_spc_path,
00282 AssocClass='CIM_ProtocolControllerForUnit',
00283 ResultClass='CIM_StorageVolume',
00284 PropertyList=property_list)