commit
e958c08fbd
@ -6,13 +6,13 @@ from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from builtins import str
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import redfish
|
||||
standard_library.install_aliases()
|
||||
|
||||
|
||||
# Get $HOME environment.
|
||||
@ -52,46 +52,57 @@ print ("Redfish API version : %s \n" % remote_mgmt.get_api_version())
|
||||
# Uncomment following line to reset the blade !!!
|
||||
# remote_mgmt.Systems.systems_dict["1"].reset_system()
|
||||
|
||||
# TODO : create an attribute to link the managed system directly
|
||||
# and avoid systems_dict["1"]
|
||||
# --> will be something like :
|
||||
# remote_mgmt.Systems.systems_dict["1"] = remote_mgmt.Systems.managed_system
|
||||
print("Bios version : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].get_bios_version()))
|
||||
print("Serial Number : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].get_serial_number()))
|
||||
print("Power State : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].get_power()))
|
||||
print("Parameter 'SystemType' : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].get_parameter("SystemType")))
|
||||
|
||||
print("Bios version : {}\n".format(remote_mgmt.Systems.systems_dict["1"].get_bios_version()))
|
||||
print("Serial Number : {}\n".format(remote_mgmt.Systems.systems_dict["1"].get_serial_number()))
|
||||
print("Power State : {}\n".format(remote_mgmt.Systems.systems_dict["1"].get_power()))
|
||||
print("Parameter 'SystemType' : {}\n".format(remote_mgmt.Systems.systems_dict["1"].get_parameter("SystemType")))
|
||||
print("Get bios parameters : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.get_parameters()))
|
||||
print("Get boot parameters : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.boot.get_parameters()))
|
||||
|
||||
print("Get bios parameters : {}\n".format(remote_mgmt.Systems.systems_dict["1"].bios.get_parameters()))
|
||||
print("Get boot parameters : {}\n".format(remote_mgmt.Systems.systems_dict["1"].bios.boot.get_parameters()))
|
||||
# print("Get bios parameter 'AdminPhone' : {}\n".format(
|
||||
# remote_mgmt.Systems.systems_dict["1"].bios.get_parameter("AdminPhone")))
|
||||
# print("Set bios parameter 'AdminPhone' to '' : {}\n".format(
|
||||
# remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("AdminPhone","")))
|
||||
|
||||
|
||||
#print("Get bios parameter 'AdminPhone' : {}\n".format(remote_mgmt.Systems.systems_dict["1"].bios.get_parameter("AdminPhone")))
|
||||
#print("Set bios parameter 'AdminPhone' to '' : {}\n".format(remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("AdminPhone","")))
|
||||
# Boot server with script
|
||||
# remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("Dhcpv4","Enabled")
|
||||
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter(
|
||||
"PreBootNetwork", "Auto")
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter(
|
||||
"UefiShellStartup", "Enabled")
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter(
|
||||
"UefiShellStartupLocation", "NetworkLocation")
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter(
|
||||
"UefiShellStartupUrl", "http://10.3.222.88/deploy/startup.nsh")
|
||||
|
||||
#Boot server with script
|
||||
#remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("Dhcpv4","Enabled")
|
||||
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("PreBootNetwork", "Auto")
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("UefiShellStartup", "Enabled")
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("UefiShellStartupLocation", "NetworkLocation")
|
||||
remote_mgmt.Systems.systems_dict["1"].bios.set_parameter("UefiShellStartupUrl", "http://10.3.222.88/deploy/startup.nsh")
|
||||
|
||||
#remote_mgmt.Systems.systems_dict["1"].set_parameter_json('{"Boot": {"BootSourceOverrideTarget": "UefiShell"}}')
|
||||
# remote_mgmt.Systems.systems_dict["1"].set_parameter_json('{"Boot": {"BootSourceOverrideEnabled" : "Continuous"}}')
|
||||
#remote_mgmt.Systems.systems_dict["1"].set_parameter_json('{"Boot": {"BootSourceOverrideEnabled" : "Once"}}')
|
||||
# remote_mgmt.Systems.systems_dict["1"].set_parameter_json(
|
||||
# '{"Boot": {"BootSourceOverrideTarget": "UefiShell"}}')
|
||||
# remote_mgmt.Systems.systems_dict["1"].set_parameter_json(
|
||||
# '{"Boot": {"BootSourceOverrideEnabled" : "Continuous"}}')
|
||||
# remote_mgmt.Systems.systems_dict["1"].set_parameter_json(
|
||||
# '{"Boot": {"BootSourceOverrideEnabled" : "Once"}}')
|
||||
|
||||
mySystem = remote_mgmt.Systems.systems_dict["1"]
|
||||
mySystem.set_boot_source_override("None","Disabled")
|
||||
#Uncomment the next line to reset the server
|
||||
#mySystem.reset_system()
|
||||
mySystem.set_boot_source_override("None", "Disabled")
|
||||
# Uncomment the next line to reset the server
|
||||
# mySystem.reset_system()
|
||||
|
||||
|
||||
print("Get manager firmware version : {}\n".format(remote_mgmt.Managers.managers_dict["1"].get_firmware_version()))
|
||||
print("Get system Bios version : {}\n".format(remote_mgmt.Systems.systems_dict["1"].get_bios_version()))
|
||||
print("Get manager firmware version : {}\n".format(
|
||||
remote_mgmt.Managers.managers_dict["1"].get_firmware_version()))
|
||||
print("Get system Bios version : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].get_bios_version()))
|
||||
|
||||
#Reset of the system is required to apply the changes
|
||||
#remote_mgmt.Systems.systems_dict["1"].reset_system()
|
||||
# Reset of the system is required to apply the changes
|
||||
# remote_mgmt.Systems.systems_dict["1"].reset_system()
|
||||
|
||||
remote_mgmt.logout()
|
||||
|
@ -6,12 +6,12 @@ from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import redfish
|
||||
standard_library.install_aliases()
|
||||
|
||||
# Get $HOME environment.
|
||||
HOME = os.getenv('HOME')
|
||||
@ -49,7 +49,8 @@ except redfish.exception.RedfishException as e:
|
||||
print("Redfish API version : {} \n".format(remote_mgmt.get_api_version()))
|
||||
print("UUID : {} \n".format(remote_mgmt.Root.get_api_UUID()))
|
||||
print("System 1 :\n")
|
||||
print("Bios version : {}\n".format(remote_mgmt.Systems.systems_dict["1"].get_bios_version()))
|
||||
print("Bios version : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["1"].get_bios_version()))
|
||||
print("System 2 :\n")
|
||||
print("Bios version : {}\n".format(remote_mgmt.Systems.systems_dict["2"].get_parameter("SerialNumber")))
|
||||
#print remoteMgmt.get_api_link_to_server()
|
||||
print("Bios version : {}\n".format(
|
||||
remote_mgmt.Systems.systems_dict["2"].get_parameter("SerialNumber")))
|
||||
|
@ -12,6 +12,8 @@ redfish-client ::
|
||||
redfish-client [options] config show
|
||||
redfish-client [options] config showall
|
||||
redfish-client [options] manager getinfo [<manager_name>]
|
||||
redfish-client [options] chassis getinfo [<manager_name>]
|
||||
redfish-client [options] system getinfo [<manager_name>]
|
||||
redfish-client (-h | --help)
|
||||
redfish-client --version
|
||||
|
||||
@ -36,7 +38,6 @@ from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from builtins import str
|
||||
from builtins import object
|
||||
|
||||
@ -50,6 +51,7 @@ import configparser
|
||||
import jinja2
|
||||
import requests.packages.urllib3
|
||||
import redfish
|
||||
standard_library.install_aliases()
|
||||
|
||||
|
||||
class InventoryFile(object):
|
||||
@ -87,7 +89,7 @@ class InventoryFile(object):
|
||||
|
||||
def manager_incorect(self, exception):
|
||||
''' Log and exit if manager name is incorect'''
|
||||
logger.error('Incorect manager name : %s' % exception.args)
|
||||
logger.error('Incorrect manager name : %s' % exception.args)
|
||||
sys.exit(1)
|
||||
|
||||
def check_manager(self, manager_name):
|
||||
@ -220,6 +222,27 @@ class RedfishClientException(Exception):
|
||||
if __name__ == '__main__':
|
||||
'''Main application redfish-client'''
|
||||
# Functions
|
||||
def get_redfish_data(connection_parameters, check_SSL):
|
||||
if not connection_parameters['login']:
|
||||
simulator = True
|
||||
enforceSSL = False
|
||||
else:
|
||||
simulator = False
|
||||
enforceSSL = True
|
||||
try:
|
||||
redfish_data = redfish.connect(connection_parameters['url'],
|
||||
connection_parameters['login'],
|
||||
connection_parameters['password'],
|
||||
verify_cert=check_SSL,
|
||||
simulator=simulator,
|
||||
enforceSSL=enforceSSL)
|
||||
return(redfish_data)
|
||||
except redfish.exception.RedfishException as e:
|
||||
logger.error(str(e.message))
|
||||
sys.stderr.write(str(e.message))
|
||||
sys.stderr.write(str(e.advices))
|
||||
sys.exit(1)
|
||||
|
||||
def show_manager(all=False):
|
||||
'''Display manager info
|
||||
|
||||
@ -232,7 +255,7 @@ if __name__ == '__main__':
|
||||
if(not inventory.get_managers()):
|
||||
print("None")
|
||||
else:
|
||||
for manager in inventory.get_managers():
|
||||
for manager in sorted(inventory.get_managers()):
|
||||
print(manager)
|
||||
if all is True:
|
||||
info = inventory.get_manager_info(manager)
|
||||
@ -240,35 +263,21 @@ if __name__ == '__main__':
|
||||
print('\tLogin : {}'.format(info['login']))
|
||||
print('\tPassword : {}'.format(info['password']))
|
||||
|
||||
def get_manager_info(manager_name, check_SSL):
|
||||
connection_parameters = inventory.get_manager_info(manager_name)
|
||||
if not connection_parameters['login']:
|
||||
simulator = True
|
||||
enforceSSL = False
|
||||
else:
|
||||
simulator = False
|
||||
enforceSSL = True
|
||||
try:
|
||||
print('Gathering data from manager, please wait...\n')
|
||||
# TODO : Add a rotating star showing program is running ?
|
||||
# Could be a nice exercice for learning python. :)
|
||||
logger.info('Gathering data from manager')
|
||||
remote_mgmt = redfish.connect(connection_parameters['url'],
|
||||
connection_parameters['login'],
|
||||
connection_parameters['password'],
|
||||
verify_cert=check_SSL,
|
||||
simulator=simulator,
|
||||
enforceSSL=enforceSSL
|
||||
)
|
||||
except redfish.exception.RedfishException as e:
|
||||
logger.error(str(e.message))
|
||||
sys.stderr.write(str(e.message))
|
||||
sys.stderr.write(str(e.advices))
|
||||
sys.exit(1)
|
||||
|
||||
def display_manager_info(redfish_data):
|
||||
# Display manager information using jinja2 template
|
||||
render_template("manager_info.template")
|
||||
|
||||
def display_chassis_info(redfish_data):
|
||||
# Display system information using jinja2 template
|
||||
render_template("chassis_info.template")
|
||||
|
||||
def display_system_info(redfish_data):
|
||||
# Display system information using jinja2 template
|
||||
render_template("system_info.template")
|
||||
|
||||
def render_template(template):
|
||||
try:
|
||||
template = jinja2_env.get_template("manager_info.template")
|
||||
template = jinja2_env.get_template(template)
|
||||
except jinja2.exceptions.TemplateNotFound as e:
|
||||
print('Template "{}" not found in {}.'
|
||||
.format(e.message, jinja2_env.loader.searchpath[0]))
|
||||
@ -276,7 +285,7 @@ if __name__ == '__main__':
|
||||
% (e.message, jinja2_env.loader.searchpath[0]))
|
||||
sys.exit(1)
|
||||
|
||||
print(template.render(r=remote_mgmt))
|
||||
print(template.render(r=redfish_data))
|
||||
|
||||
#################################################################
|
||||
# Main program
|
||||
@ -406,21 +415,34 @@ if __name__ == '__main__':
|
||||
arguments['<changed_value>'])
|
||||
logger.debug(inventory.data)
|
||||
inventory.save()
|
||||
if arguments['manager'] is True:
|
||||
logger.debug("Manager commands")
|
||||
if arguments['getinfo'] is True:
|
||||
logger.debug('getinfo command')
|
||||
# If manager is not defined set it to 'default'
|
||||
if not arguments['<manager_name>']:
|
||||
manager_name = 'default'
|
||||
else:
|
||||
manager_name = arguments['<manager_name>']
|
||||
# Check if the default section is available in our conf file
|
||||
inventory.check_manager(manager_name)
|
||||
if arguments['--insecure'] is True:
|
||||
get_manager_info(manager_name, False)
|
||||
else:
|
||||
get_manager_info(manager_name, True)
|
||||
elif arguments['getinfo'] is True:
|
||||
logger.debug('getinfo command')
|
||||
# If manager is not defined set it to 'default'
|
||||
if not arguments['<manager_name>']:
|
||||
manager_name = 'default'
|
||||
else:
|
||||
manager_name = arguments['<manager_name>']
|
||||
# Check if the default section is available in our conf file
|
||||
inventory.check_manager(manager_name)
|
||||
connection_parameters = inventory.get_manager_info(manager_name)
|
||||
|
||||
print('Gathering data from manager, please wait...\n')
|
||||
# TODO : Add a rotating star showing program is running ?
|
||||
# Could be a nice exercice for learning python. :)
|
||||
logger.info('Gathering data from manager')
|
||||
|
||||
if arguments['--insecure'] is True:
|
||||
redfish_data = get_redfish_data(connection_parameters, False)
|
||||
else:
|
||||
redfish_data = get_redfish_data(connection_parameters, True)
|
||||
if arguments['manager'] is True:
|
||||
logger.debug("Manager commands")
|
||||
display_manager_info(redfish_data)
|
||||
elif arguments['system'] is True:
|
||||
logger.debug("system commands")
|
||||
display_system_info(redfish_data)
|
||||
elif arguments['chassis'] is True:
|
||||
logger.debug("chassis commands")
|
||||
display_chassis_info(redfish_data)
|
||||
logger.info("Client session terminated")
|
||||
sys.exit(0)
|
||||
|
91
redfish-client/templates/chassis_info.template
Normal file
91
redfish-client/templates/chassis_info.template
Normal file
@ -0,0 +1,91 @@
|
||||
Redfish API version : {{ r.get_api_version() }}
|
||||
{{ r.Root.get_name() }}
|
||||
|
||||
Chassis information :
|
||||
=====================
|
||||
{% for chassis_index in r.Chassis.chassis_dict | sort %}
|
||||
{%- set chassis = r.Chassis.chassis_dict[chassis_index] %}
|
||||
Chassis id {{ chassis_index }}:
|
||||
Manufacturer : {{ chassis.get_manufacturer() }}
|
||||
Model : {{ chassis.get_model() }}
|
||||
Chassis Type : {{ chassis.get_type() }}
|
||||
PartNumber : {{ chassis.get_part_number() }}
|
||||
SKU : {{ chassis.get_sku() }}
|
||||
Serial : {{ chassis.get_serial_number() }}
|
||||
AssetTag : {{ chassis.get_asset_tag() }}
|
||||
Status : State : {{ chassis.get_status().Health }} / Health : {{ chassis.get_status().Health }}
|
||||
{%- if chassis.thermal %}
|
||||
Temperatures :
|
||||
{%- if chassis.thermal.get_temperatures() == 'Not available' %}
|
||||
Not available
|
||||
{%- else %}
|
||||
{%- for sensor, temp in chassis.thermal.get_temperatures().items() | sort %}
|
||||
{{ sensor }} : {{ temp }}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
Fans :
|
||||
{%- if chassis.thermal.get_fans() == 'Not available' %}
|
||||
Not available
|
||||
{%- else %}
|
||||
{%- for fan, rpm in chassis.thermal.get_fans().items() | sort %}
|
||||
{{ fan }} : {{ rpm }}
|
||||
{%- endfor %}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
{#
|
||||
Hostname : {{ system.get_hostname() }}
|
||||
Bios version : {{ system.get_bios_version() }}
|
||||
CPU number : {{ system.get_cpucount() }}
|
||||
CPU model : {{ system.get_cpumodel() }}
|
||||
|
||||
{%- if system.processors_collection %}
|
||||
CPU details :
|
||||
{%- for cpu_index in system.processors_collection.processors_dict | sort %}
|
||||
{%- set cpu = system.processors_collection.processors_dict[cpu_index] %}
|
||||
Processor id {{ cpu_index }} :
|
||||
Speed : {{ cpu.get_speed() }}
|
||||
Cores : {{ cpu.get_cores() }}
|
||||
Threads : {{ cpu.get_threads() }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
Available memory : {{ system.get_memory() }}
|
||||
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
||||
Power : {{ system.get_power() }}
|
||||
Description : {{ system.get_description() }}
|
||||
Chassis : {{ system.get_chassis() | join(', ') }}
|
||||
Managers : {{ system.get_managers() | join(', ') }}
|
||||
IndicatorLED : {{ system.get_indicatorled() }}
|
||||
|
||||
Ethernet Interface :
|
||||
{%- if system.ethernet_interfaces_collection %}
|
||||
{%- for ethernetinterface_index in system.ethernet_interfaces_collection.ethernet_interfaces_dict | sort %}
|
||||
{%- set ei = system.ethernet_interfaces_collection.ethernet_interfaces_dict[ethernetinterface_index] %}
|
||||
Ethernet Interface id {{ ethernetinterface_index }} :
|
||||
{{ ei.get_name() }}
|
||||
FQDN : {{ ei.get_fqdn() }}
|
||||
Mac address : {{ ei.get_mac() }}
|
||||
Address ipv4 : {{ ei.get_ipv4() | join(', ') }}
|
||||
Address ipv6 : {{ ei.get_ipv6() | join(', ') }}
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
This system has no ethernet interface
|
||||
{%- endif %}
|
||||
|
||||
Simple Storage :
|
||||
{%- if system.simple_storage_collection %}
|
||||
{%- for simplestorage_index in system.simple_storage_collection.simple_storage_dict | sort %}
|
||||
{%- set ss = system.simple_storage_collection.simple_storage_dict[simplestorage_index] %}
|
||||
Simple Storage id {{ simplestorage_index }} :
|
||||
{{ ss.get_name() }}
|
||||
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
||||
{%- for dev in ss.get_devices() %}
|
||||
Device id {{ loop.index }} : {{ dev.Name }} {{ dev.Manufacturer }} {{ dev.Model }}
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
This system has no simple storage
|
||||
{%- endif %}
|
||||
--------------------------------------------------------------------------------
|
||||
#}
|
||||
{% endfor %}
|
@ -9,7 +9,7 @@ Manager id {{ manager_index }}:
|
||||
UUID : {{ manager.get_uuid() }}
|
||||
Type : {{ manager.get_type() }}
|
||||
Firmware version : {{ manager.get_firmware_version() }}
|
||||
State : {{ manager.get_status() }}
|
||||
Status : State : {{ manager.get_status().Health }} / Health : {{ manager.get_status().Health }}
|
||||
Ethernet Interface :
|
||||
{%- if manager.ethernet_interfaces_collection %}
|
||||
{%- for ethernetinterface_index in manager.ethernet_interfaces_collection.ethernet_interfaces_dict | sort %}
|
||||
|
68
redfish-client/templates/system_info.template
Normal file
68
redfish-client/templates/system_info.template
Normal file
@ -0,0 +1,68 @@
|
||||
Redfish API version : {{ r.get_api_version() }}
|
||||
{{ r.Root.get_name() }}
|
||||
|
||||
Systems information :
|
||||
=====================
|
||||
{% for system_index in r.Systems.systems_dict | sort %}
|
||||
{%- set system = r.Systems.systems_dict[system_index] %}
|
||||
System id {{ system_index }}:
|
||||
UUID : {{ system.get_uuid() }}
|
||||
Type : {{ system.get_type() }}
|
||||
Manufacturer : {{ system.get_manufacturer() }}
|
||||
Model : {{ system.get_model() }}
|
||||
SKU : {{ system.get_sku() }}
|
||||
Serial : {{ system.get_serial_number() }}
|
||||
Hostname : {{ system.get_hostname() }}
|
||||
Bios version : {{ system.get_bios_version() }}
|
||||
CPU number : {{ system.get_cpucount() }}
|
||||
CPU model : {{ system.get_cpumodel() }}
|
||||
|
||||
{%- if system.processors_collection %}
|
||||
CPU details :
|
||||
{%- for cpu_index in system.processors_collection.processors_dict | sort %}
|
||||
{%- set cpu = system.processors_collection.processors_dict[cpu_index] %}
|
||||
Processor id {{ cpu_index }} :
|
||||
Speed : {{ cpu.get_speed() }}
|
||||
Cores : {{ cpu.get_cores() }}
|
||||
Threads : {{ cpu.get_threads() }}
|
||||
{% endfor %}
|
||||
{%- endif %}
|
||||
Available memory : {{ system.get_memory() }} GB
|
||||
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
||||
Power : {{ system.get_power() }}
|
||||
Description : {{ system.get_description() }}
|
||||
Chassis : {{ system.get_chassis() | join(', ') }}
|
||||
Managers : {{ system.get_managers() | join(', ') }}
|
||||
IndicatorLED : {{ system.get_indicatorled() }}
|
||||
|
||||
Ethernet Interface :
|
||||
{%- if system.ethernet_interfaces_collection %}
|
||||
{%- for ethernetinterface_index in system.ethernet_interfaces_collection.ethernet_interfaces_dict | sort %}
|
||||
{%- set ei = system.ethernet_interfaces_collection.ethernet_interfaces_dict[ethernetinterface_index] %}
|
||||
Ethernet Interface id {{ ethernetinterface_index }} :
|
||||
{{ ei.get_name() }}
|
||||
FQDN : {{ ei.get_fqdn() }}
|
||||
Mac address : {{ ei.get_mac() }}
|
||||
Address ipv4 : {{ ei.get_ipv4() | join(', ') }}
|
||||
Address ipv6 : {{ ei.get_ipv6() | join(', ') }}
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
This system has no ethernet interface
|
||||
{%- endif %}
|
||||
|
||||
Simple Storage :
|
||||
{%- if system.simple_storage_collection %}
|
||||
{%- for simplestorage_index in system.simple_storage_collection.simple_storage_dict | sort %}
|
||||
{%- set ss = system.simple_storage_collection.simple_storage_dict[simplestorage_index] %}
|
||||
Simple Storage id {{ simplestorage_index }} :
|
||||
{{ ss.get_name() }}
|
||||
Status : State : {{ system.get_status().Health }} / Health : {{ system.get_status().Health }}
|
||||
{%- for dev in ss.get_devices() %}
|
||||
Device id {{ loop.index }} : {{ dev.Name }} {{ dev.Manufacturer }} {{ dev.Model }}
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
{%- else %}
|
||||
This system has no simple storage
|
||||
{%- endif %}
|
||||
--------------------------------------------------------------------------------
|
||||
{% endfor %}
|
@ -17,10 +17,10 @@ from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
import pbr.version
|
||||
|
||||
from redfish.main import *
|
||||
from redfish.main import connect
|
||||
standard_library.install_aliases()
|
||||
|
||||
try:
|
||||
__version__ = pbr.version.VersionInfo('redfish').release_string()
|
||||
|
@ -8,7 +8,6 @@ from future import standard_library
|
||||
import logging
|
||||
import sys
|
||||
import os
|
||||
import getpass
|
||||
from logging.handlers import RotatingFileHandler
|
||||
standard_library.install_aliases()
|
||||
|
||||
@ -30,8 +29,8 @@ if not os.path.exists(REDFISH_HOME):
|
||||
os.mkdir(REDFISH_HOME)
|
||||
except IOError:
|
||||
print('ERROR: can\'t create {}.\n'.format(REDFISH_HOME))
|
||||
print(' Try to create directory {}'.format(os.path.dirname(REDFISH_LOGFILE)))
|
||||
print(' using: mkdir -p {}'.format(os.path.dirname(REDFISH_LOGFILE)))
|
||||
print(' Try to create directory {}'.format(REDFISH_HOME))
|
||||
print(' using: mkdir -p {}'.format(REDFISH_HOME))
|
||||
sys.exit(1)
|
||||
|
||||
REDFISH_LOGFILE = os.path.join(REDFISH_HOME, "python-redfish.log")
|
||||
@ -59,15 +58,18 @@ def initialize_logger(REDFISH_LOGFILE,
|
||||
logger = logging.getLogger(logger_name)
|
||||
logger.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s :: %(levelname)s :: %(message)s'
|
||||
)
|
||||
'%(asctime)s :: %(levelname)s :: %(message)s')
|
||||
|
||||
try:
|
||||
file_handler = RotatingFileHandler(os.path.expandvars(REDFISH_LOGFILE), 'a', 1000000, 1)
|
||||
file_handler = RotatingFileHandler(
|
||||
os.path.expandvars(REDFISH_LOGFILE), 'a', 1000000, 1)
|
||||
except IOError:
|
||||
print('ERROR: {} does not exist or is not writeable.\n'.format(REDFISH_LOGFILE))
|
||||
print(' Try to create directory {}'.format(os.path.dirname(REDFISH_LOGFILE)))
|
||||
print(' using: mkdir -p {}'.format(os.path.dirname(REDFISH_LOGFILE)))
|
||||
print('ERROR: {} does not exist or is not writeable.\n'.format(
|
||||
REDFISH_LOGFILE))
|
||||
print(' Try to create directory {}'.format(os.path.dirname(
|
||||
REDFISH_LOGFILE)))
|
||||
print(' using: mkdir -p {}'.format(os.path.dirname(
|
||||
REDFISH_LOGFILE)))
|
||||
sys.exit(1)
|
||||
|
||||
# First logger to file
|
||||
|
@ -5,9 +5,9 @@ from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from builtins import str
|
||||
from . import config
|
||||
standard_library.install_aliases()
|
||||
|
||||
|
||||
class RedfishException(Exception):
|
||||
@ -28,7 +28,8 @@ class ConnectionFailureException(RedfishException):
|
||||
'3- Check if your device has a valid trusted certificat\n' + \
|
||||
' You can use openssl to validate it using the command :\n' + \
|
||||
' openssl s_client -showcerts -connect <server>:443\n' + \
|
||||
'4- Use option "--insecure" to connect without checking certificate\n'
|
||||
'4- Use option "--insecure" to connect without checking' + \
|
||||
' certificate\n'
|
||||
|
||||
|
||||
class InvalidRedfishContentException(RedfishException):
|
||||
|
@ -29,8 +29,9 @@ resources.
|
||||
A URI should be treated by the client as opaque, and thus should not be
|
||||
attempted to be understood or deconstructed by the client. Only specific top
|
||||
level URIs (any URI in this sample code) may be assumed, and even these may be
|
||||
absent based upon the implementation (e.g. there might be no /redfish/v1/Systems
|
||||
collection on something that doesn't have compute nodes.)
|
||||
absent based upon the implementation
|
||||
(e.g. there might be no /redfish/v1/Systems collection on something
|
||||
that doesn't have compute nodes.)
|
||||
|
||||
The other URIs must be discovered dynamically by following href links. This is
|
||||
because the API will eventually be implemented on a system that breaks any
|
||||
@ -125,7 +126,6 @@ standard_library.install_aliases()
|
||||
from builtins import object
|
||||
|
||||
import json
|
||||
import socket
|
||||
from urllib.parse import urlparse, urljoin, urlunparse
|
||||
import requests
|
||||
from . import config
|
||||
@ -142,8 +142,7 @@ def connect(
|
||||
password,
|
||||
simulator=False,
|
||||
enforceSSL=True,
|
||||
verify_cert=True
|
||||
):
|
||||
verify_cert=True):
|
||||
|
||||
return RedfishConnection(
|
||||
url,
|
||||
@ -206,9 +205,6 @@ class RedfishConnection(object):
|
||||
"this is insecure and can allow" +
|
||||
" a man in the middle attack")
|
||||
|
||||
# Show redfish standard headers
|
||||
config.logger.debug(self.connection_parameters.headers)
|
||||
|
||||
config.logger.debug("Root url : %s",
|
||||
self.connection_parameters.rooturl)
|
||||
self.Root = types.Root(self.connection_parameters.rooturl,
|
||||
@ -218,8 +214,10 @@ class RedfishConnection(object):
|
||||
mapping.redfish_version = self.get_api_version()
|
||||
mapping.redfish_root_name = self.Root.get_name()
|
||||
|
||||
# Instantiate a global mapping object to handle Redfish version variation
|
||||
mapping.redfish_mapper = mapping.RedfishVersionMapping(self.get_api_version(), self.Root.get_name())
|
||||
# Instantiate a global mapping object to handle
|
||||
# Redfish version variation
|
||||
mapping.redfish_mapper = mapping.RedfishVersionMapping(
|
||||
self.get_api_version(), self.Root.get_name())
|
||||
|
||||
# Now we need to login otherwise we are not allowed to extract data
|
||||
if self.__simulator is False:
|
||||
@ -229,9 +227,8 @@ class RedfishConnection(object):
|
||||
config.logger.info("Login successful")
|
||||
except "Error getting token":
|
||||
config.logger.error("Login fail, fail to get auth token")
|
||||
raise exception.AuthenticationFailureException("Fail to get an auth token.")
|
||||
|
||||
|
||||
raise exception.AuthenticationFailureException(
|
||||
"Fail to get an auth token.")
|
||||
|
||||
# Structure change with mockup 1.0.0, there is no links
|
||||
# section anymore.
|
||||
@ -241,28 +238,25 @@ class RedfishConnection(object):
|
||||
|
||||
# Types
|
||||
self.SessionService = types.SessionService(
|
||||
self.Root.get_link_url(
|
||||
mapping.redfish_mapper.map_sessionservice()),
|
||||
self.connection_parameters
|
||||
)
|
||||
self.Root.get_link_url(
|
||||
mapping.redfish_mapper.map_sessionservice()),
|
||||
self.connection_parameters)
|
||||
|
||||
self.Managers = types.ManagersCollection(self.Root.get_link_url("Managers"),
|
||||
self.connection_parameters
|
||||
)
|
||||
self.Managers = types.ManagersCollection(
|
||||
self.Root.get_link_url("Managers"),
|
||||
self.connection_parameters)
|
||||
|
||||
self.Systems = types.SystemsCollection(self.Root.get_link_url("Systems"),
|
||||
self.connection_parameters
|
||||
)
|
||||
self.Systems = types.SystemsCollection(
|
||||
self.Root.get_link_url("Systems"),
|
||||
self.connection_parameters)
|
||||
|
||||
# self.Chassis
|
||||
self.Chassis = types.ChassisCollection(
|
||||
self.Root.get_link_url("Chassis"), self.connection_parameters)
|
||||
|
||||
# self.EventService
|
||||
# self.AccountService
|
||||
# self.Tasks
|
||||
|
||||
|
||||
|
||||
|
||||
# ========================================================================
|
||||
# systemCollectionLink = getattr(self.root.Links.Systems,"@odata.id")
|
||||
# self.systemCollection = self.apiUrl.redfish.v1.Systems.get()
|
||||
@ -282,8 +276,7 @@ class RedfishConnection(object):
|
||||
def login(self):
|
||||
# Craft full url
|
||||
url = self.Root.get_link_url(
|
||||
mapping.redfish_mapper.map_sessionservice()
|
||||
)
|
||||
mapping.redfish_mapper.map_sessionservice())
|
||||
|
||||
# Handle login with redfish 1.00, url must be :
|
||||
# /rest/v1/SessionService/Sessions as specified by the specification
|
||||
@ -295,14 +288,17 @@ class RedfishConnection(object):
|
||||
"Password": self.connection_parameters.password}
|
||||
config.logger.debug(requestBody)
|
||||
headers = self.connection_parameters.headers
|
||||
# =======================================================================
|
||||
# Tortilla seems not able to provide the header of a post request answer.
|
||||
# ====================================================================
|
||||
# Tortilla seems not able to provide the header of a post request
|
||||
# answer.
|
||||
# However this is required by redfish standard to get X-Auth-Token.
|
||||
# So jump to "requests" library to get the required token.
|
||||
# TODO : Patch tortilla to handle this case.
|
||||
# =======================================================================
|
||||
# sessionsUrl = tortilla.wrap("https://10.3.222.104/rest/v1/Sessions", debug=TORTILLADEBUG)
|
||||
# sessions = sessionsUrl.post(verify=self.verify_cert, data=requestBody)
|
||||
# ====================================================================
|
||||
# sessionsUrl = tortilla.wrap(
|
||||
# "https://10.3.222.104/rest/v1/Sessions", debug=TORTILLADEBUG)
|
||||
# sessions = sessionsUrl.post(
|
||||
# verify=self.verify_cert, data=requestBody)
|
||||
auth = requests.post(url,
|
||||
data=json.dumps(requestBody),
|
||||
headers=headers,
|
||||
|
@ -4,13 +4,14 @@ from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from builtins import object
|
||||
standard_library.install_aliases()
|
||||
|
||||
redfish_mapper = None
|
||||
redfish_version = None
|
||||
redfish_root_name = None
|
||||
|
||||
|
||||
class RedfishVersionMapping(object):
|
||||
'''Implements basic url path mapping beetween Redfish versions.'''
|
||||
|
||||
@ -24,7 +25,7 @@ class RedfishVersionMapping(object):
|
||||
return 'SessionService'
|
||||
|
||||
def map_links(self, data_dict=None):
|
||||
if data_dict == None:
|
||||
if data_dict is None:
|
||||
if self.__version == '0.95':
|
||||
return 'links'
|
||||
else:
|
||||
@ -39,7 +40,7 @@ class RedfishVersionMapping(object):
|
||||
return 'Links'
|
||||
|
||||
def map_links_ref(self, data_dict=None):
|
||||
if data_dict == None:
|
||||
if data_dict is None:
|
||||
if self.__version == '0.95':
|
||||
return 'href'
|
||||
else:
|
||||
@ -49,11 +50,11 @@ class RedfishVersionMapping(object):
|
||||
try:
|
||||
data_dict.href
|
||||
return 'href'
|
||||
except AttributeError:
|
||||
pass
|
||||
except AttributeError:
|
||||
pass
|
||||
return '@odata.id'
|
||||
|
||||
|
||||
def map_members(self):
|
||||
if self.__version == '0.95':
|
||||
return 'Member'
|
||||
return 'Members'
|
||||
return 'Members'
|
||||
|
600
redfish/types.py
600
redfish/types.py
@ -18,6 +18,8 @@ from . import mapping
|
||||
from . import exception
|
||||
standard_library.install_aliases()
|
||||
|
||||
standard_library.install_aliases()
|
||||
|
||||
# Global variable
|
||||
|
||||
|
||||
@ -26,11 +28,16 @@ class Base(object):
|
||||
def __init__(self, url, connection_parameters):
|
||||
'''Class constructor'''
|
||||
global TORTILLADEBUG
|
||||
self.connection_parameters = connection_parameters # Uggly hack to check
|
||||
self.connection_parameters = connection_parameters # Uggly hack
|
||||
self.url = url
|
||||
self.api_url = tortilla.wrap(url, debug=config.TORTILLADEBUG)
|
||||
|
||||
config.logger.debug(connection_parameters.headers)
|
||||
config.logger.debug(
|
||||
"------------------------------------------------------------")
|
||||
config.logger.debug("Url: %s" % url)
|
||||
config.logger.debug("Header: %s" % connection_parameters.headers)
|
||||
config.logger.debug(
|
||||
"------------------------------------------------------------")
|
||||
|
||||
try:
|
||||
self.data = self.api_url.get(
|
||||
@ -48,7 +55,7 @@ class Base(object):
|
||||
'Ivalid content : Content does not appear to be a valid ' + \
|
||||
'Redfish json\n'
|
||||
raise exception.InvalidRedfishContentException(msg)
|
||||
config.logger.debug(self.data)
|
||||
config.logger.debug(pprint.PrettyPrinter(indent=4).pformat(self.data))
|
||||
|
||||
def get_link_url(self, link_type):
|
||||
'''Need to be explained.
|
||||
@ -62,7 +69,9 @@ class Base(object):
|
||||
if float(mapping.redfish_version) < 1.00:
|
||||
links = getattr(self.data, mapping.redfish_mapper.map_links())
|
||||
if link_type in links:
|
||||
return urljoin(self.url, links[link_type][mapping.redfish_mapper.map_links_ref()])
|
||||
return urljoin(
|
||||
self.url,
|
||||
links[link_type][mapping.redfish_mapper.map_links_ref()])
|
||||
raise AttributeError
|
||||
else:
|
||||
links = getattr(self.data, link_type)
|
||||
@ -140,27 +149,134 @@ class BaseCollection(Base):
|
||||
|
||||
self.links = []
|
||||
|
||||
#linksmembers = self.data.Links.Members
|
||||
#linksmembers = self.data.links.Member
|
||||
# linksmembers = self.data.Links.Members
|
||||
# linksmembers = self.data.links.Member
|
||||
if float(mapping.redfish_version) < 1.00:
|
||||
linksmembers = getattr(self.data, mapping.redfish_mapper.map_links())
|
||||
linksmembers = getattr(linksmembers, mapping.redfish_mapper.map_members())
|
||||
linksmembers = getattr(
|
||||
self.data, mapping.redfish_mapper.map_links())
|
||||
linksmembers = getattr(
|
||||
linksmembers, mapping.redfish_mapper.map_members())
|
||||
else:
|
||||
linksmembers = getattr(self.data, mapping.redfish_mapper.map_members())
|
||||
linksmembers = getattr(
|
||||
self.data, mapping.redfish_mapper.map_members())
|
||||
for link in linksmembers:
|
||||
#self.links.append(getattr(link,'@odata.id'))
|
||||
#self.links.append(getattr(link,'href'))
|
||||
self.links.append(urljoin(self.url, getattr(link, mapping.redfish_mapper.map_links_ref())))
|
||||
# self.links.append(getattr(link,'@odata.id'))
|
||||
# self.links.append(getattr(link,'href'))
|
||||
self.links.append(urljoin(
|
||||
self.url, getattr(
|
||||
link, mapping.redfish_mapper.map_links_ref())))
|
||||
|
||||
config.logger.debug(self.links)
|
||||
|
||||
|
||||
class Device(Base):
|
||||
'''Abstract class to add common methods between devices
|
||||
(Chassis, Servers, System).
|
||||
'''
|
||||
def get_uuid(self):
|
||||
'''Get device uuid
|
||||
|
||||
:returns: device uuid or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.UUID
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_status(self):
|
||||
'''Get device status
|
||||
|
||||
:returns: device status or "Not available"
|
||||
:rtype: dict
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.Status
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_model(self):
|
||||
'''Get device model
|
||||
|
||||
:returns: device model or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.Model
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_manufacturer(self):
|
||||
'''Get device manufacturer
|
||||
|
||||
:returns: device manufacturer or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.Manufacturer
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_serial_number(self):
|
||||
'''Get serial number of the device.
|
||||
|
||||
:returns: serial number or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.SerialNumber
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_asset_tag(self):
|
||||
'''Get asset tag of the device.
|
||||
|
||||
:returns: asset tag or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.AssetTag
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_sku(self):
|
||||
'''Get sku number of the device.
|
||||
|
||||
:returns: sku number or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.SKU
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_part_number(self):
|
||||
'''Get part number of the device.
|
||||
|
||||
:returns: part number or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.PartNumber
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
|
||||
class Root(Base):
|
||||
'''Class to manage redfish Root data.'''
|
||||
def get_api_version(self):
|
||||
'''Return api version.
|
||||
|
||||
:returns: string -- version
|
||||
:returns: api version
|
||||
:rtype: string
|
||||
:raises: AttributeError
|
||||
|
||||
'''
|
||||
@ -174,44 +290,39 @@ class Root(Base):
|
||||
return(version)
|
||||
|
||||
def get_api_UUID(self):
|
||||
'''Return UUID version.
|
||||
'''Return api UUID.
|
||||
|
||||
:returns: string -- UUID
|
||||
:returns: api UUID
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
return self.data.UUID
|
||||
|
||||
def get_api_link_to_server(self):
|
||||
'''Return api link to server.
|
||||
|
||||
:returns: string -- path
|
||||
|
||||
'''
|
||||
return getattr(self.root.Links.Systems, '@odata.id')
|
||||
|
||||
|
||||
class SessionService(Base):
|
||||
'''Class to manage redfish SessionService data.'''
|
||||
pass
|
||||
|
||||
|
||||
class Managers(Base):
|
||||
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 ?
|
||||
# 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
|
||||
# )
|
||||
# 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
|
||||
@ -220,6 +331,18 @@ class Managers(Base):
|
||||
# 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
|
||||
|
||||
@ -233,43 +356,11 @@ class Managers(Base):
|
||||
# This is the case with the mockup for manager 2 and 3
|
||||
return "Not available"
|
||||
|
||||
def get_type(self):
|
||||
'''Get manager type
|
||||
|
||||
:returns: string -- manager type or "Not available"
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.ManagerType
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_uuid(self):
|
||||
'''Get manager type
|
||||
|
||||
:returns: string -- manager uuid or "Not available"
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.UUID
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_status(self):
|
||||
'''Get manager status
|
||||
|
||||
:returns: string -- manager status or "Not available"
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.Status.State
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_managed_chassis(self):
|
||||
'''Get managed chassis ids by the manager
|
||||
|
||||
:returns: list -- chassis ids or "Not available"
|
||||
:returns: chassis ids or "Not available"
|
||||
:rtype: list
|
||||
|
||||
'''
|
||||
chassis_list = []
|
||||
@ -277,7 +368,9 @@ class Managers(Base):
|
||||
|
||||
try:
|
||||
for chassis in links.ManagerForChassis:
|
||||
result = re.search(r'Chassis/(\w+)', chassis[mapping.redfish_mapper.map_links_ref(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:
|
||||
@ -286,7 +379,8 @@ class Managers(Base):
|
||||
def get_managed_systems(self):
|
||||
'''Get managed systems ids by the manager
|
||||
|
||||
:returns: list -- chassis ids or "Not available"
|
||||
:returns: systems ids or "Not available"
|
||||
:rtype: list
|
||||
|
||||
'''
|
||||
systems_list = []
|
||||
@ -294,7 +388,9 @@ class Managers(Base):
|
||||
|
||||
try:
|
||||
for systems in links.ManagerForServers:
|
||||
result = re.search(r'Systems/(\w+)', systems[mapping.redfish_mapper.map_links_ref(systems)])
|
||||
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:
|
||||
@ -328,10 +424,11 @@ class ManagersCollection(BaseCollection):
|
||||
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)
|
||||
self.managers_dict[index.group(1)] = Managers(
|
||||
link, connection_parameters)
|
||||
|
||||
|
||||
class Systems(Base):
|
||||
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.
|
||||
@ -343,6 +440,33 @@ class Systems(Base):
|
||||
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.
|
||||
|
||||
@ -366,43 +490,150 @@ class Systems(Base):
|
||||
def get_bios_version(self):
|
||||
'''Get bios version of the system.
|
||||
|
||||
:returns: string -- bios version
|
||||
:returns: bios version or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
# Returned by proliant
|
||||
return self.data.Bios.Current.VersionString
|
||||
except:
|
||||
# Returned by mockup.
|
||||
# Hopefully this kind of discrepencies will be fixed with
|
||||
# Redfish 1.0 (August)
|
||||
return self.data.BiosVersion
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_serial_number(self):
|
||||
'''Get serial number of the system.
|
||||
def get_hostname(self):
|
||||
'''Get hostname of the system.
|
||||
|
||||
:returns: string -- serial number
|
||||
:returns: hostname or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
# Returned by proliant
|
||||
return self.data.SerialNumber
|
||||
except:
|
||||
# Returned by mockup.
|
||||
# Hopefully this kind of discrepencies will be fixed with
|
||||
# Redfish 1.0 (August)
|
||||
return ''
|
||||
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: string -- power status or NULL if there is an issue
|
||||
:returns: system power state or "Not available"
|
||||
:rtype: string
|
||||
|
||||
'''
|
||||
try:
|
||||
return self.data.Power
|
||||
except:
|
||||
return ''
|
||||
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
|
||||
@ -455,14 +686,16 @@ class SystemsCollection(BaseCollection):
|
||||
|
||||
for link in self.links:
|
||||
index = re.search(r'Systems/(\w+)', link)
|
||||
self.systems_dict[index.group(1)] = Systems(link, connection_parameters)
|
||||
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)
|
||||
self.boot = Boot(re.findall('.+/Bios', url)[0] +
|
||||
'/Boot/Settings', connection_parameters)
|
||||
|
||||
|
||||
class Boot(Base):
|
||||
@ -500,9 +733,13 @@ class EthernetInterfaces(Base):
|
||||
|
||||
'''
|
||||
try:
|
||||
# Proliant firmware seems to not follow redfish systax
|
||||
return self.data.MacAddress
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
try:
|
||||
return self.data.MACAddress
|
||||
except AttributeError:
|
||||
return "Not available"
|
||||
|
||||
def get_fqdn(self):
|
||||
'''Get EthernetInterface fqdn
|
||||
@ -551,3 +788,180 @@ class EthernetInterfaces(Base):
|
||||
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