diff --git a/solumclient/builder/__init__.py b/solumclient/builder/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/solumclient/builder/client.py b/solumclient/builder/client.py new file mode 100644 index 0000000..7b222a3 --- /dev/null +++ b/solumclient/builder/client.py @@ -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) diff --git a/solumclient/builder/v1/__init__.py b/solumclient/builder/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/solumclient/builder/v1/client.py b/solumclient/builder/v1/client.py new file mode 100644 index 0000000..fdfa26d --- /dev/null +++ b/solumclient/builder/v1/client.py @@ -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) diff --git a/solumclient/builder/v1/image.py b/solumclient/builder/v1/image.py new file mode 100644 index 0000000..57cd905 --- /dev/null +++ b/solumclient/builder/v1/image.py @@ -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 "" % 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) diff --git a/solumclient/client.py b/solumclient/client.py index d12f3f0..8b2bbbd 100644 --- a/solumclient/client.py +++ b/solumclient/client.py @@ -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) diff --git a/solumclient/common/auth.py b/solumclient/common/auth.py index b032e6d..4837e55 100644 --- a/solumclient/common/auth.py +++ b/solumclient/common/auth.py @@ -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"] diff --git a/solumclient/common/base.py b/solumclient/common/base.py index 518ba64..326c9eb 100644 --- a/solumclient/common/base.py +++ b/solumclient/common/base.py @@ -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) diff --git a/solumclient/common/cli_utils.py b/solumclient/common/cli_utils.py index 103e81b..dbce2b2 100644 --- a/solumclient/common/cli_utils.py +++ b/solumclient/common/cli_utils.py @@ -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) diff --git a/solumclient/tests/builder/__init__.py b/solumclient/tests/builder/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/solumclient/tests/builder/test_client.py b/solumclient/tests/builder/test_client.py new file mode 100644 index 0000000..02b65a5 --- /dev/null +++ b/solumclient/tests/builder/test_client.py @@ -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', **{}) diff --git a/solumclient/tests/builder/v1/__init__.py b/solumclient/tests/builder/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/solumclient/tests/builder/v1/test_image.py b/solumclient/tests/builder/v1/test_image.py new file mode 100644 index 0000000..11e77d9 --- /dev/null +++ b/solumclient/tests/builder/v1/test_image.py @@ -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']) diff --git a/solumclient/tests/common/test_auth.py b/solumclient/tests/common/test_auth.py index 488893c..228da1e 100644 --- a/solumclient/tests/common/test_auth.py +++ b/solumclient/tests/common/test_auth.py @@ -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()