Add support for key manager project quota API
Add get, update, and delete methods for ProjectQuota in key-manager. Include related documentation, unit tests, and functional tests. Change-Id: I9d995066a2183dd9310ad276a273fa725c0e57b2 Signed-off-by: jbeen <jeongwon.been@gmail.com>
This commit is contained in:
@@ -45,3 +45,10 @@ Secret Store Operations
|
||||
:noindex:
|
||||
:members: secret_stores, get_global_default_secret_store,
|
||||
get_preferred_secret_store
|
||||
|
||||
ProjectQuota Operations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. autoclass:: openstack.key_manager.v1._proxy.Proxy
|
||||
:noindex:
|
||||
:members: update_project_quota, delete_project_quota, get_project_quota
|
||||
|
||||
@@ -6,5 +6,6 @@ KeyManager Resources
|
||||
|
||||
v1/container
|
||||
v1/order
|
||||
v1/project_quota
|
||||
v1/secret
|
||||
v1/secret_store
|
||||
|
||||
12
doc/source/user/resources/key_manager/v1/project_quota.rst
Normal file
12
doc/source/user/resources/key_manager/v1/project_quota.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
openstack.key_manager.v1.project_quota
|
||||
======================================
|
||||
|
||||
.. automodule:: openstack.key_manager.v1.project_quota
|
||||
|
||||
The ProjectQuota Class
|
||||
----------------------
|
||||
|
||||
The ``ProjectQuota`` class inherits from :class:`~openstack.resource.Resource`.
|
||||
|
||||
.. autoclass:: openstack.key_manager.v1.project_quota.ProjectQuota
|
||||
:members:
|
||||
@@ -14,6 +14,7 @@ import typing as ty
|
||||
|
||||
from openstack.key_manager.v1 import container as _container
|
||||
from openstack.key_manager.v1 import order as _order
|
||||
from openstack.key_manager.v1 import project_quota as _project_quota
|
||||
from openstack.key_manager.v1 import secret as _secret
|
||||
from openstack.key_manager.v1 import secret_store as _secret_store
|
||||
from openstack import proxy
|
||||
@@ -24,6 +25,7 @@ class Proxy(proxy.Proxy):
|
||||
_resource_registry = {
|
||||
"container": _container.Container,
|
||||
"order": _order.Order,
|
||||
"project_quota": _project_quota.ProjectQuota,
|
||||
"secret": _secret.Secret,
|
||||
"secret_store": _secret_store.SecretStore,
|
||||
}
|
||||
@@ -313,6 +315,47 @@ class Proxy(proxy.Proxy):
|
||||
base_path='/secret-stores/preferred',
|
||||
)
|
||||
|
||||
def delete_project_quota(self, project_id, ignore_missing=True):
|
||||
"""Delete a project quota
|
||||
|
||||
:param project_id: A project ID.
|
||||
:param bool ignore_missing: When set to ``False``
|
||||
:class:`~openstack.exceptions.NotFoundException` will be
|
||||
raised when the project quota does not exist.
|
||||
When set to ``True``, no exception will be set when
|
||||
attempting to delete a nonexistent project quota.
|
||||
|
||||
:returns: ``None``
|
||||
"""
|
||||
self._delete(
|
||||
_project_quota.ProjectQuota,
|
||||
project_id,
|
||||
ignore_missing=ignore_missing,
|
||||
)
|
||||
|
||||
def get_project_quota(self, project_id):
|
||||
"""Get a single project quota
|
||||
|
||||
:param project_id: A project ID.
|
||||
|
||||
:returns: One :class:`~openstack.key_manager.v1.project_quota.ProjectQuota`
|
||||
:raises: :class:`~openstack.exceptions.NotFoundException`
|
||||
when no resource can be found.
|
||||
"""
|
||||
return self._get(_project_quota.ProjectQuota, project_id)
|
||||
|
||||
def update_project_quota(self, project_id, **attrs):
|
||||
"""Update a project quota
|
||||
|
||||
:param project_id: A project ID.
|
||||
:param attrs: The attributes to update on the project quota represented
|
||||
by ``project quota``.
|
||||
|
||||
:returns: The updated project quota
|
||||
:rtype: :class:`~openstack.key_manager.v1.project_quota.ProjectQuota`
|
||||
"""
|
||||
return self._update(_project_quota.ProjectQuota, project_id, **attrs)
|
||||
|
||||
# ========== Utilities ==========
|
||||
|
||||
def wait_for_status(
|
||||
|
||||
38
openstack/key_manager/v1/project_quota.py
Normal file
38
openstack/key_manager/v1/project_quota.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# 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 ProjectQuota(resource.Resource):
|
||||
resource_key = 'project_quotas'
|
||||
resources_key = 'project_quotas'
|
||||
base_path = '/project-quotas'
|
||||
|
||||
# capabilities
|
||||
allow_create = True
|
||||
allow_fetch = True
|
||||
allow_commit = True
|
||||
allow_delete = True
|
||||
allow_list = True
|
||||
|
||||
# Properties
|
||||
#: Contains the configured quota value of the requested project for the secret resource.
|
||||
secrets = resource.Body("secrets")
|
||||
#: Contains the configured quota value of the requested project for the orders resource.
|
||||
orders = resource.Body("orders")
|
||||
#: Contains the configured quota value of the requested project for the containers resource.
|
||||
containers = resource.Body("containers")
|
||||
#: Contains the configured quota value of the requested project for the consumers resource.
|
||||
consumers = resource.Body("consumers")
|
||||
#: Contains the configured quota value of the requested project for the CAs resource.
|
||||
cas = resource.Body("cas")
|
||||
@@ -0,0 +1,87 @@
|
||||
# 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 exceptions as sdk_exc
|
||||
from openstack.key_manager.v1 import project_quota as _project_quota
|
||||
from openstack.tests.functional import base
|
||||
|
||||
# NOTE(jbeen): Barbican policy may require 'key-manager:service-admin' for
|
||||
# project quotas. Create and assign it per test project to avoid 403 errors.
|
||||
ADMIN_ROLE_NAME = 'key-manager:service-admin'
|
||||
|
||||
|
||||
class TestProjectQuota(base.BaseFunctionalTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.require_service('key-manager')
|
||||
|
||||
self.project_name = self.getUniqueString('project')
|
||||
self.project = self.system_admin_cloud.identity.create_project(
|
||||
name=self.project_name,
|
||||
)
|
||||
self.addCleanup(
|
||||
self.system_admin_cloud.identity.delete_project, self.project
|
||||
)
|
||||
|
||||
self.role = self.system_admin_cloud.identity.create_role(
|
||||
name=ADMIN_ROLE_NAME
|
||||
)
|
||||
self.addCleanup(
|
||||
self.system_admin_cloud.identity.delete_role, self.role.id
|
||||
)
|
||||
|
||||
self.user_id = self.system_admin_cloud.current_user_id
|
||||
self.system_admin_cloud.identity.assign_project_role_to_user(
|
||||
project=self.project, user=self.user_id, role=self.role
|
||||
)
|
||||
self.addCleanup(
|
||||
self.system_admin_cloud.identity.unassign_project_role_from_user,
|
||||
project=self.project,
|
||||
user=self.user_id,
|
||||
role=self.role,
|
||||
)
|
||||
|
||||
self._set_operator_cloud(project_id=self.project.id)
|
||||
|
||||
def test_project_quotas(self):
|
||||
# update project quota
|
||||
project_quota = self.operator_cloud.key_manager.update_project_quota(
|
||||
self.project.id,
|
||||
secrets=1,
|
||||
orders=2,
|
||||
containers=3,
|
||||
consumers=4,
|
||||
cas=5,
|
||||
)
|
||||
|
||||
self.assertIsInstance(project_quota, _project_quota.ProjectQuota)
|
||||
self.assertIsNotNone(project_quota.id)
|
||||
self.assertEqual(1, project_quota.secrets)
|
||||
self.assertEqual(2, project_quota.orders)
|
||||
self.assertEqual(3, project_quota.containers)
|
||||
self.assertEqual(4, project_quota.consumers)
|
||||
self.assertEqual(5, project_quota.cas)
|
||||
|
||||
# get project quota
|
||||
project_id = self.project.id
|
||||
project_quota = self.operator_cloud.key_manager.get_project_quota(
|
||||
project_id
|
||||
)
|
||||
self.assertIsInstance(project_quota, _project_quota.ProjectQuota)
|
||||
|
||||
# delete project quota
|
||||
self.operator_cloud.key_manager.delete_project_quota(project_quota)
|
||||
self.assertRaises(
|
||||
sdk_exc.NotFoundException,
|
||||
self.operator_cloud.key_manager.get_project_quota,
|
||||
project_quota,
|
||||
)
|
||||
44
openstack/tests/unit/key_manager/v1/test_project_quota.py
Normal file
44
openstack/tests/unit/key_manager/v1/test_project_quota.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# 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.key_manager.v1 import project_quota
|
||||
from openstack.tests.unit import base
|
||||
|
||||
|
||||
EXAMPLE = {
|
||||
'secrets': 10,
|
||||
'orders': 20,
|
||||
'containers': -1,
|
||||
'consumers': 10,
|
||||
'cas': 5,
|
||||
}
|
||||
|
||||
|
||||
class TestProjectQuota(base.TestCase):
|
||||
def test_basic(self):
|
||||
sot = project_quota.ProjectQuota()
|
||||
self.assertEqual('project_quotas', sot.resource_key)
|
||||
self.assertEqual('project_quotas', sot.resources_key)
|
||||
self.assertEqual('/project-quotas', 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 = project_quota.ProjectQuota(**EXAMPLE)
|
||||
self.assertEqual(EXAMPLE['secrets'], sot.secrets)
|
||||
self.assertEqual(EXAMPLE['orders'], sot.orders)
|
||||
self.assertEqual(EXAMPLE['containers'], sot.containers)
|
||||
self.assertEqual(EXAMPLE['consumers'], sot.consumers)
|
||||
self.assertEqual(EXAMPLE['cas'], sot.cas)
|
||||
@@ -13,6 +13,7 @@
|
||||
from openstack.key_manager.v1 import _proxy
|
||||
from openstack.key_manager.v1 import container
|
||||
from openstack.key_manager.v1 import order
|
||||
from openstack.key_manager.v1 import project_quota
|
||||
from openstack.key_manager.v1 import secret
|
||||
from openstack.key_manager.v1 import secret_store
|
||||
from openstack.tests.unit import test_proxy_base
|
||||
@@ -103,3 +104,25 @@ class TestKeyManagerSecret(TestKeyManagerProxy):
|
||||
class TestKeyManagerSecretStore(TestKeyManagerProxy):
|
||||
def test_secret_stores(self):
|
||||
self.verify_list(self.proxy.secret_stores, secret_store.SecretStore)
|
||||
|
||||
|
||||
class TestKeyManagerProjectQuota(TestKeyManagerProxy):
|
||||
def test_project_quota_delete(self):
|
||||
self.verify_delete(
|
||||
self.proxy.delete_project_quota, project_quota.ProjectQuota, False
|
||||
)
|
||||
|
||||
def test_project_quota_delete_ignore(self):
|
||||
self.verify_delete(
|
||||
self.proxy.delete_project_quota, project_quota.ProjectQuota, True
|
||||
)
|
||||
|
||||
def test_project_quota_get(self):
|
||||
self.verify_get(
|
||||
self.proxy.get_project_quota, project_quota.ProjectQuota
|
||||
)
|
||||
|
||||
def test_project_quota_update(self):
|
||||
self.verify_update(
|
||||
self.proxy.update_project_quota, project_quota.ProjectQuota
|
||||
)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Add support for key manager project quota API
|
||||
Reference in New Issue
Block a user