diff --git a/keystoneclient/tests/v2_0/test_extensions.py b/keystoneclient/tests/v2_0/test_extensions.py new file mode 100644 index 000000000..6f4787d9c --- /dev/null +++ b/keystoneclient/tests/v2_0/test_extensions.py @@ -0,0 +1,66 @@ +# 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 httpretty + +from keystoneclient.tests.v2_0 import utils +from keystoneclient.v2_0 import extensions + + +class ExtensionTests(utils.TestCase): + def setUp(self): + super(ExtensionTests, self).setUp() + self.TEST_EXTENSIONS = { + 'extensions': { + "values": [ + { + 'name': 'OpenStack Keystone User CRUD', + 'namespace': 'http://docs.openstack.org/' + 'identity/api/ext/OS-KSCRUD/v1.0', + 'updated': '2013-07-07T12:00:0-00:00', + 'alias': 'OS-KSCRUD', + 'description': + 'OpenStack extensions to Keystone v2.0 API' + ' enabling User Operations.', + 'links': + '[{"href":' + '"https://github.com/openstack/identity-api", "type":' + ' "text/html", "rel": "describedby"}]', + }, + { + 'name': 'OpenStack EC2 API', + 'namespace': 'http://docs.openstack.org/' + 'identity/api/ext/OS-EC2/v1.0', + 'updated': '2013-09-07T12:00:0-00:00', + 'alias': 'OS-EC2', + 'description': 'OpenStack EC2 Credentials backend.', + 'links': '[{"href":' + '"https://github.com/openstack/identity-api", "type":' + ' "text/html", "rel": "describedby"}]', + } + ] + } + } + + @httpretty.activate + def test_list(self): + self.stub_url(httpretty.GET, ['extensions'], json=self.TEST_EXTENSIONS) + extensions_list = self.client.extensions.list() + self.assertEqual(2, len(extensions_list)) + for extension in extensions_list: + self.assertIsInstance(extension, extensions.Extension) + self.assertIsNotNone(extension.alias) + self.assertIsNotNone(extension.description) + self.assertIsNotNone(extension.links) + self.assertIsNotNone(extension.name) + self.assertIsNotNone(extension.namespace) + self.assertIsNotNone(extension.updated) diff --git a/keystoneclient/v2_0/client.py b/keystoneclient/v2_0/client.py index 3a281ad1f..8dcd778c7 100644 --- a/keystoneclient/v2_0/client.py +++ b/keystoneclient/v2_0/client.py @@ -20,6 +20,7 @@ from keystoneclient import exceptions from keystoneclient import httpclient from keystoneclient.v2_0 import ec2 from keystoneclient.v2_0 import endpoints +from keystoneclient.v2_0 import extensions from keystoneclient.v2_0 import roles from keystoneclient.v2_0 import services from keystoneclient.v2_0 import tenants @@ -129,6 +130,7 @@ class Client(httpclient.HTTPClient): """Initialize a new client for the Keystone v2.0 API.""" super(Client, self).__init__(**kwargs) self.endpoints = endpoints.EndpointManager(self) + self.extensions = extensions.ExtensionManager(self) self.roles = roles.RoleManager(self) self.services = services.ServiceManager(self) self.tenants = tenants.TenantManager(self) diff --git a/keystoneclient/v2_0/extensions.py b/keystoneclient/v2_0/extensions.py new file mode 100644 index 000000000..9f209a5a4 --- /dev/null +++ b/keystoneclient/v2_0/extensions.py @@ -0,0 +1,29 @@ +# 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 keystoneclient import base + + +class Extension(base.Resource): + """Represents an Identity API extension.""" + def __repr__(self): + return "" % self._info + + +class ExtensionManager(base.ManagerWithFind): + """Manager class for listing Identity API extensions.""" + + resource_class = Extension + + def list(self): + """List all available extentions.""" + return self._list('/extensions', 'extensions')