Skip to content

Commit 8d15671

Browse files
committed
Add Block Storage Quotas
Like compute before it, we need to tweak quotas to allow services to provision sane amounts. These are typically set at a paltry 100 volumes and 1TB.
1 parent 27ab3ff commit 8d15671

File tree

7 files changed

+204
-5
lines changed

7 files changed

+204
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/dist
2+
/venv
23
/python_unikorn_openstack_policy.egg-info/
34
__pycache__
45
*.swp

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ openstack network create --provider-network-type vlan --provider-physical-networ
7878

7979
### Installation
8080

81+
```bash
82+
python3 -m venv venv
83+
source venv/bin/activat
84+
pip3 install build pylint
85+
```
86+
8187
> [!NOTE]
8288
> Running the following will install all the necessary dependencies.
8389
> This also includes any commands required for the the following sections.
@@ -90,6 +96,7 @@ pip3 install dist/python_unikorn_openstack_policy-0.1.0-py3-none-any.whl
9096
### Generating Policy Files
9197

9298
```bash
99+
oslopolicy-policy-generator --namespace unikorn_openstack_policy_blockstorage
93100
oslopolicy-policy-generator --namespace unikorn_openstack_policy_compute
94101
oslopolicy-policy-generator --namespace unikorn_openstack_policy_network
95102
```

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,22 @@ classifiers = [
2424
"Programming Language :: Python :: 3 :: Only",
2525
]
2626
dependencies = [
27-
"oslo.config",
27+
"cinder",
2828
"neutron",
29-
"nova"
29+
"nova",
30+
"oslo.config",
3031
]
3132

3233
[project.urls]
3334
homepage = "https://github.com/unikorn-cloud/python-unikorn-openstack-policy"
3435

3536
[project.entry-points."oslo.policy.policies"]
37+
unikorn_openstack_policy_blockstorage = "unikorn_openstack_policy.blockstorage:list_rules"
3638
unikorn_openstack_policy_compute = "unikorn_openstack_policy.compute:list_rules"
3739
unikorn_openstack_policy_network = "unikorn_openstack_policy.network:list_rules"
3840

3941
[project.entry-points."oslo.policy.enforcer"]
42+
unikorn_openstack_policy_blockstorage = "unikorn_openstack_policy.blockstorage:get_enforcer"
4043
unikorn_openstack_policy_compute = "unikorn_openstack_policy.compute:get_enforcer"
4144
unikorn_openstack_policy_network = "unikorn_openstack_policy.network:get_enforcer"
4245

requirements.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Copyright 2024 the Unikorn Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Defines Oslo Policy Rules.
17+
"""
18+
19+
# pylint: disable=line-too-long
20+
21+
from cinder import policies
22+
from cinder.policies import quotas
23+
from oslo_config import cfg
24+
from oslo_policy import policy
25+
from unikorn_openstack_policy import base
26+
27+
rules = [
28+
# The domain manager needs to be able to alter the default quotas
29+
# or it won't we able to fulfill any cluster creation requests.
30+
policy.RuleDefault(
31+
name=quotas.UPDATE_POLICY,
32+
check_str='rule:is_project_manager',
33+
description='Update the block storage quotas',
34+
)
35+
]
36+
37+
38+
def list_rules():
39+
"""Implements the "oslo.policy.policies" entry point"""
40+
41+
# For every defined rule, look for a corresponding one sourced directly
42+
# from nova, this means we can augment the exact rule defined for a
43+
# specific version of nova,
44+
return base.inherit_rules(rules, list(policies.list_rules()))
45+
46+
47+
def get_enforcer():
48+
"""Implements the "oslo.policy.enforcer" entry point"""
49+
50+
enforcer = policy.Enforcer(conf=cfg.CONF)
51+
enforcer.register_defaults(list_rules())
52+
53+
return enforcer
54+
55+
56+
# vi: ts=4 et:

unikorn_openstack_policy/compute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
policy.RuleDefault(
3030
name='os_compute_api:os-quota-sets:update',
3131
check_str='rule:is_project_manager',
32-
description='Update the quotas',
32+
description='Update the compute quotas',
3333
)
3434
]
3535

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
# Copyright 2024 the Unikorn Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""
16+
Unit tests for OpenStack policies.
17+
"""
18+
19+
from cinder.policies import quotas
20+
from oslo_policy import policy
21+
22+
from unikorn_openstack_policy import blockstorage
23+
from unikorn_openstack_policy.tests import base
24+
25+
class ProjectAdminBlockStoragePolicyTests(base.PolicyTestsBase):
26+
"""
27+
Checks policy enforcement for project scoped admin role.
28+
"""
29+
30+
# Request context.
31+
context = None
32+
33+
def setUp(self):
34+
"""Perform setup actions for all tests"""
35+
self.setup(blockstorage.get_enforcer())
36+
self.context = self.project_admin_context
37+
38+
def test_update_quota_sets(self):
39+
"""Admin can update quota sets"""
40+
self.assertTrue(self.enforce(
41+
quotas.UPDATE_POLICY, self.target, self.context))
42+
43+
44+
class DomainAdminBlockStoragePolicyTests(ProjectAdminBlockStoragePolicyTests):
45+
"""
46+
Checks policy enforcement for domain scoped admin role
47+
"""
48+
49+
def setUp(self):
50+
self.setup(blockstorage.get_enforcer())
51+
self.context = self.domain_admin_context
52+
53+
54+
class ProjectManagerBlockStoragePolicyTests(base.PolicyTestsBase):
55+
"""
56+
Checks policy enforcement for project scoped manager role
57+
"""
58+
59+
# Request context.
60+
context = None
61+
62+
def setUp(self):
63+
"""Perform setup actions for all tests"""
64+
self.setup(blockstorage.get_enforcer())
65+
self.context = self.project_manager_context
66+
67+
def test_update_quota_sets(self):
68+
"""Project manager can update quota sets"""
69+
self.assertTrue(self.enforce(
70+
quotas.UPDATE_POLICY, self.target, self.context))
71+
self.assertRaises(
72+
policy.PolicyNotAuthorized,
73+
self.enforce,
74+
quotas.UPDATE_POLICY, self.alt_target, self.context)
75+
76+
77+
class DomainManagerBlockStoragePolicyTests(base.PolicyTestsBase):
78+
"""
79+
Checks policy enforcement for the manager role.
80+
"""
81+
82+
def setUp(self):
83+
"""Perform setup actions for all tests"""
84+
self.setup(blockstorage.get_enforcer())
85+
self.context = self.domain_manager_context
86+
87+
def test_update_quota_sets(self):
88+
"""Domain manager cannot update quota sets"""
89+
self.assertRaises(
90+
policy.PolicyNotAuthorized,
91+
self.enforce,
92+
quotas.UPDATE_POLICY, self.target, self.context)
93+
self.assertRaises(
94+
policy.PolicyNotAuthorized,
95+
self.enforce,
96+
quotas.UPDATE_POLICY, self.alt_target, self.context)
97+
98+
99+
class ProjectMemberBlockStoragePolicyTests(base.PolicyTestsBase):
100+
"""
101+
Checks policy enforcement for the member role.
102+
"""
103+
104+
def setUp(self):
105+
"""Perform setup actions for all tests"""
106+
self.setup(blockstorage.get_enforcer())
107+
self.context = self.project_member_context
108+
109+
def test_update_quota_sets(self):
110+
"""Project member cannot create quota sets"""
111+
self.assertRaises(
112+
policy.PolicyNotAuthorized,
113+
self.enforce,
114+
quotas.UPDATE_POLICY, self.target, self.context)
115+
116+
117+
class DomainMemberBlockStoragePolicyTests(base.PolicyTestsBase):
118+
"""
119+
Checks policy enforcement for the member role.
120+
"""
121+
122+
def setUp(self):
123+
"""Perform setup actions for all tests"""
124+
self.setup(blockstorage.get_enforcer())
125+
self.context = self.domain_member_context
126+
127+
def test_update_quota_sets(self):
128+
"""Domain member cannot create quota sets"""
129+
self.assertRaises(
130+
policy.PolicyNotAuthorized,
131+
self.enforce,
132+
quotas.UPDATE_POLICY, self.target, self.context)
133+
134+
# vi: ts=4 et:

0 commit comments

Comments
 (0)