Allow service role to create/update port device_id
The ``device_id`` field on ports is used by other OpenStack projects to save what resource is using a port and for these OpenStack projects to support the Secure RBAC community goal they need to be able to update this field. This is required for OpenStack projects such as Nova that tracks instance UUID in device_id on a port and Octavia that also uses the device_id field. This allows the ``service`` role to update the device_id field and doesn't touch any existing policies that already exist for the field. Related-Bug: #2105502 Closes-Bug: #2107039 Change-Id: I227416a7420412a39e450352915eff5967172c64
This commit is contained in:
@@ -81,6 +81,20 @@ rules = [
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since=versionutils.deprecated.WALLABY)
|
||||
),
|
||||
policy.DocumentedRuleDefault(
|
||||
name='create_port:device_id',
|
||||
check_str=neutron_policy.policy_or(
|
||||
base.ADMIN_OR_PROJECT_MEMBER,
|
||||
base.SERVICE),
|
||||
scope_types=['project'],
|
||||
description='Specify ``device_id`` attribute when creating a port',
|
||||
operations=ACTION_POST,
|
||||
deprecated_rule=policy.DeprecatedRule(
|
||||
name='create_port:device_id',
|
||||
check_str=neutron_policy.RULE_ANY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since=versionutils.deprecated.WALLABY)
|
||||
),
|
||||
policy.DocumentedRuleDefault(
|
||||
name='create_port:device_owner',
|
||||
check_str=neutron_policy.policy_or(
|
||||
@@ -460,6 +474,20 @@ rules = [
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since=versionutils.deprecated.WALLABY)
|
||||
),
|
||||
policy.DocumentedRuleDefault(
|
||||
name='update_port:device_id',
|
||||
check_str=neutron_policy.policy_or(
|
||||
base.ADMIN_OR_PROJECT_MEMBER,
|
||||
base.SERVICE),
|
||||
scope_types=['project'],
|
||||
description='Update ``device_id`` attribute of a port',
|
||||
operations=ACTION_PUT,
|
||||
deprecated_rule=policy.DeprecatedRule(
|
||||
name='update_port:device_id',
|
||||
check_str=neutron_policy.RULE_ANY,
|
||||
deprecated_reason=DEPRECATED_REASON,
|
||||
deprecated_since=versionutils.deprecated.WALLABY)
|
||||
),
|
||||
policy.DocumentedRuleDefault(
|
||||
name='update_port:device_owner',
|
||||
check_str=neutron_policy.policy_or(
|
||||
|
@@ -62,6 +62,16 @@ class SystemAdminTests(PortAPITestCase):
|
||||
base_policy.InvalidScope,
|
||||
policy.enforce, self.context, 'create_port', self.alt_target)
|
||||
|
||||
def test_create_port_with_device_id(self):
|
||||
self.assertRaises(
|
||||
base_policy.InvalidScope,
|
||||
policy.enforce, self.context, 'create_port:device_id',
|
||||
self.target)
|
||||
self.assertRaises(
|
||||
base_policy.InvalidScope,
|
||||
policy.enforce, self.context, 'create_port:device_id',
|
||||
self.alt_target)
|
||||
|
||||
def test_create_port_with_device_owner(self):
|
||||
self.assertRaises(
|
||||
base_policy.InvalidScope,
|
||||
@@ -270,6 +280,16 @@ class SystemAdminTests(PortAPITestCase):
|
||||
base_policy.InvalidScope,
|
||||
policy.enforce, self.context, 'update_port', self.alt_target)
|
||||
|
||||
def test_update_port_with_device_id(self):
|
||||
self.assertRaises(
|
||||
base_policy.InvalidScope,
|
||||
policy.enforce, self.context, 'update_port:device_id',
|
||||
self.target)
|
||||
self.assertRaises(
|
||||
base_policy.InvalidScope,
|
||||
policy.enforce, self.context, 'update_port:device_id',
|
||||
self.alt_target)
|
||||
|
||||
def test_update_port_with_device_owner(self):
|
||||
self.assertRaises(
|
||||
base_policy.InvalidScope,
|
||||
@@ -441,6 +461,14 @@ class AdminTests(PortAPITestCase):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port', self.alt_target))
|
||||
|
||||
def test_create_port_with_device_id(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port:device_id',
|
||||
self.target))
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port:device_id',
|
||||
self.alt_target))
|
||||
|
||||
def test_create_port_with_device_owner(self):
|
||||
target = self.target.copy()
|
||||
target['device_owner'] = 'network:test'
|
||||
@@ -650,6 +678,14 @@ class AdminTests(PortAPITestCase):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port', self.alt_target))
|
||||
|
||||
def test_update_port_with_device_id(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port:device_id',
|
||||
self.target))
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port:device_id',
|
||||
self.alt_target))
|
||||
|
||||
def test_update_port_with_device_owner(self):
|
||||
target = self.target.copy()
|
||||
target['device_owner'] = 'network:test'
|
||||
@@ -809,6 +845,15 @@ class ProjectManagerTests(AdminTests):
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'create_port', self.alt_target)
|
||||
|
||||
def test_create_port_with_device_id(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port:device_id',
|
||||
self.target))
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'create_port:device_id',
|
||||
self.alt_target)
|
||||
|
||||
def test_create_port_with_device_owner(self):
|
||||
target = self.target.copy()
|
||||
target['device_owner'] = 'network:test'
|
||||
@@ -1051,6 +1096,14 @@ class ProjectManagerTests(AdminTests):
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'update_port', self.alt_target)
|
||||
|
||||
def test_update_port_with_device_id(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port:device_id', self.target))
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'update_port:device_id',
|
||||
self.alt_target)
|
||||
|
||||
def test_update_port_with_device_owner(self):
|
||||
target = self.target.copy()
|
||||
target['device_owner'] = 'network:test'
|
||||
@@ -1437,6 +1490,16 @@ class ProjectReaderTests(ProjectMemberTests):
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'create_port', self.alt_target)
|
||||
|
||||
def test_create_port_with_device_id(self):
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'create_port:device_id',
|
||||
self.target)
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'create_port:device_id',
|
||||
self.alt_target)
|
||||
|
||||
def test_create_port_with_binding_vnic_type(self):
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
@@ -1463,6 +1526,16 @@ class ProjectReaderTests(ProjectMemberTests):
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'update_port', self.alt_target)
|
||||
|
||||
def test_update_port_with_device_id(self):
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'update_port:device_id',
|
||||
self.target)
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
policy.enforce, self.context, 'update_port:device_id',
|
||||
self.alt_target)
|
||||
|
||||
def test_update_port_with_binding_vnic_type(self):
|
||||
self.assertRaises(
|
||||
base_policy.PolicyNotAuthorized,
|
||||
@@ -1500,6 +1573,14 @@ class ServiceRoleTests(PortAPITestCase):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port', self.target))
|
||||
|
||||
def test_create_port_with_device_id(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port:device_id',
|
||||
self.target))
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'create_port:device_id',
|
||||
self.alt_target))
|
||||
|
||||
def test_create_port_with_device_owner(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(
|
||||
@@ -1608,6 +1689,14 @@ class ServiceRoleTests(PortAPITestCase):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port', self.target))
|
||||
|
||||
def test_update_port_with_device_id(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port:device_id',
|
||||
self.target))
|
||||
self.assertTrue(
|
||||
policy.enforce(self.context, 'update_port:device_id',
|
||||
self.alt_target))
|
||||
|
||||
def test_update_port_with_device_owner(self):
|
||||
self.assertTrue(
|
||||
policy.enforce(
|
||||
|
@@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added ``service`` role to the ``create_port:device_id`` and
|
||||
``update_port:device_id`` policies to allow service users
|
||||
for other OpenStack projects to complete Secure RBAC.
|
Reference in New Issue
Block a user