Merge "Register default quota policies in code"
This commit is contained in:
@@ -1,12 +1,4 @@
|
|||||||
{
|
{
|
||||||
"default": "rule:admin_or_owner",
|
|
||||||
|
|
||||||
"quotas:get": "rule:default",
|
|
||||||
"quotas:get_all": "rule:admin_api",
|
|
||||||
"quotas:create": "rule:admin_api",
|
|
||||||
"quotas:update": "rule:admin_api",
|
|
||||||
"quotas:delete": "rule:admin_api",
|
|
||||||
|
|
||||||
"certificate:rotate_ca": "rule:admin_or_owner",
|
"certificate:rotate_ca": "rule:admin_or_owner",
|
||||||
"certificate:create": "rule:admin_or_user or rule:cluster_user",
|
"certificate:create": "rule:admin_or_user or rule:cluster_user",
|
||||||
"certificate:get": "rule:admin_or_user or rule:cluster_user",
|
"certificate:get": "rule:admin_or_user or rule:cluster_user",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from magnum.common.policies import bay
|
|||||||
from magnum.common.policies import baymodel
|
from magnum.common.policies import baymodel
|
||||||
from magnum.common.policies import cluster
|
from magnum.common.policies import cluster
|
||||||
from magnum.common.policies import cluster_template
|
from magnum.common.policies import cluster_template
|
||||||
|
from magnum.common.policies import quota
|
||||||
|
|
||||||
|
|
||||||
def list_rules():
|
def list_rules():
|
||||||
@@ -27,5 +28,6 @@ def list_rules():
|
|||||||
bay.list_rules(),
|
bay.list_rules(),
|
||||||
baymodel.list_rules(),
|
baymodel.list_rules(),
|
||||||
cluster.list_rules(),
|
cluster.list_rules(),
|
||||||
cluster_template.list_rules()
|
cluster_template.list_rules(),
|
||||||
|
quota.list_rules()
|
||||||
)
|
)
|
||||||
|
|||||||
80
magnum/common/policies/quota.py
Normal file
80
magnum/common/policies/quota.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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 oslo_policy import policy
|
||||||
|
|
||||||
|
from magnum.common.policies import base
|
||||||
|
|
||||||
|
QUOTA = 'quotas:%s'
|
||||||
|
|
||||||
|
rules = [
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=QUOTA % 'create',
|
||||||
|
check_str=base.RULE_ADMIN_API,
|
||||||
|
description='Create quota.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/quotas',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=QUOTA % 'delete',
|
||||||
|
check_str=base.RULE_ADMIN_API,
|
||||||
|
description='Delete quota for a given project_id and resource.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/quotas/{project_id}/{resource}',
|
||||||
|
'method': 'DELETE'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=QUOTA % 'get',
|
||||||
|
check_str=base.RULE_ADMIN_OR_OWNER,
|
||||||
|
description='Retrieve Quota information for the given project_id.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/quotas/{project_id}/{resource}',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=QUOTA % 'get_all',
|
||||||
|
check_str=base.RULE_ADMIN_API,
|
||||||
|
description='Retrieve a list of quotas.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/quotas',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=QUOTA % 'update',
|
||||||
|
check_str=base.RULE_ADMIN_API,
|
||||||
|
description='Update quota for a given project_id.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/quotas/{project_id}/{resource}',
|
||||||
|
'method': 'PATCH'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def list_rules():
|
||||||
|
return rules
|
||||||
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
policy_data = """
|
policy_data = """
|
||||||
{
|
{
|
||||||
"default": "rule:admin_or_owner",
|
|
||||||
|
|
||||||
"certificate:create": "",
|
"certificate:create": "",
|
||||||
"certificate:get": "",
|
"certificate:get": "",
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,9 @@ class TestRotateCaCertificate(api_base.FunctionalTest):
|
|||||||
self.conductor_api_class.return_value = self.conductor_api
|
self.conductor_api_class.return_value = self.conductor_api
|
||||||
self.addCleanup(conductor_api_patcher.stop)
|
self.addCleanup(conductor_api_patcher.stop)
|
||||||
|
|
||||||
def test_rotate_ca_cert(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_rotate_ca_cert(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
fake_cert = api_utils.cert_post_data()
|
fake_cert = api_utils.cert_post_data()
|
||||||
mock_cert = mock.MagicMock()
|
mock_cert = mock.MagicMock()
|
||||||
mock_cert.as_dict.return_value = fake_cert
|
mock_cert.as_dict.return_value = fake_cert
|
||||||
@@ -227,7 +229,9 @@ class TestRotateCaCertificateNonTls(api_base.FunctionalTest):
|
|||||||
self.conductor_api_class.return_value = self.conductor_api
|
self.conductor_api_class.return_value = self.conductor_api
|
||||||
self.addCleanup(conductor_api_patcher.stop)
|
self.addCleanup(conductor_api_patcher.stop)
|
||||||
|
|
||||||
def test_rotate_ca_cert_non_tls(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_rotate_ca_cert_non_tls(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
fake_cert = api_utils.cert_post_data()
|
fake_cert = api_utils.cert_post_data()
|
||||||
mock_cert = mock.MagicMock()
|
mock_cert = mock.MagicMock()
|
||||||
mock_cert.as_dict.return_value = fake_cert
|
mock_cert.as_dict.return_value = fake_cert
|
||||||
|
|||||||
@@ -36,24 +36,32 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestQuota, self).setUp()
|
super(TestQuota, self).setUp()
|
||||||
|
|
||||||
def test_empty(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_empty(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
response = self.get_json('/quotas')
|
response = self.get_json('/quotas')
|
||||||
self.assertEqual([], response['quotas'])
|
self.assertEqual([], response['quotas'])
|
||||||
|
|
||||||
def test_one(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_one(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota = obj_utils.create_test_quota(self.context)
|
quota = obj_utils.create_test_quota(self.context)
|
||||||
response = self.get_json('/quotas')
|
response = self.get_json('/quotas')
|
||||||
self.assertEqual(quota.project_id, response['quotas'][0]["project_id"])
|
self.assertEqual(quota.project_id, response['quotas'][0]["project_id"])
|
||||||
self._verify_attrs(self._quota_attrs, response['quotas'][0])
|
self._verify_attrs(self._quota_attrs, response['quotas'][0])
|
||||||
|
|
||||||
def test_get_one(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_get_one(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota = obj_utils.create_test_quota(self.context)
|
quota = obj_utils.create_test_quota(self.context)
|
||||||
response = self.get_json('/quotas/%s/%s' % (quota['project_id'],
|
response = self.get_json('/quotas/%s/%s' % (quota['project_id'],
|
||||||
quota['resource']))
|
quota['resource']))
|
||||||
self.assertEqual(quota.project_id, response['project_id'])
|
self.assertEqual(quota.project_id, response['project_id'])
|
||||||
self.assertEqual(quota.resource, response['resource'])
|
self.assertEqual(quota.resource, response['resource'])
|
||||||
|
|
||||||
def test_get_one_not_found(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_get_one_not_found(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
response = self.get_json(
|
response = self.get_json(
|
||||||
'/quotas/fake_project/invalid_res',
|
'/quotas/fake_project/invalid_res',
|
||||||
expect_errors=True)
|
expect_errors=True)
|
||||||
@@ -174,7 +182,9 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
self.assertEqual(1, len(response['quotas']))
|
self.assertEqual(1, len(response['quotas']))
|
||||||
self.assertEqual('proj-id-1', response['quotas'][0]['project_id'])
|
self.assertEqual('proj-id-1', response['quotas'][0]['project_id'])
|
||||||
|
|
||||||
def test_get_all_non_admin(self):
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
|
def test_get_all_non_admin(self, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota_list = []
|
quota_list = []
|
||||||
for i in range(4):
|
for i in range(4):
|
||||||
quota = obj_utils.create_test_quota(self.context,
|
quota = obj_utils.create_test_quota(self.context,
|
||||||
@@ -186,8 +196,10 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
self.assertEqual(1, len(response['quotas']))
|
self.assertEqual(1, len(response['quotas']))
|
||||||
self.assertEqual('proj-id-2', response['quotas'][0]['project_id'])
|
self.assertEqual('proj-id-2', response['quotas'][0]['project_id'])
|
||||||
|
|
||||||
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
||||||
def test_create_quota(self, mock_keystone):
|
def test_create_quota(self, mock_keystone, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota_dict = apiutils.quota_post_data()
|
quota_dict = apiutils.quota_post_data()
|
||||||
response = self.post_json('/quotas', quota_dict)
|
response = self.post_json('/quotas', quota_dict)
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
@@ -224,8 +236,10 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
self.assertEqual(400, response.status_int)
|
self.assertEqual(400, response.status_int)
|
||||||
self.assertTrue(response.json['errors'])
|
self.assertTrue(response.json['errors'])
|
||||||
|
|
||||||
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
||||||
def test_create_quota_no_project_id(self, mock_keystone):
|
def test_create_quota_no_project_id(self, mock_keystone, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota_dict = apiutils.quota_post_data()
|
quota_dict = apiutils.quota_post_data()
|
||||||
del quota_dict['project_id']
|
del quota_dict['project_id']
|
||||||
response = self.post_json('/quotas', quota_dict, expect_errors=True)
|
response = self.post_json('/quotas', quota_dict, expect_errors=True)
|
||||||
@@ -233,8 +247,10 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
self.assertEqual(400, response.status_int)
|
self.assertEqual(400, response.status_int)
|
||||||
self.assertTrue(response.json['errors'])
|
self.assertTrue(response.json['errors'])
|
||||||
|
|
||||||
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
||||||
def test_patch_quota(self, mock_keystone):
|
def test_patch_quota(self, mock_keystone, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota_dict = apiutils.quota_post_data(hard_limit=5)
|
quota_dict = apiutils.quota_post_data(hard_limit=5)
|
||||||
response = self.post_json('/quotas', quota_dict)
|
response = self.post_json('/quotas', quota_dict)
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
@@ -248,8 +264,10 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
self.assertEqual(202, response.status_int)
|
self.assertEqual(202, response.status_int)
|
||||||
self.assertEqual(20, response.json['hard_limit'])
|
self.assertEqual(20, response.json['hard_limit'])
|
||||||
|
|
||||||
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
||||||
def test_patch_quota_not_found(self, mock_keystone):
|
def test_patch_quota_not_found(self, mock_keystone, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota_dict = apiutils.quota_post_data()
|
quota_dict = apiutils.quota_post_data()
|
||||||
response = self.post_json('/quotas', quota_dict)
|
response = self.post_json('/quotas', quota_dict)
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
@@ -264,8 +282,10 @@ class TestQuota(api_base.FunctionalTest):
|
|||||||
self.assertEqual(404, response.status_int)
|
self.assertEqual(404, response.status_int)
|
||||||
self.assertTrue(response.json['errors'])
|
self.assertTrue(response.json['errors'])
|
||||||
|
|
||||||
|
@mock.patch("magnum.common.policy.enforce")
|
||||||
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
@mock.patch.object(clients.OpenStackClients, 'keystone')
|
||||||
def test_delete_quota(self, mock_keystone):
|
def test_delete_quota(self, mock_keystone, mock_policy):
|
||||||
|
mock_policy.return_value = True
|
||||||
quota_dict = apiutils.quota_post_data()
|
quota_dict = apiutils.quota_post_data()
|
||||||
response = self.post_json('/quotas', quota_dict)
|
response = self.post_json('/quotas', quota_dict)
|
||||||
self.assertEqual('application/json', response.content_type)
|
self.assertEqual('application/json', response.content_type)
|
||||||
|
|||||||
Reference in New Issue
Block a user