sushy/sushy/connector.py

145 lines
4.9 KiB
Python

# Copyright 2017 Red Hat, Inc.
# 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.
import json
import logging
import requests
from six.moves.urllib import parse
from sushy import exceptions
LOG = logging.getLogger(__name__)
class Connector(object):
def __init__(self, url, username=None, password=None, verify=True):
self._url = url
self._session = requests.Session()
self._session.verify = verify
if username and password:
self._session.auth = (username, password)
def close(self):
"""Close this connector and the associated HTTP session."""
self._session.close()
def _op(self, method, path='', data=None, headers=None):
"""Generic RESTful request handler.
:param method: The HTTP method to be used, e.g: GET, POST,
PUT, PATCH, etc...
:param path: The sub-URI path to the resource.
:param data: Optional JSON data.
:param headers: Optional dictionary of headers.
:returns: The response object from the requests library.
:raises: ConnectionError
:raises: HTTPError
"""
if headers is None:
headers = {}
if data is not None:
data = json.dumps(data)
headers['Content-Type'] = 'application/json'
url = parse.urljoin(self._url, path)
# TODO(lucasagomes): We should mask the data to remove sensitive
# information
LOG.debug('HTTP request: %(method)s %(url)s; '
'headers: %(headers)s; body: %(data)s',
{'method': method, 'url': url, 'headers': headers,
'data': data})
try:
response = self._session.request(method, url, data=data,
headers=headers)
except requests.ConnectionError as e:
raise exceptions.ConnectionError(url=url, error=e)
exceptions.raise_for_response(method, url, response)
LOG.debug('HTTP response for %(method)s %(url)s: '
'status code: %(code)s',
{'method': method, 'url': url,
'code': response.status_code})
return response
def get(self, path='', data=None, headers=None):
"""HTTP GET method.
:param path: Optional sub-URI path to the resource.
:param data: Optional JSON data.
:param headers: Optional dictionary of headers.
:returns: The response object from the requests library.
:raises: ConnectionError
:raises: HTTPError
"""
return self._op('GET', path, data, headers)
def post(self, path='', data=None, headers=None):
"""HTTP POST method.
:param path: Optional sub-URI path to the resource.
:param data: Optional JSON data.
:param headers: Optional dictionary of headers.
:returns: The response object from the requests library.
:raises: ConnectionError
:raises: HTTPError
"""
return self._op('POST', path, data, headers)
def patch(self, path='', data=None, headers=None):
"""HTTP PATCH method.
:param path: Optional sub-URI path to the resource.
:param data: Optional JSON data.
:param headers: Optional dictionary of headers.
:returns: The response object from the requests library.
:raises: ConnectionError
:raises: HTTPError
"""
return self._op('PATCH', path, data, headers)
def put(self, path='', data=None, headers=None):
"""HTTP PUT method.
:param path: Optional sub-URI path to the resource.
:param data: Optional JSON data.
:param headers: Optional dictionary of headers.
:returns: The response object from the requests library.
:raises: ConnectionError
:raises: HTTPError
"""
return self._op('PUT', path, data, headers)
def delete(self, path='', data=None, headers=None):
"""HTTP DELETE method.
:param path: Optional sub-URI path to the resource.
:param data: Optional JSON data.
:param headers: Optional dictionary of headers.
:returns: The response object from the requests library.
:raises: ConnectionError
:raises: HTTPError
"""
return self._op('DELETE', path, data, headers)
def __enter__(self):
return self
def __exit__(self, *_args):
self.close()