Fix up code-base to pass hacking
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Craton API Client Library and Command-Line Application."""
|
||||
|
||||
import pbr.version
|
||||
|
||||
|
@@ -11,8 +11,11 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Client for CRUD operations."""
|
||||
import copy
|
||||
|
||||
from oslo_utils import strutils
|
||||
|
||||
|
||||
class CRUDClient(object):
|
||||
"""Class that handles the basic create, read, upload, delete workflow."""
|
||||
@@ -22,6 +25,7 @@ class CRUDClient(object):
|
||||
resource_class = None
|
||||
|
||||
def __init__(self, session, url):
|
||||
"""Initialize our Client with a session and base url."""
|
||||
self.session = session
|
||||
self.url = url.rstrip('/')
|
||||
|
||||
@@ -37,11 +41,11 @@ class CRUDClient(object):
|
||||
The child class of the CRUDClient may set the ``base_path``, e.g.,
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
base_path = '/regions'
|
||||
|
||||
And it's ``key``, e.g.,
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
key = 'region'
|
||||
@@ -179,13 +183,17 @@ class Resource(object):
|
||||
return self._info == other._info
|
||||
|
||||
def is_loaded(self):
|
||||
"""Check if the resource has been loaded."""
|
||||
return self._loaded
|
||||
|
||||
def set_loaded(self, val):
|
||||
"""Set whether the resource has been loaded or not."""
|
||||
self._loaded = val
|
||||
|
||||
def to_dict(self):
|
||||
"""Return the resource as a dictionary."""
|
||||
return copy.deepcopy(self._info)
|
||||
|
||||
def delete(self):
|
||||
"""Delete the resource from the service."""
|
||||
return self.manager.delete(self)
|
||||
|
@@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
"""Exception classes and logic for cratonclient."""
|
||||
|
||||
|
||||
class ClientException(Exception):
|
||||
"""Base exception class for all exceptions in cratonclient."""
|
||||
|
||||
@@ -32,8 +33,13 @@ class Timeout(ClientException):
|
||||
"""Catch-all class for connect and read timeouts from requests."""
|
||||
|
||||
message = 'Request timed out'
|
||||
|
||||
|
||||
def __init__(self, message=None, **kwargs):
|
||||
"""Initialize our Timeout exception.
|
||||
|
||||
This takes an optional keyword-only argument of
|
||||
``original_exception``.
|
||||
"""
|
||||
self.original_exception = kwargs.pop('exception', None)
|
||||
super(Timeout, self).__init__(message)
|
||||
|
||||
@@ -45,6 +51,14 @@ class HTTPError(ClientException):
|
||||
status_code = None
|
||||
|
||||
def __init__(self, message=None, **kwargs):
|
||||
"""Initialize our HTTPError instance.
|
||||
|
||||
Optional keyword-only arguments include:
|
||||
|
||||
- response: for the response generating the error
|
||||
- original_exception: in the event that this is a requests exception
|
||||
that we are re-raising.
|
||||
"""
|
||||
self.response = kwargs.pop('response', None)
|
||||
self.original_exception = kwargs.pop('exception', None)
|
||||
self.status_code = (self.status_code
|
||||
@@ -82,7 +96,7 @@ class BadRequest(HTTPClientError):
|
||||
|
||||
class Unauthorized(HTTPClientError):
|
||||
"""Client is unauthorized to access the resource in question."""
|
||||
|
||||
|
||||
status_code = 401
|
||||
message = ("The user has either provided insufficient parameters for "
|
||||
"authentication or is not authorized to access this resource.")
|
||||
|
@@ -14,8 +14,11 @@
|
||||
"""Craton-specific session details."""
|
||||
import logging
|
||||
|
||||
from oslo_utils import encodeutils
|
||||
from oslo_utils import strutils
|
||||
import requests
|
||||
from requests import exceptions as requests_exc
|
||||
import six
|
||||
|
||||
import cratonclient
|
||||
from cratonclient import exceptions as exc
|
||||
@@ -31,7 +34,21 @@ class Session(object):
|
||||
immediately.
|
||||
"""
|
||||
|
||||
def __init__(self, session=None, username=None, token=None, project_id=None):
|
||||
def __init__(self, session=None, username=None, token=None,
|
||||
project_id=None):
|
||||
"""Initialize our Session.
|
||||
|
||||
:param session:
|
||||
The session instance (either keystoneauth1's session or requests
|
||||
Session) to use as an underlying HTTP transport. If not provided,
|
||||
we will create a requests Session object.
|
||||
:param str username:
|
||||
The username of the person authenticating against the API.
|
||||
:param str token:
|
||||
The authentication token of the user authenticating.
|
||||
:param str project_id:
|
||||
The user's project id in Craton.
|
||||
"""
|
||||
if session is None:
|
||||
session = requests.Session()
|
||||
|
||||
@@ -48,28 +65,135 @@ class Session(object):
|
||||
self._session.headers['Accept'] = 'application/json'
|
||||
|
||||
def delete(self, url, **kwargs):
|
||||
"""Make a DELETE request with url and optional parameters.
|
||||
|
||||
See the :meth:`Session.request` documentation for more details.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.delete('http://example.com')
|
||||
"""
|
||||
return self.request('DELETE', url, **kwargs)
|
||||
|
||||
def get(self, url, **kwargs):
|
||||
"""Make a GET request with url and optional parameters.
|
||||
|
||||
See the :meth:`Session.request` documentation for more details.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.get('http://example.com')
|
||||
"""
|
||||
return self.request('GET', url, **kwargs)
|
||||
|
||||
def head(self, url, **kwargs):
|
||||
"""Make a HEAD request with url and optional parameters.
|
||||
|
||||
See the :meth:`Session.request` documentation for more details.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.head('http://example.com')
|
||||
"""
|
||||
return self.request('HEAD', url, **kwargs)
|
||||
|
||||
def options(self, url, **kwargs):
|
||||
"""Make an OPTIONS request with url and optional parameters.
|
||||
|
||||
See the :meth:`Session.request` documentation for more details.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.options('http://example.com')
|
||||
"""
|
||||
return self.request('OPTIONS', url, **kwargs)
|
||||
|
||||
def post(self, url, **kwargs):
|
||||
"""Make a POST request with url and optional parameters.
|
||||
|
||||
See the :meth:`Session.request` documentation for more details.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.post(
|
||||
... 'http://example.com',
|
||||
... data=b'foo',
|
||||
... headers={'Content-Type': 'text/plain'},
|
||||
... )
|
||||
"""
|
||||
return self.request('POST', url, **kwargs)
|
||||
|
||||
def put(self, url, **kwargs):
|
||||
"""Make a PUT request with url and optional parameters.
|
||||
|
||||
See the :meth:`Session.request` documentation for more details.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.put(
|
||||
... 'http://example.com',
|
||||
... data=b'foo',
|
||||
... headers={'Content-Type': 'text/plain'},
|
||||
... )
|
||||
"""
|
||||
return self.request('PUT', url, **kwargs)
|
||||
|
||||
def request(self, method, url, **kwargs):
|
||||
"""Make a request with a method, url, and optional parameters.
|
||||
|
||||
See also: python-requests.org for documentation of acceptable
|
||||
parameters.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from cratonclient import session as craton
|
||||
>>> session = craton.Session(
|
||||
... username='demo',
|
||||
... token='p@$$w0rd',
|
||||
... project_id='1',
|
||||
... )
|
||||
>>> response = session.request('GET', 'http://example.com')
|
||||
"""
|
||||
self._http_log_request(method=method,
|
||||
url=url,
|
||||
data=kwargs.get('data'),
|
||||
headers=kwargs.get('headers', {}).copy())
|
||||
url=url,
|
||||
data=kwargs.get('data'),
|
||||
headers=kwargs.get('headers', {}).copy())
|
||||
try:
|
||||
response = self._session.request(method=method,
|
||||
url=url,
|
||||
@@ -91,7 +215,6 @@ class Session(object):
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def _http_log_request(self, url, method=None, data=None,
|
||||
headers=None, logger=LOG):
|
||||
if not logger.isEnabledFor(logging.DEBUG):
|
||||
@@ -135,16 +258,14 @@ class Session(object):
|
||||
if not logger.isEnabledFor(logging.DEBUG):
|
||||
return
|
||||
|
||||
text = _remove_service_catalog(response.text)
|
||||
|
||||
string_parts = [
|
||||
'RESP:',
|
||||
'[%s]' % response.status_code
|
||||
]
|
||||
for header in six.iteritems(response.headers):
|
||||
string_parts.append('%s: %s' % self._process_header(header))
|
||||
if text:
|
||||
if response.text:
|
||||
string_parts.append('\nRESP BODY: %s\n' %
|
||||
strutils.mask_password(text))
|
||||
strutils.mask_password(response.text))
|
||||
|
||||
logger.debug(' '.join(string_parts))
|
||||
|
@@ -8,4 +8,5 @@
|
||||
# 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.
|
||||
# under the License.
|
||||
"""Command-line application that interfaces with Craton API."""
|
||||
|
@@ -9,13 +9,11 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Main shell for parsing arguments directed toward Craton.
|
||||
"""
|
||||
"""Main shell for parsing arguments directed toward Craton."""
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry-point for cratonclient's CLI."""
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@@ -10,8 +10,6 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""
|
||||
Command-line interface to the OpenStack Craton API V1.
|
||||
"""
|
||||
"""Command-line interface to the OpenStack Craton API V1."""
|
||||
|
||||
# TODO (cmspence): from cratonclient.v1 import client
|
||||
# TODO(cmspence): from cratonclient.v1 import client
|
||||
|
@@ -0,0 +1,12 @@
|
||||
# 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 suite for Craton client and shell."""
|
||||
|
@@ -14,10 +14,10 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Base TestCase for all cratonclient tests."""
|
||||
|
||||
from oslotest import base
|
||||
|
||||
|
||||
class TestCase(base.BaseTestCase):
|
||||
|
||||
"""Test case base class for all unit tests."""
|
||||
|
@@ -11,18 +11,14 @@
|
||||
# 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_cratonclient
|
||||
----------------------------------
|
||||
|
||||
Tests for `cratonclient` module.
|
||||
"""
|
||||
"""Tests for `cratonclient` module."""
|
||||
|
||||
from cratonclient.tests import base
|
||||
|
||||
|
||||
class TestCratonclient(base.TestCase):
|
||||
"""Tests for the top-level module."""
|
||||
|
||||
def test_something(self):
|
||||
"""Do nothing."""
|
||||
pass
|
||||
|
@@ -21,11 +21,11 @@ import cratonclient
|
||||
from cratonclient import session
|
||||
from cratonclient.tests import base
|
||||
|
||||
|
||||
USERNAME = 'example'
|
||||
TOKEN = uuid.uuid4().hex
|
||||
TOKEN = uuid.uuid4().hex
|
||||
PROJECT_ID = 1
|
||||
|
||||
|
||||
class TestSession(base.TestCase):
|
||||
"""Test our session class."""
|
||||
|
||||
@@ -53,11 +53,10 @@ class TestSession(base.TestCase):
|
||||
'X-Auth-Token': TOKEN,
|
||||
'X-Auth-Project': str(PROJECT_ID),
|
||||
'User-Agent': 'python-cratonclient/{0} {1}'.format(
|
||||
cratonclient.__version__,
|
||||
cratonclient.__version__,
|
||||
requests_session.headers['User-Agent']),
|
||||
'Connection': 'keep-alive',
|
||||
'Accept-Encoding': 'gzip, deflate',
|
||||
'Accept': 'application/json',
|
||||
}
|
||||
self.assertItemsEqual(expected_headers, craton._session.headers)
|
||||
|
||||
|
@@ -8,4 +8,5 @@
|
||||
# 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.
|
||||
# under the License.
|
||||
"""Unit tests for cratonclient."""
|
||||
|
@@ -12,8 +12,8 @@
|
||||
|
||||
"""Tests for `cratonclient.shell.main` module."""
|
||||
|
||||
from cratonclient.tests import base
|
||||
from cratonclient.shell import main
|
||||
from cratonclient.tests import base
|
||||
|
||||
|
||||
class TestMainShell(base.TestCase):
|
||||
@@ -21,5 +21,4 @@ class TestMainShell(base.TestCase):
|
||||
|
||||
def test_main_returns_successfully(self):
|
||||
"""Verify that cratonclient shell main returns as expected."""
|
||||
|
||||
self.assertEqual(main.main(), 0)
|
||||
|
@@ -11,3 +11,4 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
"""Client library for version 1 of Craton's API."""
|
||||
|
Reference in New Issue
Block a user