Skip to content

Commit

Permalink
Merge branch 'master' into unity_1123
Browse files Browse the repository at this point in the history
  • Loading branch information
tanjiangyu-ghca authored Dec 24, 2021
2 parents c04375e + 9162c7d commit 27bfa2e
Show file tree
Hide file tree
Showing 10 changed files with 2,218 additions and 0 deletions.
Empty file.
Empty file.
373 changes: 373 additions & 0 deletions delfin/drivers/fujitsu/eternus/cli_handler.py

Large diffs are not rendered by default.

225 changes: 225 additions & 0 deletions delfin/drivers/fujitsu/eternus/consts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# Copyright 2020 The SODA Authors.
# Copyright (c) 2016 Huawei Technologies Co., Ltd.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from delfin.common import constants

# get_storage function part
GET_STORAGE_NAME = 'show storage-system-name'
GET_STORAGE_VENDOR = 'FUJITSU'
GET_ENCLOSURE_STATUS = 'show enclosure-status'
GET_STORAGE_STATUS = 'show status'
GET_STORAGE_SERIAL_NUMBER = 'show boxid'
GET_STORAGE_FIRMWARE_VERSION = 'show firmware-version'
GET_STORAGE_TOTAL_CAPACITY = 'show storage-cluster-license'
GET_STORAGE_CONTROLLER = 'show fru-ce'
GET_STORAGE_CONTROLLER_STATUS = 'show enclosure-status -type all'
FIRMWARE_VERSION_CURRENT_COUNT = 3
FIRMWARE_VERSION_LENGTH = 4
CURRENT = 'Current'
FIRMWARE_VERSION_NUMBER = 1

# list_volume function part
GET_LIST_VOLUMES_CSV = 'show volumes -csv'
GET_LIST_VOLUMES = 'show volumes'
GET_LIST_VOLUMES_TYPE_TPV = 'show volumes -type tpv'
GET_LIST_VOLUMES_TYPE_FTV = 'show volumes -type ftv'
GET_LIST_VOLUMES_TYPE = 'show volumes -type '
VOLUMES_TYPE_FTV = 'ftv'
VOLUMES_TYPE_TPV = 'tpv'
CLI_STR = 'CLI>'
SPECIAL_CHARACTERS_ONE = '^'
SPECIAL_CHARACTERS_TWO = '--'
VOLUME_TYPE_OPEN = 'open'
VOLUME_ID_COUNT = 0
VOLUME_NAME_COUNT = 1
VOLUME_STATUS_COUNT = 2
VOLUME_TYPE_COUNT = 3
NATIVE_STORAGE_POOL_ID_COUNT = 5
TOTAL_CAPACITY_COUNT = 7
DEFAULT_USED_CAPACITY = 0
DEFAULT_FREE_CAPACITY = 0
VOLUMES_CYCLE = 5
VOLUMES_LENGTH = 6

# list_storage_pools function part
GET_STORAGE_POOL_CSV = 'show raid-groups -csv'
GET_STORAGE_POOL = 'show raid-groups'
POOL_ID_COUNT = 0
POOL_NAME_COUNT = 1
POOL_STATUS_COUNT = 4
POOL_TOTAL_CAPACITY_COUNT = 5
POOL_FREE_CAPACITY_COUNT = 6
POOL_CYCLE = 5
POOL_LENGTH = 6

GET_DISK_COMMAND = 'show disks -disk all'

# port
GET_PORT_FC_PARAMETERS = 'show fc-parameters'
GET_PORT_FCOE_PARAMETERS = 'show fcoe-parameters'
PORT_NEWLINE_PATTERN = 'CM#\\d.*Port#\\d Information'
DATA_KEY_INDEX = 1
DATA_VALUE_INDEX = 2

CONTROLLER_NEWLINE_PATTERN = 'CM#\\d Information'
COMMON_VALUE_PATTERN = '\\[.*\\]'
SIZE_PATTERN = "\\d+(?:\\.\\d+)?"
POOL_TITLE_PATTERN = "^\\[RAID Group No\\.\\],\\[RAID Group Name"
VOLUME_TITLE_PATTERN = "^\\[Volume No\\.\\],\\[Volume Name]"
CONTROLLER_STATUS_PATTERN = 'Controller Module Status/Status Code'
CONTROLLER_STATUS_NORMAL_KEY = 'Normal'

# list_disk function part
SPECIFIC_CHARACTER_ONE = '['
SPECIFIC_CHARACTER_TWO = ']'

# list_alert function
SHOW_EVENTS_SEVERITY_WARNING = 'show events -severity warning'
SHOW_EVENTS_SEVERITY_ERROR = 'show events -severity error'
SHOW_EVENTS_LEVEL_WARNING = 'show events -level warning'
SHOW_EVENTS_LEVEL_ERROR = 'show events -level error'
OCCUR_TIME_RANGE = 19
SEVERITY_RANGE_BEGIN = 22
SEVERITY_RANGE_END = 34
CODE_RANGE_BEGIN = 38
CODE_RANGE_END = 46
DESCRIPTION_RANGE = 48
TIME_PATTERN = '%Y-%m-%d %H:%M:%S'
ALERT_EXE_TIME = 5
DEFAULT_EXE_TIME = 0.5


class DIGITAL_CONSTANT(object):
ZERO_INT = 0
ONE_INT = 1
MINUS_ONE_INT = -1
TWO_INT = 2
THREE_INT = 3
FIVE_INT = 5
SIX_INT = 6
MINUS_SIX_INT = -6
SEVEN_INT = 7
THOUSAND_INT = 1000


STORAGE_STATUS_MAP = {'normal': constants.StorageStatus.NORMAL,
'offline': constants.StorageStatus.OFFLINE,
'abnormal': constants.StorageStatus.ABNORMAL,
'degraded': constants.StorageStatus.DEGRADED,
'Empty': constants.StorageStatus.OFFLINE,
'Normal': constants.StorageStatus.NORMAL,
'Pinned Data': constants.StorageStatus.OFFLINE,
'Unused': constants.StorageStatus.OFFLINE,
'Warning': constants.StorageStatus.OFFLINE,
'Maintenance': constants.StorageStatus.ABNORMAL,
'Error': constants.StorageStatus.ABNORMAL,
'Loop Down': constants.StorageStatus.OFFLINE,
'Not Ready': constants.StorageStatus.ABNORMAL,
'Subsystem Down': constants.StorageStatus.ABNORMAL,
'Change Assigned CM': constants.StorageStatus.ABNORMAL}

STORAGE_POOL_STATUS_MAP = {'Available': constants.StoragePoolStatus.NORMAL,
'Spare in Use': constants.StoragePoolStatus.NORMAL,
'Readying': constants.StoragePoolStatus.NORMAL,
'Rebuild': constants.StoragePoolStatus.NORMAL,
'Copyback': constants.StoragePoolStatus.NORMAL,
'Redundant Copy':
constants.StoragePoolStatus.NORMAL,
'Partially Exposed Rebuild':
constants.StoragePoolStatus.ABNORMAL,
'Exposed Rebuild':
constants.StoragePoolStatus.ABNORMAL,
'Exposed': constants.StoragePoolStatus.ABNORMAL,
'Partially Exposed':
constants.StoragePoolStatus.ABNORMAL,
'No Disk Path':
constants.StoragePoolStatus.ABNORMAL,
'SED Locked': constants.StoragePoolStatus.ABNORMAL,
'Broken': constants.StoragePoolStatus.ABNORMAL,
'Unknown': constants.StoragePoolStatus.ABNORMAL}

LIST_VOLUMES_STATUS_MAP = {
'normal': constants.StorageStatus.NORMAL,
'offline': constants.StorageStatus.OFFLINE,
'abnormal': constants.StorageStatus.ABNORMAL,
'degraded': constants.StorageStatus.DEGRADED,
'Available': constants.StorageStatus.NORMAL,
'Spare in Use': constants.StorageStatus.ABNORMAL,
'Readying': constants.StorageStatus.ABNORMAL,
'Rebuild': constants.StorageStatus.ABNORMAL,
'Copyback': constants.StorageStatus.ABNORMAL,
'Redundant Copy': constants.StorageStatus.ABNORMAL,
'Partially Exposed Rebuild': constants.StorageStatus.ABNORMAL,
'Exposed': constants.StorageStatus.ABNORMAL,
'Partially Exposed': constants.StorageStatus.ABNORMAL,
'Not Ready': constants.StorageStatus.ABNORMAL,
'Broken': constants.StorageStatus.ABNORMAL,
'Data Lost': constants.StorageStatus.ABNORMAL,
'Not Available': constants.StorageStatus.OFFLINE,
'Unknown': constants.StorageStatus.ABNORMAL,
}

SEVERITY_MAP = {
'Warning': constants.Severity.WARNING,
'warning': constants.Severity.WARNING,
'Error': constants.Severity.FATAL,
'error': constants.Severity.FATAL
}

DiskPhysicalTypeMap = {
'Nearline': constants.DiskPhysicalType.UNKNOWN,
'Online': constants.DiskPhysicalType.UNKNOWN,
'SSD': constants.DiskPhysicalType.SSD,
'SAS': constants.DiskPhysicalType.SAS,
'unknown': constants.DiskPhysicalType.UNKNOWN
}

DiskLogicalTypeMap = {
'Data': constants.DiskLogicalType.MEMBER,
'Spare': constants.DiskLogicalType.SPARE,
'unknown': constants.DiskLogicalType.UNKNOWN,
}

DISK_STATUS_MAP = {
'Available': constants.DiskStatus.NORMAL,
'Spare': constants.DiskStatus.NORMAL,
'Present': constants.DiskStatus.NORMAL,
'Readying': constants.DiskStatus.NORMAL,
'Rebuild/Copyback': constants.DiskStatus.NORMAL,
'Copyback': constants.DiskStatus.NORMAL,
'Rebuild': constants.DiskStatus.NORMAL,
'Redundant': constants.DiskStatus.NORMAL,
'Not Supported': constants.DiskStatus.ABNORMAL,
'Not Exist': constants.DiskStatus.ABNORMAL,
'Failed Usable': constants.DiskStatus.ABNORMAL,
'Broken': constants.DiskStatus.NORMAL,
'Not Available': constants.DiskStatus.ABNORMAL,
'Formatting': constants.DiskStatus.NORMAL,
'Not Format': constants.DiskStatus.NORMAL
}

PARSE_ALERT_ALERT_ID = '1.3.6.1.4.1.211.1.21.1.150.1.1'
PARSE_ALERT_DESCRIPTION = '1.3.6.1.4.1.211.1.21.1.150.10'
PARSE_ALERT_SEVERITY = '1.3.6.1.4.1.211.1.21.1.150.14.1.1'
PARSE_ALERT_LOCATION = '1.3.6.1.4.1.211.1.21.1.150.7'

PARSE_ALERT_SEVERITY_MAP = {
'unknown': constants.Severity.NOT_SPECIFIED,
'unused': constants.Severity.NOT_SPECIFIED,
'ok': constants.Severity.INFORMATIONAL,
'warning': constants.Severity.WARNING,
'failed': constants.Severity.FATAL
}
131 changes: 131 additions & 0 deletions delfin/drivers/fujitsu/eternus/eternus_ssh_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Copyright 2020 The SODA Authors.
# Copyright 2011 OpenStack LLC
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import time

import paramiko
import six
from oslo_log import log as logging
from cryptography.hazmat.primitives.asymmetric import dsa

from delfin import cryptor
from delfin import exception, utils
from delfin.drivers.utils.ssh_client import SSHPool

LOG = logging.getLogger(__name__)


def override_check_dsa_parameters(parameters):
if parameters.p.bit_length() not in [512, 1024, 2048, 3072, 4096]:
raise ValueError(
"p must be exactly 1024, 2048, 3072, or 4096 bits long"
)
if parameters.q.bit_length() not in [160, 224, 256]:
raise ValueError("q must be exactly 160, 224, or 256 bits long")

if not (1 < parameters.g < parameters.p):
raise ValueError("g, p don't satisfy 1 < g < p.")


dsa._check_dsa_parameters = override_check_dsa_parameters


class EternusSSHPool(SSHPool):
def create(self):
ssh = paramiko.SSHClient()
try:
if self.ssh_pub_key is None:
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
else:
host_key = '%s %s %s' % \
(self.ssh_host, self.ssh_pub_key_type,
self.ssh_pub_key)
self.set_host_key(host_key, ssh)
try:
ssh.connect(hostname=self.ssh_host, port=self.ssh_port,
username=self.ssh_username,
password=cryptor.decode(self.ssh_password),
timeout=self.ssh_conn_timeout)
except Exception as e:
if 'Authentication failed' in six.text_type(e):
ssh.connect(hostname=self.ssh_host, port=self.ssh_port,
username=self.ssh_username,
password=cryptor.decode(self.ssh_password),
timeout=self.ssh_conn_timeout,
look_for_keys=False)
else:
raise e
if self.conn_timeout:
transport = ssh.get_transport()
transport.set_keepalive(self.SOCKET_TIMEOUT)
return ssh
except Exception as e:
err = six.text_type(e)
LOG.error(err)
if 'timed out' in err:
raise exception.InvalidIpOrPort()
elif 'No authentication methods available' in err \
or 'Authentication failed' in err:
raise exception.InvalidUsernameOrPassword()
elif 'not a valid RSA private key file' in err:
raise exception.InvalidPrivateKey()
elif 'not found in known_hosts' in err:
raise exception.SSHNotFoundKnownHosts(self.ssh_host)
else:
raise exception.SSHException(err)

def do_exec_shell(self, command_list, exe_time):
result = ''
try:
with self.item() as ssh:
if command_list and ssh:
channel = ssh.invoke_shell()
for command in command_list:
utils.check_ssh_injection(command)
channel.send(command + '\r\n')
time.sleep(exe_time)
channel.send("exit" + "\r\n")
channel.close()
while True:
resp = channel.recv(9999).decode('utf8')
if not resp:
time.sleep(exe_time)
break
result += resp
if 'is not a recognized command' in result \
or 'Unknown command' in result:
raise exception.StorageBackendException(result)
except paramiko.AuthenticationException as ae:
LOG.error('doexec Authentication error:{}'.format(ae))
raise exception.InvalidUsernameOrPassword()
except Exception as e:
err = six.text_type(e)
LOG.error(err)
if 'timed out' in err \
or 'SSH connect timeout' in err:
raise exception.SSHConnectTimeout()
elif 'No authentication methods available' in err \
or 'Authentication failed' in err \
or 'Invalid username or password' in err:
raise exception.InvalidUsernameOrPassword()
elif 'not a valid RSA private key file' in err \
or 'not a valid RSA private key' in err:
raise exception.InvalidPrivateKey()
elif 'Unable to connect to port' in err \
or 'Invalid ip or port' in err:
raise exception.InvalidIpOrPort()
else:
raise exception.SSHException(err)
return result
Loading

0 comments on commit 27bfa2e

Please sign in to comment.