Base API facade
This patch adds base class for implementing facades that will provide access to appropriate API resources and encapsulate the implementation of the API wrapper. Blueprint: re-thinking-fuel-client Change-Id: I2a8b08204a7848dd99e3f2197be7e3fe9eb218dd
This commit is contained in:
@@ -11,6 +11,9 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from fuelclient import v1
|
||||
|
||||
try:
|
||||
import pkg_resources
|
||||
try:
|
||||
@@ -20,3 +23,32 @@ try:
|
||||
__version__ = ""
|
||||
except ImportError:
|
||||
__version__ = ""
|
||||
|
||||
version_map = {
|
||||
'v1': {
|
||||
}
|
||||
}
|
||||
|
||||
def get_client(resource, version='v1'):
|
||||
"""Gets an API client for a resource
|
||||
|
||||
python-fuelclient provides access to Fuel's API
|
||||
through a set of per-resource facades. In order to
|
||||
get a proper facade it's necessary to specify the name
|
||||
of the API resource and the version of Fuel's API.
|
||||
|
||||
:param resource: Name of the resource to get a facade for.
|
||||
:type resource: str
|
||||
Valid values are environment, node and task
|
||||
:param version: Version of the Fuel's API
|
||||
:type version: str,
|
||||
Available: v1. Default: v1.
|
||||
:return: Facade to the specified resource that wraps
|
||||
calls to the specified version of the API.
|
||||
|
||||
"""
|
||||
try:
|
||||
return version_map[version][resource].get_client()
|
||||
except KeyError:
|
||||
msg = 'Cannot load API client for "{r}" in the API version "{v}".'
|
||||
raise ValueError(msg.format(r=resource, v=version))
|
||||
|
||||
@@ -18,11 +18,31 @@ import sys
|
||||
|
||||
import mock
|
||||
|
||||
import fuelclient
|
||||
from fuelclient import main as main_mod
|
||||
from fuelclient.tests import base
|
||||
|
||||
|
||||
class BaseCLITest(base.UnitTestCase):
|
||||
"""Base class for testing the new CLI
|
||||
|
||||
It mocks the whole API layer in order to be sure the
|
||||
tests test only the stuff which is responsible for
|
||||
the command line application. That allows to find bugs
|
||||
more precisely and not confuse them with the bugs in the
|
||||
API wrapper.
|
||||
|
||||
"""
|
||||
def setUp(self):
|
||||
self._get_client_patcher = mock.patch.object(fuelclient, 'get_client')
|
||||
self.m_get_client = self._get_client_patcher.start()
|
||||
|
||||
self.m_client = mock.MagicMock()
|
||||
self.m_get_client.return_value = self.m_client
|
||||
|
||||
def tearDown(self):
|
||||
self._get_client_patcher.stop()
|
||||
|
||||
def exec_v2_command(self, *args, **kwargs):
|
||||
"""Executes fuelclient with the specified arguments."""
|
||||
|
||||
|
||||
0
fuelclient/tests/lib/__init__.py
Normal file
0
fuelclient/tests/lib/__init__.py
Normal file
45
fuelclient/tests/lib/test_api.py
Normal file
45
fuelclient/tests/lib/test_api.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# 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 mock
|
||||
from mock import patch
|
||||
import requests_mock as rm
|
||||
from six.moves.urllib import parse as urlparse
|
||||
|
||||
from fuelclient import client
|
||||
from fuelclient.tests import base
|
||||
|
||||
|
||||
class BaseLibTest(base.UnitTestCase):
|
||||
def setUp(self):
|
||||
self.m_request = rm.Mocker()
|
||||
self.m_request.start()
|
||||
|
||||
self.session_adapter = self.m_request._adapter.register_uri(rm.ANY,
|
||||
rm.ANY)
|
||||
|
||||
self.api_client_patcher = patch.object(client.Client,
|
||||
'auth_required',
|
||||
new_callable=mock.PropertyMock)
|
||||
self.m_api_client = self.api_client_patcher.start()
|
||||
self.m_api_client.return_value = False
|
||||
|
||||
def tearDown(self):
|
||||
self.m_request.stop()
|
||||
self.api_client_patcher.stop()
|
||||
|
||||
def get_object_uri(self, collection_path, object_id, attribute='/'):
|
||||
return urlparse.urljoin(collection_path, str(object_id) + attribute)
|
||||
@@ -0,0 +1,18 @@
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
|
||||
__all__ = (
|
||||
)
|
||||
|
||||
35
fuelclient/v1/base_v1.py
Normal file
35
fuelclient/v1/base_v1.py
Normal file
@@ -0,0 +1,35 @@
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# 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 abc
|
||||
|
||||
import six
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseV1Client(object):
|
||||
|
||||
@abc.abstractproperty
|
||||
def _entity_wrapper(self):
|
||||
pass
|
||||
|
||||
def get_all(self):
|
||||
result = self._entity_wrapper.get_all_data()
|
||||
|
||||
return result
|
||||
|
||||
def get_by_id(self, entity_id):
|
||||
obj = self._entity_wrapper(obj_id=entity_id)
|
||||
|
||||
return obj.data
|
||||
Reference in New Issue
Block a user