Add solum builder client
This client will be used to communicate with builder service from solum. Generalize KeystoneAuthPlugin so that it can be used by both solumclient and builder client. Fixed a bug in solumclient/common/base.py Change-Id: I86630f40b32c6fcada5aa292fae8e36cecab9908
This commit is contained in:
0
solumclient/builder/__init__.py
Normal file
0
solumclient/builder/__init__.py
Normal file
34
solumclient/builder/client.py
Normal file
34
solumclient/builder/client.py
Normal file
@@ -0,0 +1,34 @@
|
||||
# Copyright 2014 - Noorul Islam K M
|
||||
#
|
||||
# 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.
|
||||
|
||||
from solumclient.common import auth
|
||||
from solumclient.openstack.common.apiclient import client
|
||||
|
||||
API_NAME = 'builder'
|
||||
VERSION_MAP = {
|
||||
'1': 'solumclient.builder.v1.client.Client',
|
||||
}
|
||||
|
||||
|
||||
def Client(version, **kwargs):
|
||||
client_class = client.BaseClient.get_class(API_NAME, version, VERSION_MAP)
|
||||
keystone_auth = auth.KeystoneAuthPlugin(
|
||||
username=kwargs.get('username'),
|
||||
password=kwargs.get('password'),
|
||||
tenant_name=kwargs.get('tenant_name'),
|
||||
token=kwargs.get('token'),
|
||||
auth_url=kwargs.get('auth_url'),
|
||||
endpoint=kwargs.get('endpoint'))
|
||||
http_client = client.HTTPClient(keystone_auth)
|
||||
return client_class(http_client)
|
0
solumclient/builder/v1/__init__.py
Normal file
0
solumclient/builder/v1/__init__.py
Normal file
25
solumclient/builder/v1/client.py
Normal file
25
solumclient/builder/v1/client.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Copyright 2014 - Noorul Islam K M
|
||||
#
|
||||
# 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.
|
||||
|
||||
from solumclient.builder.v1 import image
|
||||
from solumclient.openstack.common.apiclient import client
|
||||
|
||||
|
||||
class Client(client.BaseClient):
|
||||
"""Client for the Solum v1 API."""
|
||||
|
||||
def __init__(self, http_client, extensions=None):
|
||||
"""Initialize a new client for the Builder v1 API."""
|
||||
super(Client, self).__init__(http_client, extensions)
|
||||
self.images = image.ImageManager(self)
|
33
solumclient/builder/v1/image.py
Normal file
33
solumclient/builder/v1/image.py
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright 2014 - Noorul Islam K M
|
||||
#
|
||||
# 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.
|
||||
|
||||
from solumclient.common import base as solum_base
|
||||
from solumclient.openstack.common.apiclient import base as apiclient_base
|
||||
|
||||
|
||||
class Image(apiclient_base.Resource):
|
||||
def __repr__(self):
|
||||
return "<Image %s>" % self._info
|
||||
|
||||
|
||||
class ImageManager(solum_base.CrudManager):
|
||||
resource_class = Image
|
||||
collection_key = 'images'
|
||||
key = 'image'
|
||||
|
||||
def create(self, **kwargs):
|
||||
return super(ImageManager, self).create(base_url="/v1", **kwargs)
|
||||
|
||||
def get(self, **kwargs):
|
||||
return super(ImageManager, self).get(base_url="/v1", **kwargs)
|
@@ -29,7 +29,7 @@ def Client(version, **kwargs):
|
||||
tenant_name=kwargs.get('tenant_name'),
|
||||
token=kwargs.get('token'),
|
||||
auth_url=kwargs.get('auth_url'),
|
||||
solum_url=kwargs.get('solum_url'))
|
||||
endpoint=kwargs.get('endpoint'))
|
||||
http_client = client.HTTPClient(keystone_auth)
|
||||
return client_class(http_client)
|
||||
|
||||
@@ -41,7 +41,7 @@ def get_client(api_version, **kwargs):
|
||||
:param api_version: the API version to use
|
||||
:param kwargs: keyword args containing credentials, either:
|
||||
* os_auth_token: pre-existing token to re-use
|
||||
* solum_url: solum API endpoint
|
||||
* endpoint: solum API endpoint
|
||||
or:
|
||||
* os_username: name of user
|
||||
* os_password: user's password
|
||||
@@ -54,7 +54,7 @@ def get_client(api_version, **kwargs):
|
||||
'tenant_name': kwargs.get('os_tenant_name'),
|
||||
'token': kwargs.get('os_auth_token'),
|
||||
'auth_url': kwargs.get('os_auth_url'),
|
||||
'solum_url': kwargs.get('solum_url')
|
||||
'endpoint': kwargs.get('solum_url')
|
||||
}
|
||||
|
||||
return Client(api_version, **cli_kwargs)
|
||||
|
@@ -26,7 +26,7 @@ class KeystoneAuthPlugin(auth.BaseAuthPlugin):
|
||||
"tenant_name",
|
||||
"token",
|
||||
"auth_url",
|
||||
"solum_url"
|
||||
"endpoint"
|
||||
]
|
||||
|
||||
def _do_authenticate(self, http_client):
|
||||
@@ -43,13 +43,13 @@ class KeystoneAuthPlugin(auth.BaseAuthPlugin):
|
||||
def token_and_endpoint(self, endpoint_type, service_type):
|
||||
token = endpoint = None
|
||||
|
||||
if self.opts.get('token') and self.opts.get('solum_url'):
|
||||
if self.opts.get('token') and self.opts.get('endpoint'):
|
||||
token = self.opts.get('token')
|
||||
endpoint = self.opts.get('solum_url')
|
||||
endpoint = self.opts.get('endpoint')
|
||||
|
||||
elif hasattr(self, '_ksclient'):
|
||||
token = self._ksclient.auth_token
|
||||
endpoint = (self.opts.get('solum_url') or
|
||||
endpoint = (self.opts.get('endpoint') or
|
||||
self._ksclient.service_catalog.url_for(
|
||||
service_type=service_type,
|
||||
endpoint_type=endpoint_type))
|
||||
@@ -63,7 +63,7 @@ class KeystoneAuthPlugin(auth.BaseAuthPlugin):
|
||||
"""
|
||||
|
||||
if self.opts.get('token'):
|
||||
lookup_table = ["token", "solum_url"]
|
||||
lookup_table = ["token", "endpoint"]
|
||||
else:
|
||||
lookup_table = ["username", "password", "tenant_name", "auth_url"]
|
||||
|
||||
|
@@ -114,5 +114,4 @@ class CrudManager(ManagerMixin, base.CrudManager):
|
||||
def create(self, **kwargs):
|
||||
kwargs = self._filter_kwargs(kwargs)
|
||||
return self._post(
|
||||
self.build_url(**kwargs),
|
||||
{self.key: kwargs})
|
||||
self.build_url(**kwargs), kwargs)
|
||||
|
@@ -76,7 +76,6 @@ class CommandsBase(object):
|
||||
# Remove arguments that are not to be passed to the client in this
|
||||
# case.
|
||||
del client_args['os_auth_token']
|
||||
del client_args['solum_url']
|
||||
|
||||
if not parsed.os_username:
|
||||
raise exc.CommandError("You must provide a username via "
|
||||
@@ -98,6 +97,10 @@ class CommandsBase(object):
|
||||
"either --os-auth-url or via "
|
||||
"env[OS_AUTH_URL]")
|
||||
|
||||
else:
|
||||
client_args['endpoint'] = client_args['solum_url']
|
||||
|
||||
del client_args['solum_url']
|
||||
self.client = solum_client.get_client(parsed.solum_api_version,
|
||||
**client_args)
|
||||
|
||||
|
0
solumclient/tests/builder/__init__.py
Normal file
0
solumclient/tests/builder/__init__.py
Normal file
31
solumclient/tests/builder/test_client.py
Normal file
31
solumclient/tests/builder/test_client.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# Copyright 2014 - Noorul Islam K M
|
||||
#
|
||||
# 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 solumclient.builder import client
|
||||
from solumclient.common import auth
|
||||
from solumclient.openstack.common.apiclient import exceptions
|
||||
from solumclient.tests import base
|
||||
|
||||
|
||||
class ClientTest(base.TestCase):
|
||||
|
||||
def test_client_unsupported_version(self):
|
||||
self.assertRaises(exceptions.UnsupportedVersion,
|
||||
client.Client, '111.11', **{})
|
||||
|
||||
def test_client(self):
|
||||
with mock.patch.object(auth, 'KeystoneAuthPlugin'):
|
||||
client.Client('1', **{})
|
0
solumclient/tests/builder/v1/__init__.py
Normal file
0
solumclient/tests/builder/v1/__init__.py
Normal file
73
solumclient/tests/builder/v1/test_image.py
Normal file
73
solumclient/tests/builder/v1/test_image.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# Copyright 2014 - Noorul Islam K M
|
||||
#
|
||||
# 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.
|
||||
|
||||
from solumclient.builder.v1 import client as builder_client
|
||||
from solumclient.builder.v1 import image
|
||||
from solumclient.openstack.common.apiclient import fake_client
|
||||
from solumclient.tests import base
|
||||
|
||||
image_fixture = {
|
||||
'uri': 'http://example.com/v1/images/i1',
|
||||
'name': 'php-web-app',
|
||||
'source_uri': 'git://example.com/project/app.git',
|
||||
'type': 'image',
|
||||
'description': 'A php web application',
|
||||
'tags': ['small'],
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
'user_id': '55f41cf46df74320b9486a35f5d28a11',
|
||||
}
|
||||
|
||||
fixtures_get = {
|
||||
'/v1/images/i1': {
|
||||
'GET': (
|
||||
{},
|
||||
image_fixture
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fixtures_create = {
|
||||
'/v1/images': {
|
||||
'POST': (
|
||||
{},
|
||||
image_fixture
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class ImageManagerTest(base.TestCase):
|
||||
|
||||
def test_create(self):
|
||||
fake_http_client = fake_client.FakeHTTPClient(fixtures=fixtures_create)
|
||||
api_client = builder_client.Client(fake_http_client)
|
||||
mgr = image.ImageManager(api_client)
|
||||
image_obj = mgr.create()
|
||||
self.assertIn('Image', repr(image_obj))
|
||||
self.assertEqual(image_obj.uri, image_fixture['uri'])
|
||||
self.assertEqual(image_obj.type, image_fixture['type'])
|
||||
self.assertEqual(image_obj.project_id, image_fixture['project_id'])
|
||||
self.assertEqual(image_obj.user_id, image_fixture['user_id'])
|
||||
|
||||
def test_get(self):
|
||||
fake_http_client = fake_client.FakeHTTPClient(fixtures=fixtures_get)
|
||||
api_client = builder_client.Client(fake_http_client)
|
||||
mgr = image.ImageManager(api_client)
|
||||
image_obj = mgr.get(image_id='i1')
|
||||
self.assertIn('Image', repr(image_obj))
|
||||
self.assertEqual(image_obj.uri, image_fixture['uri'])
|
||||
self.assertEqual(image_obj.type, image_fixture['type'])
|
||||
self.assertEqual(image_obj.project_id, image_fixture['project_id'])
|
||||
self.assertEqual(image_obj.user_id, image_fixture['user_id'])
|
@@ -29,7 +29,7 @@ class KeystoneAuthPluginTest(base.TestCase):
|
||||
password="fake-password",
|
||||
tenant_name="fake-tenant-name",
|
||||
auth_url="http://auth",
|
||||
solum_url="http://solum")
|
||||
endpoint="http://solum")
|
||||
self.cs = client.HTTPClient(auth_plugin=plugin)
|
||||
|
||||
def test_authenticate(self, mock_ksclient):
|
||||
@@ -59,7 +59,7 @@ class KeystoneAuthPluginTokenTest(base.TestCase):
|
||||
def test_token_and_endpoint(self, mock_ksclient):
|
||||
plugin = auth.KeystoneAuthPlugin(
|
||||
token="fake-token",
|
||||
solum_url="http://solum")
|
||||
endpoint="http://solum")
|
||||
cs = client.HTTPClient(auth_plugin=plugin)
|
||||
|
||||
cs.authenticate()
|
||||
|
Reference in New Issue
Block a user