Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pure Modifying field Values #340

Merged
merged 8 commits into from
Dec 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions delfin/drivers/pure/flasharray/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
# Normal value of the controller status
NORMAL_CONTROLLER_STATUS = 'ready'

# disk type
DISK_TYPE_NVRAM = 'NVRAM'

# The account password is incorrect during login.
LOGIN_PASSWORD_ERR = 'invalid credentials'

# list_port: Add ":" to the WWN every 2 sequences.
SPLICE_WWN_SERIAL = 2
SPLICE_WWN_COLON = ':'
Expand All @@ -64,18 +70,20 @@
'recovery': constants.Category.RECOVERY,
'notSpecified': constants.Category.NOT_SPECIFIED}
CONTROLLER_STATUS_MAP = {'normal': constants.ControllerStatus.NORMAL,
'ready': constants.ControllerStatus.NORMAL,
'ok': constants.ControllerStatus.NORMAL,
'offline': constants.ControllerStatus.OFFLINE,
'not_installed': constants.ControllerStatus.OFFLINE,
'fault': constants.ControllerStatus.FAULT,
'degraded': constants.ControllerStatus.DEGRADED,
'unknown': constants.ControllerStatus.UNKNOWN,
'unready': constants.ControllerStatus.UNKNOWN}
DISK_STATUS_MAP = {'normal': constants.DiskStatus.NORMAL,
'healthy': constants.DiskStatus.NORMAL,
'abnormal': constants.DiskStatus.ABNORMAL,
'unhealthy': constants.DiskStatus.ABNORMAL,
'offline': constants.DiskStatus.OFFLINE}

PORT_STATUS_MAP = {'ok': constants.PortHealthStatus.NORMAL,
'not_installed': constants.PortHealthStatus.ABNORMAL
}

PARSE_ALERT_ALERT_ID = '1.3.6.1.2.1.1.3.0'
PARSE_ALERT_STORAGE_NAME = '1.3.6.1.4.1.40482.3.1'
Expand Down
119 changes: 64 additions & 55 deletions delfin/drivers/pure/flasharray/pure_flasharray.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime
import hashlib
import time

from oslo_log import log

Expand Down Expand Up @@ -55,22 +56,18 @@ def get_storage(self, context):
self.rest_handler.REST_STORAGE_URL)
total_capacity = None
used_capacity = None
raw_capacity = None
if storages:
for storage in storages:
used_capacity = int(storage.get('volumes',
used_capacity = int(storage.get('total',
consts.DEFAULT_CAPACITY))
raw_capacity = int(storage.get('capacity',
consts.DEFAULT_CAPACITY))
shared_space = int(storage.get('shared_space',
consts.DEFAULT_CAPACITY))
system = int(storage.get('system', consts.DEFAULT_CAPACITY))
snapshots = int(storage.get('snapshots',
consts.DEFAULT_CAPACITY))
total_capacity =\
raw_capacity - shared_space - system - snapshots
total_capacity = int(storage.get('capacity',
consts.DEFAULT_CAPACITY))
break

raw_capacity = consts.DEFAULT_CAPACITY
disks = self.list_disks(context)
if disks:
for disk in disks:
raw_capacity = raw_capacity + disk.get('capacity')
arrays = self.rest_handler.rest_call(self.rest_handler.REST_ARRAY_URL)
storage_name = None
serial_number = None
Expand All @@ -79,7 +76,6 @@ def get_storage(self, context):
storage_name = arrays.get('array_name')
serial_number = arrays.get('id')
version = arrays.get('version')

model = None
status = constants.StorageStatus.NORMAL
controllers = self.rest_handler.rest_call(
Expand All @@ -88,8 +84,9 @@ def get_storage(self, context):
for controller in controllers:
if controller.get('mode') == consts.CONTROLLER_PRIMARY:
model = controller.get('model')
if controller.get('status') != consts.NORMAL_CONTROLLER_STATUS:
status = constants.StorageStatus.ABNORMAL
if controller.get('status') != \
consts.NORMAL_CONTROLLER_STATUS:
status = constants.StorageStatus.ABNORMAL
if not all((storages, arrays, controllers)):
LOG.error('get_storage error, Unable to obtain data.')
raise exception.StorageBackendException('Unable to obtain data')
Expand All @@ -113,26 +110,37 @@ def list_alerts(self, context, query_para=None):
if alerts:
for alert in alerts:
alerts_model = dict()
opened = alert.get('opened')
time_difference = time.mktime(
time.localtime()) - time.mktime(time.gmtime())
timestamp = (int(datetime.datetime.strptime
(opened, '%Y-%m-%dT%H:%M:%SZ').timestamp()
+ time_difference) *
consts.DEFAULT_LIST_ALERTS_TIME_CONVERSION) if\
opened is not None else None
if query_para is not None:
try:
if timestamp is None or timestamp \
< int(query_para.get('begin_time')) or \
timestamp > int(query_para.get('end_time')):
continue
except Exception as e:
LOG.error(e)
alerts_model['occur_time'] = timestamp
alerts_model['alert_id'] = alert.get('id')
alerts_model['severity'] = consts.SEVERITY_MAP.get(
alert.get('current_severity'),
constants.Severity.NOT_SPECIFIED)
alerts_model['category'] = constants.Category.FAULT
time = alert.get('opened')
alerts_model['occur_time'] = int(datetime.datetime.strptime(
time, '%Y-%m-%dT%H:%M:%SZ').timestamp()
* consts.DEFAULT_LIST_ALERTS_TIME_CONVERSION) \
if time is not None else None
component_name = alert.get('component_name')
alerts_model['location'] = component_name
alerts_model['type'] = constants.EventType.EQUIPMENT_ALARM
alerts_model['resource_type'] = constants.DEFAULT_RESOURCE_TYPE
event = alert.get('event')
alerts_model['alert_name'] = event
alerts_model['sequence_number'] = alert.get('id')
alerts_model['match_key'] = hashlib.md5(str(alert.get('id')).
encode()).hexdigest()
alerts_model['description'] = '({}:{}): {}'.\
alerts_model['description'] = '({}:{}): {}'. \
format(alert.get('component_type'), component_name, event)
alerts_list.append(alerts_model)
return alerts_list
Expand Down Expand Up @@ -171,14 +179,17 @@ def list_controllers(self, context):
list_controllers = []
controllers = self.rest_handler.rest_call(
self.rest_handler.REST_CONTROLLERS_URL)
hardware = self.get_hardware()
if controllers:
for controller in controllers:
controllers_dict = dict()
controller_name = controller.get('name')
controllers_dict['name'] = controller_name
controllers_dict['status'] = consts.CONTROLLER_STATUS_MAP. \
get(controller.get('status'),
constants.ControllerStatus.UNKNOWN)
controllers_dict['status'] = hardware.get(
controller_name, {}).get('status')
controllers_dict['status'] = consts.CONTROLLER_STATUS_MAP.get(
hardware.get(controller_name, {}).get('status'),
constants.ControllerStatus.UNKNOWN)
controllers_dict['soft_version'] = controller.get('version')
controllers_dict['storage_id'] = self.storage_id
controllers_dict['id'] = controller_name
Expand All @@ -193,10 +204,14 @@ def list_disks(self, context):
disks = self.rest_handler.rest_call(self.rest_handler.REST_DISK_URL)
if disks:
for disk in disks:
disk_type = disk.get('type')
if disk_type == consts.DISK_TYPE_NVRAM or disk_type is None:
continue
disk_dict = dict()
drive_name = disk.get('name')
disk_dict['name'] = drive_name
physical_type = disk.get('type', "").lower()
physical_type = disk_type.lower() if disk_type is not None \
else None
disk_dict['physical_type'] = physical_type \
if physical_type in constants.DiskPhysicalType.ALL else \
constants.DiskPhysicalType.UNKNOWN
Expand All @@ -211,7 +226,6 @@ def list_disks(self, context):
disk_dict['model'] = hardware_object.get('model')
disk_dict['serial_number'] = hardware_object. \
get('serial_number')

disk_dict['native_disk_id'] = drive_name
disk_dict['id'] = drive_name
disk_dict['location'] = drive_name
Expand All @@ -230,6 +244,7 @@ def get_hardware(self):
hardware_map['speed'] = hardware_value.get('speed')
hardware_map['serial_number'] = hardware_value.get('serial')
hardware_map['model'] = hardware_value.get('model')
hardware_map['status'] = hardware_value.get('status')
hardware_dict[hardware_value.get('name')] = hardware_map
return hardware_dict

Expand Down Expand Up @@ -260,25 +275,19 @@ def list_ports(self, context):
if speed is None:
hardware_result['connection_status'] = \
constants.PortConnectionStatus.UNKNOWN
hardware_result['health_status'] = constants.PortHealthStatus.\
UNKNOWN
elif speed == consts.CONSTANT_ZERO:
hardware_result['connection_status'] = \
constants.PortConnectionStatus.DISCONNECTED
hardware_result['health_status'] = constants.PortHealthStatus.\
ABNORMAL
hardware_result['speed'] = speed
else:
hardware_result['connection_status'] = \
constants.PortConnectionStatus.CONNECTED
hardware_result['health_status'] = constants.PortHealthStatus.\
NORMAL
hardware_result['speed'] = int(speed)

hardware_result['health_status'] = consts.PORT_STATUS_MAP.get(
hardware.get('status'), constants.PortHealthStatus.UNKNOWN)
port = ports.get(hardware_name)
if port:
hardware_result['wwn'] = port.get('wwn')

network = networks.get(hardware_name)
if network:
hardware_result['mac_address'] = network.get('mac_address')
Expand All @@ -288,6 +297,26 @@ def list_ports(self, context):
list_ports.append(hardware_result)
return list_ports

def get_network(self):
networks_object = dict()
networks = self.rest_handler.rest_call(
self.rest_handler.REST_NETWORK_URL)
if networks:
for network in networks:
network_dict = dict()
network_dict['mac_address'] = network.get('hwaddr')
services_list = network.get('services')
if services_list:
for services in services_list:
network_dict['logical_type'] = services if \
services in constants.PortLogicalType.ALL else None
break
network_dict['ipv4_mask'] = network.get('netmask')
network_dict['ipv4'] = network.get('address')
network_name = network.get('name').upper()
networks_object[network_name] = network_dict
return networks_object

def get_ports(self):
ports_dict = dict()
ports = self.rest_handler.rest_call(self.rest_handler.REST_PORT_URL)
Expand All @@ -311,26 +340,6 @@ def get_splice_wwn(wwn):
wwn_splice = '{}{}'.format(wwn_splice, wwn_list[serial])
return wwn_splice

def get_network(self):
networks_object = dict()
networks = self.rest_handler.rest_call(
self.rest_handler.REST_NETWORK_URL)
if networks:
for network in networks:
network_dict = dict()
network_dict['mac_address'] = network.get('hwaddr')
services_list = network.get('services')
if services_list:
for services in services_list:
network_dict['logical_type'] = services if \
services in constants.PortLogicalType.ALL else None
break
network_dict['ipv4_mask'] = network.get('netmask')
network_dict['ipv4'] = network.get('address')
network_name = network.get('name').upper()
networks_object[network_name] = network_dict
return networks_object

def list_storage_pools(self, context):
return []

Expand Down
11 changes: 8 additions & 3 deletions delfin/drivers/pure/flasharray/rest_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RestHandler(RestClient):
REST_DISK_URL = '/api/1.17/drive'
REST_HARDWARE_URL = '/api/1.17/hardware'
REST_CONTROLLERS_URL = '/api/1.17/array?controllers=true'
REST_ALERTS_URL = '/api/1.17/message?flagged=true'
REST_ALERTS_URL = '/api/1.17/message?flagged=true&open=true'
REST_AUTH_URL = '/api/1.17/auth/apitoken'
REST_SESSION_URL = '/api/1.17/auth/session'

Expand All @@ -33,6 +33,12 @@ def login(self):
self.init_http_head()
token_res = self.do_call(RestHandler.REST_AUTH_URL, data,
method='POST')
if token_res.json().get('msg') == consts.LOGIN_PASSWORD_ERR:
LOG.error("Login error, Obtaining the token is abnormal. "
"status_code:%s, URL: %s",
token_res.status_code, RestHandler.REST_AUTH_URL)
raise exception.InvalidUsernameOrPassword(
'Obtaining the token is abnormal')
if token_res.status_code != consts.SUCCESS_STATUS_CODE or not \
token_res.json().get('api_token'):
LOG.error("Login error, Obtaining the token is abnormal. "
Expand All @@ -45,8 +51,7 @@ def login(self):
if session_res.status_code != consts.SUCCESS_STATUS_CODE or not \
session_res.json().get('username'):
LOG.error("Login error, Obtaining the session is abnormal."
"status_code:%s, URL: %s",
session_res.status_code,
"status_code:%s, URL: %s", session_res.status_code,
RestHandler.REST_SESSION_URL)
raise exception.StorageBackendException(
'Obtaining the session is abnormal.')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,8 @@ def test_list_volumes(self):

def test_get_storage(self):
RestHandler.rest_call = mock.Mock(
side_effect=[storage_info, storage_id_info, controllers_info])
side_effect=[storage_info, hardware_info, drive_info,
storage_id_info, controllers_info])
storage_object = self.driver.get_storage(context)
self.assertEqual(storage_object.get('name'),
storage_id_info.get('array_name'))
Expand All @@ -319,7 +320,7 @@ def test_parse_alert(self):

def test_list_controllers(self):
RestHandler.rest_call = mock.Mock(
side_effect=[controllers_info])
side_effect=[controllers_info, hardware_info])
list_controllers = self.driver.list_controllers(context)
self.assertEqual(list_controllers[0].get('name'),
controllers_info[0].get('name'))
Expand Down