more cleanup
- clean up the RedfishConnection constructor - add some better doc strings - other tiny things
This commit is contained in:
parent
c96a363994
commit
030079ccc0
@ -129,33 +129,42 @@ import sys
|
|||||||
|
|
||||||
|
|
||||||
class RedfishConnection(object):
|
class RedfishConnection(object):
|
||||||
|
"""Implements basic connection handling for Redfish APIs."""
|
||||||
|
|
||||||
def __init__(self, host, user_name, password):
|
def __init__(self, host, user_name, password,
|
||||||
|
auth_token=None, enforce_SSL=True):
|
||||||
super(RedfishConnection, self).__init__()
|
super(RedfishConnection, self).__init__()
|
||||||
self.host = host
|
self.host = host
|
||||||
self.user_name = user_name
|
self.user_name = user_name
|
||||||
self.password = password
|
self.password = password
|
||||||
authen = {'Password': self.password, 'UserName': self.user_name}
|
self.auth_token = auth_token
|
||||||
self.rest_post(self.host, '/rest/v1/sessions', None, json.dumps(authen),
|
self.enforse_SSL = enforse_SSL
|
||||||
self.user_name, self.password)
|
# TODO: cache the token returned by this call
|
||||||
|
auth_dict = {'Password': self.password, 'UserName': self.user_name}
|
||||||
|
self.rest_post(self.host, '/rest/v1/sessions', None,
|
||||||
|
json.dumps(auth_dict), self.user_name, self.password)
|
||||||
|
# TODO: do some schema discovery here and cache the result
|
||||||
|
|
||||||
# XXX add members, we're going to have to cache
|
def _op(self, operation, suburi, request_headers=None, request_body=None):
|
||||||
|
"""
|
||||||
|
REST operation generic handler
|
||||||
|
|
||||||
def _op(self, operation, host, suburi, request_headers, request_body,
|
:param operation: GET, POST, etc
|
||||||
user_name, password, x_auth_token=None, enforce_SSL=True):
|
:param suburi: the URI path to the resource
|
||||||
"""REST operation generic handler"""
|
:param request_headers: optional dict of headers
|
||||||
|
:param request_body: optional JSON body
|
||||||
|
"""
|
||||||
|
|
||||||
url = urlparse('https://' + host + suburi)
|
url = urlparse('https://' + self.host + suburi)
|
||||||
|
|
||||||
if request_headers is None:
|
if not isinstance(request_headers, dict): request_headers = dict()
|
||||||
request_headers = dict()
|
|
||||||
|
|
||||||
# if X-Auth-Token specified, supply it instead of basic auth
|
# if X-Auth-Token specified, supply it instead of basic auth
|
||||||
if x_auth_token is not None:
|
if self.auth_token is not None:
|
||||||
request_headers['X-Auth-Token'] = x_auth_token
|
request_headers['X-Auth-Token'] = self.auth_token
|
||||||
# else use user_name/password and Basic Auth
|
# else use user_name/password and Basic Auth
|
||||||
elif user_name is not None and password is not None:
|
elif self.user_name is not None and self.password is not None:
|
||||||
request_headers['Authorization'] = "BASIC " + base64.b64encode(user_name + ":" + password)
|
request_headers['Authorization'] = "BASIC " + base64.b64encode(self.user_name + ":" + self.password)
|
||||||
# TODO: add support for other types of auth
|
# TODO: add support for other types of auth
|
||||||
|
|
||||||
# TODO: think about redirects....
|
# TODO: think about redirects....
|
||||||
@ -218,54 +227,77 @@ class RedfishConnection(object):
|
|||||||
|
|
||||||
return resp.status, headers, response
|
return resp.status, headers, response
|
||||||
|
|
||||||
|
def rest_get(self, suburi, request_headers):
|
||||||
|
"""REST GET
|
||||||
|
|
||||||
def rest_get(self, host, suburi, request_headers, user_name, password):
|
:param: suburi
|
||||||
"""Generic REST GET handler"""
|
:param: request_headers
|
||||||
|
"""
|
||||||
|
if not isinstance(request_headers, dict): request_headers = dict()
|
||||||
# NOTE: be prepared for various HTTP responses including 500, 404, etc.
|
# NOTE: be prepared for various HTTP responses including 500, 404, etc.
|
||||||
# XXX need parameter sanitization; request_headers must be a dict or None
|
return self._op('GET', suburi, request_headers, None)
|
||||||
return self._op('GET', host, suburi, request_headers, None, user_name, password)
|
|
||||||
|
|
||||||
|
def rest_patch(self, suburi, request_headers, request_body):
|
||||||
|
"""REST PATCH
|
||||||
|
|
||||||
def rest_patch(self, server, suburi, request_headers, request_body, user_name, password):
|
:param: suburi
|
||||||
"""REST PATCH"""
|
:param: request_headers
|
||||||
|
:param: request_body
|
||||||
|
NOTE: this body is a dict, not a JSONPATCH document.
|
||||||
|
redfish does not follow IETF JSONPATCH standard
|
||||||
|
https://tools.ietf.org/html/rfc6902
|
||||||
|
"""
|
||||||
if not isinstance(request_headers, dict): request_headers = dict()
|
if not isinstance(request_headers, dict): request_headers = dict()
|
||||||
request_headers['Content-Type'] = 'application/json'
|
request_headers['Content-Type'] = 'application/json'
|
||||||
return self._op('PATCH', server, suburi, request_headers, request_body, user_name, password)
|
return self._op('PATCH', suburi, request_headers, request_body)
|
||||||
# NOTE: be prepared for various HTTP responses including 500, 404, 202 etc.
|
# NOTE: be prepared for various HTTP responses including 500, 404, 202 etc.
|
||||||
|
|
||||||
|
def rest_put(self, suburi, request_headers, request_body):
|
||||||
|
"""REST PUT
|
||||||
|
|
||||||
def rest_put(self, host, suburi, request_headers, request_body, user_name, password):
|
:param: suburi
|
||||||
"""REST PUT"""
|
:param: request_headers
|
||||||
|
:param: request_body
|
||||||
|
"""
|
||||||
if not isinstance(request_headers, dict): request_headers = dict()
|
if not isinstance(request_headers, dict): request_headers = dict()
|
||||||
request_headers['Content-Type'] = 'application/json'
|
request_headers['Content-Type'] = 'application/json'
|
||||||
return self._op('PUT', host, suburi, request_headers, request_body, user_name, password)
|
return self._op('PUT', suburi, request_headers, request_body)
|
||||||
# NOTE: be prepared for various HTTP responses including 500, 404, 202 etc.
|
# NOTE: be prepared for various HTTP responses including 500, 404, 202 etc.
|
||||||
|
|
||||||
# REST POST
|
def rest_post(self, suburi, request_headers, request_body):
|
||||||
def rest_post(self, host, suburi, request_headers, request_body, user_name, password):
|
"""REST POST
|
||||||
|
|
||||||
|
:param: suburi
|
||||||
|
:param: request_headers
|
||||||
|
:param: request_body
|
||||||
|
"""
|
||||||
if not isinstance(request_headers, dict): request_headers = dict()
|
if not isinstance(request_headers, dict): request_headers = dict()
|
||||||
request_headers['Content-Type'] = 'application/json'
|
request_headers['Content-Type'] = 'application/json'
|
||||||
return self._op('POST', host, suburi, request_headers, request_body, user_name, password)
|
return self._op('POST', suburi, request_headers, request_body)
|
||||||
# NOTE: don't assume any newly created resource is included in the response. Only the Location header matters.
|
# NOTE: don't assume any newly created resource is included in the response. Only the Location header matters.
|
||||||
# the response body may be the new resource, it may be an ExtendedError, or it may be empty.
|
# the response body may be the new resource, it may be an ExtendedError, or it may be empty.
|
||||||
|
|
||||||
# REST DELETE
|
def rest_delete(self, suburi, request_headers):
|
||||||
def rest_delete(self, host, suburi, request_headers, user_name, password):
|
"""REST DELETE
|
||||||
return self._op('DELETE', host, suburi, request_headers, None, user_name, password)
|
|
||||||
|
:param: suburi
|
||||||
|
:param: request_headers
|
||||||
|
"""
|
||||||
|
if not isinstance(request_headers, dict): request_headers = dict()
|
||||||
|
return self._op('DELETE', suburi, request_headers, None)
|
||||||
# NOTE: be prepared for various HTTP responses including 500, 404, etc.
|
# NOTE: be prepared for various HTTP responses including 500, 404, etc.
|
||||||
# NOTE: response may be an ExtendedError or may be empty
|
# NOTE: response may be an ExtendedError or may be empty
|
||||||
|
|
||||||
|
|
||||||
# this is a generator that returns collection members
|
# this is a generator that returns collection members
|
||||||
def collection(self, host, collection_uri, request_headers, user_name, password):
|
def collection(self, collection_uri, request_headers):
|
||||||
"""
|
"""
|
||||||
collections are of two tupes:
|
collections are of two tupes:
|
||||||
- array of things that are fully expanded (details)
|
- array of things that are fully expanded (details)
|
||||||
- array of URLs (links)
|
- array of URLs (links)
|
||||||
"""
|
"""
|
||||||
# get the collection
|
# get the collection
|
||||||
status, headers, thecollection = rest_get(
|
status, headers, thecollection = self.rest_get(
|
||||||
host, collection_uri, request_headers, user_name, password)
|
collection_uri, request_headers)
|
||||||
|
|
||||||
# TODO: commment this
|
# TODO: commment this
|
||||||
while status < 300:
|
while status < 300:
|
||||||
|
@ -27,15 +27,8 @@ from redfish import connection
|
|||||||
|
|
||||||
class RedfishOperation(connection.RedfishConnection):
|
class RedfishOperation(connection.RedfishConnection):
|
||||||
|
|
||||||
def __init__(self, host, user_name, password):
|
|
||||||
super(RedfishOperation, self).__init__(host,
|
|
||||||
user_name, password)
|
|
||||||
# XXX add members, we're going to have to cache
|
|
||||||
|
|
||||||
# noinspection PyPep8Naming
|
|
||||||
def reset_server(self):
|
def reset_server(self):
|
||||||
(status, headers, system) = self.rest_get(self.host,
|
(status, headers, system) = self.rest_get('/rest/v1/Systems', None)
|
||||||
'/rest/v1/Systems', None, self.user_name, self.password)
|
|
||||||
|
|
||||||
memberuri = system['links']['Member'][0]['href']
|
memberuri = system['links']['Member'][0]['href']
|
||||||
# verify expected type
|
# verify expected type
|
||||||
@ -51,7 +44,6 @@ class RedfishOperation(connection.RedfishConnection):
|
|||||||
|
|
||||||
# perform the POST action
|
# perform the POST action
|
||||||
print('POST ' + json.dumps(action) + ' to ' + memberuri)
|
print('POST ' + json.dumps(action) + ' to ' + memberuri)
|
||||||
(status, headers, response) = self.rest_post(self.host, memberuri, None,
|
(status, headers, response) = self.rest_post(memberuri, None, action)
|
||||||
action, self.user_name, self.password)
|
|
||||||
print('POST response = ' + str(status))
|
print('POST response = ' + str(status))
|
||||||
connection.print_extended_error(response)
|
connection.print_extended_error(response)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user