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 json
|
||||
import redfish
|
||||
from time import sleep
|
||||
|
||||
|
||||
# Get $HOME environment.
|
||||
HOME = os.getenv('HOME')
|
||||
@ -24,17 +24,26 @@ except IOError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
URL = config["Nodes"]["default"]["url"]
|
||||
USER_NAME = config["Nodes"]["default"]["login"]
|
||||
PASSWORD = config["Nodes"]["default"]["password"]
|
||||
URL = config["Managers"]["default"]["url"]
|
||||
USER_NAME = config["Managers"]["default"]["login"]
|
||||
PASSWORD = config["Managers"]["default"]["password"]
|
||||
|
||||
''' 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())
|
||||
|
||||
# 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
|
||||
# and avoid systems_list[0]
|
||||
|
@ -23,13 +23,22 @@ except IOError as e:
|
||||
print(e)
|
||||
sys.exit(1)
|
||||
|
||||
URL = config["Nodes"]["default"]["url"]
|
||||
USER_NAME = config["Nodes"]["default"]["login"]
|
||||
PASSWORD = config["Nodes"]["default"]["password"]
|
||||
URL = config["Managers"]["default"]["url"]
|
||||
USER_NAME = config["Managers"]["default"]["login"]
|
||||
PASSWORD = config["Managers"]["default"]["password"]
|
||||
|
||||
''' remoteMgmt is a redfish.RedfishConnection object '''
|
||||
remote_mgmt = redfish.connect(URL, USER_NAME, PASSWORD,
|
||||
simulator=True, enforceSSL=False)
|
||||
try:
|
||||
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("UUID : {} \n".format(remote_mgmt.Root.get_api_UUID()))
|
||||
|
@ -1,21 +1,52 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
|
||||
import config
|
||||
|
||||
|
||||
class RedfishException(Exception):
|
||||
"""Base class for redfish exceptions"""
|
||||
def __init__(self, message=None, **kwargs):
|
||||
def __init__(self, message, **kwargs):
|
||||
self.kwargs = kwargs
|
||||
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):
|
||||
def __init__(self, message=None, **kwargs):
|
||||
super(AuthenticationFailureException, self).__init__(message=None, **kwargs)
|
||||
config.logger.error(message)
|
||||
# TODO
|
||||
# Give a bit more details about the failure (check login etc...)
|
||||
sys.exit(1)
|
||||
def __init__(self, message, **kwargs):
|
||||
super(AuthenticationFailureException, self).__init__(message, **kwargs)
|
||||
self.message += str(kwargs['code'])
|
||||
self.queryAnswer = kwargs['queryAnswer']
|
||||
if kwargs['code'] == 400:
|
||||
self.message += ': ' + self.queryAnswer['Messages'][0]['MessageID']
|
||||
self.advices = '1- Check your credentials\n'
|
||||
self.message += '\n'
|
||||
|
||||
|
||||
class LogoutFailureException(RedfishException):
|
||||
pass
|
||||
|
@ -294,6 +294,7 @@ class RedfishConnection(object):
|
||||
|
||||
# Craft request body and header
|
||||
requestBody = {"UserName": self.connection_parameters.user_name , "Password": self.connection_parameters.password}
|
||||
config.logger.debug(requestBody)
|
||||
header = {'Content-type': 'application/json'}
|
||||
# =======================================================================
|
||||
# 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.
|
||||
# =======================================================================
|
||||
if auth.status_code != 201:
|
||||
raise exception.AuthenticationFailureException("Login request return an invalid status code")
|
||||
#sysraise "Error getting token", auth.status_code
|
||||
try:
|
||||
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.user_uri = auth.headers.get("location")
|
||||
|
@ -1,12 +1,14 @@
|
||||
# coding=utf-8
|
||||
|
||||
import pprint
|
||||
import re
|
||||
from urlparse import urljoin
|
||||
import requests
|
||||
import simplejson
|
||||
import tortilla
|
||||
import config
|
||||
import mapping
|
||||
import re
|
||||
import exception
|
||||
|
||||
# Global variable
|
||||
|
||||
@ -28,10 +30,25 @@ class Base(object):
|
||||
headers={'x-auth-token': connection_parameters.auth_token}
|
||||
)
|
||||
except requests.ConnectionError as e:
|
||||
print e
|
||||
# Log and transmit the exception.
|
||||
config.logger.error("Connection error : %s", e)
|
||||
raise e
|
||||
config.logger.info("Raise a RedfishException to upper level")
|
||||
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
|
||||
|
||||
def get_link_url(self, link_type):
|
||||
|
Loading…
x
Reference in New Issue
Block a user