Merge "Add oem data"
This commit is contained in:
commit
4b902f2233
@ -19,13 +19,13 @@ CPU model : {{ system.get_cpumodel() }}
|
|||||||
|
|
||||||
{%- if system.processors_collection %}
|
{%- if system.processors_collection %}
|
||||||
CPU details :
|
CPU details :
|
||||||
{%- for cpu_index in system.processors_collection.processors_dict | sort %}
|
{%- for cpu_index in system.processors_collection.processors_dict | sort %}
|
||||||
{%- set cpu = system.processors_collection.processors_dict[cpu_index] %}
|
{%- set cpu = system.processors_collection.processors_dict[cpu_index] %}
|
||||||
Processor id {{ cpu_index }} :
|
Processor id {{ cpu_index }} :
|
||||||
Speed : {{ cpu.get_speed() }}
|
Speed : {{ cpu.get_speed() }}
|
||||||
Cores : {{ cpu.get_cores() }}
|
Cores : {{ cpu.get_cores() }}
|
||||||
Threads : {{ cpu.get_threads() }}
|
Threads : {{ cpu.get_threads() }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
Available memory : {{ system.get_memory() }} GB
|
Available memory : {{ system.get_memory() }} GB
|
||||||
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
||||||
@ -47,8 +47,27 @@ Ethernet Interface :
|
|||||||
Address ipv6 : {{ ei.get_ipv6() | join(', ') }}
|
Address ipv6 : {{ ei.get_ipv6() | join(', ') }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
This system has no ethernet interface
|
This system has no ethernet interface as Redfish standard data
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
Looking for potential OEM information :
|
||||||
|
{%- if system.data.Oem.Hp %}
|
||||||
|
Supplemental information from HPE OEM part.
|
||||||
|
{%- if system.network_adapters_collection %}
|
||||||
|
{%- for networkadapter_index in system.network_adapters_collection.network_adapters_dict | sort %}
|
||||||
|
{%- set na = system.network_adapters_collection.network_adapters_dict[networkadapter_index] %}
|
||||||
|
Network adapter id {{ networkadapter_index }} :
|
||||||
|
{{ na.get_name() }}
|
||||||
|
{#- Removing these information because the FW is not providing them correctly
|
||||||
|
{{ na.get_structured_name() }}
|
||||||
|
{{ na.get_uefi_path() }}
|
||||||
|
#}
|
||||||
|
Mac address : {{ na.get_mac() | join(', ') }}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- else %}
|
||||||
|
This system has no supplemental OEM information
|
||||||
|
{%- endif %}
|
||||||
|
|
||||||
|
|
||||||
Simple Storage :
|
Simple Storage :
|
||||||
{%- if system.simple_storage_collection %}
|
{%- if system.simple_storage_collection %}
|
||||||
@ -57,12 +76,33 @@ Simple Storage :
|
|||||||
Simple Storage id {{ simplestorage_index }} :
|
Simple Storage id {{ simplestorage_index }} :
|
||||||
{{ ss.get_name() }}
|
{{ ss.get_name() }}
|
||||||
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
||||||
{%- for dev in ss.get_devices() %}
|
{%- for dev in ss.get_devices() %}
|
||||||
Device id {{ loop.index }} : {{ dev.Name }} {{ dev.Manufacturer }} {{ dev.Model }}
|
Device id {{ loop.index }} : {{ dev.Name }} {{ dev.Manufacturer }} {{ dev.Model }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
This system has no simple storage
|
This system has no simple storage as Redfish standard data
|
||||||
|
{%- endif %}
|
||||||
|
Looking for potential OEM information :
|
||||||
|
{%- if system.data.Oem.Hp %}
|
||||||
|
Supplemental information from HPE OEM part.
|
||||||
|
{%- if system.smart_storage %}
|
||||||
|
{%- for array_controllers_index in system.smart_storage.array_controllers_collection.array_controllers_dict | sort %}
|
||||||
|
{%- set ac = system.smart_storage.array_controllers_collection.array_controllers_dict[array_controllers_index] %}
|
||||||
|
Array controller id {{ array_controllers_index }} :
|
||||||
|
{{ ac.get_name() }}
|
||||||
|
{%- for logical_drives_index in ac.logical_drives_collection.logical_drives_dict | sort %}
|
||||||
|
{%- set ld = ac.logical_drives_collection.logical_drives_dict[logical_drives_index] %}
|
||||||
|
Logical drive id {{ logical_drives_index }} :
|
||||||
|
{{ ld.get_name() }}
|
||||||
|
Status : State : {{ ld.get_status().Health }} / Health : {{ ld.get_status().Health }}
|
||||||
|
Capacity : {{ ld.get_capacity() }} MB
|
||||||
|
Raid : {{ ld.get_raid() }}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endfor %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- else %}
|
||||||
|
This system has no supplemental OEM information
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
{% endfor %}
|
{% endfor %}
|
@ -128,7 +128,7 @@ import json
|
|||||||
from urllib.parse import urlparse, urljoin, urlunparse
|
from urllib.parse import urlparse, urljoin, urlunparse
|
||||||
import requests
|
import requests
|
||||||
from . import config
|
from . import config
|
||||||
from . import types
|
from . import standard
|
||||||
from . import mapping
|
from . import mapping
|
||||||
from . import exception
|
from . import exception
|
||||||
standard_library.install_aliases()
|
standard_library.install_aliases()
|
||||||
@ -207,8 +207,8 @@ class RedfishConnection(object):
|
|||||||
|
|
||||||
config.logger.debug("Root url : %s",
|
config.logger.debug("Root url : %s",
|
||||||
self.connection_parameters.rooturl)
|
self.connection_parameters.rooturl)
|
||||||
self.Root = types.Root(self.connection_parameters.rooturl,
|
self.Root = standard.Root(self.connection_parameters.rooturl,
|
||||||
self.connection_parameters)
|
self.connection_parameters)
|
||||||
|
|
||||||
config.logger.info("API Version : %s", self.get_api_version())
|
config.logger.info("API Version : %s", self.get_api_version())
|
||||||
mapping.redfish_version = self.get_api_version()
|
mapping.redfish_version = self.get_api_version()
|
||||||
@ -236,21 +236,21 @@ class RedfishConnection(object):
|
|||||||
# TODO : Add a switch to allow the both structure
|
# TODO : Add a switch to allow the both structure
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
|
|
||||||
# Types
|
# standard
|
||||||
self.SessionService = types.SessionService(
|
self.SessionService = standard.SessionService(
|
||||||
self.Root.get_link_url(
|
self.Root.get_link_url(
|
||||||
mapping.redfish_mapper.map_sessionservice()),
|
mapping.redfish_mapper.map_sessionservice()),
|
||||||
self.connection_parameters)
|
self.connection_parameters)
|
||||||
|
|
||||||
self.Managers = types.ManagersCollection(
|
self.Managers = standard.ManagersCollection(
|
||||||
self.Root.get_link_url("Managers"),
|
self.Root.get_link_url("Managers"),
|
||||||
self.connection_parameters)
|
self.connection_parameters)
|
||||||
|
|
||||||
self.Systems = types.SystemsCollection(
|
self.Systems = standard.SystemsCollection(
|
||||||
self.Root.get_link_url("Systems"),
|
self.Root.get_link_url("Systems"),
|
||||||
self.connection_parameters)
|
self.connection_parameters)
|
||||||
|
|
||||||
self.Chassis = types.ChassisCollection(
|
self.Chassis = standard.ChassisCollection(
|
||||||
self.Root.get_link_url("Chassis"), self.connection_parameters)
|
self.Root.get_link_url("Chassis"), self.connection_parameters)
|
||||||
|
|
||||||
# self.EventService
|
# self.EventService
|
||||||
|
13
redfish/oem/__init__.py
Normal file
13
redfish/oem/__init__.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# 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.
|
155
redfish/oem/hpe.py
Normal file
155
redfish/oem/hpe.py
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from future import standard_library
|
||||||
|
|
||||||
|
import re
|
||||||
|
from ..types import Base, BaseCollection, Device
|
||||||
|
standard_library.install_aliases()
|
||||||
|
|
||||||
|
# Global variable
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkAdaptersCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish hpe oem NetworkAdaptersCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(NetworkAdaptersCollection, self).__init__(url,
|
||||||
|
connection_parameters)
|
||||||
|
self.network_adapters_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'NetworkAdapters/(\w+)', link)
|
||||||
|
self.network_adapters_dict[index.group(1)] = NetworkAdapters(
|
||||||
|
link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class NetworkAdapters(Device):
|
||||||
|
'''Class to manage redfish hpe oem NetworkAdapters data.'''
|
||||||
|
|
||||||
|
def get_mac(self):
|
||||||
|
'''Get NetworkAdapters mac address
|
||||||
|
|
||||||
|
:returns: mac adresses or "Not available"
|
||||||
|
:rtype: list
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
macaddresses = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
for port in self.data.PhysicalPorts:
|
||||||
|
mac = port['MacAddress']
|
||||||
|
macaddresses.append(mac)
|
||||||
|
|
||||||
|
return macaddresses
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_structured_name(self):
|
||||||
|
'''Get NetworkAdapters StructuredName
|
||||||
|
|
||||||
|
:returns: StructuredName or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.StructuredName
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_uefi_path(self):
|
||||||
|
'''Get networkadapters uefi path
|
||||||
|
|
||||||
|
:returns: UEFIDevicePath or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.UEFIDevicePath
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
|
class SmartStorage(Base):
|
||||||
|
'''Class to manage redfish hpe oem SmartStorage data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(SmartStorage, self).__init__(url, connection_parameters)
|
||||||
|
try:
|
||||||
|
self.array_controllers_collection = \
|
||||||
|
ArrayControllersCollection(
|
||||||
|
self.get_link_url('ArrayControllers', self.data.Links),
|
||||||
|
connection_parameters)
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have ArrayControllers
|
||||||
|
self.array_controllers_collection = None
|
||||||
|
|
||||||
|
|
||||||
|
class ArrayControllersCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish hpe oem ArrayControllersCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(ArrayControllersCollection, self).__init__(url,
|
||||||
|
connection_parameters)
|
||||||
|
self.array_controllers_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'ArrayControllers/(\w+)', link)
|
||||||
|
self.array_controllers_dict[index.group(1)] = ArrayControllers(
|
||||||
|
link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class ArrayControllers(Device):
|
||||||
|
'''Class to manage redfish hpe oem ArrayControllers data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(ArrayControllers, self).__init__(url, connection_parameters)
|
||||||
|
try:
|
||||||
|
self.logical_drives_collection = \
|
||||||
|
LogicalDrivesCollection(
|
||||||
|
self.get_link_url('LogicalDrives', self.data.Links),
|
||||||
|
connection_parameters)
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have ArrayControllers
|
||||||
|
self.logical_drives_collection = None
|
||||||
|
|
||||||
|
|
||||||
|
class LogicalDrivesCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish hpe oem LogicalDrivesCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(LogicalDrivesCollection, self).__init__(url,
|
||||||
|
connection_parameters)
|
||||||
|
self.logical_drives_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'LogicalDrives/(\w+)', link)
|
||||||
|
self.logical_drives_dict[index.group(1)] = LogicalDrives(
|
||||||
|
link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class LogicalDrives(Device):
|
||||||
|
'''Class to manage redfish hpe oem LogicalDrives data.'''
|
||||||
|
def get_capacity(self):
|
||||||
|
'''Get Logical drive capacity
|
||||||
|
|
||||||
|
:returns: Logical drive capacity or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.CapacityMiB
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_raid(self):
|
||||||
|
'''Get Logical drive raid configuration
|
||||||
|
|
||||||
|
:returns: Logical drive raid configuration or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.Raid
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
736
redfish/standard.py
Normal file
736
redfish/standard.py
Normal file
@ -0,0 +1,736 @@
|
|||||||
|
# coding=utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from future import standard_library
|
||||||
|
|
||||||
|
import re
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
import requests
|
||||||
|
from .types import Base, BaseCollection, Device
|
||||||
|
from . import mapping
|
||||||
|
from . import exception
|
||||||
|
from .oem import hpe
|
||||||
|
standard_library.install_aliases()
|
||||||
|
|
||||||
|
|
||||||
|
class Root(Base):
|
||||||
|
'''Class to manage redfish Root data.'''
|
||||||
|
def get_api_version(self):
|
||||||
|
'''Return api version.
|
||||||
|
|
||||||
|
:returns: api version
|
||||||
|
:rtype: string
|
||||||
|
:raises: AttributeError
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
version = self.data.RedfishVersion
|
||||||
|
except AttributeError:
|
||||||
|
version = self.data.ServiceVersion
|
||||||
|
|
||||||
|
version = version.replace('.', '')
|
||||||
|
version = version[0] + '.' + version[1:]
|
||||||
|
return(version)
|
||||||
|
|
||||||
|
def get_api_UUID(self):
|
||||||
|
'''Return api UUID.
|
||||||
|
|
||||||
|
:returns: api UUID
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
return self.data.UUID
|
||||||
|
|
||||||
|
|
||||||
|
class SessionService(Base):
|
||||||
|
'''Class to manage redfish SessionService data.'''
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Managers(Device):
|
||||||
|
'''Class to manage redfish Managers.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(Managers, self).__init__(url, connection_parameters)
|
||||||
|
try:
|
||||||
|
# New proliant firmware now respects Redfish v1.00, so seems to
|
||||||
|
# correct below statement
|
||||||
|
# TODO : better handle exception and if possible support
|
||||||
|
# old firmware ?
|
||||||
|
self.ethernet_interfaces_collection = \
|
||||||
|
EthernetInterfacesCollection(
|
||||||
|
self.get_link_url('EthernetInterfaces'),
|
||||||
|
connection_parameters)
|
||||||
|
|
||||||
|
# Works on proliant, need to treat 095 vs 0.96 differences
|
||||||
|
# self.ethernet_interfaces_collection = \
|
||||||
|
# EthernetInterfacesCollection(
|
||||||
|
# self.get_link_url('EthernetNICs'),
|
||||||
|
# connection_parameters)
|
||||||
|
except exception.InvalidRedfishContentException:
|
||||||
|
# This is to avoid invalid content from the mockup
|
||||||
|
self.ethernet_interfaces_collection = None
|
||||||
|
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have EthernetInterfaces
|
||||||
|
self.ethernet_interfaces_collection = None
|
||||||
|
|
||||||
|
def get_type(self):
|
||||||
|
'''Get manager type
|
||||||
|
|
||||||
|
:returns: manager type or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.ManagerType
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_firmware_version(self):
|
||||||
|
'''Get firmware version of the manager
|
||||||
|
|
||||||
|
:returns: string -- bios version or "Not available"
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.FirmwareVersion
|
||||||
|
except AttributeError:
|
||||||
|
# We are here because the attribute could be not defined.
|
||||||
|
# This is the case with the mockup for manager 2 and 3
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_managed_chassis(self):
|
||||||
|
'''Get managed chassis ids by the manager
|
||||||
|
|
||||||
|
:returns: chassis ids or "Not available"
|
||||||
|
:rtype: list
|
||||||
|
|
||||||
|
'''
|
||||||
|
chassis_list = []
|
||||||
|
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
||||||
|
|
||||||
|
try:
|
||||||
|
for chassis in links.ManagerForChassis:
|
||||||
|
result = re.search(
|
||||||
|
r'Chassis/(\w+)',
|
||||||
|
chassis[mapping.redfish_mapper.map_links_ref(chassis)])
|
||||||
|
chassis_list.append(result.group(1))
|
||||||
|
return chassis_list
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_managed_systems(self):
|
||||||
|
'''Get managed systems ids by the manager
|
||||||
|
|
||||||
|
:returns: systems ids or "Not available"
|
||||||
|
:rtype: list
|
||||||
|
|
||||||
|
'''
|
||||||
|
systems_list = []
|
||||||
|
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
||||||
|
|
||||||
|
try:
|
||||||
|
for systems in links.ManagerForServers:
|
||||||
|
result = re.search(
|
||||||
|
r'Systems/(\w+)',
|
||||||
|
systems[mapping.redfish_mapper.map_links_ref(systems)])
|
||||||
|
systems_list.append(result.group(1))
|
||||||
|
return systems_list
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
'''Reset the manager.
|
||||||
|
|
||||||
|
:returns: string -- http response of POST request
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Craft the request
|
||||||
|
link = getattr(self.data.Actions, "#Manager.Reset")
|
||||||
|
link = link.target
|
||||||
|
|
||||||
|
reset_url = urljoin(self.url, link)
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
reset_url,
|
||||||
|
verify=self.connection_parameters.verify_cert,
|
||||||
|
headers=self.connection_parameters.headers)
|
||||||
|
# TODO : treat response.
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
class ManagersCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish ManagersCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
'''Class constructor'''
|
||||||
|
super(ManagersCollection, self).__init__(url, connection_parameters)
|
||||||
|
self.managers_dict = {}
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'Managers/(\w+)', link)
|
||||||
|
self.managers_dict[index.group(1)] = Managers(
|
||||||
|
link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class Systems(Device):
|
||||||
|
'''Class to manage redfish Systems data.'''
|
||||||
|
# TODO : Need to discuss with Bruno the required method.
|
||||||
|
# Also to check with the ironic driver requirement.
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
'''Class constructor'''
|
||||||
|
super(Systems, self).__init__(url, connection_parameters)
|
||||||
|
try:
|
||||||
|
self.bios = Bios(url + 'Bios/Settings', connection_parameters)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.ethernet_interfaces_collection = \
|
||||||
|
EthernetInterfacesCollection(
|
||||||
|
self.get_link_url('EthernetInterfaces'),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have EthernetInterfaces
|
||||||
|
self.ethernet_interfaces_collection = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.processors_collection = \
|
||||||
|
ProcessorsCollection(
|
||||||
|
self.get_link_url('Processors'),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have Processors detailed data
|
||||||
|
self.processors_collection = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.simple_storage_collection = \
|
||||||
|
SimpleStorageCollection(
|
||||||
|
self.get_link_url('SimpleStorage'),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have Processors detailed data
|
||||||
|
self.simple_storage_collection = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.data.Oem.Hp
|
||||||
|
try:
|
||||||
|
self.network_adapters_collection = \
|
||||||
|
hpe.NetworkAdaptersCollection(
|
||||||
|
self.get_link_url('NetworkAdapters',
|
||||||
|
self.data.Oem.Hp.Links),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have NetworkAdapters
|
||||||
|
self.network_adapters_collection = None
|
||||||
|
try:
|
||||||
|
self.smart_storage = \
|
||||||
|
hpe.SmartStorage(
|
||||||
|
self.get_link_url('SmartStorage',
|
||||||
|
self.data.Oem.Hp.Links),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have SmartStorage
|
||||||
|
self.smart_storage = None
|
||||||
|
except AttributeError:
|
||||||
|
# This means we don't have oem data
|
||||||
|
pass
|
||||||
|
|
||||||
|
def reset_system(self):
|
||||||
|
'''Force reset of the system.
|
||||||
|
|
||||||
|
:returns: string -- http response of POST request
|
||||||
|
|
||||||
|
'''
|
||||||
|
# Craft the request
|
||||||
|
action = dict()
|
||||||
|
action['Action'] = 'Reset'
|
||||||
|
action['ResetType'] = 'ForceRestart'
|
||||||
|
|
||||||
|
# Debug the url and perform the POST action
|
||||||
|
# print self.api_url
|
||||||
|
response = self.api_url.post(
|
||||||
|
verify=self.connection_parameters.verify_cert,
|
||||||
|
headers=self.connection_parameters.headers,
|
||||||
|
data=action)
|
||||||
|
# TODO : treat response.
|
||||||
|
return response
|
||||||
|
|
||||||
|
def get_bios_version(self):
|
||||||
|
'''Get bios version of the system.
|
||||||
|
|
||||||
|
:returns: bios version or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.BiosVersion
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_hostname(self):
|
||||||
|
'''Get hostname of the system.
|
||||||
|
|
||||||
|
:returns: hostname or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.HostName
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_indicatorled(self):
|
||||||
|
'''Get indicatorled of the system.
|
||||||
|
|
||||||
|
:returns: indicatorled status or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.IndicatorLED
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_power(self):
|
||||||
|
'''Get power status of the system.
|
||||||
|
|
||||||
|
:returns: system power state or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.PowerState
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
'''Get description of the system.
|
||||||
|
|
||||||
|
:returns: system description or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.Description
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_cpucount(self):
|
||||||
|
'''Get the number of cpu in the system.
|
||||||
|
|
||||||
|
:returns: number of cpu or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.ProcessorSummary.Count
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_cpumodel(self):
|
||||||
|
'''Get the cpu model available in the system.
|
||||||
|
|
||||||
|
:returns: cpu model or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.ProcessorSummary.Model
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_memory(self):
|
||||||
|
'''Get the memory available in the system.
|
||||||
|
|
||||||
|
:returns: memory available or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.MemorySummary.TotalSystemMemoryGiB
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_type(self):
|
||||||
|
'''Get system type
|
||||||
|
|
||||||
|
:returns: system type or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.SystemType
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_chassis(self):
|
||||||
|
'''Get chassis ids used by the system
|
||||||
|
|
||||||
|
:returns: chassis ids or "Not available"
|
||||||
|
:rtype: list
|
||||||
|
|
||||||
|
'''
|
||||||
|
chassis_list = []
|
||||||
|
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
||||||
|
|
||||||
|
try:
|
||||||
|
for chassis in links.Chassis:
|
||||||
|
result = re.search(
|
||||||
|
r'Chassis/(\w+)',
|
||||||
|
chassis[mapping.redfish_mapper.map_links_ref(chassis)])
|
||||||
|
chassis_list.append(result.group(1))
|
||||||
|
return chassis_list
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_managers(self):
|
||||||
|
'''Get manager ids used by the system
|
||||||
|
|
||||||
|
:returns: managers ids or "Not available"
|
||||||
|
:rtype: list
|
||||||
|
|
||||||
|
'''
|
||||||
|
managers_list = []
|
||||||
|
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
||||||
|
|
||||||
|
try:
|
||||||
|
for manager in links.ManagedBy:
|
||||||
|
result = re.search(
|
||||||
|
r'Managers/(\w+)',
|
||||||
|
manager[mapping.redfish_mapper.map_links_ref(manager)])
|
||||||
|
managers_list.append(result.group(1))
|
||||||
|
return managers_list
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def set_parameter_json(self, value):
|
||||||
|
'''Generic function to set any system parameter using json structure
|
||||||
|
|
||||||
|
:param value: json structure with value to update
|
||||||
|
:returns: string -- http response of PATCH request
|
||||||
|
|
||||||
|
'''
|
||||||
|
# perform the POST action
|
||||||
|
# print self.api_url.url()
|
||||||
|
response = requests.patch(
|
||||||
|
self.api_url.url(),
|
||||||
|
verify=self.connection_parameters.verify_cert,
|
||||||
|
headers=self.connection_parameters.headers,
|
||||||
|
data=value)
|
||||||
|
return response.reason
|
||||||
|
|
||||||
|
def set_boot_source_override(self, target, enabled):
|
||||||
|
'''Shotcut function to set boot source
|
||||||
|
|
||||||
|
:param target: new boot source. Supported values:
|
||||||
|
"None",
|
||||||
|
"Pxe",
|
||||||
|
"Floppy",
|
||||||
|
"Cd",
|
||||||
|
"Usb",
|
||||||
|
"Hdd",
|
||||||
|
"BiosSetup",
|
||||||
|
"Utilities",
|
||||||
|
"Diags",
|
||||||
|
"UefiShell",
|
||||||
|
"UefiTarget"
|
||||||
|
:param enabled: Supported values:
|
||||||
|
"Disabled",
|
||||||
|
"Once",
|
||||||
|
"Continuous"
|
||||||
|
:returns: string -- http response of PATCH request
|
||||||
|
'''
|
||||||
|
return self.set_parameter_json(
|
||||||
|
'{"Boot": {"BootSourceOverrideTarget": "' +
|
||||||
|
target + '"},{"BootSourceOverrideEnabled" : "' + enabled + '"}}')
|
||||||
|
|
||||||
|
|
||||||
|
class SystemsCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish SystemsCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(SystemsCollection, self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
self.systems_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'Systems/(\w+)', link)
|
||||||
|
self.systems_dict[index.group(1)] = Systems(
|
||||||
|
link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class Bios(Base):
|
||||||
|
'''Class to manage redfish Bios data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(Bios, self).__init__(url, connection_parameters)
|
||||||
|
self.boot = Boot(re.findall('.+/Bios', url)[0] +
|
||||||
|
'/Boot/Settings', connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class Boot(Base):
|
||||||
|
'''Class to manage redfish Boot data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(Boot, self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class EthernetInterfacesCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish EthernetInterfacesColkection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(EthernetInterfacesCollection,
|
||||||
|
self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
self.ethernet_interfaces_dict = {}
|
||||||
|
|
||||||
|
# Url returned by the mock up is wrong
|
||||||
|
# /redfish/v1/Managers/EthernetInterfaces/1 returns a 404.
|
||||||
|
# --> this is not true anymore (2016/01/03)
|
||||||
|
# The correct one should be /redfish/v1/Managers/1/EthernetInterfaces/1
|
||||||
|
# --> correct by mockup return invalid content (not json)
|
||||||
|
# Check more than 1 hour for this bug.... grrr....
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'EthernetInterfaces/(\w+)', link)
|
||||||
|
self.ethernet_interfaces_dict[index.group(1)] = \
|
||||||
|
EthernetInterfaces(link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class EthernetInterfaces(Base):
|
||||||
|
'''Class to manage redfish EthernetInterfaces.'''
|
||||||
|
def get_mac(self):
|
||||||
|
'''Get EthernetInterface MacAddress
|
||||||
|
|
||||||
|
:returns: string -- interface macaddress or "Not available"
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
# Proliant firmware seems to not follow redfish systax
|
||||||
|
return self.data.MacAddress
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
return self.data.MACAddress
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_fqdn(self):
|
||||||
|
'''Get EthernetInterface fqdn
|
||||||
|
|
||||||
|
:returns: string -- interface fqdn or "Not available"
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.FQDN
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_ipv4(self):
|
||||||
|
'''Get EthernetInterface ipv4 address
|
||||||
|
|
||||||
|
:returns: list -- interface ip addresses or "Not available"
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
ipaddresses = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
for ip_settings in self.data.IPv4Addresses:
|
||||||
|
address = ip_settings['Address']
|
||||||
|
ipaddresses.append(address)
|
||||||
|
|
||||||
|
return ipaddresses
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_ipv6(self):
|
||||||
|
'''Get EthernetInterface ipv6 address
|
||||||
|
|
||||||
|
:returns: list -- interface ip addresses or "Not available"
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
ipaddresses = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
for ip_settings in self.data.IPv6Addresses:
|
||||||
|
address = ip_settings['Address']
|
||||||
|
ipaddresses.append(address)
|
||||||
|
|
||||||
|
return ipaddresses
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
|
class ProcessorsCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish ProcessorsCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(ProcessorsCollection,
|
||||||
|
self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
self.processors_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'Processors/(\w+)', link)
|
||||||
|
self.processors_dict[index.group(1)] = \
|
||||||
|
Processors(link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class Processors(Base):
|
||||||
|
'''Class to manage redfish Processors.'''
|
||||||
|
def get_speed(self):
|
||||||
|
'''Get processor speed
|
||||||
|
|
||||||
|
:returns: processor speed or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.MaxSpeedMHz
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_cores(self):
|
||||||
|
'''Get processor cores number
|
||||||
|
|
||||||
|
:returns: cores number or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.TotalCores
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_threads(self):
|
||||||
|
'''Get processor threads number
|
||||||
|
|
||||||
|
:returns: threads number or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.TotalThreads
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleStorageCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish SimpleStorageCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(SimpleStorageCollection,
|
||||||
|
self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
self.simple_storage_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'SimpleStorage/(\w+)', link)
|
||||||
|
self.simple_storage_dict[index.group(1)] = \
|
||||||
|
SimpleStorage(link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleStorage(Base):
|
||||||
|
'''Class to manage redfish SimpleStorage'''
|
||||||
|
def get_status(self):
|
||||||
|
'''Get storage status
|
||||||
|
|
||||||
|
:returns: storage status or "Not available"
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.Status
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_devices(self):
|
||||||
|
'''Get storage devices
|
||||||
|
|
||||||
|
:returns: storage devices or "Not available"
|
||||||
|
:rtype: list of dict
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.Devices
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
|
class ChassisCollection(BaseCollection):
|
||||||
|
'''Class to manage redfish ChassisCollection data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
super(ChassisCollection, self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
self.chassis_dict = {}
|
||||||
|
|
||||||
|
for link in self.links:
|
||||||
|
index = re.search(r'Chassis/(\w+)', link)
|
||||||
|
self.chassis_dict[index.group(1)] = Chassis(
|
||||||
|
link, connection_parameters)
|
||||||
|
|
||||||
|
|
||||||
|
class Chassis(Device):
|
||||||
|
'''Class to manage redfish Chassis data.'''
|
||||||
|
def __init__(self, url, connection_parameters):
|
||||||
|
'''Class constructor'''
|
||||||
|
super(Chassis, self).__init__(url, connection_parameters)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.thermal = Thermal(self.get_link_url('Thermal'),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
self.thermal = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.power = Power(self.get_link_url('Power'),
|
||||||
|
connection_parameters)
|
||||||
|
except AttributeError:
|
||||||
|
self.Power = None
|
||||||
|
|
||||||
|
def get_type(self):
|
||||||
|
'''Get chassis type
|
||||||
|
|
||||||
|
:returns: chassis type or "Not available"
|
||||||
|
:rtype: string
|
||||||
|
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
return self.data.ChassisType
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
|
class Thermal(Base):
|
||||||
|
'''Class to manage redfish Thermal data.'''
|
||||||
|
def get_temperatures(self):
|
||||||
|
'''Get chassis sensors name and temparature
|
||||||
|
|
||||||
|
:returns: chassis sensor and temperature
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
'''
|
||||||
|
temperatures = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
for sensor in self.data.Temperatures:
|
||||||
|
temperatures[sensor.Name] = sensor.ReadingCelsius
|
||||||
|
return temperatures
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
def get_fans(self):
|
||||||
|
'''Get chassis fan name and rpm
|
||||||
|
|
||||||
|
:returns: chassis fan and rpm
|
||||||
|
:rtype: dict
|
||||||
|
|
||||||
|
'''
|
||||||
|
fans = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
for fan in self.data.Fans:
|
||||||
|
fans[fan.FanName] = fan.ReadingRPM
|
||||||
|
return fans
|
||||||
|
except AttributeError:
|
||||||
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
|
class Power(Base):
|
||||||
|
'''Class to manage redfish Power data.'''
|
||||||
|
pass
|
710
redfish/types.py
710
redfish/types.py
@ -7,7 +7,6 @@ from future import standard_library
|
|||||||
from builtins import object
|
from builtins import object
|
||||||
|
|
||||||
import pprint
|
import pprint
|
||||||
import re
|
|
||||||
from urllib.parse import urljoin
|
from urllib.parse import urljoin
|
||||||
import requests
|
import requests
|
||||||
import simplejson
|
import simplejson
|
||||||
@ -18,7 +17,6 @@ from . import mapping
|
|||||||
from . import exception
|
from . import exception
|
||||||
standard_library.install_aliases()
|
standard_library.install_aliases()
|
||||||
|
|
||||||
standard_library.install_aliases()
|
|
||||||
|
|
||||||
# Global variable
|
# Global variable
|
||||||
|
|
||||||
@ -57,24 +55,29 @@ class Base(object):
|
|||||||
raise exception.InvalidRedfishContentException(msg)
|
raise exception.InvalidRedfishContentException(msg)
|
||||||
config.logger.debug(pprint.PrettyPrinter(indent=4).pformat(self.data))
|
config.logger.debug(pprint.PrettyPrinter(indent=4).pformat(self.data))
|
||||||
|
|
||||||
def get_link_url(self, link_type):
|
def get_link_url(self, link_type, data_subset=None):
|
||||||
'''Need to be explained.
|
'''Need to be explained.
|
||||||
|
|
||||||
:param parameter_name: name of the parameter
|
:param parameter_name: name of the parameter
|
||||||
:returns: string -- parameter value
|
:returns: string -- parameter value
|
||||||
'''
|
'''
|
||||||
|
if not data_subset:
|
||||||
|
data = self.data
|
||||||
|
else:
|
||||||
|
data = data_subset
|
||||||
|
|
||||||
self.links = []
|
self.links = []
|
||||||
|
|
||||||
# Manage standard < 1.0
|
# Manage standard < 1.0
|
||||||
if float(mapping.redfish_version) < 1.00:
|
if float(mapping.redfish_version) < 1.00:
|
||||||
links = getattr(self.data, mapping.redfish_mapper.map_links())
|
links = getattr(data, mapping.redfish_mapper.map_links())
|
||||||
if link_type in links:
|
if link_type in links:
|
||||||
return urljoin(
|
return urljoin(
|
||||||
self.url,
|
self.url,
|
||||||
links[link_type][mapping.redfish_mapper.map_links_ref()])
|
links[link_type][mapping.redfish_mapper.map_links_ref()])
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
else:
|
else:
|
||||||
links = getattr(self.data, link_type)
|
links = getattr(data, link_type)
|
||||||
link = getattr(links, mapping.redfish_mapper.map_links_ref())
|
link = getattr(links, mapping.redfish_mapper.map_links_ref())
|
||||||
return urljoin(self.url, link)
|
return urljoin(self.url, link)
|
||||||
|
|
||||||
@ -268,700 +271,3 @@ class Device(Base):
|
|||||||
return self.data.PartNumber
|
return self.data.PartNumber
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return "Not available"
|
return "Not available"
|
||||||
|
|
||||||
|
|
||||||
class Root(Base):
|
|
||||||
'''Class to manage redfish Root data.'''
|
|
||||||
def get_api_version(self):
|
|
||||||
'''Return api version.
|
|
||||||
|
|
||||||
:returns: api version
|
|
||||||
:rtype: string
|
|
||||||
:raises: AttributeError
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
version = self.data.RedfishVersion
|
|
||||||
except AttributeError:
|
|
||||||
version = self.data.ServiceVersion
|
|
||||||
|
|
||||||
version = version.replace('.', '')
|
|
||||||
version = version[0] + '.' + version[1:]
|
|
||||||
return(version)
|
|
||||||
|
|
||||||
def get_api_UUID(self):
|
|
||||||
'''Return api UUID.
|
|
||||||
|
|
||||||
:returns: api UUID
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
return self.data.UUID
|
|
||||||
|
|
||||||
|
|
||||||
class SessionService(Base):
|
|
||||||
'''Class to manage redfish SessionService data.'''
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Managers(Device):
|
|
||||||
'''Class to manage redfish Managers.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(Managers, self).__init__(url, connection_parameters)
|
|
||||||
try:
|
|
||||||
# New proliant firmware now respects Redfish v1.00, so seems to
|
|
||||||
# correct below statement
|
|
||||||
# TODO : better handle exception and if possible support
|
|
||||||
# old firmware ?
|
|
||||||
self.ethernet_interfaces_collection = \
|
|
||||||
EthernetInterfacesCollection(
|
|
||||||
self.get_link_url('EthernetInterfaces'),
|
|
||||||
connection_parameters)
|
|
||||||
|
|
||||||
# Works on proliant, need to treat 095 vs 0.96 differences
|
|
||||||
# self.ethernet_interfaces_collection = \
|
|
||||||
# EthernetInterfacesCollection(
|
|
||||||
# self.get_link_url('EthernetNICs'),
|
|
||||||
# connection_parameters)
|
|
||||||
except exception.InvalidRedfishContentException:
|
|
||||||
# This is to avoid invalid content from the mockup
|
|
||||||
self.ethernet_interfaces_collection = None
|
|
||||||
|
|
||||||
except AttributeError:
|
|
||||||
# This means we don't have EthernetInterfaces
|
|
||||||
self.ethernet_interfaces_collection = None
|
|
||||||
|
|
||||||
def get_type(self):
|
|
||||||
'''Get manager type
|
|
||||||
|
|
||||||
:returns: manager type or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.ManagerType
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_firmware_version(self):
|
|
||||||
'''Get firmware version of the manager
|
|
||||||
|
|
||||||
:returns: string -- bios version or "Not available"
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.FirmwareVersion
|
|
||||||
except AttributeError:
|
|
||||||
# We are here because the attribute could be not defined.
|
|
||||||
# This is the case with the mockup for manager 2 and 3
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_managed_chassis(self):
|
|
||||||
'''Get managed chassis ids by the manager
|
|
||||||
|
|
||||||
:returns: chassis ids or "Not available"
|
|
||||||
:rtype: list
|
|
||||||
|
|
||||||
'''
|
|
||||||
chassis_list = []
|
|
||||||
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
|
||||||
|
|
||||||
try:
|
|
||||||
for chassis in links.ManagerForChassis:
|
|
||||||
result = re.search(
|
|
||||||
r'Chassis/(\w+)',
|
|
||||||
chassis[mapping.redfish_mapper.map_links_ref(chassis)])
|
|
||||||
chassis_list.append(result.group(1))
|
|
||||||
return chassis_list
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_managed_systems(self):
|
|
||||||
'''Get managed systems ids by the manager
|
|
||||||
|
|
||||||
:returns: systems ids or "Not available"
|
|
||||||
:rtype: list
|
|
||||||
|
|
||||||
'''
|
|
||||||
systems_list = []
|
|
||||||
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
|
||||||
|
|
||||||
try:
|
|
||||||
for systems in links.ManagerForServers:
|
|
||||||
result = re.search(
|
|
||||||
r'Systems/(\w+)',
|
|
||||||
systems[mapping.redfish_mapper.map_links_ref(systems)])
|
|
||||||
systems_list.append(result.group(1))
|
|
||||||
return systems_list
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
'''Reset the manager.
|
|
||||||
|
|
||||||
:returns: string -- http response of POST request
|
|
||||||
|
|
||||||
'''
|
|
||||||
# Craft the request
|
|
||||||
link = getattr(self.data.Actions, "#Manager.Reset")
|
|
||||||
link = link.target
|
|
||||||
|
|
||||||
reset_url = urljoin(self.url, link)
|
|
||||||
|
|
||||||
response = requests.post(
|
|
||||||
reset_url,
|
|
||||||
verify=self.connection_parameters.verify_cert,
|
|
||||||
headers=self.connection_parameters.headers)
|
|
||||||
# TODO : treat response.
|
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
class ManagersCollection(BaseCollection):
|
|
||||||
'''Class to manage redfish ManagersCollection data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
'''Class constructor'''
|
|
||||||
super(ManagersCollection, self).__init__(url, connection_parameters)
|
|
||||||
self.managers_dict = {}
|
|
||||||
for link in self.links:
|
|
||||||
index = re.search(r'Managers/(\w+)', link)
|
|
||||||
self.managers_dict[index.group(1)] = Managers(
|
|
||||||
link, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class Systems(Device):
|
|
||||||
'''Class to manage redfish Systems data.'''
|
|
||||||
# TODO : Need to discuss with Bruno the required method.
|
|
||||||
# Also to check with the ironic driver requirement.
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
'''Class constructor'''
|
|
||||||
super(Systems, self).__init__(url, connection_parameters)
|
|
||||||
try:
|
|
||||||
self.bios = Bios(url + 'Bios/Settings', connection_parameters)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.ethernet_interfaces_collection = \
|
|
||||||
EthernetInterfacesCollection(
|
|
||||||
self.get_link_url('EthernetInterfaces'),
|
|
||||||
connection_parameters)
|
|
||||||
except AttributeError:
|
|
||||||
# This means we don't have EthernetInterfaces
|
|
||||||
self.ethernet_interfaces_collection = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.processors_collection = \
|
|
||||||
ProcessorsCollection(
|
|
||||||
self.get_link_url('Processors'),
|
|
||||||
connection_parameters)
|
|
||||||
except AttributeError:
|
|
||||||
# This means we don't have Processors detailed data
|
|
||||||
self.processors_collection = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.simple_storage_collection = \
|
|
||||||
SimpleStorageCollection(
|
|
||||||
self.get_link_url('SimpleStorage'),
|
|
||||||
connection_parameters)
|
|
||||||
except AttributeError:
|
|
||||||
# This means we don't have Processors detailed data
|
|
||||||
self.simple_storage_collection = None
|
|
||||||
|
|
||||||
def reset_system(self):
|
|
||||||
'''Force reset of the system.
|
|
||||||
|
|
||||||
:returns: string -- http response of POST request
|
|
||||||
|
|
||||||
'''
|
|
||||||
# Craft the request
|
|
||||||
action = dict()
|
|
||||||
action['Action'] = 'Reset'
|
|
||||||
action['ResetType'] = 'ForceRestart'
|
|
||||||
|
|
||||||
# Debug the url and perform the POST action
|
|
||||||
# print self.api_url
|
|
||||||
response = self.api_url.post(
|
|
||||||
verify=self.connection_parameters.verify_cert,
|
|
||||||
headers=self.connection_parameters.headers,
|
|
||||||
data=action)
|
|
||||||
# TODO : treat response.
|
|
||||||
return response
|
|
||||||
|
|
||||||
def get_bios_version(self):
|
|
||||||
'''Get bios version of the system.
|
|
||||||
|
|
||||||
:returns: bios version or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.BiosVersion
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_hostname(self):
|
|
||||||
'''Get hostname of the system.
|
|
||||||
|
|
||||||
:returns: hostname or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.HostName
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_indicatorled(self):
|
|
||||||
'''Get indicatorled of the system.
|
|
||||||
|
|
||||||
:returns: indicatorled status or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.IndicatorLED
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_power(self):
|
|
||||||
'''Get power status of the system.
|
|
||||||
|
|
||||||
:returns: system power state or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.PowerState
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_description(self):
|
|
||||||
'''Get description of the system.
|
|
||||||
|
|
||||||
:returns: system description or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.Description
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_cpucount(self):
|
|
||||||
'''Get the number of cpu in the system.
|
|
||||||
|
|
||||||
:returns: number of cpu or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.ProcessorSummary.Count
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_cpumodel(self):
|
|
||||||
'''Get the cpu model available in the system.
|
|
||||||
|
|
||||||
:returns: cpu model or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.ProcessorSummary.Model
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_memory(self):
|
|
||||||
'''Get the memory available in the system.
|
|
||||||
|
|
||||||
:returns: memory available or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.MemorySummary.TotalSystemMemoryGiB
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_type(self):
|
|
||||||
'''Get system type
|
|
||||||
|
|
||||||
:returns: system type or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.SystemType
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_chassis(self):
|
|
||||||
'''Get chassis ids used by the system
|
|
||||||
|
|
||||||
:returns: chassis ids or "Not available"
|
|
||||||
:rtype: list
|
|
||||||
|
|
||||||
'''
|
|
||||||
chassis_list = []
|
|
||||||
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
|
||||||
|
|
||||||
try:
|
|
||||||
for chassis in links.Chassis:
|
|
||||||
result = re.search(
|
|
||||||
r'Chassis/(\w+)',
|
|
||||||
chassis[mapping.redfish_mapper.map_links_ref(chassis)])
|
|
||||||
chassis_list.append(result.group(1))
|
|
||||||
return chassis_list
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_managers(self):
|
|
||||||
'''Get manager ids used by the system
|
|
||||||
|
|
||||||
:returns: managers ids or "Not available"
|
|
||||||
:rtype: list
|
|
||||||
|
|
||||||
'''
|
|
||||||
managers_list = []
|
|
||||||
links = getattr(self.data, mapping.redfish_mapper.map_links(self.data))
|
|
||||||
|
|
||||||
try:
|
|
||||||
for manager in links.ManagedBy:
|
|
||||||
result = re.search(
|
|
||||||
r'Managers/(\w+)',
|
|
||||||
manager[mapping.redfish_mapper.map_links_ref(manager)])
|
|
||||||
managers_list.append(result.group(1))
|
|
||||||
return managers_list
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def set_parameter_json(self, value):
|
|
||||||
'''Generic function to set any system parameter using json structure
|
|
||||||
|
|
||||||
:param value: json structure with value to update
|
|
||||||
:returns: string -- http response of PATCH request
|
|
||||||
|
|
||||||
'''
|
|
||||||
# perform the POST action
|
|
||||||
# print self.api_url.url()
|
|
||||||
response = requests.patch(
|
|
||||||
self.api_url.url(),
|
|
||||||
verify=self.connection_parameters.verify_cert,
|
|
||||||
headers=self.connection_parameters.headers,
|
|
||||||
data=value)
|
|
||||||
return response.reason
|
|
||||||
|
|
||||||
def set_boot_source_override(self, target, enabled):
|
|
||||||
'''Shotcut function to set boot source
|
|
||||||
|
|
||||||
:param target: new boot source. Supported values:
|
|
||||||
"None",
|
|
||||||
"Pxe",
|
|
||||||
"Floppy",
|
|
||||||
"Cd",
|
|
||||||
"Usb",
|
|
||||||
"Hdd",
|
|
||||||
"BiosSetup",
|
|
||||||
"Utilities",
|
|
||||||
"Diags",
|
|
||||||
"UefiShell",
|
|
||||||
"UefiTarget"
|
|
||||||
:param enabled: Supported values:
|
|
||||||
"Disabled",
|
|
||||||
"Once",
|
|
||||||
"Continuous"
|
|
||||||
:returns: string -- http response of PATCH request
|
|
||||||
'''
|
|
||||||
return self.set_parameter_json(
|
|
||||||
'{"Boot": {"BootSourceOverrideTarget": "' +
|
|
||||||
target + '", "BootSourceOverrideEnabled" : "' + enabled + '"}}')
|
|
||||||
|
|
||||||
|
|
||||||
class SystemsCollection(BaseCollection):
|
|
||||||
'''Class to manage redfish SystemsCollection data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(SystemsCollection, self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
self.systems_dict = {}
|
|
||||||
|
|
||||||
for link in self.links:
|
|
||||||
index = re.search(r'Systems/(\w+)', link)
|
|
||||||
self.systems_dict[index.group(1)] = Systems(
|
|
||||||
link, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class Bios(Base):
|
|
||||||
'''Class to manage redfish Bios data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(Bios, self).__init__(url, connection_parameters)
|
|
||||||
self.boot = Boot(re.findall('.+/Bios', url)[0] +
|
|
||||||
'/Boot/Settings', connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class Boot(Base):
|
|
||||||
'''Class to manage redfish Boot data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(Boot, self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class EthernetInterfacesCollection(BaseCollection):
|
|
||||||
'''Class to manage redfish EthernetInterfacesColkection data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(EthernetInterfacesCollection,
|
|
||||||
self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
self.ethernet_interfaces_dict = {}
|
|
||||||
|
|
||||||
# Url returned by the mock up is wrong
|
|
||||||
# /redfish/v1/Managers/EthernetInterfaces/1 returns a 404.
|
|
||||||
# --> this is not true anymore (2016/01/03)
|
|
||||||
# The correct one should be /redfish/v1/Managers/1/EthernetInterfaces/1
|
|
||||||
# --> correct by mockup return invalid content (not json)
|
|
||||||
# Check more than 1 hour for this bug.... grrr....
|
|
||||||
for link in self.links:
|
|
||||||
index = re.search(r'EthernetInterfaces/(\w+)', link)
|
|
||||||
self.ethernet_interfaces_dict[index.group(1)] = \
|
|
||||||
EthernetInterfaces(link, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class EthernetInterfaces(Base):
|
|
||||||
'''Class to manage redfish EthernetInterfaces.'''
|
|
||||||
def get_mac(self):
|
|
||||||
'''Get EthernetInterface MacAddress
|
|
||||||
|
|
||||||
:returns: string -- interface macaddress or "Not available"
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
# Proliant firmware seems to not follow redfish systax
|
|
||||||
return self.data.MacAddress
|
|
||||||
except AttributeError:
|
|
||||||
try:
|
|
||||||
return self.data.MACAddress
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_fqdn(self):
|
|
||||||
'''Get EthernetInterface fqdn
|
|
||||||
|
|
||||||
:returns: string -- interface fqdn or "Not available"
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.FQDN
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_ipv4(self):
|
|
||||||
'''Get EthernetInterface ipv4 address
|
|
||||||
|
|
||||||
:returns: list -- interface ip addresses or "Not available"
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
ipaddresses = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
for ip_settings in self.data.IPv4Addresses:
|
|
||||||
address = ip_settings['Address']
|
|
||||||
ipaddresses.append(address)
|
|
||||||
|
|
||||||
return ipaddresses
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_ipv6(self):
|
|
||||||
'''Get EthernetInterface ipv6 address
|
|
||||||
|
|
||||||
:returns: list -- interface ip addresses or "Not available"
|
|
||||||
|
|
||||||
'''
|
|
||||||
|
|
||||||
ipaddresses = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
for ip_settings in self.data.IPv6Addresses:
|
|
||||||
address = ip_settings['Address']
|
|
||||||
ipaddresses.append(address)
|
|
||||||
|
|
||||||
return ipaddresses
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessorsCollection(BaseCollection):
|
|
||||||
'''Class to manage redfish ProcessorsCollection data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(ProcessorsCollection,
|
|
||||||
self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
self.processors_dict = {}
|
|
||||||
|
|
||||||
for link in self.links:
|
|
||||||
index = re.search(r'Processors/(\w+)', link)
|
|
||||||
self.processors_dict[index.group(1)] = \
|
|
||||||
Processors(link, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class Processors(Base):
|
|
||||||
'''Class to manage redfish Processors.'''
|
|
||||||
def get_speed(self):
|
|
||||||
'''Get processor speed
|
|
||||||
|
|
||||||
:returns: processor speed or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.MaxSpeedMHz
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_cores(self):
|
|
||||||
'''Get processor cores number
|
|
||||||
|
|
||||||
:returns: cores number or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.TotalCores
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_threads(self):
|
|
||||||
'''Get processor threads number
|
|
||||||
|
|
||||||
:returns: threads number or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.TotalThreads
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleStorageCollection(BaseCollection):
|
|
||||||
'''Class to manage redfish SimpleStorageCollection data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(SimpleStorageCollection,
|
|
||||||
self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
self.simple_storage_dict = {}
|
|
||||||
|
|
||||||
for link in self.links:
|
|
||||||
index = re.search(r'SimpleStorage/(\w+)', link)
|
|
||||||
self.simple_storage_dict[index.group(1)] = \
|
|
||||||
SimpleStorage(link, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleStorage(Base):
|
|
||||||
'''Class to manage redfish SimpleStorage'''
|
|
||||||
def get_status(self):
|
|
||||||
'''Get storage status
|
|
||||||
|
|
||||||
:returns: storage status or "Not available"
|
|
||||||
:rtype: dict
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.Status
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_devices(self):
|
|
||||||
'''Get storage devices
|
|
||||||
|
|
||||||
:returns: storage devices or "Not available"
|
|
||||||
:rtype: list of dict
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.Devices
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
|
|
||||||
class ChassisCollection(BaseCollection):
|
|
||||||
'''Class to manage redfish ChassisCollection data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
super(ChassisCollection, self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
self.chassis_dict = {}
|
|
||||||
|
|
||||||
for link in self.links:
|
|
||||||
index = re.search(r'Chassis/(\w+)', link)
|
|
||||||
self.chassis_dict[index.group(1)] = Chassis(
|
|
||||||
link, connection_parameters)
|
|
||||||
|
|
||||||
|
|
||||||
class Chassis(Device):
|
|
||||||
'''Class to manage redfish Chassis data.'''
|
|
||||||
def __init__(self, url, connection_parameters):
|
|
||||||
'''Class constructor'''
|
|
||||||
super(Chassis, self).__init__(url, connection_parameters)
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.thermal = Thermal(self.get_link_url('Thermal'),
|
|
||||||
connection_parameters)
|
|
||||||
except AttributeError:
|
|
||||||
self.thermal = None
|
|
||||||
|
|
||||||
try:
|
|
||||||
self.power = Power(self.get_link_url('Power'),
|
|
||||||
connection_parameters)
|
|
||||||
except AttributeError:
|
|
||||||
self.Power = None
|
|
||||||
|
|
||||||
def get_type(self):
|
|
||||||
'''Get chassis type
|
|
||||||
|
|
||||||
:returns: chassis type or "Not available"
|
|
||||||
:rtype: string
|
|
||||||
|
|
||||||
'''
|
|
||||||
try:
|
|
||||||
return self.data.ChassisType
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
|
|
||||||
class Thermal(Base):
|
|
||||||
'''Class to manage redfish Thermal data.'''
|
|
||||||
def get_temperatures(self):
|
|
||||||
'''Get chassis sensors name and temparature
|
|
||||||
|
|
||||||
:returns: chassis sensor and temperature
|
|
||||||
:rtype: dict
|
|
||||||
|
|
||||||
'''
|
|
||||||
temperatures = {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
for sensor in self.data.Temperatures:
|
|
||||||
temperatures[sensor.Name] = sensor.ReadingCelsius
|
|
||||||
return temperatures
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
def get_fans(self):
|
|
||||||
'''Get chassis fan name and rpm
|
|
||||||
|
|
||||||
:returns: chassis fan and rpm
|
|
||||||
:rtype: dict
|
|
||||||
|
|
||||||
'''
|
|
||||||
fans = {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
for fan in self.data.Fans:
|
|
||||||
fans[fan.FanName] = fan.ReadingRPM
|
|
||||||
return fans
|
|
||||||
except AttributeError:
|
|
||||||
return "Not available"
|
|
||||||
|
|
||||||
|
|
||||||
class Power(Base):
|
|
||||||
'''Class to manage redfish Power data.'''
|
|
||||||
pass
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user