00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 from lsm import Capabilities, LsmError, ErrorNumber
00016 import dmtf
00017 from smis_common import SmisCommon
00018
00019 MASK_TYPE_NO_SUPPORT = 0
00020 MASK_TYPE_MASK = 1
00021 MASK_TYPE_GROUP = 2
00022
00023
00024 def _rs_supported_capabilities(smis_common, system_id, cap):
00025 """
00026 Interrogate the supported features of the replication service
00027 """
00028 cim_rs = smis_common.cim_rs_of_sys_id(system_id, raise_error=False)
00029 if cim_rs:
00030 rs_cap = smis_common.Associators(
00031 cim_rs.path,
00032 AssocClass='CIM_ElementCapabilities',
00033 ResultClass='CIM_ReplicationServiceCapabilities',
00034 PropertyList=['SupportedReplicationTypes',
00035 'SupportedAsynchronousActions',
00036 'SupportedSynchronousActions'])[0]
00037
00038 s_rt = rs_cap['SupportedReplicationTypes']
00039 async_actions = rs_cap['SupportedAsynchronousActions']
00040 sync_actions = rs_cap['SupportedSynchronousActions']
00041
00042 if dmtf.REPLICA_CAP_ACTION_CREATE_ELEMENT in async_actions or \
00043 dmtf.REPLICA_CAP_ACTION_CREATE_ELEMENT in sync_actions:
00044 cap.set(Capabilities.VOLUME_REPLICATE)
00045 else:
00046 return
00047
00048 if dmtf.REPLICA_CAP_TYPE_SYNC_SNAPSHOT_LOCAL in s_rt or \
00049 dmtf.REPLICA_CAP_TYPE_ASYNC_SNAPSHOT_LOCAL in s_rt:
00050 cap.set(Capabilities.VOLUME_REPLICATE_CLONE)
00051
00052 if dmtf.REPLICA_CAP_TYPE_SYNC_CLONE_LOCAL in s_rt or \
00053 dmtf.REPLICA_CAP_TYPE_ASYNC_CLONE_LOCAL in s_rt:
00054 cap.set(Capabilities.VOLUME_REPLICATE_COPY)
00055 else:
00056
00057
00058 cim_scs = smis_common.cim_scs_of_sys_id(system_id, raise_error=False)
00059
00060 if cim_scs:
00061 cim_sc_cap = smis_common.Associators(
00062 cim_scs.path,
00063 AssocClass='CIM_ElementCapabilities',
00064 ResultClass='CIM_StorageConfigurationCapabilities',
00065 PropertyList=['SupportedCopyTypes'])[0]
00066
00067 if cim_sc_cap is not None and 'SupportedCopyTypes' in cim_sc_cap:
00068 sct = cim_sc_cap['SupportedCopyTypes']
00069
00070 if sct and len(sct):
00071 cap.set(Capabilities.VOLUME_REPLICATE)
00072
00073 if dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_ASSOC in sct:
00074 cap.set(Capabilities.VOLUME_REPLICATE_CLONE)
00075
00076 if dmtf.ST_CONF_CAP_COPY_TYPE_UNSYNC_UNASSOC in sct:
00077 cap.set(Capabilities.VOLUME_REPLICATE_COPY)
00078
00079
00080 def _bsp_cap_set(smis_common, system_id, cap):
00081 """
00082 Set capabilities for these methods:
00083 volumes()
00084 volume_create()
00085 volume_resize()
00086 volume_delete()
00087 """
00088
00089 cim_scs = smis_common.cim_scs_of_sys_id(system_id, raise_error=False)
00090
00091 if cim_scs is None:
00092 return
00093
00094
00095
00096
00097
00098
00099
00100
00101 cim_scs_cap = smis_common.Associators(
00102 cim_scs.path,
00103 AssocClass='CIM_ElementCapabilities',
00104 ResultClass='CIM_StorageConfigurationCapabilities',
00105 PropertyList=['SupportedAsynchronousActions',
00106 'SupportedSynchronousActions',
00107 'SupportedStorageElementTypes'])[0]
00108
00109 element_types = cim_scs_cap['SupportedStorageElementTypes']
00110 sup_actions = []
00111
00112 if 'SupportedSynchronousActions' in cim_scs_cap:
00113 if cim_scs_cap['SupportedSynchronousActions']:
00114 sup_actions.extend(cim_scs_cap['SupportedSynchronousActions'])
00115
00116 if 'SupportedAsynchronousActions' in cim_scs_cap:
00117 if cim_scs_cap['SupportedAsynchronousActions']:
00118 sup_actions.extend(cim_scs_cap['SupportedAsynchronousActions'])
00119
00120 if dmtf.SCS_CAP_SUP_ST_VOLUME in element_types or \
00121 dmtf.SCS_CAP_SUP_THIN_ST_VOLUME in element_types:
00122 cap.set(Capabilities.VOLUMES)
00123 if dmtf.SCS_CAP_SUP_THIN_ST_VOLUME in element_types:
00124 cap.set(Capabilities.VOLUME_THIN)
00125
00126 if dmtf.SCS_CAP_VOLUME_CREATE in sup_actions:
00127 cap.set(Capabilities.VOLUME_CREATE)
00128
00129 if dmtf.SCS_CAP_VOLUME_DELETE in sup_actions:
00130 cap.set(Capabilities.VOLUME_DELETE)
00131
00132 if dmtf.SCS_CAP_VOLUME_MODIFY in sup_actions:
00133 cap.set(Capabilities.VOLUME_RESIZE)
00134
00135 return
00136
00137
00138 def _disk_cap_set(smis_common, cim_sys_path, cap):
00139 if not smis_common.profile_check(SmisCommon.SNIA_DISK_LITE_PROFILE,
00140 SmisCommon.SMIS_SPEC_VER_1_4,
00141 raise_error=False):
00142 return
00143
00144 cap.set(Capabilities.DISKS)
00145 return
00146
00147
00148 def _group_mask_map_cap_set(smis_common, cim_sys_path, cap):
00149 """
00150 We set caps for these methods recording to 1.5+ Group M&M profile:
00151 access_groups()
00152 access_groups_granted_to_volume()
00153 volumes_accessible_by_access_group()
00154 access_group_initiator_add()
00155 access_group_initiator_delete()
00156 volume_mask()
00157 volume_unmask()
00158 access_group_create()
00159 access_group_delete()
00160 """
00161
00162
00163 cap.set(Capabilities.ACCESS_GROUPS)
00164 cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
00165 cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
00166 cap.set(Capabilities.VOLUME_MASK)
00167 if fc_tgt_is_supported(smis_common):
00168 cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
00169 cap.set(Capabilities.ACCESS_GROUP_CREATE_WWPN)
00170 if iscsi_tgt_is_supported(smis_common):
00171 cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
00172 cap.set(Capabilities.ACCESS_GROUP_CREATE_ISCSI_IQN)
00173
00174
00175 cap.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
00176
00177 cim_gmm_cap_pros = [
00178 'SupportedAsynchronousActions',
00179 'SupportedSynchronousActions',
00180 'SupportedDeviceGroupFeatures']
00181
00182 cim_gmm_cap = smis_common.Associators(
00183 cim_sys_path,
00184 AssocClass='CIM_ElementCapabilities',
00185 ResultClass='CIM_GroupMaskingMappingCapabilities',
00186 PropertyList=cim_gmm_cap_pros)[0]
00187
00188
00189
00190 if dmtf.GMM_CAP_DEV_MG_ALLOW_EMPTY_W_SPC in \
00191 cim_gmm_cap['SupportedDeviceGroupFeatures']:
00192 cap.set(Capabilities.VOLUME_UNMASK)
00193
00194
00195
00196 elif ((dmtf.GMM_CAP_DELETE_SPC in
00197 cim_gmm_cap['SupportedSynchronousActions']) or
00198 (dmtf.GMM_CAP_DELETE_SPC in
00199 cim_gmm_cap['SupportedAsynchronousActions'])):
00200 cap.set(Capabilities.VOLUME_UNMASK)
00201
00202
00203 if ((dmtf.GMM_CAP_DELETE_GROUP in
00204 cim_gmm_cap['SupportedSynchronousActions']) or
00205 (dmtf.GMM_CAP_DELETE_GROUP in
00206 cim_gmm_cap['SupportedAsynchronousActions'])):
00207 cap.set(Capabilities.ACCESS_GROUP_DELETE)
00208 return None
00209
00210
00211 def _mask_map_cap_set(smis_common, cim_sys_path, cap):
00212 """
00213 In SNIA SMI-S 1.4rev6 'Masking and Mapping' profile:
00214 CIM_ControllerConfigurationService is mandatory
00215 and it's ExposePaths() and HidePaths() are mandatory
00216 """
00217 if not smis_common.profile_check(SmisCommon.SNIA_MASK_PROFILE,
00218 SmisCommon.SMIS_SPEC_VER_1_4,
00219 raise_error=False):
00220 return
00221
00222 cap.set(Capabilities.ACCESS_GROUPS)
00223 cap.set(Capabilities.VOLUME_MASK)
00224 cap.set(Capabilities.VOLUME_UNMASK)
00225 cap.set(Capabilities.ACCESS_GROUP_INITIATOR_DELETE)
00226 cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
00227 cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
00228
00229
00230
00231 if cim_sys_path.classname == 'Clar_StorageSystem':
00232 return
00233
00234 if fc_tgt_is_supported(smis_common):
00235 cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
00236 if iscsi_tgt_is_supported(smis_common):
00237 cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
00238 return
00239
00240
00241 def _tgt_cap_set(smis_common, cim_sys_path, cap):
00242
00243
00244
00245 if cim_sys_path.classname == 'LSIESG_MegaRAIDHBA':
00246 return
00247
00248 flag_fc_support = fc_tgt_is_supported(smis_common)
00249 flag_iscsi_support = iscsi_tgt_is_supported(smis_common)
00250
00251 if flag_fc_support or flag_iscsi_support:
00252 cap.set(Capabilities.TARGET_PORTS)
00253 return
00254
00255
00256 def mask_type(smis_common, raise_error=False):
00257 """
00258 Return MASK_TYPE_NO_SUPPORT, MASK_TYPE_MASK or MASK_TYPE_GROUP
00259 if 'Group Masking and Mapping' profile is supported, return
00260 MASK_TYPE_GROUP
00261
00262 If raise_error == False, just return MASK_TYPE_NO_SUPPORT
00263 or, raise NO_SUPPORT error.
00264 """
00265 if smis_common.profile_check(SmisCommon.SNIA_GROUP_MASK_PROFILE,
00266 SmisCommon.SMIS_SPEC_VER_1_5,
00267 raise_error=False):
00268 return MASK_TYPE_GROUP
00269 if smis_common.profile_check(SmisCommon.SNIA_MASK_PROFILE,
00270 SmisCommon.SMIS_SPEC_VER_1_4,
00271 raise_error=False):
00272 return MASK_TYPE_MASK
00273 if raise_error:
00274 raise LsmError(ErrorNumber.NO_SUPPORT,
00275 "Target SMI-S provider does not support "
00276 "%s version %s or %s version %s" %
00277 (SmisCommon.SNIA_MASK_PROFILE,
00278 SmisCommon.SMIS_SPEC_VER_1_4,
00279 SmisCommon.SNIA_GROUP_MASK_PROFILE,
00280 SmisCommon.SMIS_SPEC_VER_1_5))
00281 return MASK_TYPE_NO_SUPPORT
00282
00283
00284 def fc_tgt_is_supported(smis_common):
00285 """
00286 Return True if FC Target Port 1.4+ profile is supported.
00287 """
00288 flag_fc_support = smis_common.profile_check(
00289 SmisCommon.SNIA_FC_TGT_PORT_PROFILE,
00290 SmisCommon.SMIS_SPEC_VER_1_4,
00291 raise_error=False)
00292
00293
00294
00295
00296 if not flag_fc_support:
00297 flag_fc_support = smis_common.profile_check(
00298 'FC Target Port',
00299 SmisCommon.SMIS_SPEC_VER_1_4,
00300 raise_error=False)
00301 if flag_fc_support:
00302 return True
00303 else:
00304 return False
00305
00306
00307 def iscsi_tgt_is_supported(smis_common):
00308 """
00309 Return True if FC Target Port 1.1+ profile is supported.
00310 We use CIM_iSCSIProtocolEndpoint as it's a start point we are
00311 using in our code of target_ports().
00312 """
00313 if smis_common.profile_check(SmisCommon.SNIA_ISCSI_TGT_PORT_PROFILE,
00314 SmisCommon.SMIS_SPEC_VER_1_1,
00315 raise_error=False):
00316 return True
00317 return False
00318
00319
00320 def multi_sys_is_supported(smis_common):
00321 """
00322 Return True if Multiple ComputerSystem 1.1+ profile is supported.
00323 Return False else.
00324 """
00325 flag_multi_sys_support = smis_common.profile_check(
00326 SmisCommon.SNIA_MULTI_SYS_PROFILE,
00327 SmisCommon.SMIS_SPEC_VER_1_1,
00328 raise_error=False)
00329 if flag_multi_sys_support:
00330 return True
00331 else:
00332 return False
00333
00334
00335 def get(smis_common, cim_sys, system):
00336 cap = Capabilities()
00337
00338 if smis_common.is_netappe():
00339 _rs_supported_capabilities(smis_common, system.id, cap)
00340
00341
00342
00343
00344
00345 return cap
00346
00347
00348 _bsp_cap_set(smis_common, system.id, cap)
00349
00350
00351 _disk_cap_set(smis_common, cim_sys.path, cap)
00352
00353
00354 mt = mask_type(smis_common)
00355 if cim_sys.path.classname == 'Clar_StorageSystem':
00356 mt = MASK_TYPE_MASK
00357
00358 if mask_type == MASK_TYPE_GROUP:
00359 _group_mask_map_cap_set(smis_common, cim_sys.path, cap)
00360 else:
00361 _mask_map_cap_set(smis_common, cim_sys.path, cap)
00362
00363
00364 _tgt_cap_set(smis_common, cim_sys.path, cap)
00365
00366 _rs_supported_capabilities(smis_common, system.id, cap)
00367 return cap