def query_aggr_storage_disk(na_server, aggr): """Queries for storage disks associated to an aggregate.""" query = {'storage-disk-info': {'disk-raid-info': {'disk-aggregate-info': {'aggregate-name': aggr}}}} des_attr = {'storage-disk-info': {'disk-raid-info': ['effective-disk-type']}} try: result = netapp_api.invoke_api(na_server, api_name='storage-disk-get-iter', api_family='cm', query=query, des_result=des_attr, additional_elems=None, is_iter=True) for res in result: attr_list = res.get_child_by_name('attributes-list') if attr_list: storage_disks = attr_list.get_children() for disk in storage_disks: raid_info = disk.get_child_by_name('disk-raid-info') if raid_info: eff_disk_type =\ raid_info.get_child_content('effective-disk-type') if eff_disk_type: return eff_disk_type else: continue except Exception as e: LOG.debug("Exception querying storage disk. %s", e) return 'unknown'
def query_cluster_vols_for_ssc(na_server, vserver, volume=None): """Queries cluster volumes for ssc.""" query = {'volume-attributes': None} volume_id = {'volume-id-attributes': {'owning-vserver-name': vserver}} if volume: volume_id['volume-id-attributes']['name'] = volume query['volume-attributes'] = volume_id des_attr = {'volume-attributes': ['volume-id-attributes', 'volume-space-attributes', 'volume-state-attributes', 'volume-qos-attributes']} result = netapp_api.invoke_api(na_server, api_name='volume-get-iter', api_family='cm', query=query, des_result=des_attr, additional_elems=None, is_iter=True) vols = set() for res in result: records = res.get_child_content('num-records') if records > 0: attr_list = res.get_child_by_name('attributes-list') if attr_list: vol_attrs = attr_list.get_children() vols_found = create_vol_list(vol_attrs) vols.update(vols_found) return vols
def query_aggr_storage_disk(na_server, aggr): """Queries for storage disks associated to an aggregate.""" query = {"storage-disk-info": {"disk-raid-info": {"disk-aggregate-info": {"aggregate-name": aggr}}}} des_attr = {"storage-disk-info": {"disk-raid-info": ["effective-disk-type"]}} try: result = netapp_api.invoke_api( na_server, api_name="storage-disk-get-iter", api_family="cm", query=query, des_result=des_attr, additional_elems=None, is_iter=True, ) for res in result: attr_list = res.get_child_by_name("attributes-list") if attr_list: storage_disks = attr_list.get_children() for disk in storage_disks: raid_info = disk.get_child_by_name("disk-raid-info") if raid_info: eff_disk_type = raid_info.get_child_content("effective-disk-type") if eff_disk_type: return eff_disk_type else: continue except Exception as e: LOG.debug("Exception querying storage disk. %s", e) return "unknown"
def get_snapmirror_vol_dict(na_server, vserver, volume=None): """Queries snapmirror volumes.""" mirrored_vols = {} query_attr = {"source-vserver": vserver} if volume: query_attr["source-volume"] = volume query = {"snapmirror-info": query_attr} try: result = netapp_api.invoke_api( na_server, api_name="snapmirror-get-iter", api_family="cm", query=query, is_iter=True ) for res in result: attr_list = res.get_child_by_name("attributes-list") if attr_list: snap_info = attr_list.get_children() for snap in snap_info: src_volume = snap.get_child_content("source-volume") v_snap = {} v_snap["dest_loc"] = snap.get_child_content("destination-location") v_snap["rel_type"] = snap.get_child_content("relationship-type") v_snap["mirr_state"] = snap.get_child_content("mirror-state") if mirrored_vols.get(src_volume): mirrored_vols.get(src_volume).append(v_snap) else: mirrored_vols[src_volume] = [v_snap] except Exception as e: LOG.debug("Exception querying mirror information. %s", e) return mirrored_vols
def get_sis_vol_dict(na_server, vserver, volume=None): """Queries sis for volumes. If volume is present sis is queried for it. Records dedup and compression enabled. """ sis_vols = {} query_attr = {"vserver": vserver} if volume: vol_path = "/vol/%s" % (volume) query_attr["path"] = vol_path query = {"sis-status-info": query_attr} try: result = netapp_api.invoke_api(na_server, api_name="sis-get-iter", api_family="cm", query=query, is_iter=True) for res in result: attr_list = res.get_child_by_name("attributes-list") if attr_list: sis_status = attr_list.get_children() for sis in sis_status: path = sis.get_child_content("path") if not path: continue (___, __, vol) = path.rpartition("/") if not vol: continue v_sis = {} v_sis["compression"] = na_utils.to_bool(sis.get_child_content("is-compression-enabled")) v_sis["dedup"] = na_utils.to_bool(sis.get_child_content("state")) sis_vols[vol] = v_sis except Exception as e: LOG.debug("Exception querying sis information. %s", e) return sis_vols
def query_aggr_options(na_server, aggr_name): """Queries cluster aggr for attributes. Currently queries for raid and ha-policy. """ add_elems = {'aggregate': aggr_name} attrs = {} try: result = netapp_api.invoke_api(na_server, api_name='aggr-options-list-info', api_family='cm', query=None, des_result=None, additional_elems=add_elems, is_iter=False) for res in result: options = res.get_child_by_name('options') if options: op_list = options.get_children() for op in op_list: if op.get_child_content('name') == 'ha_policy': attrs['ha_policy'] = op.get_child_content('value') if op.get_child_content('name') == 'raidtype': attrs['raid_type'] = op.get_child_content('value') except Exception as e: LOG.debug("Exception querying aggr options. %s", e) return attrs
def test_invoke_api_invalid_input(self, na_server): """Tests Zapi Invocation Type Error""" na_server = None api_name = zapi_fakes.FAKE_API_NAME invoke_generator = netapp_api.invoke_api(na_server, api_name) self.assertRaises(exception.InvalidInput, invoke_generator.next)
def query_cluster_vols_for_ssc(na_server, vserver, volume=None): """Queries cluster volumes for ssc.""" query = {"volume-attributes": None} volume_id = {"volume-id-attributes": {"owning-vserver-name": vserver}} if volume: volume_id["volume-id-attributes"]["name"] = volume query["volume-attributes"] = volume_id des_attr = { "volume-attributes": [ "volume-id-attributes", "volume-space-attributes", "volume-state-attributes", "volume-qos-attributes", ] } result = netapp_api.invoke_api( na_server, api_name="volume-get-iter", api_family="cm", query=query, des_result=des_attr, additional_elems=None, is_iter=True, ) vols = set() for res in result: records = res.get_child_content("num-records") if records > 0: attr_list = res.get_child_by_name("attributes-list") if attr_list: vol_attrs = attr_list.get_children() vols_found = create_vol_list(vol_attrs) vols.update(vols_found) return vols
def check_apis_on_cluster(self, api_list=None): """Checks API availability and permissions on cluster. Checks API availability and permissions for executing user. Returns a list of failed apis. """ api_list = api_list or [] failed_apis = [] if api_list: api_version = self.connection.get_api_version() if api_version: major, minor = api_version if major == 1 and minor < 20: for api_name in api_list: na_el = netapp_api.NaElement(api_name) try: self.connection.invoke_successfully(na_el) except Exception as e: if isinstance(e, netapp_api.NaApiError): if (e.code == netapp_api. NaErrors['API_NOT_FOUND'].code or e.code == netapp_api. NaErrors['INSUFFICIENT_PRIVS'].code): failed_apis.append(api_name) elif major == 1 and minor >= 20: failed_apis = copy.copy(api_list) result = netapp_api.invoke_api( self.connection, api_name='system-user-capability-get-iter', api_family='cm', additional_elems=None, is_iter=True) for res in result: attr_list = res.get_child_by_name('attributes-list') if attr_list: capabilities = attr_list.get_children() for capability in capabilities: op_list = capability.get_child_by_name( 'operation-list') if op_list: ops = op_list.get_children() for op in ops: apis = op.get_child_content('api-name') if apis: api_list = apis.split(',') for api_name in api_list: if (api_name and api_name.strip() in failed_apis): failed_apis.remove( api_name) else: continue else: msg = _("Unsupported Clustered Data ONTAP version.") raise exception.VolumeBackendAPIException(data=msg) else: msg = _("Data ONTAP API version could not be determined.") raise exception.VolumeBackendAPIException(data=msg) return failed_apis
def test_invoke_api_invalid_input(self, na_server): """Tests Zapi Invocation Type Error""" na_server = None api_name = zapi_fakes.FAKE_API_NAME invoke_generator = netapp_api.invoke_api(na_server, api_name) self.assertRaises(exception.InvalidInput, next, invoke_generator)
def query_cluster_vols_for_ssc(na_server, vserver, volume=None): """Queries cluster volumes for ssc.""" query = {'volume-attributes': None} volume_id = {'volume-id-attributes': {'owning-vserver-name': vserver}} if volume: volume_id['volume-id-attributes']['name'] = volume query['volume-attributes'] = volume_id des_attr = { 'volume-attributes': [ 'volume-id-attributes', 'volume-space-attributes', 'volume-state-attributes', 'volume-qos-attributes' ] } result = netapp_api.invoke_api(na_server, api_name='volume-get-iter', api_family='cm', query=query, des_result=des_attr, additional_elems=None, is_iter=True) vols = set() for res in result: records = res.get_child_content('num-records') if records > 0: attr_list = res.get_child_by_name('attributes-list') if attr_list: vol_attrs = attr_list.get_children() vols_found = create_vol_list(vol_attrs) vols.update(vols_found) return vols
def get_snapmirror_vol_dict(na_server, vserver, volume=None): """Queries snapmirror volumes.""" mirrored_vols = {} query_attr = {'source-vserver': vserver} if volume: query_attr['source-volume'] = volume query = {'snapmirror-info': query_attr} try: result = netapp_api.invoke_api(na_server, api_name='snapmirror-get-iter', api_family='cm', query=query, is_iter=True) for res in result: attr_list = res.get_child_by_name('attributes-list') if attr_list: snap_info = attr_list.get_children() for snap in snap_info: src_volume = snap.get_child_content('source-volume') v_snap = {} v_snap['dest_loc'] =\ snap.get_child_content('destination-location') v_snap['rel_type'] =\ snap.get_child_content('relationship-type') v_snap['mirr_state'] =\ snap.get_child_content('mirror-state') if mirrored_vols.get(src_volume): mirrored_vols.get(src_volume).append(v_snap) else: mirrored_vols[src_volume] = [v_snap] except Exception as e: LOG.debug("Exception querying mirror information. %s", e) return mirrored_vols
def query_aggr_options(na_server, aggr_name): """Queries cluster aggr for attributes. Currently queries for raid and ha-policy. """ add_elems = {"aggregate": aggr_name} attrs = {} try: result = netapp_api.invoke_api( na_server, api_name="aggr-options-list-info", api_family="cm", query=None, des_result=None, additional_elems=add_elems, is_iter=False, ) for res in result: options = res.get_child_by_name("options") if options: op_list = options.get_children() for op in op_list: if op.get_child_content("name") == "ha_policy": attrs["ha_policy"] = op.get_child_content("value") if op.get_child_content("name") == "raidtype": attrs["raid_type"] = op.get_child_content("value") except Exception as e: LOG.debug("Exception querying aggr options. %s", e) return attrs
def test_invoke_api_valid(self, params): """Test invoke_api with valid naserver""" self.mock_object(netapp_api, 'create_api_request', mock.Mock( return_value='success')) self.mock_object(netapp_api.NaServer, 'invoke_successfully', mock.Mock( return_value=netapp_api.NaElement('success'))) invoke_generator = netapp_api.invoke_api(**params) self.assertEqual(netapp_api.NaElement('success').to_string(), next(invoke_generator).to_string())
def test_invoke_api_valid(self, params): """Test invoke_api with valid naserver""" self.mock_object(netapp_api, 'create_api_request', mock.Mock( return_value='success')) self.mock_object(netapp_api.NaServer, 'invoke_successfully', mock.Mock( return_value=netapp_api.NaElement('success'))) invoke_generator = netapp_api.invoke_api(**params) self.assertEqual(netapp_api.NaElement('success').to_string(), invoke_generator.next().to_string())
def get_vserver_ips(self, vserver): """Get ips for the vserver.""" result = netapp_api.invoke_api( self.connection, api_name='net-interface-get-iter', is_iter=True, tunnel=vserver) if_list = [] for res in result: records = res.get_child_content('num-records') if records > 0: attr_list = res['attributes-list'] ifs = attr_list.get_children() if_list.extend(ifs) return if_list
def get_sis_vol_dict(na_server, vserver, volume=None): """Queries sis for volumes. If volume is present sis is queried for it. Records dedup and compression enabled. """ sis_vols = {} query_attr = {'vserver': vserver} if volume: vol_path = '/vol/%s' % (volume) query_attr['path'] = vol_path query = {'sis-status-info': query_attr} try: result = netapp_api.invoke_api(na_server, api_name='sis-get-iter', api_family='cm', query=query, is_iter=True) for res in result: attr_list = res.get_child_by_name('attributes-list') if attr_list: sis_status = attr_list.get_children() for sis in sis_status: path = sis.get_child_content('path') if not path: continue (___, __, vol) = path.rpartition('/') if not vol: continue v_sis = {} v_sis['compression'] = na_utils.to_bool( sis.get_child_content('is-compression-enabled')) v_sis['dedup'] = na_utils.to_bool( sis.get_child_content('state')) sis_vols[vol] = v_sis except Exception as e: LOG.debug("Exception querying sis information. %s", e) return sis_vols
def check_apis_on_cluster(self, api_list=None): """Checks API availability and permissions on cluster. Checks API availability and permissions for executing user. Returns a list of failed apis. """ api_list = api_list or [] failed_apis = [] if api_list: api_version = self.connection.get_api_version() if api_version: major, minor = api_version if major == 1 and minor < 20: for api_name in api_list: na_el = netapp_api.NaElement(api_name) try: self.connection.invoke_successfully(na_el) except Exception as e: if isinstance(e, netapp_api.NaApiError): if (e.code == netapp_api.NaErrors ['API_NOT_FOUND'].code or e.code == netapp_api.NaErrors ['INSUFFICIENT_PRIVS'].code): failed_apis.append(api_name) elif major == 1 and minor >= 20: failed_apis = copy.copy(api_list) result = netapp_api.invoke_api( self.connection, api_name='system-user-capability-get-iter', api_family='cm', additional_elems=None, is_iter=True) for res in result: attr_list = res.get_child_by_name('attributes-list') if attr_list: capabilities = attr_list.get_children() for capability in capabilities: op_list = capability.get_child_by_name( 'operation-list') if op_list: ops = op_list.get_children() for op in ops: apis = op.get_child_content( 'api-name') if apis: api_list = apis.split(',') for api_name in api_list: if (api_name and api_name.strip() in failed_apis): failed_apis.remove( api_name) else: continue else: msg = _("Unsupported Clustered Data ONTAP version.") raise exception.VolumeBackendAPIException(data=msg) else: msg = _("Data ONTAP API version could not be determined.") raise exception.VolumeBackendAPIException(data=msg) return failed_apis