Merge "[NetApp ONTAP] Add filtering to API trace logging"

This commit is contained in:
Zuul 2018-07-17 19:59:25 +00:00 committed by Gerrit Code Review
commit 79bc41e025
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()
@ -405,7 +404,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)
@ -444,7 +442,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)
@ -661,7 +658,6 @@ class NetAppCmodeNfsDriver(nfs_base.NetAppNfsDriver,
return cloned
@utils.trace_method
def unmanage(self, volume):
"""Removes the specified volume from Cinder management.
@ -706,7 +702,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.
@ -719,7 +714,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.
@ -732,7 +726,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.
@ -754,7 +747,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.
@ -766,7 +758,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.
@ -826,7 +817,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.