Improve error management
- Better handle connection errors. - Better handle login errors. - Improve exception process. - Update examples. - Make examples compatible with new configuration file. - Show exception handling. - Validate trusted SSL connection. - Various PEP8 corrections.
This commit is contained in:
parent
4ef8d92da7
commit
466534359c
@ -6,7 +6,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import redfish
|
import redfish
|
||||||
from time import sleep
|
|
||||||
|
|
||||||
# Get $HOME environment.
|
# Get $HOME environment.
|
||||||
HOME = os.getenv('HOME')
|
HOME = os.getenv('HOME')
|
||||||
@ -24,17 +24,26 @@ except IOError as e:
|
|||||||
print(e)
|
print(e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
URL = config["Nodes"]["default"]["url"]
|
URL = config["Managers"]["default"]["url"]
|
||||||
USER_NAME = config["Nodes"]["default"]["login"]
|
USER_NAME = config["Managers"]["default"]["login"]
|
||||||
PASSWORD = config["Nodes"]["default"]["password"]
|
PASSWORD = config["Managers"]["default"]["password"]
|
||||||
|
|
||||||
''' remote_mgmt is a redfish.RedfishConnection object '''
|
''' remote_mgmt is a redfish.RedfishConnection object '''
|
||||||
remote_mgmt = redfish.connect(URL, USER_NAME, PASSWORD, verify_cert=False)
|
try:
|
||||||
|
remote_mgmt = redfish.connect(URL,
|
||||||
|
USER_NAME,
|
||||||
|
PASSWORD,
|
||||||
|
simulator=False,
|
||||||
|
verify_cert=False)
|
||||||
|
except redfish.exception.RedfishException as e:
|
||||||
|
sys.stderr.write(str(e.message))
|
||||||
|
sys.stderr.write(str(e.advices))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
print ("Redfish API version : %s \n" % remote_mgmt.get_api_version())
|
print ("Redfish API version : %s \n" % remote_mgmt.get_api_version())
|
||||||
|
|
||||||
# Uncomment following line to reset the blade !!!
|
# Uncomment following line to reset the blade !!!
|
||||||
#remote_mgmt.Systems.systems_list[0].reset_system()
|
# remote_mgmt.Systems.systems_list[0].reset_system()
|
||||||
|
|
||||||
# TODO : create an attribute to link the managed system directly
|
# TODO : create an attribute to link the managed system directly
|
||||||
# and avoid systems_list[0]
|
# and avoid systems_list[0]
|
||||||
|
@ -23,13 +23,22 @@ except IOError as e:
|
|||||||
print(e)
|
print(e)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
URL = config["Nodes"]["default"]["url"]
|
URL = config["Managers"]["default"]["url"]
|
||||||
USER_NAME = config["Nodes"]["default"]["login"]
|
USER_NAME = config["Managers"]["default"]["login"]
|
||||||
PASSWORD = config["Nodes"]["default"]["password"]
|
PASSWORD = config["Managers"]["default"]["password"]
|
||||||
|
|
||||||
''' remoteMgmt is a redfish.RedfishConnection object '''
|
''' remoteMgmt is a redfish.RedfishConnection object '''
|
||||||
remote_mgmt = redfish.connect(URL, USER_NAME, PASSWORD,
|
try:
|
||||||
simulator=True, enforceSSL=False)
|
remote_mgmt = redfish.connect(URL,
|
||||||
|
USER_NAME,
|
||||||
|
PASSWORD,
|
||||||
|
simulator=True,
|
||||||
|
enforceSSL=False)
|
||||||
|
except redfish.exception.RedfishException as e:
|
||||||
|
sys.stderr.write(e.message)
|
||||||
|
sys.stderr.write(e.advices)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
print("Redfish API version : {} \n".format(remote_mgmt.get_api_version()))
|
print("Redfish API version : {} \n".format(remote_mgmt.get_api_version()))
|
||||||
print("UUID : {} \n".format(remote_mgmt.Root.get_api_UUID()))
|
print("UUID : {} \n".format(remote_mgmt.Root.get_api_UUID()))
|
||||||
|
@ -1,21 +1,52 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import sys
|
|
||||||
import config
|
import config
|
||||||
|
|
||||||
|
|
||||||
class RedfishException(Exception):
|
class RedfishException(Exception):
|
||||||
"""Base class for redfish exceptions"""
|
"""Base class for redfish exceptions"""
|
||||||
def __init__(self, message=None, **kwargs):
|
def __init__(self, message, **kwargs):
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.message = message
|
self.message = message
|
||||||
|
self.advices = None
|
||||||
|
config.logger.error(message)
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectionFailureException(RedfishException):
|
||||||
|
def __init__(self, message, **kwargs):
|
||||||
|
super(ConnectionFailureException, self).__init__(message, **kwargs)
|
||||||
|
self.advices = '1- Check if the url is the correct one\n' + \
|
||||||
|
'2- Check if your device is answering on the network\n'
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidRedfishContentException(RedfishException):
|
||||||
|
def __init__(self, message, **kwargs):
|
||||||
|
super(InvalidRedfishContentException, self).__init__(message, **kwargs)
|
||||||
|
self.advices = \
|
||||||
|
'1- Check if the url is the correct one\n' + \
|
||||||
|
' Most of the time you are not pointing to the rest API\n'
|
||||||
|
|
||||||
|
|
||||||
|
class NonTrustedCertificatException(RedfishException):
|
||||||
|
def __init__(self, message, **kwargs):
|
||||||
|
super(NonTrustedCertificatException, self).__init__(message, **kwargs)
|
||||||
|
self.advices = \
|
||||||
|
'1- Check if the url is the correct one\n' + \
|
||||||
|
'2- 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'
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationFailureException(RedfishException):
|
class AuthenticationFailureException(RedfishException):
|
||||||
def __init__(self, message=None, **kwargs):
|
def __init__(self, message, **kwargs):
|
||||||
super(AuthenticationFailureException, self).__init__(message=None, **kwargs)
|
super(AuthenticationFailureException, self).__init__(message, **kwargs)
|
||||||
config.logger.error(message)
|
self.message += str(kwargs['code'])
|
||||||
# TODO
|
self.queryAnswer = kwargs['queryAnswer']
|
||||||
# Give a bit more details about the failure (check login etc...)
|
if kwargs['code'] == 400:
|
||||||
sys.exit(1)
|
self.message += ': ' + self.queryAnswer['Messages'][0]['MessageID']
|
||||||
|
self.advices = '1- Check your credentials\n'
|
||||||
|
self.message += '\n'
|
||||||
|
|
||||||
|
|
||||||
class LogoutFailureException(RedfishException):
|
class LogoutFailureException(RedfishException):
|
||||||
pass
|
pass
|
||||||
|
@ -294,6 +294,7 @@ class RedfishConnection(object):
|
|||||||
|
|
||||||
# Craft request body and header
|
# Craft request body and header
|
||||||
requestBody = {"UserName": self.connection_parameters.user_name , "Password": self.connection_parameters.password}
|
requestBody = {"UserName": self.connection_parameters.user_name , "Password": self.connection_parameters.password}
|
||||||
|
config.logger.debug(requestBody)
|
||||||
header = {'Content-type': 'application/json'}
|
header = {'Content-type': 'application/json'}
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
# 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.
|
||||||
@ -313,8 +314,11 @@ class RedfishConnection(object):
|
|||||||
# TODO : Manage exception with a class.
|
# TODO : Manage exception with a class.
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
if auth.status_code != 201:
|
if auth.status_code != 201:
|
||||||
raise exception.AuthenticationFailureException("Login request return an invalid status code")
|
try:
|
||||||
#sysraise "Error getting token", auth.status_code
|
answer=auth.json()
|
||||||
|
except ValueError as e:
|
||||||
|
answer = ""
|
||||||
|
raise exception.AuthenticationFailureException("Login request return an invalid status code ", code=auth.status_code, queryAnswer=answer)
|
||||||
|
|
||||||
self.connection_parameters.auth_token = auth.headers.get("x-auth-token")
|
self.connection_parameters.auth_token = auth.headers.get("x-auth-token")
|
||||||
self.connection_parameters.user_uri = auth.headers.get("location")
|
self.connection_parameters.user_uri = auth.headers.get("location")
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
import pprint
|
import pprint
|
||||||
|
import re
|
||||||
from urlparse import urljoin
|
from urlparse import urljoin
|
||||||
import requests
|
import requests
|
||||||
|
import simplejson
|
||||||
import tortilla
|
import tortilla
|
||||||
import config
|
import config
|
||||||
import mapping
|
import mapping
|
||||||
import re
|
import exception
|
||||||
|
|
||||||
# Global variable
|
# Global variable
|
||||||
|
|
||||||
@ -28,10 +30,25 @@ class Base(object):
|
|||||||
headers={'x-auth-token': connection_parameters.auth_token}
|
headers={'x-auth-token': connection_parameters.auth_token}
|
||||||
)
|
)
|
||||||
except requests.ConnectionError as e:
|
except requests.ConnectionError as e:
|
||||||
print e
|
|
||||||
# Log and transmit the exception.
|
# Log and transmit the exception.
|
||||||
config.logger.error("Connection error : %s", e)
|
config.logger.info("Raise a RedfishException to upper level")
|
||||||
raise e
|
msg = "Connection error : {}\n".format(e.message)
|
||||||
|
raise exception.ConnectionFailureException(msg)
|
||||||
|
except simplejson.scanner.JSONDecodeError as e:
|
||||||
|
# Log and transmit the exception.
|
||||||
|
config.logger.info("Raise a RedfishException to upper level")
|
||||||
|
msg = \
|
||||||
|
"Ivalid content : Content does not appear to be a valid " + \
|
||||||
|
"Redfish json\n"
|
||||||
|
raise exception.InvalidRedfishContentException(msg)
|
||||||
|
except TypeError as e:
|
||||||
|
# This happen connecting to a manager using non trusted
|
||||||
|
# SSL certificats.
|
||||||
|
# The exception is not what could be expected in such case but this
|
||||||
|
# is the one provided by Tortilla.
|
||||||
|
config.logger.info("Raise a RedfishException to upper level")
|
||||||
|
msg = "Connection error\n"
|
||||||
|
raise exception.NonTrustedCertificatException(msg)
|
||||||
print self.data
|
print self.data
|
||||||
|
|
||||||
def get_link_url(self, link_type):
|
def get_link_url(self, link_type):
|
||||||
|
Loading…
Reference in New Issue
Block a user