Merge "Document RBAC Policy allowed values"

This commit is contained in:
Zuul
2018-01-22 05:08:08 +00:00
committed by Gerrit Code Review
2 changed files with 41 additions and 24 deletions

View File

@@ -13,6 +13,7 @@
from heat.common import exception from heat.common import exception
from heat.common.i18n import _ from heat.common.i18n import _
from heat.engine import constraints
from heat.engine import properties from heat.engine import properties
from heat.engine.resources.openstack.neutron import neutron from heat.engine.resources.openstack.neutron import neutron
from heat.engine import support from heat.engine import support
@@ -54,13 +55,17 @@ class RBACPolicy(neutron.NeutronResource):
# Change it when neutron supports more function in the future. # Change it when neutron supports more function in the future.
SUPPORTED_TYPES_ACTIONS = { SUPPORTED_TYPES_ACTIONS = {
OBJECT_NETWORK: [ACCESS_AS_SHARED, ACCESS_AS_EXTERNAL], OBJECT_NETWORK: [ACCESS_AS_SHARED, ACCESS_AS_EXTERNAL],
OBJECT_QOS_POLICY: [ACCESS_AS_SHARED]} OBJECT_QOS_POLICY: [ACCESS_AS_SHARED],
}
properties_schema = { properties_schema = {
OBJECT_TYPE: properties.Schema( OBJECT_TYPE: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Type of the object that RBAC policy affects.'), _('Type of the object that RBAC policy affects.'),
required=True, required=True,
constraints=[
constraints.AllowedValues(OBJECT_TYPE_KEYS)
]
), ),
TARGET_TENANT: properties.Schema( TARGET_TENANT: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
@@ -70,8 +75,14 @@ class RBACPolicy(neutron.NeutronResource):
), ),
ACTION: properties.Schema( ACTION: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Action for the RBAC policy.'), _('Action for the RBAC policy. The allowed actions differ for '
'different object types - only %(network)s objects can have an '
'%(external)s action.') % {'network': OBJECT_NETWORK,
'external': ACCESS_AS_EXTERNAL},
required=True, required=True,
constraints=[
constraints.AllowedValues(ACTION_KEYS)
]
), ),
OBJECT_ID: properties.Schema( OBJECT_ID: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
@@ -123,25 +134,26 @@ class RBACPolicy(neutron.NeutronResource):
self.client().delete_rbac_policy(self.resource_id) self.client().delete_rbac_policy(self.resource_id)
def validate(self): def validate(self):
"""Validate the provided params.""" """Validate the provided properties."""
super(RBACPolicy, self).validate() super(RBACPolicy, self).validate()
action = self.properties[self.ACTION] action = self.properties[self.ACTION]
obj_type = self.properties[self.OBJECT_TYPE] obj_type = self.properties[self.OBJECT_TYPE]
# Validate obj_type and action per SUPPORTED_TYPES_ACTIONS. # Validate obj_type and action per SUPPORTED_TYPES_ACTIONS.
if obj_type not in self.SUPPORTED_TYPES_ACTIONS:
msg = (_("Invalid object_type: %(obj_type)s. "
"Valid object_type :%(value)s") %
{'obj_type': obj_type,
'value': self.SUPPORTED_TYPES_ACTIONS.keys()})
raise exception.StackValidationFailed(message=msg)
if action not in self.SUPPORTED_TYPES_ACTIONS[obj_type]: if action not in self.SUPPORTED_TYPES_ACTIONS[obj_type]:
msg = (_("Invalid action %(action)s for object type " valid_actions = ', '.join(self.SUPPORTED_TYPES_ACTIONS[obj_type])
"%(obj_type)s. Valid actions :%(value)s") % msg = (_('Invalid action "%(action)s" for object type '
'%(obj_type)s. Valid actions: %(valid_actions)s') %
{'action': action, 'obj_type': obj_type, {'action': action, 'obj_type': obj_type,
'value': self.SUPPORTED_TYPES_ACTIONS[obj_type]}) 'valid_actions': valid_actions})
raise exception.StackValidationFailed(message=msg) properties_section = self.properties.error_prefix[0]
path = [self.stack.t.RESOURCES, self.t.name,
self.stack.t.get_section_name(properties_section),
self.ACTION]
raise exception.StackValidationFailed(error='Property error',
path=path,
message=msg)
def resource_mapping(): def resource_mapping():

View File

@@ -57,16 +57,13 @@ class RBACPolicyTest(common.HeatTestCase):
def test_create_qos_policy_rbac(self): def test_create_qos_policy_rbac(self):
self._test_create(obj_type='qos_policy') self._test_create(obj_type='qos_policy')
def _test_validate_invalid_action(self, def _test_validate_invalid_action(self, msg,
invalid_action='invalid', invalid_action='invalid',
obj_type='network'): obj_type='network'):
tpl = yaml.safe_load(inline_templates.RBAC_TEMPLATE) tpl = yaml.safe_load(inline_templates.RBAC_TEMPLATE)
tpl['resources']['rbac']['properties']['action'] = invalid_action tpl['resources']['rbac']['properties']['action'] = invalid_action
tpl['resources']['rbac']['properties']['object_type'] = obj_type tpl['resources']['rbac']['properties']['object_type'] = obj_type
self._create_stack(tmpl=yaml.safe_dump(tpl)) self._create_stack(tmpl=yaml.safe_dump(tpl))
msg = ("Invalid action %(action)s for object type %(type)s." %
{'action': invalid_action,
'type': obj_type})
self.patchobject(type(self.rbac), 'is_service_available', self.patchobject(type(self.rbac), 'is_service_available',
return_value=(True, None)) return_value=(True, None))
@@ -75,21 +72,29 @@ class RBACPolicyTest(common.HeatTestCase):
self.rbac.validate) self.rbac.validate)
def test_validate_action_for_network(self): def test_validate_action_for_network(self):
self._test_validate_invalid_action() msg = ('Property error: resources.rbac.properties.action: '
'"invalid" is not an allowed value '
r'\[access_as_shared, access_as_external\]')
self._test_validate_invalid_action(msg)
def test_validate_action_for_qos_policy(self): def test_validate_action_for_qos_policy(self):
self._test_validate_invalid_action( msg = ('Property error: resources.rbac.properties.action: '
obj_type='qos_policy') '"invalid" is not an allowed value '
r'\[access_as_shared, access_as_external\]')
self._test_validate_invalid_action(msg, obj_type='qos_policy')
# we dont support access_as_external for qos_policy # we dont support access_as_external for qos_policy
self._test_validate_invalid_action( msg = ('Property error: resources.rbac.properties.action: '
obj_type='qos_policy', 'Invalid action "access_as_external" for object type '
invalid_action='access_as_external') 'qos_policy. Valid actions: access_as_shared')
self._test_validate_invalid_action(msg,
obj_type='qos_policy',
invalid_action='access_as_external')
def test_validate_invalid_type(self): def test_validate_invalid_type(self):
tpl = yaml.safe_load(inline_templates.RBAC_TEMPLATE) tpl = yaml.safe_load(inline_templates.RBAC_TEMPLATE)
tpl['resources']['rbac']['properties']['object_type'] = 'networks' tpl['resources']['rbac']['properties']['object_type'] = 'networks'
self._create_stack(tmpl=yaml.safe_dump(tpl)) self._create_stack(tmpl=yaml.safe_dump(tpl))
msg = "Invalid object_type: networks. " msg = '"networks" is not an allowed value'
self.patchobject(type(self.rbac), 'is_service_available', self.patchobject(type(self.rbac), 'is_service_available',
return_value=(True, None)) return_value=(True, None))