[NetApp ONTAP] Add filtering to API trace logging

API Tracing is valuable when diagnosing problems or
unexpected behaviors with the ONTAP Cinder drivers.

However, turning it on may spam logs and make it rather
harder to trace through specific API calls.

Added an API trace pattern filter in order to filter out
undesired API calls from the DEBUG log.

Change-Id: Ic0563848205a941cf8e779eee42e24ecdaf847dd
This commit is contained in:
Rodrigo Barbieri 2018-06-29 10:06:37 -03:00
parent b9e1552016
commit bb0aac560d
18 changed files with 297 additions and 213 deletions

View File

@ -333,6 +333,7 @@ def list_opts():
cinder_volume_drivers_netapp_options.netapp_nfs_extra_opts,
cinder_volume_drivers_netapp_options.netapp_san_opts,
cinder_volume_drivers_netapp_options.netapp_replication_opts,
cinder_volume_drivers_netapp_options.netapp_support_opts,
cinder_volume_drivers_nexenta_options.NEXENTA_CONNECTION_OPTS,
cinder_volume_drivers_nexenta_options.NEXENTA_ISCSI_OPTS,
cinder_volume_drivers_nexenta_options.NEXENTA_DATASET_OPTS,

View File

@ -225,7 +225,6 @@ class NetAppApiServerTests(test.TestCase):
def test_send_http_request_valid(self):
"""Tests the method send_http_request with valid parameters"""
na_element = zapi_fakes.FAKE_NA_ELEMENT
self.root._trace = True
self.mock_object(self.root, '_create_request',
return_value=('abc', zapi_fakes.FAKE_NA_ELEMENT))
self.mock_object(netapp_api, 'LOG')

View File

@ -34,7 +34,8 @@ CONNECTION_INFO = {'hostname': 'hostname',
'transport_type': 'https',
'port': 443,
'username': 'admin',
'password': 'passw0rd'}
'password': 'passw0rd',
'api_trace_pattern': 'fake_regex'}
class NetAppBaseClientTestCase(test.TestCase):
@ -53,7 +54,8 @@ class NetAppBaseClientTestCase(test.TestCase):
self.fake_lun = six.text_type(uuid.uuid4())
self.fake_size = '1024'
self.fake_metadata = {'OsType': 'linux', 'SpaceReserved': 'true'}
self.mock_send_request = self.mock_object(self.client, 'send_request')
self.mock_send_request = self.mock_object(
self.client.connection, 'send_request')
def test_get_ontapi_version(self):
version_response = netapp_api.NaElement(
@ -534,7 +536,7 @@ class NetAppBaseClientTestCase(test.TestCase):
'volume': fake.SNAPSHOT['volume_id'],
'snapshot': fake.SNAPSHOT['name'],
}
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.delete_snapshot(api_args['volume'],
api_args['snapshot'])
@ -543,8 +545,8 @@ class NetAppBaseClientTestCase(test.TestCase):
'volume': api_args['volume'],
'snapshot': api_args['snapshot'],
}
self.client.send_request.assert_called_once_with('snapshot-delete',
asserted_api_args)
self.client.connection.send_request.assert_called_once_with(
'snapshot-delete', asserted_api_args)
def test_create_cg_snapshot(self):
self.mock_object(self.client, '_start_cg_snapshot',
@ -571,21 +573,21 @@ class NetAppBaseClientTestCase(test.TestCase):
'timeout': 'relaxed',
'volumes': [{'volume-name': fake.CG_VOLUME_NAME}],
}
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client._start_cg_snapshot([fake.CG_VOLUME_NAME],
snapshot_init['snapshot'])
self.client.send_request.assert_called_once_with('cg-start',
snapshot_init)
self.client.connection.send_request.assert_called_once_with(
'cg-start', snapshot_init)
def test_commit_cg_snapshot(self):
snapshot_commit = {'cg-id': fake.CG_VOLUME_ID}
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client._commit_cg_snapshot(snapshot_commit['cg-id'])
self.client.send_request.assert_called_once_with(
self.client.connection.send_request.assert_called_once_with(
'cg-commit', {'cg-id': snapshot_commit['cg-id']})
def test_wait_for_busy_snapshot_raise_exception(self):
@ -609,7 +611,7 @@ class NetAppBaseClientTestCase(test.TestCase):
mock_get_snapshot.assert_has_calls(calls)
def test_rename_snapshot(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.rename_snapshot(
fake.SNAPSHOT['volume_id'], fake.SNAPSHOT_NAME,
@ -622,5 +624,5 @@ class NetAppBaseClientTestCase(test.TestCase):
client_base.DELETED_PREFIX + fake.SNAPSHOT_NAME,
}
self.client.send_request.assert_called_once_with(
self.client.connection.send_request.assert_called_once_with(
'snapshot-rename', api_args)

View File

@ -42,7 +42,8 @@ CONNECTION_INFO = {'hostname': 'hostname',
'port': 443,
'username': 'admin',
'password': 'passw0rd',
'vserver': 'fake_vserver'}
'vserver': 'fake_vserver',
'api_trace_pattern': 'fake_regex'}
@ddt.ddt
@ -64,7 +65,8 @@ class NetAppCmodeClientTestCase(test.TestCase):
self.vserver = CONNECTION_INFO['vserver']
self.fake_volume = six.text_type(uuid.uuid4())
self.fake_lun = six.text_type(uuid.uuid4())
self.mock_send_request = self.mock_object(self.client, 'send_request')
self.mock_send_request = self.mock_object(
self.client.connection, 'send_request')
def _mock_api_error(self, code='fake'):
return mock.Mock(side_effect=netapp_api.NaApiError(code=code))
@ -115,7 +117,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
fake_client.STORAGE_DISK_GET_ITER_RESPONSE_PAGE_3),
]
mock_send_request = self.mock_object(
self.client, 'send_request',
self.client.connection, 'send_request',
side_effect=copy.deepcopy(api_responses))
storage_disk_get_iter_args = {
@ -156,7 +158,8 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.STORAGE_DISK_GET_ITER_RESPONSE)
mock_send_request = self.mock_object(self.client, 'send_request',
mock_send_request = self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
storage_disk_get_iter_args = {
@ -183,7 +186,8 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_send_iter_request_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
mock_send_request = self.mock_object(self.client, 'send_request',
mock_send_request = self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
result = self.client.send_iter_request('storage-disk-get-iter')
@ -202,7 +206,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_send_iter_request_invalid(self, fake_response):
api_response = netapp_api.NaElement(fake_response)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -268,7 +272,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -1558,7 +1562,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
flexvol_name=fake_client.VOLUME_NAMES[0])
def test_create_flexvol(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.create_flexvol(
fake_client.VOLUME_NAME, fake_client.VOLUME_AGGREGATE_NAME, 100)
@ -1571,15 +1575,15 @@ class NetAppCmodeClientTestCase(test.TestCase):
'junction-path': '/%s' % fake_client.VOLUME_NAME,
}
self.client.send_request.assert_called_once_with('volume-create',
volume_create_args)
self.client.connection.send_request.assert_called_once_with(
'volume-create', volume_create_args)
@ddt.data('dp', 'rw', None)
def test_create_volume_with_extra_specs(self, volume_type):
self.mock_object(self.client, 'enable_flexvol_dedupe')
self.mock_object(self.client, 'enable_flexvol_compression')
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.create_flexvol(
fake_client.VOLUME_NAME, fake_client.VOLUME_AGGREGATE_NAME, 100,
@ -1603,8 +1607,8 @@ class NetAppCmodeClientTestCase(test.TestCase):
volume_create_args['junction-path'] = ('/%s' %
fake_client.VOLUME_NAME)
self.client.send_request.assert_called_with('volume-create',
volume_create_args)
self.client.connection.send_request.assert_called_with(
'volume-create', volume_create_args)
self.client.enable_flexvol_dedupe.assert_called_once_with(
fake_client.VOLUME_NAME)
self.client.enable_flexvol_compression.assert_called_once_with(
@ -1644,7 +1648,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_flexvol_exists_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -1652,7 +1656,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_rename_flexvol(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.rename_flexvol(fake_client.VOLUME_NAME, 'new_name')
@ -1661,12 +1665,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
'new-volume-name': 'new_name',
}
self.client.send_request.assert_called_once_with(
self.client.connection.send_request.assert_called_once_with(
'volume-rename', volume_rename_api_args)
def test_mount_flexvol_default_junction_path(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.mount_flexvol(fake_client.VOLUME_NAME)
@ -1675,12 +1679,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
'junction-path': '/%s' % fake_client.VOLUME_NAME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('volume-mount', volume_mount_args)])
def test_mount_flexvol(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
fake_path = '/fake_path'
self.client.mount_flexvol(fake_client.VOLUME_NAME,
@ -1691,34 +1695,34 @@ class NetAppCmodeClientTestCase(test.TestCase):
'junction-path': fake_path,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('volume-mount', volume_mount_args)])
def test_enable_flexvol_dedupe(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.enable_flexvol_dedupe(fake_client.VOLUME_NAME)
sis_enable_args = {'path': '/vol/%s' % fake_client.VOLUME_NAME}
self.client.send_request.assert_called_once_with('sis-enable',
sis_enable_args)
self.client.connection.send_request.assert_called_once_with(
'sis-enable', sis_enable_args)
def test_disable_flexvol_dedupe(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.disable_flexvol_dedupe(fake_client.VOLUME_NAME)
sis_disable_args = {'path': '/vol/%s' % fake_client.VOLUME_NAME}
self.client.send_request.assert_called_once_with('sis-disable',
sis_disable_args)
self.client.connection.send_request.assert_called_once_with(
'sis-disable', sis_disable_args)
def test_enable_flexvol_compression(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.enable_flexvol_compression(fake_client.VOLUME_NAME)
@ -1727,12 +1731,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
'enable-compression': 'true'
}
self.client.send_request.assert_called_once_with('sis-set-config',
sis_set_config_args)
self.client.connection.send_request.assert_called_once_with(
'sis-set-config', sis_set_config_args)
def test_disable_flexvol_compression(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.disable_flexvol_compression(fake_client.VOLUME_NAME)
@ -1741,8 +1745,8 @@ class NetAppCmodeClientTestCase(test.TestCase):
'enable-compression': 'false'
}
self.client.send_request.assert_called_once_with('sis-set-config',
sis_set_config_args)
self.client.connection.send_request.assert_called_once_with(
'sis-set-config', sis_set_config_args)
def test_get_flexvol_dedupe_info(self):
@ -1867,19 +1871,19 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.CLONE_SPLIT_STATUS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
result = self.client.get_clone_split_info(fake_client.VOLUME_NAMES[0])
self.assertEqual(fake_client.VOLUME_CLONE_SPLIT_STATUS, result)
self.client.send_request.assert_called_once_with(
self.client.connection.send_request.assert_called_once_with(
'clone-split-status', {'volume-name': fake_client.VOLUME_NAMES[0]})
def test_get_clone_split_info_api_error(self):
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
side_effect=self._mock_api_error())
@ -1892,7 +1896,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.CLONE_SPLIT_STATUS_NO_DATA_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -1933,7 +1937,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -1944,7 +1948,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_is_flexvol_mirrored_api_error(self):
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
side_effect=self._mock_api_error())
@ -1999,7 +2003,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -2010,7 +2014,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_is_flexvol_encrypted_api_error(self):
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
side_effect=self._mock_api_error())
@ -2023,13 +2027,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.AGGR_GET_ITER_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
result = self.client._get_aggregates()
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('aggr-get-iter', {}, enable_tunneling=False)])
self.assertListEqual(
[aggr.to_string() for aggr in api_response.get_child_by_name(
@ -2040,7 +2044,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.AGGR_GET_SPACE_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -2068,7 +2072,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
'desired-attributes': desired_attributes
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('aggr-get-iter', aggr_get_iter_args,
enable_tunneling=False)])
self.assertListEqual(
@ -2079,13 +2083,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregates_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
result = self.client._get_aggregates()
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('aggr-get-iter', {}, enable_tunneling=False)])
self.assertListEqual([], result)
@ -2126,7 +2130,9 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_node_for_aggregate_api_not_found(self):
api_error = self._mock_api_error(netapp_api.EAPINOTFOUND)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(self.client.connection,
'send_request',
side_effect=api_error)
result = self.client.get_node_for_aggregate(
fake_client.VOLUME_AGGREGATE_NAME)
@ -2135,7 +2141,9 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_node_for_aggregate_api_error(self):
self.mock_object(self.client, 'send_request', self._mock_api_error())
self.mock_object(self.client.connection,
'send_request',
self._mock_api_error())
self.assertRaises(netapp_api.NaApiError,
self.client.get_node_for_aggregate,
@ -2144,7 +2152,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_node_for_aggregate_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -2194,7 +2202,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregate_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -2204,7 +2212,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregate_api_error(self):
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
side_effect=self._mock_api_error())
@ -2215,7 +2223,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregate_api_not_found(self):
api_error = netapp_api.NaApiError(code=netapp_api.EAPINOTFOUND)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_iter_request',
side_effect=api_error)
@ -2227,7 +2235,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.SYSTEM_NODE_GET_ITER_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
mock.Mock(return_value=api_response))
@ -2238,7 +2246,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_list_cluster_nodes_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
mock.Mock(return_value=api_response))
@ -2490,7 +2498,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregate_capacity_not_found(self):
api_response = netapp_api.NaElement(fake_client.NO_RECORDS_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -2501,7 +2509,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregate_capacity_api_error(self):
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
side_effect=self._mock_api_error())
@ -2513,7 +2521,8 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_get_aggregate_capacity_api_not_found(self):
api_error = netapp_api.NaApiError(code=netapp_api.EAPINOTFOUND)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
result = self.client.get_aggregate_capacity(
fake_client.VOLUME_AGGREGATE_NAME)
@ -2711,7 +2720,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_create_cluster_peer(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.create_cluster_peer(['fake_address_1', 'fake_address_2'],
'fake_user', 'fake_password',
@ -2726,7 +2735,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
'password': 'fake_password',
'passphrase': 'fake_passphrase',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('cluster-peer-create', cluster_peer_create_args)])
def test_get_cluster_peers(self):
@ -2795,12 +2804,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_delete_cluster_peer(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.delete_cluster_peer(fake_client.CLUSTER_NAME)
cluster_peer_delete_args = {'cluster-name': fake_client.CLUSTER_NAME}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('cluster-peer-delete', cluster_peer_delete_args)])
def test_get_cluster_peer_policy(self):
@ -2809,7 +2818,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.CLUSTER_PEER_POLICY_GET_RESPONSE)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -2820,7 +2829,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
'passphrase-minimum-length': 8,
}
self.assertEqual(expected, result)
self.assertTrue(self.client.send_request.called)
self.assertTrue(self.client.connection.send_request.called)
def test_get_cluster_peer_policy_not_supported(self):
@ -2830,25 +2839,25 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_set_cluster_peer_policy_not_supported(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.set_cluster_peer_policy()
self.assertFalse(self.client.send_request.called)
self.assertFalse(self.client.connection.send_request.called)
def test_set_cluster_peer_policy_no_arguments(self):
self.client.features.add_feature('CLUSTER_PEER_POLICY')
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.set_cluster_peer_policy()
self.assertFalse(self.client.send_request.called)
self.assertFalse(self.client.connection.send_request.called)
def test_set_cluster_peer_policy(self):
self.client.features.add_feature('CLUSTER_PEER_POLICY')
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.set_cluster_peer_policy(
is_unauthenticated_access_permitted=True,
@ -2858,13 +2867,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'is-unauthenticated-access-permitted': 'true',
'passphrase-minlength': '12',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('cluster-peer-policy-modify',
cluster_peer_policy_modify_args)])
def test_create_vserver_peer(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.create_vserver_peer('fake_vserver', 'fake_vserver_peer')
@ -2875,12 +2884,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
{'vserver-peer-application': 'snapmirror'},
],
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('vserver-peer-create', vserver_peer_create_args)])
def test_delete_vserver_peer(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.delete_vserver_peer('fake_vserver', 'fake_vserver_peer')
@ -2888,12 +2897,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
'vserver': 'fake_vserver',
'peer-vserver': 'fake_vserver_peer',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('vserver-peer-delete', vserver_peer_delete_args)])
def test_accept_vserver_peer(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.accept_vserver_peer('fake_vserver', 'fake_vserver_peer')
@ -2901,7 +2910,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
'vserver': 'fake_vserver',
'peer-vserver': 'fake_vserver_peer',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('vserver-peer-accept', vserver_peer_accept_args)])
def test_get_vserver_peers(self):
@ -2964,7 +2973,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
{'schedule': None, 'policy': None})
@ddt.unpack
def test_create_snapmirror(self, schedule, policy):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.create_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -2982,12 +2991,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
snapmirror_create_args['schedule'] = schedule
if policy:
snapmirror_create_args['policy'] = policy
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-create', snapmirror_create_args)])
def test_create_snapmirror_already_exists(self):
api_error = netapp_api.NaApiError(code=netapp_api.ERELATION_EXISTS)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.client.create_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3000,12 +3010,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-volume': fake_client.SM_DEST_VOLUME,
'relationship-type': 'data_protection',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-create', snapmirror_create_args)])
def test_create_snapmirror_error(self):
api_error = netapp_api.NaApiError(code=0)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.assertRaises(netapp_api.NaApiError,
self.client.create_snapmirror,
@ -3013,7 +3024,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
fake_client.SM_SOURCE_VOLUME,
fake_client.SM_DEST_VSERVER,
fake_client.SM_DEST_VOLUME)
self.assertTrue(self.client.send_request.called)
self.assertTrue(self.client.connection.send_request.called)
@ddt.data(
{
@ -3030,7 +3041,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
api_response = netapp_api.NaElement(
fake_client.SNAPMIRROR_INITIALIZE_RESULT)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -3050,7 +3061,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
snapmirror_initialize_args['source-snapshot'] = source_snapshot
if transfer_priority:
snapmirror_initialize_args['transfer-priority'] = transfer_priority
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-initialize', snapmirror_initialize_args)])
expected = {
@ -3065,7 +3076,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
@ddt.data(True, False)
def test_release_snapmirror(self, relationship_info_only):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.release_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3084,12 +3095,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
}
}
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-release-iter', snapmirror_release_args)])
def test_quiesce_snapmirror(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.quiesce_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3101,13 +3112,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-quiesce', snapmirror_quiesce_args)])
@ddt.data(True, False)
def test_abort_snapmirror(self, clear_checkpoint):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.abort_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3121,13 +3132,14 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-volume': fake_client.SM_DEST_VOLUME,
'clear-checkpoint': 'true' if clear_checkpoint else 'false',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-abort', snapmirror_abort_args)])
def test_abort_snapmirror_no_transfer_in_progress(self):
api_error = netapp_api.NaApiError(
code=netapp_api.ENOTRANSFER_IN_PROGRESS)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.client.abort_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3140,12 +3152,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-volume': fake_client.SM_DEST_VOLUME,
'clear-checkpoint': 'false',
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-abort', snapmirror_abort_args)])
def test_abort_snapmirror_error(self):
api_error = netapp_api.NaApiError(code=0)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.assertRaises(netapp_api.NaApiError,
self.client.abort_snapmirror,
@ -3156,7 +3169,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_break_snapmirror(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.break_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3168,7 +3181,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-break', snapmirror_break_args)])
@ddt.data(
@ -3189,7 +3202,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
def test_modify_snapmirror(self, schedule, policy, tries,
max_transfer_rate):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.modify_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3211,12 +3224,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
snapmirror_modify_args['tries'] = tries
if max_transfer_rate:
snapmirror_modify_args['max-transfer-rate'] = max_transfer_rate
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-modify', snapmirror_modify_args)])
def test_delete_snapmirror(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.delete_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3232,12 +3245,12 @@ class NetAppCmodeClientTestCase(test.TestCase):
}
}
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-destroy-iter', snapmirror_delete_args)])
def test_update_snapmirror(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.update_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3249,13 +3262,14 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-update', snapmirror_update_args)])
def test_update_snapmirror_already_transferring(self):
api_error = netapp_api.NaApiError(
code=netapp_api.ETRANSFER_IN_PROGRESS)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.client.update_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3267,12 +3281,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-update', snapmirror_update_args)])
def test_update_snapmirror_already_transferring_two(self):
api_error = netapp_api.NaApiError(code=netapp_api.EANOTHER_OP_ACTIVE)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.client.update_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3284,12 +3299,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-update', snapmirror_update_args)])
def test_update_snapmirror_error(self):
api_error = netapp_api.NaApiError(code=0)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.assertRaises(netapp_api.NaApiError,
self.client.update_snapmirror,
@ -3299,7 +3315,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
fake_client.SM_DEST_VOLUME)
def test_resume_snapmirror(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.resume_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3311,13 +3327,14 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-resume', snapmirror_resume_args)])
def test_resume_snapmirror_not_quiesed(self):
api_error = netapp_api.NaApiError(
code=netapp_api.ERELATION_NOT_QUIESCED)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.client.resume_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3329,12 +3346,13 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-resume', snapmirror_resume_args)])
def test_resume_snapmirror_error(self):
api_error = netapp_api.NaApiError(code=0)
self.mock_object(self.client, 'send_request', side_effect=api_error)
self.mock_object(
self.client.connection, 'send_request', side_effect=api_error)
self.assertRaises(netapp_api.NaApiError,
self.client.resume_snapmirror,
@ -3344,7 +3362,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
fake_client.SM_DEST_VOLUME)
def test_resync_snapmirror(self):
self.mock_object(self.client, 'send_request')
self.mock_object(self.client.connection, 'send_request')
self.client.resync_snapmirror(
fake_client.SM_SOURCE_VSERVER, fake_client.SM_SOURCE_VOLUME,
@ -3356,7 +3374,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
'destination-vserver': fake_client.SM_DEST_VSERVER,
'destination-volume': fake_client.SM_DEST_VOLUME,
}
self.client.send_request.assert_has_calls([
self.client.connection.send_request.assert_has_calls([
mock.call('snapmirror-resync', snapmirror_resync_args)])
def test__get_snapmirrors(self):
@ -3545,7 +3563,7 @@ class NetAppCmodeClientTestCase(test.TestCase):
@ddt.unpack
def test_get_snapshots_marked_for_deletion(self, mock_return, expected):
api_response = netapp_api.NaElement(mock_return)
self.mock_object(self.client,
self.mock_object(self.client.connection,
'send_request',
return_value=api_response)
@ -3568,6 +3586,6 @@ class NetAppCmodeClientTestCase(test.TestCase):
},
}
self.client.send_request.assert_called_once_with(
self.client.connection.send_request.assert_called_once_with(
'snapshot-get-iter', api_args)
self.assertListEqual(expected, result)

View File

@ -80,6 +80,7 @@ class NetAppBlockStorageCmodeLibraryTestCase(test.TestCase):
config.netapp_transport_type = 'https'
config.netapp_server_port = '443'
config.netapp_vserver = 'openstack'
config.netapp_api_trace_pattern = 'fake_regex'
return config
@mock.patch.object(perf_cmode, 'PerformanceCmodeLibrary', mock.Mock())

View File

@ -81,6 +81,7 @@ class NetAppCmodeNfsDriverTestCase(test.TestCase):
config.netapp_server_port = '80'
config.netapp_vserver = fake.VSERVER_NAME
config.netapp_copyoffload_tool_path = 'copyoffload_tool_path'
config.netapp_api_trace_pattern = 'fake_regex'
return config
@ddt.data({'active_backend_id': None, 'targets': ['dev1', 'dev2']},

View File

@ -155,5 +155,6 @@ def get_fake_cmode_config(backend_name):
config.append_config_values(na_opts.netapp_cluster_opts)
config.append_config_values(na_opts.netapp_san_opts)
config.append_config_values(na_opts.netapp_replication_opts)
config.append_config_values(na_opts.netapp_support_opts)
return config

View File

@ -46,6 +46,8 @@ class NetAppCDOTDataMotionTestCase(test.TestCase):
group=self.backend)
CONF.set_override('netapp_server_port', 8866,
group=self.backend)
CONF.set_override('netapp_api_trace_pattern', "fake_regex",
group=self.backend)
def test_get_backend_configuration(self):
self.mock_object(utils, 'CONF')
@ -88,7 +90,7 @@ class NetAppCDOTDataMotionTestCase(test.TestCase):
self.mock_cmode_client.assert_called_once_with(
hostname='fake_hostname', password='fake_password',
username='fake_user', transport_type='https', port=8866,
trace=mock.ANY, vserver=None)
trace=mock.ANY, vserver=None, api_trace_pattern="fake_regex")
def test_get_client_for_backend_with_vserver(self):
self.mock_object(utils, 'get_backend_configuration',
@ -102,7 +104,8 @@ class NetAppCDOTDataMotionTestCase(test.TestCase):
self.mock_cmode_client.assert_called_once_with(
hostname='fake_hostname', password='fake_password',
username='fake_user', transport_type='https', port=8866,
trace=mock.ANY, vserver='fake_vserver')
trace=mock.ANY, vserver='fake_vserver',
api_trace_pattern="fake_regex")
@ddt.ddt

View File

@ -28,8 +28,11 @@ from oslo_concurrency import processutils as putils
from cinder import context
from cinder import exception
from cinder import test
from cinder.tests.unit.volume.drivers.netapp.dataontap.client import (
fakes as zapi_fakes)
import cinder.tests.unit.volume.drivers.netapp.fakes as fake
from cinder import version
from cinder.volume.drivers.netapp.dataontap.client import api as netapp_api
from cinder.volume.drivers.netapp import utils as na_utils
from cinder.volume import qos_specs
from cinder.volume import volume_types
@ -158,6 +161,22 @@ class NetAppDriverUtilsTestCase(test.TestCase):
self.assertEqual(fake_extra_specs, result)
def test_trace_filter_func_api(self):
na_utils.setup_api_trace_pattern("^(?!(perf)).*$")
na_element = zapi_fakes.FAKE_NA_ELEMENT
all_args = {'na_element': na_element}
self.assertTrue(na_utils.trace_filter_func_api(all_args))
def test_trace_filter_func_api_invalid(self):
all_args = {'fake': 'not_na_element'}
self.assertTrue(na_utils.trace_filter_func_api(all_args))
def test_trace_filter_func_api_filtered(self):
na_utils.setup_api_trace_pattern("^(?!(perf)).*$")
na_element = netapp_api.NaElement("perf-object-counter-list-info")
all_args = {'na_element': na_element}
self.assertFalse(na_utils.trace_filter_func_api(all_args))
def test_get_volume_extra_specs_no_type_id(self):
fake_volume = {}
self.mock_object(context, 'get_admin_context')

View File

@ -34,6 +34,7 @@ from cinder import exception
from cinder.i18n import _
from cinder import ssh_utils
from cinder import utils
from cinder.volume.drivers.netapp import utils as na_utils
LOG = logging.getLogger(__name__)
@ -67,7 +68,7 @@ class NaServer(object):
def __init__(self, host, server_type=SERVER_TYPE_FILER,
transport_type=TRANSPORT_TYPE_HTTP,
style=STYLE_LOGIN_PASSWORD, username=None,
password=None, port=None):
password=None, port=None, api_trace_pattern=None):
self._host = host
self.set_server_type(server_type)
self.set_transport_type(transport_type)
@ -78,6 +79,9 @@ class NaServer(object):
self._password = password
self._refresh_conn = True
if api_trace_pattern is not None:
na_utils.setup_api_trace_pattern(api_trace_pattern)
LOG.debug('Using NetApp controller: %s', self._host)
def set_transport_type(self, transport_type):
@ -171,7 +175,7 @@ class NaServer(object):
"""Set the vserver to use if tunneling gets enabled."""
self._vserver = vserver
@utils.trace_api
@utils.trace_api(filter_function=na_utils.trace_filter_func_api)
def send_http_request(self, na_element, enable_tunneling=False):
"""Invoke the API on the server."""
if not na_element or not isinstance(na_element, NaElement):
@ -221,6 +225,13 @@ class NaServer(object):
or 'Execution status is failed due to unknown reason'
raise NaApiError(code, msg)
def send_request(self, api_name, api_args=None, enable_tunneling=True):
"""Sends request to Ontapi."""
request = NaElement(api_name)
if api_args:
request.translate_struct(api_args)
return self.invoke_successfully(request, enable_tunneling)
def _create_request(self, na_element, enable_tunneling=False):
"""Creates request in the desired format."""
netapp_elem = NaElement('netapp')

View File

@ -41,12 +41,14 @@ class Client(object):
host = kwargs['hostname']
username = kwargs['username']
password = kwargs['password']
api_trace_pattern = kwargs['api_trace_pattern']
self.connection = netapp_api.NaServer(
host=host,
transport_type=kwargs['transport_type'],
port=kwargs['port'],
username=username,
password=password)
password=password,
api_trace_pattern=api_trace_pattern)
self.ssh_client = self._init_ssh_client(host, username, password)
@ -82,13 +84,6 @@ class Client(object):
if not isinstance(elem, netapp_api.NaElement):
raise ValueError('Expects NaElement')
def send_request(self, api_name, api_args=None, enable_tunneling=True):
"""Sends request to Ontapi."""
request = netapp_api.NaElement(api_name)
if api_args:
request.translate_struct(api_args)
return self.connection.invoke_successfully(request, enable_tunneling)
def create_lun(self, volume_name, lun_name, size, metadata,
qos_policy_group_name=None):
"""Issues API request for creating LUN on volume."""
@ -288,9 +283,9 @@ class Client(object):
"""Gets info about one or more Data ONTAP performance counters."""
api_args = {'objectname': object_name}
result = self.send_request('perf-object-counter-list-info',
api_args,
enable_tunneling=False)
result = self.connection.send_request('perf-object-counter-list-info',
api_args,
enable_tunneling=False)
counters = result.get_child_by_name(
'counters') or netapp_api.NaElement('None')
@ -317,7 +312,7 @@ class Client(object):
def delete_snapshot(self, volume_name, snapshot_name):
"""Deletes a volume snapshot."""
api_args = {'volume': volume_name, 'snapshot': snapshot_name}
self.send_request('snapshot-delete', api_args)
self.connection.send_request('snapshot-delete', api_args)
def create_cg_snapshot(self, volume_names, snapshot_name):
"""Creates a consistency group snapshot out of one or more flexvols.
@ -341,12 +336,12 @@ class Client(object):
{'volume-name': volume_name} for volume_name in volume_names
],
}
result = self.send_request('cg-start', snapshot_init)
result = self.connection.send_request('cg-start', snapshot_init)
return result.get_child_content('cg-id')
def _commit_cg_snapshot(self, cg_id):
snapshot_commit = {'cg-id': cg_id}
self.send_request('cg-commit', snapshot_commit)
self.connection.send_request('cg-commit', snapshot_commit)
def get_snapshot(self, volume_name, snapshot_name):
"""Gets a single snapshot."""
@ -384,4 +379,4 @@ class Client(object):
'current-name': current_name,
'new-name': new_name,
}
return self.send_request('snapshot-rename', api_args)
return self.connection.send_request('snapshot-rename', api_args)

View File

@ -111,7 +111,7 @@ class Client(client_base.Client):
api_args['max-records'] = max_page_length
# Get first page
result = self.send_request(
result = self.connection.send_request(
api_name, api_args, enable_tunneling=enable_tunneling)
# Most commonly, we can just return here if there is no more data
@ -130,7 +130,7 @@ class Client(client_base.Client):
while next_tag is not None:
next_api_args = copy.deepcopy(api_args)
next_api_args['tag'] = next_tag
next_result = self.send_request(
next_result = self.connection.send_request(
api_name, next_api_args, enable_tunneling=enable_tunneling)
next_attributes_list = next_result.get_child_by_name(
@ -204,7 +204,8 @@ class Client(client_base.Client):
try:
node_client.set_vserver(self._get_ems_log_destination_vserver())
node_client.send_request('ems-autosupport-log', message_dict)
node_client.connection.send_request('ems-autosupport-log',
message_dict)
LOG.debug('EMS executed successfully.')
except netapp_api.NaApiError as e:
LOG.warning('Failed to invoke EMS. %s', e)
@ -526,7 +527,7 @@ class Client(client_base.Client):
'file': file_path,
'vserver': self.vserver,
}
return self.send_request('file-assign-qos', api_args, False)
return self.connection.send_request('file-assign-qos', api_args, False)
def provision_qos_policy_group(self, qos_policy_group_info):
"""Create QOS policy group on the backend if appropriate."""
@ -562,9 +563,9 @@ class Client(client_base.Client):
},
},
}
result = self.send_request('qos-policy-group-get-iter',
api_args,
False)
result = self.connection.send_request('qos-policy-group-get-iter',
api_args,
False)
return self._has_records(result)
def qos_policy_group_create(self, qos_policy_group_name, max_throughput):
@ -574,7 +575,8 @@ class Client(client_base.Client):
'max-throughput': max_throughput,
'vserver': self.vserver,
}
return self.send_request('qos-policy-group-create', api_args, False)
return self.connection.send_request(
'qos-policy-group-create', api_args, False)
def qos_policy_group_modify(self, qos_policy_group_name, max_throughput):
"""Modifies a QOS policy group."""
@ -582,12 +584,14 @@ class Client(client_base.Client):
'policy-group': qos_policy_group_name,
'max-throughput': max_throughput,
}
return self.send_request('qos-policy-group-modify', api_args, False)
return self.connection.send_request(
'qos-policy-group-modify', api_args, False)
def qos_policy_group_delete(self, qos_policy_group_name):
"""Attempts to delete a QOS policy group."""
api_args = {'policy-group': qos_policy_group_name}
return self.send_request('qos-policy-group-delete', api_args, False)
return self.connection.send_request(
'qos-policy-group-delete', api_args, False)
def qos_policy_group_rename(self, qos_policy_group_name, new_name):
"""Renames a QOS policy group."""
@ -595,7 +599,8 @@ class Client(client_base.Client):
'policy-group-name': qos_policy_group_name,
'new-name': new_name,
}
return self.send_request('qos-policy-group-rename', api_args, False)
return self.connection.send_request(
'qos-policy-group-rename', api_args, False)
def mark_qos_policy_group_for_deletion(self, qos_policy_group_info):
"""Do (soft) delete of backing QOS policy group for a cinder volume."""
@ -639,7 +644,8 @@ class Client(client_base.Client):
}
try:
self.send_request('qos-policy-group-delete-iter', api_args, False)
self.connection.send_request(
'qos-policy-group-delete-iter', api_args, False)
except netapp_api.NaApiError as ex:
msg = 'Could not delete QOS policy groups. Details: %(ex)s'
msg_args = {'ex': ex}
@ -651,7 +657,8 @@ class Client(client_base.Client):
'path': path,
'qos-policy-group': qos_policy_group,
}
return self.send_request('lun-set-qos-policy-group', api_args)
return self.connection.send_request(
'lun-set-qos-policy-group', api_args)
def get_if_info_by_ip(self, ip):
"""Gets the network interface info by ip."""
@ -777,7 +784,7 @@ class Client(client_base.Client):
},
},
}
result = self.send_request(
result = self.connection.send_request(
'system-user-capability-get-iter', api_args, False)
if not self._has_records(result):
@ -812,7 +819,7 @@ class Client(client_base.Client):
raise ValueError(_('Non-getter API passed to API test method.'))
try:
self.send_request(api, enable_tunneling=False)
self.connection.send_request(api, enable_tunneling=False)
except netapp_api.NaApiError as ex:
if ex.code in (netapp_api.EAPIPRIVILEGE, netapp_api.EAPINOTFOUND):
return False
@ -1134,8 +1141,8 @@ class Client(client_base.Client):
"""Get the status of unsplit file/LUN clones in a flexvol."""
try:
result = self.send_request('clone-split-status',
{'volume-name': flexvol_name})
result = self.connection.send_request(
'clone-split-status', {'volume-name': flexvol_name})
except netapp_api.NaApiError:
LOG.exception('Failed to get clone split info for volume %s.',
flexvol_name)
@ -1243,7 +1250,7 @@ class Client(client_base.Client):
if snapshot_reserve is not None:
api_args['percentage-snapshot-reserve'] = six.text_type(
snapshot_reserve)
self.send_request('volume-create', api_args)
self.connection.send_request('volume-create', api_args)
# cDOT compression requires that deduplication be enabled.
if dedupe_enabled or compression_enabled:
@ -1280,7 +1287,7 @@ class Client(client_base.Client):
'volume': orig_flexvol_name,
'new-volume-name': new_flexvol_name,
}
self.send_request('volume-rename', api_args)
self.connection.send_request('volume-rename', api_args)
def mount_flexvol(self, flexvol_name, junction_path=None):
"""Mounts a volume on a junction path."""
@ -1289,17 +1296,17 @@ class Client(client_base.Client):
'junction-path': (junction_path if junction_path
else '/%s' % flexvol_name)
}
self.send_request('volume-mount', api_args)
self.connection.send_request('volume-mount', api_args)
def enable_flexvol_dedupe(self, flexvol_name):
"""Enable deduplication on volume."""
api_args = {'path': '/vol/%s' % flexvol_name}
self.send_request('sis-enable', api_args)
self.connection.send_request('sis-enable', api_args)
def disable_flexvol_dedupe(self, flexvol_name):
"""Disable deduplication on volume."""
api_args = {'path': '/vol/%s' % flexvol_name}
self.send_request('sis-disable', api_args)
self.connection.send_request('sis-disable', api_args)
def enable_flexvol_compression(self, flexvol_name):
"""Enable compression on volume."""
@ -1307,7 +1314,7 @@ class Client(client_base.Client):
'path': '/vol/%s' % flexvol_name,
'enable-compression': 'true'
}
self.send_request('sis-set-config', api_args)
self.connection.send_request('sis-set-config', api_args)
def disable_flexvol_compression(self, flexvol_name):
"""Disable compression on volume."""
@ -1315,7 +1322,7 @@ class Client(client_base.Client):
'path': '/vol/%s' % flexvol_name,
'enable-compression': 'false'
}
self.send_request('sis-set-config', api_args)
self.connection.send_request('sis-set-config', api_args)
@utils.trace_method
def delete_file(self, path_to_file):
@ -1327,7 +1334,7 @@ class Client(client_base.Client):
# Use fast clone deletion engine if it is supported.
if self.features.FAST_CLONE_DELETE:
api_args['is-clone-file'] = 'true'
self.send_request('file-delete-file', api_args, True)
self.connection.send_request('file-delete-file', api_args, True)
def _get_aggregates(self, aggregate_names=None, desired_attributes=None):
@ -1343,9 +1350,9 @@ class Client(client_base.Client):
if desired_attributes:
api_args['desired-attributes'] = desired_attributes
result = self.send_request('aggr-get-iter',
api_args,
enable_tunneling=False)
result = self.connection.send_request('aggr-get-iter',
api_args,
enable_tunneling=False)
if not self._has_records(result):
return []
else:
@ -1566,9 +1573,9 @@ class Client(client_base.Client):
}
}
result = self.send_request('perf-object-instance-list-info-iter',
api_args,
enable_tunneling=False)
result = self.connection.send_request(
'perf-object-instance-list-info-iter', api_args,
enable_tunneling=False)
uuids = []
@ -1595,9 +1602,8 @@ class Client(client_base.Client):
],
}
result = self.send_request('perf-object-get-instances',
api_args,
enable_tunneling=False)
result = self.connection.send_request(
'perf-object-get-instances', api_args, enable_tunneling=False)
counter_data = []
@ -1648,7 +1654,7 @@ class Client(client_base.Client):
},
}
result = self.send_request('snapshot-get-iter', api_args)
result = self.connection.send_request('snapshot-get-iter', api_args)
snapshots = []
@ -1689,7 +1695,7 @@ class Client(client_base.Client):
},
},
}
result = self.send_request('snapshot-get-iter', api_args)
result = self.connection.send_request('snapshot-get-iter', api_args)
self._handle_get_snapshot_return_failure(result, snapshot_name)
@ -1764,7 +1770,7 @@ class Client(client_base.Client):
if passphrase:
api_args['passphrase'] = passphrase
self.send_request('cluster-peer-create', api_args)
self.connection.send_request('cluster-peer-create', api_args)
def get_cluster_peers(self, remote_cluster_name=None):
"""Gets one or more cluster peer relationships."""
@ -1822,7 +1828,7 @@ class Client(client_base.Client):
"""Deletes a cluster peer relationship."""
api_args = {'cluster-name': cluster_name}
self.send_request('cluster-peer-delete', api_args)
self.connection.send_request('cluster-peer-delete', api_args)
def get_cluster_peer_policy(self):
"""Gets the cluster peering policy configuration."""
@ -1830,7 +1836,7 @@ class Client(client_base.Client):
if not self.features.CLUSTER_PEER_POLICY:
return {}
result = self.send_request('cluster-peer-policy-get')
result = self.connection.send_request('cluster-peer-policy-get')
attributes = result.get_child_by_name(
'attributes') or netapp_api.NaElement('none')
@ -1876,7 +1882,7 @@ class Client(client_base.Client):
api_args['passphrase-minlength'] = six.text_type(
passphrase_minimum_length)
self.send_request('cluster-peer-policy-modify', api_args)
self.connection.send_request('cluster-peer-policy-modify', api_args)
def create_vserver_peer(self, vserver_name, peer_vserver_name):
"""Creates a Vserver peer relationship for SnapMirrors."""
@ -1887,19 +1893,19 @@ class Client(client_base.Client):
{'vserver-peer-application': 'snapmirror'},
],
}
self.send_request('vserver-peer-create', api_args)
self.connection.send_request('vserver-peer-create', api_args)
def delete_vserver_peer(self, vserver_name, peer_vserver_name):
"""Deletes a Vserver peer relationship."""
api_args = {'vserver': vserver_name, 'peer-vserver': peer_vserver_name}
self.send_request('vserver-peer-delete', api_args)
self.connection.send_request('vserver-peer-delete', api_args)
def accept_vserver_peer(self, vserver_name, peer_vserver_name):
"""Accepts a pending Vserver peer relationship."""
api_args = {'vserver': vserver_name, 'peer-vserver': peer_vserver_name}
self.send_request('vserver-peer-accept', api_args)
self.connection.send_request('vserver-peer-accept', api_args)
def get_vserver_peers(self, vserver_name=None, peer_vserver_name=None):
"""Gets one or more Vserver peer relationships."""
@ -1962,7 +1968,7 @@ class Client(client_base.Client):
api_args['policy'] = policy
try:
self.send_request('snapmirror-create', api_args)
self.connection.send_request('snapmirror-create', api_args)
except netapp_api.NaApiError as e:
if e.code != netapp_api.ERELATION_EXISTS:
raise
@ -1984,7 +1990,8 @@ class Client(client_base.Client):
if transfer_priority:
api_args['transfer-priority'] = transfer_priority
result = self.send_request('snapmirror-initialize', api_args)
result = self.connection.send_request('snapmirror-initialize',
api_args)
result_info = {}
result_info['operation-id'] = result.get_child_content(
@ -2016,7 +2023,7 @@ class Client(client_base.Client):
}
}
}
self.send_request('snapmirror-release-iter', api_args)
self.connection.send_request('snapmirror-release-iter', api_args)
def quiesce_snapmirror(self, source_vserver, source_volume,
destination_vserver, destination_volume):
@ -2029,7 +2036,7 @@ class Client(client_base.Client):
'destination-volume': destination_volume,
'destination-vserver': destination_vserver,
}
self.send_request('snapmirror-quiesce', api_args)
self.connection.send_request('snapmirror-quiesce', api_args)
def abort_snapmirror(self, source_vserver, source_volume,
destination_vserver, destination_volume,
@ -2045,7 +2052,7 @@ class Client(client_base.Client):
'clear-checkpoint': 'true' if clear_checkpoint else 'false',
}
try:
self.send_request('snapmirror-abort', api_args)
self.connection.send_request('snapmirror-abort', api_args)
except netapp_api.NaApiError as e:
if e.code != netapp_api.ENOTRANSFER_IN_PROGRESS:
raise
@ -2061,7 +2068,7 @@ class Client(client_base.Client):
'destination-volume': destination_volume,
'destination-vserver': destination_vserver,
}
self.send_request('snapmirror-break', api_args)
self.connection.send_request('snapmirror-break', api_args)
def modify_snapmirror(self, source_vserver, source_volume,
destination_vserver, destination_volume,
@ -2085,7 +2092,7 @@ class Client(client_base.Client):
if max_transfer_rate is not None:
api_args['max-transfer-rate'] = max_transfer_rate
self.send_request('snapmirror-modify', api_args)
self.connection.send_request('snapmirror-modify', api_args)
def delete_snapmirror(self, source_vserver, source_volume,
destination_vserver, destination_volume):
@ -2102,7 +2109,7 @@ class Client(client_base.Client):
}
}
}
self.send_request('snapmirror-destroy-iter', api_args)
self.connection.send_request('snapmirror-destroy-iter', api_args)
def update_snapmirror(self, source_vserver, source_volume,
destination_vserver, destination_volume):
@ -2116,7 +2123,7 @@ class Client(client_base.Client):
'destination-vserver': destination_vserver,
}
try:
self.send_request('snapmirror-update', api_args)
self.connection.send_request('snapmirror-update', api_args)
except netapp_api.NaApiError as e:
if (e.code != netapp_api.ETRANSFER_IN_PROGRESS and
e.code != netapp_api.EANOTHER_OP_ACTIVE):
@ -2134,7 +2141,7 @@ class Client(client_base.Client):
'destination-vserver': destination_vserver,
}
try:
self.send_request('snapmirror-resume', api_args)
self.connection.send_request('snapmirror-resume', api_args)
except netapp_api.NaApiError as e:
if e.code != netapp_api.ERELATION_NOT_QUIESCED:
raise
@ -2150,7 +2157,7 @@ class Client(client_base.Client):
'destination-volume': destination_volume,
'destination-vserver': destination_vserver,
}
self.send_request('snapmirror-resync', api_args)
self.connection.send_request('snapmirror-resync', api_args)
def _get_snapmirrors(self, source_vserver=None, source_volume=None,
destination_vserver=None, destination_volume=None,

View File

@ -672,7 +672,6 @@ class NetAppNfsDriver(driver.ManageableVD,
else:
return False
@utils.trace_method
def _touch_path_to_refresh(self, path):
try:
# Touching parent directory forces NFS client to flush its cache.
@ -680,7 +679,6 @@ class NetAppNfsDriver(driver.ManageableVD,
except processutils.ProcessExecutionError:
LOG.exception("Failed to touch path %s.", path)
@utils.trace_method
def _discover_file_till_timeout(self, path, timeout=75):
"""Checks if file size at path is equal to size."""
# Sometimes nfs takes time to discover file

View File

@ -99,7 +99,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
ssc = self.ssc_library.get_ssc()
self.perf_library._update_for_failover(self.zapi_client, ssc)
@utils.trace_method
def check_for_setup_error(self):
"""Check that the driver is working and can communicate."""
self._add_looping_tasks()
@ -404,7 +403,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
return ssc_vol_name
return None
@utils.trace_method
def delete_volume(self, volume):
"""Deletes a logical volume."""
self._delete_backing_file_for_volume(volume)
@ -443,7 +441,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
'backend.', {'path': path_on_backend, 'file_id': file_id})
self.zapi_client.delete_file(path_on_backend)
@utils.trace_method
def delete_snapshot(self, snapshot):
"""Deletes a snapshot."""
self._delete_backing_file_for_snapshot(snapshot)
@ -660,7 +657,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
return cloned
@utils.trace_method
def unmanage(self, volume):
"""Removes the specified volume from Cinder management.
@ -705,7 +701,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
return flexvols
@utils.trace_method
def delete_group_snapshot(self, context, group_snapshot, snapshots):
"""Delete files backing each snapshot in the group snapshot.
@ -718,7 +713,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
return None, None
@utils.trace_method
def create_group(self, context, group):
"""Driver entry point for creating a generic volume group.
@ -731,7 +725,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
model_update = {'status': fields.GroupStatus.AVAILABLE}
return model_update
@utils.trace_method
def delete_group(self, context, group, volumes):
"""Driver entry point for deleting a generic volume group.
@ -753,7 +746,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
"deleted.", {'vol': volume})
return model_update, volumes_model_update
@utils.trace_method
def update_group(self, context, group, add_volumes=None,
remove_volumes=None):
"""Driver entry point for updating a generic volume group.
@ -765,7 +757,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
return None, None, None
@utils.trace_method
def create_group_snapshot(self, context, group_snapshot, snapshots):
"""Creates a Cinder group snapshot object.
@ -825,7 +816,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
self.zapi_client.mark_snapshot_for_deletion(
flexvol_name, group_snapshot['id'])
@utils.trace_method
def create_group_from_src(self, context, group, volumes,
group_snapshot=None, sorted_snapshots=None,
source_group=None, sorted_source_vols=None):

View File

@ -57,6 +57,7 @@ def get_backend_configuration(backend_name):
config.append_config_values(na_opts.netapp_cluster_opts)
config.append_config_values(na_opts.netapp_san_opts)
config.append_config_values(na_opts.netapp_replication_opts)
config.append_config_values(na_opts.netapp_support_opts)
return config
@ -72,7 +73,8 @@ def get_client_for_backend(backend_name, vserver_name=None):
hostname=config.netapp_server_hostname,
port=config.netapp_server_port,
vserver=vserver_name or config.netapp_vserver,
trace=utils.TRACE_API)
trace=utils.TRACE_API,
api_trace_pattern=config.netapp_api_trace_pattern)
return client

View File

@ -197,6 +197,15 @@ netapp_replication_opts = [
'SnapMirror transfers to complete before aborting '
'during a failover.'), ]
netapp_support_opts = [
cfg.StrOpt('netapp_api_trace_pattern',
default='(.*)',
help=('A regular expression to limit the API tracing. This '
'option is honored only if enabling ``api`` tracing '
'with the ``trace_flags`` option. By default, '
'all APIs will be traced.')),
]
CONF = cfg.CONF
CONF.register_opts(netapp_proxy_opts, group=conf.SHARED_CONF_GROUP)
CONF.register_opts(netapp_connection_opts, group=conf.SHARED_CONF_GROUP)
@ -209,3 +218,4 @@ CONF.register_opts(netapp_eseries_opts, group=conf.SHARED_CONF_GROUP)
CONF.register_opts(netapp_nfs_extra_opts, group=conf.SHARED_CONF_GROUP)
CONF.register_opts(netapp_san_opts, group=conf.SHARED_CONF_GROUP)
CONF.register_opts(netapp_replication_opts, group=conf.SHARED_CONF_GROUP)
CONF.register_opts(netapp_support_opts, group=conf.SHARED_CONF_GROUP)

View File

@ -57,6 +57,7 @@ BACKEND_QOS_CONSUMERS = frozenset(['back-end', 'both'])
# Secret length cannot be less than 96 bits. http://tools.ietf.org/html/rfc3723
CHAP_SECRET_LENGTH = 16
DEFAULT_CHAP_USER_NAME = 'NetApp_iSCSI_CHAP_Username'
API_TRACE_PATTERN = '(.*)'
def validate_instantiation(**kwargs):
@ -127,6 +128,25 @@ def get_volume_extra_specs(volume):
return extra_specs
def setup_api_trace_pattern(api_trace_pattern):
global API_TRACE_PATTERN
try:
re.compile(api_trace_pattern)
except (re.error, TypeError):
msg = _('Cannot parse the API trace pattern. %s is not a '
'valid python regular expression.') % api_trace_pattern
raise exception.InvalidConfigurationValue(reason=msg)
API_TRACE_PATTERN = api_trace_pattern
def trace_filter_func_api(all_args):
na_element = all_args.get('na_element')
if na_element is None:
return True
api_name = na_element.get_name()
return re.match(API_TRACE_PATTERN, api_name) is not None
def resolve_hostname(hostname):
"""Resolves host name to IP address."""
res = socket.getaddrinfo(hostname, None)[0]

View File

@ -0,0 +1,6 @@
---
features:
- The NetApp ONTAP driver supports a new configuration option
``netapp_api_trace_pattern`` to enable filtering backend API
interactions to log. This option must be specified in the backend
section when desired and it accepts a valid python regular expression.