#!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function from ansible.module_utils.six.moves import http_client from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError import urllib.request as urllib_request from pprint import pprint import ssl import json import sys import argparse __metaclass__ = type class RequestWithMethod(urllib_request.Request): def __init__(self, url, method, data=None, headers=None, origin_req_host=None, unverifiable=True): if headers is None: headers = {} self._method = method.upper() urllib_request.Request.__init__(self, url, data, headers, origin_req_host, unverifiable) def get_method(self): if self._method: return self._method else: return urllib_request.Request.get_method(self) class Request: def __init__(self): pass def open(self, method, url, token, unverified_context): timeout = 10 request = RequestWithMethod(url, method, None) headers= {'Accept': 'application/json', 'Odata-version': '4.0', 'X-auth-token': token} for header in headers: request.add_header(header, headers[header]) #pprint(vars(request)) if unverified_context: context = ssl._create_unverified_context() r = urllib_request.urlopen(request, None, timeout, context=context) else: r = urllib_request.urlopen(request, None, timeout) return r class RedfishUtils(object): def __init__(self, token): self.token = token def get_request(self, uri, unverified_context): try: resp = open_url('GET', uri, self.token, unverified_context) data = json.loads(resp.read()) headers = dict((k.lower(), v) for (k, v) in resp.info().items()) except HTTPError as e: msg = self._get_extended_message(e) return {'ret': False, 'msg': "HTTP Error %s on GET request to '%s', extended message: '%s'" % (e.code, uri, msg), 'status': e.code} except URLError as e: return {'ret': False, 'msg': "URL Error on GET request to '%s': '%s'" % (uri, e.reason)} except Exception as e: return {'ret': False, 'msg': "Failed GET request to '%s': '%s'" % (uri, to_text(e))} return {'ret': True, 'data': data, 'headers': headers, 'resp': resp} @staticmethod def _get_extended_message(error): """ Get Redfish ExtendedInfo message from response payload if present :param error: an HTTPError exception :type error: HTTPError :return: the ExtendedInfo message if present, else standard HTTP error """ msg = http_client.responses.get(error.code, '') if error.code >= 400: try: body = error.read().decode('utf-8') data = json.loads(body) ext_info = data['error']['@Message.ExtendedInfo'] # if the ExtendedInfo contains a user friendly message send it # otherwise try to send the entire contents of ExtendedInfo try: msg = ext_info[0]['Message'] except Exception: msg = str(data['error']['@Message.ExtendedInfo']) except Exception: pass return msg def open_url(method, url, token, unverified_context): return Request().open(method, url, token, unverified_context) def main(): parser = argparse.ArgumentParser() parser.add_argument('-U', '--unverified_context', action='store_true') parser.add_argument('token') args = parser.parse_args() rf_utils = RedfishUtils(args.token) r = rf_utils.get_request("https://10.137.189.246/redfish/v1/UpdateService", args.unverified_context) pprint(r) main()