Merge "Add serial number to eseries ASUP payload"
This commit is contained in:
@@ -595,6 +595,8 @@ VOLUME_MAPPING_TO_MULTIATTACH_GROUP.update(
|
||||
)
|
||||
|
||||
STORAGE_SYSTEM = {
|
||||
'chassisSerialNumber': 1,
|
||||
'fwVersion': '08.10.15.00',
|
||||
'freePoolSpace': 11142431623168,
|
||||
'driveCount': 24,
|
||||
'hostSparesUsed': 0, 'id':
|
||||
@@ -667,7 +669,26 @@ SNAPSHOT_IMAGE = {
|
||||
'pitSequenceNumber': '19'
|
||||
}
|
||||
|
||||
HARDWARE_INVENTORY_SINGLE_CONTROLLER = {
|
||||
'controllers': [
|
||||
{
|
||||
'modelName': '2752',
|
||||
'serialNumber': '021436001321'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
HARDWARE_INVENTORY = {
|
||||
'controllers': [
|
||||
{
|
||||
'modelName': '2752',
|
||||
'serialNumber': '021436000943'
|
||||
},
|
||||
{
|
||||
'modelName': '2752',
|
||||
'serialNumber': '021436001321'
|
||||
}
|
||||
],
|
||||
'iscsiPorts': [
|
||||
{
|
||||
'controllerId':
|
||||
@@ -806,7 +827,6 @@ FAKE_POOL_ACTION_PROGRESS = [
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
FAKE_RESOURCE_URL = '/devmgr/v2/devmgr/utils/about'
|
||||
FAKE_APP_VERSION = '2015.2|2015.2.dev59|vendor|Linux-3.13.0-24-generic'
|
||||
FAKE_BACKEND = 'eseriesiSCSI'
|
||||
@@ -840,8 +860,17 @@ FAKE_ASUP_DATA = {
|
||||
'model': FAKE_CONTROLLERS[0]['modelName'],
|
||||
'controller2-serial': FAKE_CONTROLLERS[1]['serialNumber'],
|
||||
'controller1-serial': FAKE_CONTROLLERS[0]['serialNumber'],
|
||||
'chassis-serial-number': FAKE_SERIAL_NUMBER[0],
|
||||
'operating-mode': 'proxy',
|
||||
}
|
||||
|
||||
GET_ASUP_RETURN = {
|
||||
'model': FAKE_CONTROLLERS[0]['modelName'],
|
||||
'serial_numbers': FAKE_SERIAL_NUMBERS,
|
||||
'firmware_version': FAKE_ASUP_DATA['system-version'],
|
||||
'chassis_sn': FAKE_ASUP_DATA['chassis-serial-number'],
|
||||
}
|
||||
|
||||
FAKE_POST_INVOKE_DATA = ('POST', '/key-values/%s' % FAKE_KEY,
|
||||
json.dumps(FAKE_ASUP_DATA))
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@ from cinder.tests.unit.volume.drivers.netapp.eseries import fakes as \
|
||||
eseries_fake
|
||||
from cinder.volume.drivers.netapp.eseries import exception as es_exception
|
||||
|
||||
|
||||
from cinder.volume.drivers.netapp.eseries import client
|
||||
from cinder.volume.drivers.netapp import utils as na_utils
|
||||
|
||||
@@ -359,16 +358,8 @@ class NetAppEseriesClientDriverTestCase(test.TestCase):
|
||||
eseries_fake.FAKE_ASUP_DATA['operating-mode'],
|
||||
eseries_fake.FAKE_ABOUT_RESPONSE['version'])))
|
||||
self.mock_object(
|
||||
self.my_client, 'get_firmware_version',
|
||||
mock.Mock(
|
||||
return_value=eseries_fake.FAKE_ABOUT_RESPONSE['version']))
|
||||
self.mock_object(
|
||||
self.my_client, 'get_serial_numbers',
|
||||
mock.Mock(return_value=eseries_fake.FAKE_SERIAL_NUMBERS))
|
||||
self.mock_object(
|
||||
self.my_client, 'get_model_name',
|
||||
mock.Mock(
|
||||
return_value=eseries_fake.FAKE_CONTROLLERS[0]['modelName']))
|
||||
self.my_client, 'get_asup_info',
|
||||
mock.Mock(return_value=eseries_fake.GET_ASUP_RETURN))
|
||||
self.mock_object(
|
||||
self.my_client, 'set_counter',
|
||||
mock.Mock(return_value={'value': 1}))
|
||||
@@ -385,38 +376,48 @@ class NetAppEseriesClientDriverTestCase(test.TestCase):
|
||||
mock_invoke.assert_called_with(*eseries_fake.FAKE_POST_INVOKE_DATA)
|
||||
|
||||
@ddt.data((eseries_fake.FAKE_SERIAL_NUMBERS,
|
||||
eseries_fake.FAKE_CONTROLLERS),
|
||||
(eseries_fake.FAKE_DEFAULT_SERIAL_NUMBER, []),
|
||||
eseries_fake.HARDWARE_INVENTORY),
|
||||
(eseries_fake.FAKE_DEFAULT_SERIAL_NUMBER, {}),
|
||||
(eseries_fake.FAKE_SERIAL_NUMBER,
|
||||
eseries_fake.FAKE_SINGLE_CONTROLLER))
|
||||
eseries_fake.HARDWARE_INVENTORY_SINGLE_CONTROLLER))
|
||||
@ddt.unpack
|
||||
def test_get_serial_numbers(self, expected_serial_numbers, controllers):
|
||||
def test_get_asup_info_serial_numbers(self, expected_serial_numbers,
|
||||
controllers):
|
||||
self.mock_object(
|
||||
client.RestClient, '_get_controllers',
|
||||
client.RestClient, 'list_hardware_inventory',
|
||||
mock.Mock(return_value=controllers))
|
||||
|
||||
serial_numbers = client.RestClient.get_serial_numbers(self.my_client)
|
||||
|
||||
self.assertEqual(expected_serial_numbers, serial_numbers)
|
||||
|
||||
def test_get_model_name(self):
|
||||
self.mock_object(
|
||||
client.RestClient, '_get_controllers',
|
||||
mock.Mock(return_value=eseries_fake.FAKE_CONTROLLERS))
|
||||
client.RestClient, 'list_storage_system',
|
||||
mock.Mock(return_value={}))
|
||||
|
||||
model = client.RestClient.get_model_name(self.my_client)
|
||||
sn = client.RestClient.get_asup_info(self.my_client)['serial_numbers']
|
||||
|
||||
self.assertEqual(eseries_fake.FAKE_CONTROLLERS[0]['modelName'],
|
||||
model)
|
||||
self.assertEqual(expected_serial_numbers, sn)
|
||||
|
||||
def test_get_model_name_empty_controllers_list(self):
|
||||
def test_get_asup_info_model_name(self):
|
||||
self.mock_object(
|
||||
client.RestClient, '_get_controllers',
|
||||
mock.Mock(return_value=[]))
|
||||
client.RestClient, 'list_hardware_inventory',
|
||||
mock.Mock(return_value=eseries_fake.HARDWARE_INVENTORY))
|
||||
self.mock_object(
|
||||
client.RestClient, 'list_storage_system',
|
||||
mock.Mock(return_value=eseries_fake.STORAGE_SYSTEM))
|
||||
|
||||
model = client.RestClient.get_model_name(self.my_client)
|
||||
model_name = client.RestClient.get_asup_info(self.my_client)['model']
|
||||
|
||||
self.assertEqual(eseries_fake.FAKE_DEFAULT_MODEL, model)
|
||||
self.assertEqual(eseries_fake.HARDWARE_INVENTORY['controllers'][0]
|
||||
['modelName'], model_name)
|
||||
|
||||
def test_get_asup_info_model_name_empty_controllers_list(self):
|
||||
self.mock_object(
|
||||
client.RestClient, 'list_hardware_inventory',
|
||||
mock.Mock(return_value={}))
|
||||
self.mock_object(
|
||||
client.RestClient, 'list_storage_system',
|
||||
mock.Mock(return_value={}))
|
||||
|
||||
model_name = client.RestClient.get_asup_info(self.my_client)['model']
|
||||
|
||||
self.assertEqual(eseries_fake.FAKE_DEFAULT_MODEL, model_name)
|
||||
|
||||
def test_get_eseries_api_info(self):
|
||||
fake_invoke_service = mock.Mock()
|
||||
@@ -712,8 +713,7 @@ class NetAppEseriesClientDriverTestCase(test.TestCase):
|
||||
|
||||
self.my_client._invoke.assert_called_once_with('DELETE', url,
|
||||
**{'object-id':
|
||||
fake_volume['id']}
|
||||
)
|
||||
fake_volume['id']})
|
||||
|
||||
@ddt.data('00.00.00.00', '01.52.9000.2', '01.52.9001.2', '01.51.9000.3',
|
||||
'01.51.9001.3', '01.51.9010.5', '0.53.9000.3', '0.53.9001.4')
|
||||
@@ -782,7 +782,6 @@ class NetAppEseriesClientDriverTestCase(test.TestCase):
|
||||
|
||||
@ddt.ddt
|
||||
class TestWebserviceClientTestCase(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""sets up the mock tests"""
|
||||
super(TestWebserviceClientTestCase, self).setUp()
|
||||
|
||||
@@ -950,16 +950,8 @@ class NetAppEseriesLibraryTestCase(test.TestCase):
|
||||
eseries_fake.FAKE_ASUP_DATA['operating-mode'])
|
||||
self.library._app_version = eseries_fake.FAKE_APP_VERSION
|
||||
self.mock_object(
|
||||
self.library._client, 'get_firmware_version',
|
||||
mock.Mock(return_value=(
|
||||
eseries_fake.FAKE_ASUP_DATA['system-version'])))
|
||||
self.mock_object(
|
||||
self.library._client, 'get_serial_numbers',
|
||||
mock.Mock(return_value=eseries_fake.FAKE_SERIAL_NUMBERS))
|
||||
self.mock_object(
|
||||
self.library._client, 'get_model_name',
|
||||
mock.Mock(
|
||||
return_value=eseries_fake.FAKE_CONTROLLERS[0]['modelName']))
|
||||
self.library._client, 'get_asup_info',
|
||||
mock.Mock(return_value=eseries_fake.GET_ASUP_RETURN))
|
||||
self.mock_object(
|
||||
self.library._client, 'set_counter',
|
||||
mock.Mock(return_value={'value': 1}))
|
||||
|
||||
@@ -731,17 +731,44 @@ class RestClient(WebserviceClient):
|
||||
path = ('/key-values/%s' % key)
|
||||
self._invoke('POST', path, json.dumps(data))
|
||||
|
||||
def get_firmware_version(self):
|
||||
"""Get firmware version information from the array."""
|
||||
return self.list_storage_system()['fwVersion']
|
||||
|
||||
def set_counter(self, key, value):
|
||||
path = ('/counters/%s/setCounter?value=%d' % (key, value))
|
||||
self._invoke('POST', path)
|
||||
|
||||
def _get_controllers(self):
|
||||
"""Get controller information from the array."""
|
||||
return self.list_hardware_inventory()['controllers']
|
||||
def get_asup_info(self):
|
||||
"""Returns a dictionary of relevant autosupport information.
|
||||
|
||||
Currently returned fields are:
|
||||
model -- E-series model name
|
||||
serial_numbers -- Serial number for each controller
|
||||
firmware_version -- Version of active firmware
|
||||
chassis_sn -- Serial number for whole chassis
|
||||
"""
|
||||
asup_info = {}
|
||||
|
||||
controllers = self.list_hardware_inventory().get('controllers')
|
||||
if controllers:
|
||||
asup_info['model'] = controllers[0].get('modelName', 'unknown')
|
||||
serial_numbers = [value['serialNumber'].rstrip()
|
||||
for __, value in enumerate(controllers)]
|
||||
serial_numbers.sort()
|
||||
for index, value in enumerate(serial_numbers):
|
||||
if not value:
|
||||
serial_numbers[index] = 'unknown'
|
||||
asup_info['serial_numbers'] = serial_numbers
|
||||
else:
|
||||
asup_info['model'] = 'unknown'
|
||||
asup_info['serial_numbers'] = ['unknown', 'unknown']
|
||||
|
||||
system_info = self.list_storage_system()
|
||||
if system_info:
|
||||
asup_info['firmware_version'] = system_info['fwVersion']
|
||||
asup_info['chassis_sn'] = system_info['chassisSerialNumber']
|
||||
else:
|
||||
asup_info['firmware_version'] = 'unknown'
|
||||
asup_info['chassis_sn'] = 'unknown'
|
||||
|
||||
return asup_info
|
||||
|
||||
def get_eseries_api_info(self, verify=False):
|
||||
"""Get E-Series API information from the array."""
|
||||
@@ -759,23 +786,3 @@ class RestClient(WebserviceClient):
|
||||
if mode_is_proxy:
|
||||
api_operating_mode = 'proxy'
|
||||
return api_operating_mode, about_response_dict['version']
|
||||
|
||||
def get_serial_numbers(self):
|
||||
"""Get the list of Serial Numbers from the array."""
|
||||
controllers = self._get_controllers()
|
||||
if not controllers:
|
||||
return ['unknown', 'unknown']
|
||||
serial_numbers = [value['serialNumber'].rstrip()
|
||||
for _, value in enumerate(controllers)]
|
||||
serial_numbers.sort()
|
||||
for index, value in enumerate(serial_numbers):
|
||||
if not value:
|
||||
serial_numbers[index] = 'unknown'
|
||||
return serial_numbers
|
||||
|
||||
def get_model_name(self):
|
||||
"""Get Model Name from the array."""
|
||||
controllers = self._get_controllers()
|
||||
if not controllers:
|
||||
return 'unknown'
|
||||
return controllers[0].get('modelName', 'unknown')
|
||||
|
||||
@@ -1023,12 +1023,14 @@ class NetAppESeriesLibrary(object):
|
||||
LOG.info(msg % self._client.api_version)
|
||||
return
|
||||
|
||||
firmware_version = self._client.get_firmware_version()
|
||||
event_source = ("Cinder driver %s" % self.DRIVER_NAME)
|
||||
category = "provisioning"
|
||||
event_description = "OpenStack Cinder connected to E-Series proxy"
|
||||
model = self._client.get_model_name()
|
||||
serial_numbers = self._client.get_serial_numbers()
|
||||
asup_info = self._client.get_asup_info()
|
||||
model = asup_info.get('model')
|
||||
firmware_version = asup_info.get('firmware_version')
|
||||
serial_numbers = asup_info.get('serial_numbers')
|
||||
chassis_sn = asup_info.get('chassis_sn')
|
||||
|
||||
key = ("openstack-%s-%s-%s"
|
||||
% (cinder_host, serial_numbers[0], serial_numbers[1]))
|
||||
@@ -1046,6 +1048,7 @@ class NetAppESeriesLibrary(object):
|
||||
'event-description': event_description,
|
||||
'controller1-serial': serial_numbers[0],
|
||||
'controller2-serial': serial_numbers[1],
|
||||
'chassis-serial-number': chassis_sn,
|
||||
'model': model,
|
||||
'system-version': firmware_version,
|
||||
'operating-mode': self._client.api_operating_mode
|
||||
|
||||
Reference in New Issue
Block a user