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:
Roman Prykhodchenko
2015-03-05 12:11:59 +01:00
parent 9917b2eab4
commit 14f2b3e0c9
6 changed files with 150 additions and 0 deletions

View File

@@ -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))

View File

@@ -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."""

View File

View 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)

View File

@@ -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
View 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