Skip to content

Add Block Storage Quotas #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/dist
/venv
/python_unikorn_openstack_policy.egg-info/
__pycache__
*.swp
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ We need the following to be allowed (non-root):
* Management of quotas
* Provisioning of provider networks in managed projects

### Block Storage Service

We need the following to be allowed (non-root):

* Management of quotas

### Design

Problem with any service that isn't Keystone is, it has zero view of identity hierarchies.
Expand Down Expand Up @@ -78,18 +84,25 @@ openstack network create --provider-network-type vlan --provider-physical-networ

### Installation

```bash
python3 -m venv venv
source venv/bin/activate
pip3 install build pylint
```

> [!NOTE]
> Running the following will install all the necessary dependencies.
> This also includes any commands required for the the following sections.

```bash
python3 -m build
pip3 install dist/python_unikorn_openstack_policy-0.1.0-py3-none-any.whl
pip3 install --force-reinstall dist/python_unikorn_openstack_policy-0.1.0-py3-none-any.whl
```

### Generating Policy Files

```bash
oslopolicy-policy-generator --namespace unikorn_openstack_policy_blockstorage
oslopolicy-policy-generator --namespace unikorn_openstack_policy_compute
oslopolicy-policy-generator --namespace unikorn_openstack_policy_network
```
Expand Down
7 changes: 5 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,22 @@ classifiers = [
"Programming Language :: Python :: 3 :: Only",
]
dependencies = [
"oslo.config",
"cinder",
"neutron",
"nova"
"nova",
"oslo.config",
]

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

[project.entry-points."oslo.policy.policies"]
unikorn_openstack_policy_blockstorage = "unikorn_openstack_policy.blockstorage:list_rules"
unikorn_openstack_policy_compute = "unikorn_openstack_policy.compute:list_rules"
unikorn_openstack_policy_network = "unikorn_openstack_policy.network:list_rules"

[project.entry-points."oslo.policy.enforcer"]
unikorn_openstack_policy_blockstorage = "unikorn_openstack_policy.blockstorage:get_enforcer"
unikorn_openstack_policy_compute = "unikorn_openstack_policy.compute:get_enforcer"
unikorn_openstack_policy_network = "unikorn_openstack_policy.network:get_enforcer"

Expand Down
2 changes: 0 additions & 2 deletions requirements.txt

This file was deleted.

56 changes: 56 additions & 0 deletions unikorn_openstack_policy/blockstorage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Copyright 2024 the Unikorn Authors.
#
# 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.

"""
Defines Oslo Policy Rules.
"""

# pylint: disable=line-too-long

from cinder import policies
from cinder.policies import quotas
from oslo_config import cfg
from oslo_policy import policy
from unikorn_openstack_policy import base

rules = [
# The domain manager needs to be able to alter the default quotas
# or it won't we able to fulfill any cluster creation requests.
policy.RuleDefault(
name=quotas.UPDATE_POLICY,
check_str='rule:is_project_manager',
description='Update the block storage quotas',
)
]


def list_rules():
"""Implements the "oslo.policy.policies" entry point"""

# For every defined rule, look for a corresponding one sourced directly
# from nova, this means we can augment the exact rule defined for a
# specific version of nova,
return base.inherit_rules(rules, list(policies.list_rules()))


def get_enforcer():
"""Implements the "oslo.policy.enforcer" entry point"""

enforcer = policy.Enforcer(conf=cfg.CONF)
enforcer.register_defaults(list_rules())

return enforcer


# vi: ts=4 et:
2 changes: 1 addition & 1 deletion unikorn_openstack_policy/compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
policy.RuleDefault(
name='os_compute_api:os-quota-sets:update',
check_str='rule:is_project_manager',
description='Update the quotas',
description='Update the compute quotas',
)
]

Expand Down
134 changes: 134 additions & 0 deletions unikorn_openstack_policy/tests/test_blockstorage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Copyright 2024 the Unikorn Authors.
#
# 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.

"""
Unit tests for OpenStack policies.
"""

from cinder.policies import quotas
from oslo_policy import policy

from unikorn_openstack_policy import blockstorage
from unikorn_openstack_policy.tests import base

class ProjectAdminBlockStoragePolicyTests(base.PolicyTestsBase):
"""
Checks policy enforcement for project scoped admin role.
"""

# Request context.
context = None

def setUp(self):
"""Perform setup actions for all tests"""
self.setup(blockstorage.get_enforcer())
self.context = self.project_admin_context

def test_update_quota_sets(self):
"""Admin can update quota sets"""
self.assertTrue(self.enforce(
quotas.UPDATE_POLICY, self.target, self.context))


class DomainAdminBlockStoragePolicyTests(ProjectAdminBlockStoragePolicyTests):
"""
Checks policy enforcement for domain scoped admin role
"""

def setUp(self):
self.setup(blockstorage.get_enforcer())
self.context = self.domain_admin_context


class ProjectManagerBlockStoragePolicyTests(base.PolicyTestsBase):
"""
Checks policy enforcement for project scoped manager role
"""

# Request context.
context = None

def setUp(self):
"""Perform setup actions for all tests"""
self.setup(blockstorage.get_enforcer())
self.context = self.project_manager_context

def test_update_quota_sets(self):
"""Project manager can update quota sets"""
self.assertTrue(self.enforce(
quotas.UPDATE_POLICY, self.target, self.context))
self.assertRaises(
policy.PolicyNotAuthorized,
self.enforce,
quotas.UPDATE_POLICY, self.alt_target, self.context)


class DomainManagerBlockStoragePolicyTests(base.PolicyTestsBase):
"""
Checks policy enforcement for the manager role.
"""

def setUp(self):
"""Perform setup actions for all tests"""
self.setup(blockstorage.get_enforcer())
self.context = self.domain_manager_context

def test_update_quota_sets(self):
"""Domain manager cannot update quota sets"""
self.assertRaises(
policy.PolicyNotAuthorized,
self.enforce,
quotas.UPDATE_POLICY, self.target, self.context)
self.assertRaises(
policy.PolicyNotAuthorized,
self.enforce,
quotas.UPDATE_POLICY, self.alt_target, self.context)


class ProjectMemberBlockStoragePolicyTests(base.PolicyTestsBase):
"""
Checks policy enforcement for the member role.
"""

def setUp(self):
"""Perform setup actions for all tests"""
self.setup(blockstorage.get_enforcer())
self.context = self.project_member_context

def test_update_quota_sets(self):
"""Project member cannot create quota sets"""
self.assertRaises(
policy.PolicyNotAuthorized,
self.enforce,
quotas.UPDATE_POLICY, self.target, self.context)


class DomainMemberBlockStoragePolicyTests(base.PolicyTestsBase):
"""
Checks policy enforcement for the member role.
"""

def setUp(self):
"""Perform setup actions for all tests"""
self.setup(blockstorage.get_enforcer())
self.context = self.domain_member_context

def test_update_quota_sets(self):
"""Domain member cannot create quota sets"""
self.assertRaises(
policy.PolicyNotAuthorized,
self.enforce,
quotas.UPDATE_POLICY, self.target, self.context)

# vi: ts=4 et:
Loading