From 7c10ff6041f2f61309b0843062b841b90e2cc8d3 Mon Sep 17 00:00:00 2001 From: Vishakha Agarwal Date: Fri, 5 Jul 2019 16:40:04 +0530 Subject: [PATCH] Add application credential CRUD support This patch adds the client support of application credentials. Change-Id: Idac1b8f4610825ca7fdf62eec4f0453398e43346 --- openstack/identity/v3/_proxy.py | 107 ++++++++++++++++++ .../identity/v3/application_credential.py | 49 ++++++++ .../tests/functional/identity/__init__.py | 0 .../tests/functional/identity/v3/__init__.py | 0 .../v3/test_application_credential.py | 68 +++++++++++ .../v3/test_application_credential.py | 55 +++++++++ ...lication-credentials-abab9106dea10c11.yaml | 5 + 7 files changed, 284 insertions(+) create mode 100644 openstack/identity/v3/application_credential.py create mode 100644 openstack/tests/functional/identity/__init__.py create mode 100644 openstack/tests/functional/identity/v3/__init__.py create mode 100644 openstack/tests/functional/identity/v3/test_application_credential.py create mode 100644 openstack/tests/unit/identity/v3/test_application_credential.py create mode 100644 releasenotes/notes/add-application-credentials-abab9106dea10c11.yaml diff --git a/openstack/identity/v3/_proxy.py b/openstack/identity/v3/_proxy.py index 39286cbbd..f0f20038f 100644 --- a/openstack/identity/v3/_proxy.py +++ b/openstack/identity/v3/_proxy.py @@ -11,6 +11,8 @@ # under the License. import openstack.exceptions as exception +from openstack.identity.v3 import application_credential as \ + _application_credential from openstack.identity.v3 import credential as _credential from openstack.identity.v3 import domain as _domain from openstack.identity.v3 import endpoint as _endpoint @@ -1212,3 +1214,108 @@ class Proxy(proxy.Proxy): group = self._get_resource(_group.Group, group) role = self._get_resource(_role.Role, role) return project.validate_group_has_role(self, group, role) + + def application_credentials(self, user, **query): + """Retrieve a generator of application credentials + + :param user: Either the ID of a user or a + :class:`~openstack.identity.v3.user.User` instance. + + :param kwargs query: Optional query parameters to be sent to + application credential the resources being returned. + + :returns: A generator of application credentials instances. + :rtype: :class:`~openstack.identity.v3.application_credential. + ApplicationCredential` + """ + user = self._get_resource(_user.User, user) + return self._list(_application_credential.ApplicationCredential, + user_id=user.id, **query) + + def get_application_credential(self, user, application_credential): + """Get a single application credential + + :param user: Either the ID of a user or a + :class:`~openstack.identity.v3.user.User` instance. + + :param application_credential: The value can be the ID of a + application credential or a :class: + `~openstack.identity.v3.application_credential. + ApplicationCredential` instance. + + :returns: One :class:`~openstack.identity.v3.application_credential. + ApplicationCredential` + :raises: :class:`~openstack.exceptions.ResourceNotFound` when no + resource can be found. + """ + user = self._get_resource(_user.User, user) + return self._get(_application_credential.ApplicationCredential, + application_credential, + user_id=user.id) + + def create_application_credential(self, user, name, **attrs): + """Create a new application credential from attributes + + :param user: Either the ID of a user or a + :class:`~openstack.identity.v3.user.User` instance. + :param name: The name of the application credential which is + unique to the user. + :param dict attrs: Keyword arguments which will be used to create + a :class:`~openstack.identity.v3.application_credential. + ApplicationCredential`, comprised of the properties on the + ApplicationCredential class. + + + :returns: The results of application credential creation. + :rtype: :class:`~openstack.identity.v3.application_credential. + ApplicationCredential` + """ + + user = self._get_resource(_user.User, user) + return self._create(_application_credential.ApplicationCredential, + name=name, + user_id=user.id, **attrs) + + def find_application_credential(self, user, name_or_id, + ignore_missing=True, **args): + """Find a single application credential + + :param user: Either the ID of a user or a + :class:`~openstack.identity.v3.user.User` instance. + :param name_or_id: The name or ID of a application credential. + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be + raised when the resource does not exist. + When set to ``True``, None will be returned when + attempting to find a nonexistent resource. + + :returns: One :class:`~openstack.identity.v3.application_credential. + ApplicationCredential` or None + """ + user = self._get_resource(_user.User, user) + return self._find(_application_credential.ApplicationCredential, + user_id=user.id, name_or_id=name_or_id, + ignore_missing=ignore_missing, **args) + + def delete_application_credential(self, user, application_credential, + ignore_missing=True): + """Delete a application credential + + :param user: Either the ID of a user or a + :class:`~openstack.identity.v3.user.User` instance. + :param application credential: The value can be either the ID of a + application credential or a :class: `~openstack.identity.v3. + application_credential.ApplicationCredential` instance. + :param bool ignore_missing: When set to ``False`` + :class:`~openstack.exceptions.ResourceNotFound` will be raised + when the application credential does not exist. When set to + ``True``, no exception will be thrown when attempting to delete + a nonexistent application credential. + + :returns: ``None`` + """ + user = self._get_resource(_user.User, user) + self._delete(_application_credential.ApplicationCredential, + application_credential, + user_id=user.id, + ignore_missing=ignore_missing) diff --git a/openstack/identity/v3/application_credential.py b/openstack/identity/v3/application_credential.py new file mode 100644 index 000000000..a3876502f --- /dev/null +++ b/openstack/identity/v3/application_credential.py @@ -0,0 +1,49 @@ +# 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 openstack import resource + + +class ApplicationCredential(resource.Resource): + resource_key = 'application_credential' + resources_key = 'application_credentials' + base_path = '/users/%(user_id)s/application_credentials' + + # capabilities + allow_create = True + allow_fetch = True + allow_commit = True + allow_delete = True + allow_list = True + + # Properties + #: User ID using application credential. *Type: string* + user_id = resource.URI('user_id') + #: User object using application credential. *Type: string* + user = resource.Body('user') + #: The links for the application credential resource. + links = resource.Body('links') + #: name of the user. *Type: string* + name = resource.Body('name') + #: secret that application credential will be created with, if any. + # *Type: string* + secret = resource.Body('secret') + #: description of application credential's purpose. *Type: string* + description = resource.Body('description') + #: expire time of application credential. *Type: string* + expires_at = resource.Body('expires_at') + #: roles of the user. *Type: list* + roles = resource.Body('roles') + #: restricts the application credential. *Type: boolean* + unrestricted = resource.Body('unrestricted', type=bool) + #: ID of project. *Type: string* + project_id = resource.Body('project_id') diff --git a/openstack/tests/functional/identity/__init__.py b/openstack/tests/functional/identity/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openstack/tests/functional/identity/v3/__init__.py b/openstack/tests/functional/identity/v3/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/openstack/tests/functional/identity/v3/test_application_credential.py b/openstack/tests/functional/identity/v3/test_application_credential.py new file mode 100644 index 000000000..21933a8b0 --- /dev/null +++ b/openstack/tests/functional/identity/v3/test_application_credential.py @@ -0,0 +1,68 @@ +# 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 openstack.tests.functional import base +from openstack import exceptions + + +class TestApplicationCredentials(base.BaseFunctionalTest): + + def setUp(self): + super(TestApplicationCredentials, self).setUp() + self.user_id = self.operator_cloud.current_user_id + + def _create_application_credentials(self): + app_creds = self.conn.identity.create_application_credential( + user=self.user_id, name='app_cred' + ) + self.addCleanup(self.conn.identity.delete_application_credential, + self.user_id, app_creds['id']) + return app_creds + + def test_create_application_credentials(self): + app_creds = self._create_application_credentials() + self.assertEqual(app_creds['user_id'], self.user_id) + + def test_get_application_credential(self): + app_creds = self._create_application_credentials() + app_cred = self.conn.identity.get_application_credential( + user=self.user_id, application_credential=app_creds['id'] + ) + self.assertEqual(app_cred['id'], app_creds['id']) + self.assertEqual(app_cred['user_id'], self.user_id) + + def test_application_credentials(self): + self._create_application_credentials() + app_creds = self.conn.identity.application_credentials( + user=self.user_id + ) + for app_cred in app_creds: + self.assertEqual(app_cred['user_id'], self.user_id) + + def test_find_application_credential(self): + app_creds = self._create_application_credentials() + app_cred = self.conn.identity.find_application_credential( + user=self.user_id, name_or_id=app_creds['id'] + ) + self.assertEqual(app_cred['id'], app_creds['id']) + self.assertEqual(app_cred['user_id'], self.user_id) + + def test_delete_application_credential(self): + app_creds = self._create_application_credentials() + self.conn.identity.delete_application_credential( + user=self.user_id, application_credential=app_creds['id'] + ) + self.assertRaises(exceptions.NotFoundException, + self.conn.identity.get_application_credential, + user=self.user_id, + application_credential=app_creds['id'] + ) diff --git a/openstack/tests/unit/identity/v3/test_application_credential.py b/openstack/tests/unit/identity/v3/test_application_credential.py new file mode 100644 index 000000000..e6cf3101d --- /dev/null +++ b/openstack/tests/unit/identity/v3/test_application_credential.py @@ -0,0 +1,55 @@ +# 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 openstack.tests.unit import base + +from openstack.identity.v3 import application_credential + +EXAMPLE = { + "user": { + "id": "8ac43bb0926245cead88676a96c750d3"}, + "name": 'monitoring', + "secret": 'rEaqvJka48mpv', + "roles": [ + {"name": "Reader"} + ], + "expires_at": '2018-02-27T18:30:59Z', + "description": "Application credential for monitoring", + "unrestricted": "False", + "project_id": "3", + "links": {"self": "http://example.com/v3/application_credential_1"} +} + + +class TestApplicationCredential(base.TestCase): + + def test_basic(self): + sot = application_credential.ApplicationCredential() + self.assertEqual('application_credential', sot.resource_key) + self.assertEqual('application_credentials', sot.resources_key) + self.assertEqual('/users/%(user_id)s/application_credentials', + sot.base_path) + self.assertTrue(sot.allow_create) + self.assertTrue(sot.allow_fetch) + self.assertTrue(sot.allow_commit) + self.assertTrue(sot.allow_delete) + self.assertTrue(sot.allow_list) + + def test_make_it(self): + sot = application_credential.ApplicationCredential(**EXAMPLE) + self.assertEqual(EXAMPLE['user'], sot.user) + self.assertEqual(EXAMPLE['name'], sot.name) + self.assertEqual(EXAMPLE['secret'], sot.secret) + self.assertEqual(EXAMPLE['description'], sot.description) + self.assertEqual(EXAMPLE['expires_at'], sot.expires_at) + self.assertEqual(EXAMPLE['project_id'], sot.project_id) + self.assertEqual(EXAMPLE['roles'], sot.roles) + self.assertEqual(EXAMPLE['links'], sot.links) diff --git a/releasenotes/notes/add-application-credentials-abab9106dea10c11.yaml b/releasenotes/notes/add-application-credentials-abab9106dea10c11.yaml new file mode 100644 index 000000000..9f4818303 --- /dev/null +++ b/releasenotes/notes/add-application-credentials-abab9106dea10c11.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Added CRUD support for `application credentials + `_.