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

Hpe 3par adds controller, disk, and port interfaces #105

Merged
merged 1 commit into from
May 28, 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
198 changes: 198 additions & 0 deletions delfin/drivers/hpe/hpe_3par/component_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
# 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 re

import six
from oslo_log import log
from oslo_utils import units

from delfin import exception
from delfin.common import constants
from delfin.drivers.hpe.hpe_3par import consts

LOG = log.getLogger(__name__)

Expand Down Expand Up @@ -211,3 +214,198 @@ def list_volumes(self, context):
(six.text_type(e))
LOG.error(err_msg)
raise exception.InvalidResults(err_msg)

def list_controllers(self, storage_id):
controllers = self.ssh_handler.get_controllers()
controller_list = []
if controllers:
node_cpu_map = self.ssh_handler.get_controllers_cpu()
node_version_map = self.ssh_handler.get_controllers_version()
for controller in controllers:
node_id = controller.get('node_id')
memory_size = int(controller.get('node_control_mem',
'0')) * units.Mi + int(
controller.get('node_data_mem', '0')) * units.Mi
cpu_info = ''
if node_cpu_map:
cpu_info_map = node_cpu_map.get(node_id)
cpu_info_keys = list(cpu_info_map.keys())
for cpu_key in cpu_info_keys:
if cpu_info:
cpu_info = '%s%s' % (cpu_info, ',')
cpu_info = '%s%s * %s MHz' % (
cpu_info, cpu_info_map.get(cpu_key), cpu_key)
soft_version = None
if node_version_map:
soft_version = node_version_map.get(node_id, '')
controller_model = {
'name': controller.get('node_name'),
'storage_id': storage_id,
'native_controller_id': node_id,
'status': consts.CONTROLLER_STATUS_MAP.get(
controller.get('node_state', '').upper(),
constants.ControllerStatus.OFFLINE),
'location': None,
'soft_version': soft_version,
'cpu_info': cpu_info,
'memory_size': str(memory_size)
}
controller_list.append(controller_model)
return controller_list

def list_disks(self, storage_id):
disks = self.ssh_handler.get_disks()
disk_list = []
if disks:
disks_inventory_map = self.ssh_handler.get_disks_inventory()
for disk in disks:
disk_id = disk.get('id')
status = consts.DISK_STATUS_MAP.get(
disk.get('state', '').upper(),
constants.DiskStatus.ABNORMAL)
capacity = int(float(disk.get("total", 0)) * units.Mi)
serial_number = None
manufacturer = None
model = None
firmware = None
if disks_inventory_map:
inventory_map = disks_inventory_map.get(disk_id)
if inventory_map:
serial_number = inventory_map.get('disk_serial')
manufacturer = inventory_map.get('disk_mfr')
model = inventory_map.get('disk_model')
firmware = inventory_map.get('disk_fw_rev')
speed = None
if disk.get('rpm'):
speed = int(disk.get('rpm')) * units.k
disk_model = {
'name': disk.get('cagepos'),
'storage_id': storage_id,
'native_disk_id': disk_id,
'serial_number': serial_number,
'manufacturer': manufacturer,
'model': model,
'firmware': firmware,
'speed': speed,
'capacity': capacity,
'status': status,
'physical_type': consts.DISK_PHYSICAL_TYPE_MAP.get(
disk.get('type').upper(),
constants.DiskPhysicalType.UNKNOWN),
'logical_type': None,
'health_score': None,
'native_disk_group_id': None,
'location': disk.get('cagepos')
}
disk_list.append(disk_model)
return disk_list

def list_ports(self, storage_id):
ports = self.ssh_handler.get_ports()
port_list = []
if ports:
ports_inventory_map = self.ssh_handler.get_ports_inventory()
ports_config_map = self.ssh_handler.get_ports_config()
ports_iscsi_map = self.ssh_handler.get_ports_iscsi()
ports_rcip_map = self.ssh_handler.get_ports_rcip()
ports_connected_map = self.ssh_handler.get_ports_connected()
ports_fcoe_map = self.ssh_handler.get_ports_fcoe()
port_fs_map = self.ssh_handler.get_ports_fs()
for port in ports:
port_id = port.get('n:s:p')
port_type = ''
if ports_inventory_map:
port_type = ports_inventory_map.get(port_id, '')
max_speed = ''
if ports_config_map:
max_speed = ports_config_map.get(port_id, '')
ip_addr = None
ip_mask = None
ipv4 = None
ipv4_mask = None
ipv6 = None
ipv6_mask = None
rate = ''
if ports_connected_map:
rate = ports_connected_map.get(port_id, '')
if not ip_addr and ports_iscsi_map:
iscsi_map = ports_iscsi_map.get(port_id)
if iscsi_map:
ip_addr = iscsi_map.get('ipaddr')
ip_mask = iscsi_map.get('netmask/prefixlen')
rate = iscsi_map.get('rate')
if not ip_addr and ports_rcip_map:
rcip_map = ports_rcip_map.get(port_id)
if rcip_map:
ip_addr = rcip_map.get('ipaddr')
ip_mask = rcip_map.get('netmask')
rate = rcip_map.get('rate')
if not ip_addr and port_fs_map:
fs_map = port_fs_map.get(port_id)
if fs_map:
ip_addr = fs_map.get('ipaddr')
ip_mask = fs_map.get('netmask')
rate = fs_map.get('rate')
if not rate and ports_fcoe_map:
fcoe_map = ports_fcoe_map.get(port_id)
if fcoe_map:
rate = fcoe_map.get('rate')
if ip_addr and ip_addr != '-':
pattern = re.compile(consts.IPV4_PATTERN)
search_obj = pattern.search(ip_addr)
if search_obj:
ipv4 = ip_addr
ipv4_mask = ip_mask
else:
ipv6 = ip_addr
ipv6_mask = ip_mask
wwn = None
mac = None
if port_type.upper() == 'ETH':
mac = port.get('port_wwn/hw_addr')
else:
wwn = port.get('port_wwn/hw_addr')
port_model = {
'name': port_id,
'storage_id': storage_id,
'native_port_id': port_id,
'location': port_id,
'connection_status':
consts.PORT_CONNECTION_STATUS_MAP.get(
port.get('state', '').upper(),
constants.PortConnectionStatus.UNKNOWN),
'health_status': constants.PortHealthStatus.NORMAL,
'type': consts.PORT_TYPE_MAP.get(port_type.upper(),
constants.PortType.OTHER),
'logical_type': None,
'speed': self.analyse_speed(rate),
'max_speed': self.analyse_speed(max_speed),
'native_parent_id': None,
'wwn': wwn,
'mac_address': mac,
'ipv4': ipv4,
'ipv4_mask': ipv4_mask,
'ipv6': ipv6,
'ipv6_mask': ipv6_mask,
}
port_list.append(port_model)
return port_list

def analyse_speed(self, speed_value):
speed = 0
try:
if speed_value == '' or speed_value == 'n/a':
return None
speeds = re.findall("\\d+", speed_value)
if speeds:
speed = int(speeds[0])
if 'Gbps' in speed_value:
speed = speed * units.G
elif 'Mbps' in speed_value:
speed = speed * units.M
elif 'Kbps' in speed_value:
speed = speed * units.k
except Exception as err:
err_msg = "analyse speed error: %s" % (six.text_type(err))
LOG.error(err_msg)
return speed
76 changes: 76 additions & 0 deletions delfin/drivers/hpe/hpe_3par/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# under the License.

# CPG's status
from delfin.common import constants

STATUS_POOL_NORMAL = 1 # CPG STATUS Normal operation
STATUS_POOL_DEGRADED = 2 # CPG STATUS Degraded state
STATUS_POOL_FAILED = 3 # CPG STATUS Abnormal operation
Expand Down Expand Up @@ -624,3 +626,77 @@
'0x09f0002': 'File Persona CPG grow limit warning',
'0x0a50001': 'File Access Auditing Alerts'
}
NODE_PATTERN = "^\\s*Node\\s+[-]*Name[-]*\\s+[-]*State[-]*\\s+Master\\s+"
CPU_PATTERN = "^\\s*Node\\s+CPU\\s+[-]*Manufacturer[-]*\\s+[-]*Serial[-]*" \
"\\s+CPUSpeed"
DISK_PATTERN = "^\\s*Id\\s+[-]*CagePos[-]*\\s+[-]*Type[-]*\\s+RPM\\s+State\\s+"
DISK_I_PATTERN = "^\\s*Id\\s+[-]*CagePos[-]*\\s+[-]*State[-]*\\s+" \
"[-]*Node_WWN[-]*\\s+[-]*MFR[-]*\\s+[-]*Model[-]*\\s+" \
"[-]*Serial[-]*\\s+[-]*FW_Rev[-]*"
PORT_PATTERN = "^\\s*N:S:P\\s+[-]*Mode[-]*\\s+[-]*State[-]*\\s+[-]*" \
"Node_WWN[-]*\\s+[-]*Port_WWN/HW_Addr[-]*\\s+"
PORT_I_PATTERN = "^\\s*N:S:P\\s+Brand\\s+Model\\s+Rev\\s+Firmware\\s+" \
"Serial\\s+HWType"
PORT_PER_PATTERN = "^\\s*N:S:P\\s+Connmode\\s+ConnType\\s+CfgRate\\s+MaxRate"
PORT_C_PATTERN = "^\\s*N:S:P\\s+Mode\\s+Device\\s+Pos\\s+Config\\s+" \
"Topology\\s+Rate"
PORT_ISCSI_PATTERN = "^\\s*N:S:P\\s+State\\s+IPAddr\\s+Netmask/PrefixLen\\s+" \
"Gateway"
PORT_RCIP_PATTERN = "^\\s*N:S:P\\s+State\\s+[-]*HwAddr[-]*\\s+IPAddr\\s+" \
"Netmask\\s+Gateway\\s+MTU\\s+Rate"
PORT_FCOE_PATTERN = "^\\s*N:S:P\\s+State\\s+"
PORT_FS_PATTERN = "^\\s*N:S:P\\s+State\\s+"
FPG_PATTERN = "^\\s*FPG\\s+[-]*Mountpath[-]*\\s+[-]*Size[-]*\\s+[-]*" \
"Available[-]*\\s+[-]*ActiveStates"
CPG_PATTERN = "^\\s*Id\\s+[-]*Name[-]*\\s+Warn"
VOLUME_PATTERN = "^\\s*Id\\s+Name\\s+Prov\\s+Compr\\s+Dedup"
FSTORE_PATTERN = "^\\s*Fstore\\s+VFS\\s+FPG\\s+State\\s+Mode"
FSHARE_PATTERN = "^\\s*ShareName\\s+Protocol\\s+VFS\\s+FileStore\\s+" \
"ShareDir\\s+State"
VFS_PATTERN = "^\\s*VFS\\s+FPG\\s+IPAddr\\s+State"
IPV4_PATTERN = "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$"
CONTROLLER_STATUS_MAP = {
'OK': constants.ControllerStatus.NORMAL,
'NORMAL': constants.ControllerStatus.NORMAL,
'DEGRADED': constants.ControllerStatus.OFFLINE,
'FAILED': constants.ControllerStatus.OFFLINE
}
DISK_PHYSICAL_TYPE_MAP = {
'FC': constants.DiskPhysicalType.UNKNOWN,
'SSD': constants.DiskPhysicalType.SSD,
'NL': constants.DiskPhysicalType.UNKNOWN
}
DISK_STATUS_MAP = {
'NORMAL': constants.DiskStatus.NORMAL,
'DEGRADED': constants.DiskStatus.ABNORMAL,
'FAILED': constants.DiskStatus.ABNORMAL,
'NEW': constants.DiskStatus.ABNORMAL
}
PORT_CONNECTION_STATUS_MAP = {
'CONFIG_WAIT': constants.PortConnectionStatus.DISCONNECTED,
'ALPA_WAIT': constants.PortConnectionStatus.DISCONNECTED,
'LOGIN_WAIT': constants.PortConnectionStatus.DISCONNECTED,
'READY': constants.PortConnectionStatus.CONNECTED,
'LOSS_SYNC': constants.PortConnectionStatus.DISCONNECTED,
'ERROR_STATE': constants.PortConnectionStatus.DISCONNECTED,
'XXX': constants.PortConnectionStatus.DISCONNECTED,
'NONPARTICIPATE': constants.PortConnectionStatus.DISCONNECTED,
'COREDUMP': constants.PortConnectionStatus.DISCONNECTED,
'OFFLINE': constants.PortConnectionStatus.DISCONNECTED,
'FWDEAD': constants.PortConnectionStatus.DISCONNECTED,
'IDLE_FOR_RESET': constants.PortConnectionStatus.DISCONNECTED,
'DHCP_IN_PROGRESS': constants.PortConnectionStatus.DISCONNECTED,
'PENDING_RESET': constants.PortConnectionStatus.DISCONNECTED
}
PORT_TYPE_MAP = {
'FC': constants.PortType.FC,
'ISCSI': constants.PortType.ISCSI,
'ETH': constants.PortType.ETH,
'CNA': constants.PortType.OTHER,
'SAS': constants.PortType.SAS,
'COMBO': constants.PortType.OTHER,
'NVMe': constants.PortType.OTHER,
'UNKNOWN': constants.PortType.OTHER,
'RCIP': constants.PortType.OTHER,
'RCFC': constants.PortType.OTHER
}
15 changes: 12 additions & 3 deletions delfin/drivers/hpe/hpe_3par/hpe_3parstor.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ def list_volumes(self, context):
return self.comhandler.list_volumes(context)

def list_controllers(self, context):
pass
return self.comhandler.list_controllers(self.storage_id)

def list_ports(self, context):
pass
return self.comhandler.list_ports(self.storage_id)

def list_disks(self, context):
pass
return self.comhandler.list_disks(self.storage_id)

def list_alerts(self, context, query_para=None):
return self.alert_handler.list_alerts(context, query_para)
Expand All @@ -95,3 +95,12 @@ def parse_alert(context, alert):

def clear_alert(self, context, alert):
return self.alert_handler.clear_alert(context, alert)

def list_filesystems(self, context):
pass

def list_qtrees(self, context):
pass

def list_shares(self, context):
pass
Loading