Add logging for RIS and RIBCL modules
This commit adds logging statement for some common functions in RIBCL and RIS module. Co-Authored-By: Debayan Ray <debayan.ray@gmail.com> Implements: blueprint enable-logging Change-Id: I9e4b18d1c5bea643e405b5d742c66426f54c2610
This commit is contained in:
parent
afbe98dd09
commit
7a803799cb
|
@ -59,9 +59,10 @@ class IloClient(operations.IloOperations):
|
|||
bios_password=bios_password,
|
||||
cacert=cacert)
|
||||
self.info = {'address': host, 'username': login, 'password': password}
|
||||
self.host = host
|
||||
self.model = self.ribcl.get_product_name()
|
||||
LOG.debug("IloClient object created for host {} [model: {}]".format(
|
||||
host, self.model))
|
||||
LOG.debug(self._("IloClient object created. "
|
||||
"Model: %(model)s"), {'model': self.model})
|
||||
|
||||
def _call_method(self, method_name, *args, **kwargs):
|
||||
"""Call the corresponding method using either RIBCL or RIS."""
|
||||
|
@ -70,9 +71,9 @@ class IloClient(operations.IloOperations):
|
|||
the_operation_object = self.ris
|
||||
method = getattr(the_operation_object, method_name)
|
||||
|
||||
LOG.debug("Calling {} method of {} for host {}".format(
|
||||
method_name, type(the_operation_object).__name__,
|
||||
the_operation_object.host))
|
||||
LOG.debug(self._("Using %(class)s for method %(method)s."),
|
||||
{'class': type(the_operation_object).__name__,
|
||||
'method': method_name})
|
||||
|
||||
return method(*args, **kwargs)
|
||||
|
||||
|
|
|
@ -25,6 +25,13 @@ class IloOperations(object):
|
|||
python as described in HP iLO 4 Scripting and Command Line Guide.
|
||||
|
||||
"""
|
||||
def _(self, msg):
|
||||
"""Prepends host information if available to msg and returns it."""
|
||||
try:
|
||||
return "[iLO %s] %s" % (self.host, msg)
|
||||
except AttributeError:
|
||||
return "[iLO <unknown>] %s" % msg
|
||||
|
||||
def get_all_licenses(self):
|
||||
"""Retrieve license type, key, installation date, etc."""
|
||||
raise exception.IloCommandNotSupportedError(ERRMSG)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
over RIBCL scripting language
|
||||
"""
|
||||
|
||||
import copy
|
||||
import re
|
||||
import xml.etree.ElementTree as etree
|
||||
|
||||
|
@ -47,6 +48,22 @@ BOOT_MODE_CMDS = [
|
|||
LOG = log.get_logger(__name__)
|
||||
|
||||
|
||||
class MaskedRequestData(object):
|
||||
def __init__(self, request_data):
|
||||
self.request_data = request_data
|
||||
|
||||
def __str__(self):
|
||||
request_data_copy = copy.deepcopy(self.request_data)
|
||||
xml_data = request_data_copy.get('data')
|
||||
if xml_data:
|
||||
xml_data = re.sub(r'USER_LOGIN="(.*?)"', r'USER_LOGIN="*****"',
|
||||
xml_data)
|
||||
xml_data = re.sub(r'PASSWORD="(.*?)"', r'PASSWORD="*****"',
|
||||
xml_data)
|
||||
request_data_copy['data'] = xml_data
|
||||
return str(request_data_copy)
|
||||
|
||||
|
||||
class RIBCLOperations(operations.IloOperations):
|
||||
"""iLO class for RIBCL interface for iLO.
|
||||
|
||||
|
@ -69,9 +86,6 @@ class RIBCLOperations(operations.IloOperations):
|
|||
if self.cacert is None:
|
||||
urllib3.disable_warnings(urllib3_exceptions.InsecureRequestWarning)
|
||||
|
||||
LOG.debug("RIBCLOperations object created for host {}".format(
|
||||
self.host))
|
||||
|
||||
def _request_ilo(self, root):
|
||||
"""Send RIBCL XML data to iLO.
|
||||
|
||||
|
@ -93,9 +107,15 @@ class RIBCLOperations(operations.IloOperations):
|
|||
kwargs['verify'] = False
|
||||
|
||||
try:
|
||||
LOG.debug(self._("POST %(url)s with request data: "
|
||||
"%(request_data)s"),
|
||||
{'url': urlstr,
|
||||
'request_data': MaskedRequestData(kwargs)})
|
||||
response = requests.post(urlstr, **kwargs)
|
||||
response.raise_for_status()
|
||||
except Exception as e:
|
||||
LOG.exception(self._("An error occurred while "
|
||||
"contacting iLO. Error: %s"), e)
|
||||
raise exception.IloConnectionError(e)
|
||||
return response.text
|
||||
|
||||
|
@ -253,13 +273,26 @@ class RIBCLOperations(operations.IloOperations):
|
|||
platform = self.get_product_name()
|
||||
msg = ("%(cmd)s is not supported on %(platform)s" %
|
||||
{'cmd': cmd, 'platform': platform})
|
||||
LOG.error(self._("Got invalid response with "
|
||||
"message: '%(message)s'"),
|
||||
{'message': msg})
|
||||
raise (exception.IloCommandNotSupportedError
|
||||
(msg, status))
|
||||
else:
|
||||
LOG.error(self._("Got invalid response with "
|
||||
"message: '%(message)s'"),
|
||||
{'message': msg})
|
||||
raise exception.IloClientInternalError(msg, status)
|
||||
if (status in exception.IloLoginFailError.statuses or
|
||||
msg in exception.IloLoginFailError.messages):
|
||||
LOG.error(self._("Got invalid response with "
|
||||
"message: '%(message)s'"),
|
||||
{'message': msg})
|
||||
raise exception.IloLoginFailError(msg, status)
|
||||
|
||||
LOG.error(self._("Got invalid response with "
|
||||
"message: '%(message)s'"),
|
||||
{'message': msg})
|
||||
raise exception.IloError(msg, status)
|
||||
|
||||
def _execute_command(self, create_command, tag_info, mode, dic={}):
|
||||
|
@ -272,6 +305,7 @@ class RIBCLOperations(operations.IloOperations):
|
|||
create_command, tag_info, mode, dic)
|
||||
d = self._request_ilo(xml)
|
||||
data = self._parse_output(d)
|
||||
LOG.debug(self._("Received response data: %s"), data)
|
||||
return data
|
||||
|
||||
def get_all_licenses(self):
|
||||
|
|
|
@ -64,9 +64,6 @@ class RISOperations(operations.IloOperations):
|
|||
if self.cacert is None:
|
||||
urllib3.disable_warnings(urllib3_exceptions.InsecureRequestWarning)
|
||||
|
||||
LOG.debug("RISOperations object created for host {}".format(
|
||||
self.host))
|
||||
|
||||
def _rest_op(self, operation, suburi, request_headers, request_body):
|
||||
"""Generic REST Operation handler."""
|
||||
|
||||
|
@ -74,6 +71,12 @@ class RISOperations(operations.IloOperations):
|
|||
# Used for logging on redirection error.
|
||||
start_url = url.geturl()
|
||||
|
||||
LOG.debug(self._("%(operation)s %(url)s "
|
||||
"with headers '%(header)s' and body '%(body)s'"),
|
||||
{'operation': operation, 'url': start_url,
|
||||
'header': request_headers,
|
||||
'body': request_body})
|
||||
|
||||
if request_headers is None:
|
||||
request_headers = {}
|
||||
|
||||
|
@ -98,6 +101,8 @@ class RISOperations(operations.IloOperations):
|
|||
try:
|
||||
response = request_method(url.geturl(), **kwargs)
|
||||
except Exception as e:
|
||||
LOG.exception(self._("An error occurred while "
|
||||
"contacting iLO. Error: %s"), e)
|
||||
raise exception.IloConnectionError(e)
|
||||
|
||||
# NOTE:Do not assume every HTTP operation will return a JSON body.
|
||||
|
@ -112,12 +117,15 @@ class RISOperations(operations.IloOperations):
|
|||
if response.status_code == 301 and 'location' in response.headers:
|
||||
url = urlparse.urlparse(response.headers['location'])
|
||||
redir_count -= 1
|
||||
LOG.debug(self._("Request redirected to %s."), url.geturl())
|
||||
else:
|
||||
break
|
||||
else:
|
||||
# Redirected for 5th time. Throw error
|
||||
msg = ("URL Redirected 5 times continuously. "
|
||||
"URL incorrect: %s" % start_url)
|
||||
msg = (self._("URL Redirected 5 times continuously. "
|
||||
"URL incorrect: %(start_url)s") %
|
||||
{'start_url': start_url})
|
||||
LOG.error(msg)
|
||||
raise exception.IloConnectionError(msg)
|
||||
|
||||
response_body = {}
|
||||
|
@ -134,11 +142,20 @@ class RISOperations(operations.IloOperations):
|
|||
try:
|
||||
gzipper = gzip.GzipFile(
|
||||
fileobj=six.BytesIO(response.text))
|
||||
LOG.debug(self._("Received compressed response "
|
||||
"for url %(url)s."),
|
||||
{'url': url.geturl()})
|
||||
uncompressed_string = gzipper.read().decode('UTF-8')
|
||||
response_body = json.loads(uncompressed_string)
|
||||
except Exception as e:
|
||||
LOG.error(self._("Got invalid response "
|
||||
"'%(response)s' for url %(url)s."),
|
||||
{'url': url.geturl(),
|
||||
'response': response.text})
|
||||
raise exception.IloError(e)
|
||||
|
||||
LOG.debug(self._("Received response %(response)s for url %(url)s."),
|
||||
{'url': url.geturl(), 'response': response_body})
|
||||
return response.status_code, response.headers, response_body
|
||||
|
||||
def _rest_get(self, suburi, request_headers=None):
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""Test Class for Common Operations."""
|
||||
|
||||
import unittest
|
||||
|
||||
from proliantutils.ilo import operations
|
||||
|
||||
|
||||
class IloOperationsTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(IloOperationsTestCase, self).setUp()
|
||||
self.operations_object = operations.IloOperations()
|
||||
|
||||
def test__okay(self):
|
||||
self.operations_object.host = '1.2.3.4'
|
||||
self.assertEqual('[iLO 1.2.3.4] foo',
|
||||
self.operations_object._('foo'))
|
||||
|
||||
def test__no_host(self):
|
||||
self.assertEqual('[iLO <unknown>] foo',
|
||||
self.operations_object._('foo'))
|
|
@ -29,6 +29,36 @@ from proliantutils.ilo import ribcl
|
|||
from proliantutils.tests.ilo import ribcl_sample_outputs as constants
|
||||
|
||||
|
||||
class MaskedRequestDataTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(MaskedRequestDataTestCase, self).setUp()
|
||||
self.maskedRequestData = ribcl.MaskedRequestData({})
|
||||
|
||||
def test___str__with_user_credential_present(self):
|
||||
xml_data = (
|
||||
'<RIBCL VERSION="2.0">'
|
||||
'<LOGIN PASSWORD="password" USER_LOGIN="admin">'
|
||||
'<RIB_INFO MODE="read">')
|
||||
masked_xml_data = (
|
||||
'\'<RIBCL VERSION="2.0">'
|
||||
'<LOGIN PASSWORD="*****" USER_LOGIN="*****">'
|
||||
'<RIB_INFO MODE="read">\'')
|
||||
self.maskedRequestData.request_data = {'headers': 'some-headers',
|
||||
'data': xml_data,
|
||||
'verify': False}
|
||||
self.assertIn(masked_xml_data, str(self.maskedRequestData))
|
||||
|
||||
def test___str__with_user_credential_not_present(self):
|
||||
xml_data = (
|
||||
'<RIBCL VERSION="2.0">'
|
||||
'<RIB_INFO MODE="read">')
|
||||
self.maskedRequestData.request_data = {'headers': 'some-headers',
|
||||
'data': xml_data,
|
||||
'verify': True}
|
||||
self.assertIn(xml_data, str(self.maskedRequestData))
|
||||
|
||||
|
||||
class IloRibclTestCaseInitTestCase(unittest.TestCase):
|
||||
|
||||
@mock.patch.object(urllib3, 'disable_warnings')
|
||||
|
|
Loading…
Reference in New Issue