Merge "[policy in code] part 2 (stacks)"
This commit is contained in:
commit
63148dcf5a
|
@ -34,36 +34,6 @@
|
||||||
"resource:signal": "",
|
"resource:signal": "",
|
||||||
"resource:mark_unhealthy": "rule:deny_stack_user",
|
"resource:mark_unhealthy": "rule:deny_stack_user",
|
||||||
"resource:show": "rule:deny_stack_user",
|
"resource:show": "rule:deny_stack_user",
|
||||||
"stacks:abandon": "rule:deny_stack_user",
|
|
||||||
"stacks:create": "rule:deny_stack_user",
|
|
||||||
"stacks:delete": "rule:deny_stack_user",
|
|
||||||
"stacks:detail": "rule:deny_stack_user",
|
|
||||||
"stacks:export": "rule:deny_stack_user",
|
|
||||||
"stacks:generate_template": "rule:deny_stack_user",
|
|
||||||
"stacks:global_index": "rule:deny_everybody",
|
|
||||||
"stacks:index": "rule:deny_stack_user",
|
|
||||||
"stacks:list_resource_types": "rule:deny_stack_user",
|
|
||||||
"stacks:list_template_versions": "rule:deny_stack_user",
|
|
||||||
"stacks:list_template_functions": "rule:deny_stack_user",
|
|
||||||
"stacks:lookup": "",
|
|
||||||
"stacks:preview": "rule:deny_stack_user",
|
|
||||||
"stacks:resource_schema": "rule:deny_stack_user",
|
|
||||||
"stacks:show": "rule:deny_stack_user",
|
|
||||||
"stacks:template": "rule:deny_stack_user",
|
|
||||||
"stacks:environment": "rule:deny_stack_user",
|
|
||||||
"stacks:files": "rule:deny_stack_user",
|
|
||||||
"stacks:update": "rule:deny_stack_user",
|
|
||||||
"stacks:update_patch": "rule:deny_stack_user",
|
|
||||||
"stacks:preview_update": "rule:deny_stack_user",
|
|
||||||
"stacks:preview_update_patch": "rule:deny_stack_user",
|
|
||||||
"stacks:validate_template": "rule:deny_stack_user",
|
|
||||||
"stacks:snapshot": "rule:deny_stack_user",
|
|
||||||
"stacks:show_snapshot": "rule:deny_stack_user",
|
|
||||||
"stacks:delete_snapshot": "rule:deny_stack_user",
|
|
||||||
"stacks:list_snapshots": "rule:deny_stack_user",
|
|
||||||
"stacks:restore_snapshot": "rule:deny_stack_user",
|
|
||||||
"stacks:list_outputs": "rule:deny_stack_user",
|
|
||||||
"stacks:show_output": "rule:deny_stack_user",
|
|
||||||
|
|
||||||
"software_configs:global_index": "rule:deny_everybody",
|
"software_configs:global_index": "rule:deny_everybody",
|
||||||
"software_configs:index": "rule:deny_stack_user",
|
"software_configs:index": "rule:deny_stack_user",
|
||||||
|
|
|
@ -168,7 +168,8 @@ class StackController(object):
|
||||||
|
|
||||||
Implements the API actions.
|
Implements the API actions.
|
||||||
"""
|
"""
|
||||||
# Define request scope (must match what is in policy.json)
|
# Define request scope (must match what is in policy.json or policies in
|
||||||
|
# code)
|
||||||
REQUEST_SCOPE = 'stacks'
|
REQUEST_SCOPE = 'stacks'
|
||||||
|
|
||||||
def __init__(self, options):
|
def __init__(self, options):
|
||||||
|
@ -329,11 +330,11 @@ class StackController(object):
|
||||||
count=count,
|
count=count,
|
||||||
include_project=cnxt.is_admin)
|
include_project=cnxt.is_admin)
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def global_index(self, req):
|
def global_index(self, req):
|
||||||
return self._index(req, use_admin_cnxt=True)
|
return self._index(req, use_admin_cnxt=True)
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def index(self, req):
|
def index(self, req):
|
||||||
"""Lists summary information for all stacks."""
|
"""Lists summary information for all stacks."""
|
||||||
global_tenant = False
|
global_tenant = False
|
||||||
|
@ -348,14 +349,14 @@ class StackController(object):
|
||||||
|
|
||||||
return self._index(req)
|
return self._index(req)
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def detail(self, req):
|
def detail(self, req):
|
||||||
"""Lists detailed information for all stacks."""
|
"""Lists detailed information for all stacks."""
|
||||||
stacks = self.rpc_client.list_stacks(req.context)
|
stacks = self.rpc_client.list_stacks(req.context)
|
||||||
|
|
||||||
return {'stacks': [stacks_view.format_stack(req, s) for s in stacks]}
|
return {'stacks': [stacks_view.format_stack(req, s) for s in stacks]}
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def preview(self, req, body):
|
def preview(self, req, body):
|
||||||
"""Preview the outcome of a template and its params."""
|
"""Preview the outcome of a template and its params."""
|
||||||
|
|
||||||
|
@ -389,7 +390,7 @@ class StackController(object):
|
||||||
raise exc.HTTPBadRequest(six.text_type(msg))
|
raise exc.HTTPBadRequest(six.text_type(msg))
|
||||||
return args
|
return args
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def create(self, req, body):
|
def create(self, req, body):
|
||||||
"""Create a new stack."""
|
"""Create a new stack."""
|
||||||
data = InstantiationData(body)
|
data = InstantiationData(body)
|
||||||
|
@ -410,7 +411,7 @@ class StackController(object):
|
||||||
)
|
)
|
||||||
return {'stack': formatted_stack}
|
return {'stack': formatted_stack}
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def lookup(self, req, stack_name, path='', body=None):
|
def lookup(self, req, stack_name, path='', body=None):
|
||||||
"""Redirect to the canonical URL for a stack."""
|
"""Redirect to the canonical URL for a stack."""
|
||||||
try:
|
try:
|
||||||
|
@ -429,7 +430,7 @@ class StackController(object):
|
||||||
|
|
||||||
raise exc.HTTPFound(location=location)
|
raise exc.HTTPFound(location=location)
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def show(self, req, identity):
|
def show(self, req, identity):
|
||||||
"""Gets detailed information for a stack."""
|
"""Gets detailed information for a stack."""
|
||||||
params = req.params
|
params = req.params
|
||||||
|
@ -450,7 +451,7 @@ class StackController(object):
|
||||||
|
|
||||||
return {'stack': stacks_view.format_stack(req, stack)}
|
return {'stack': stacks_view.format_stack(req, stack)}
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def template(self, req, identity):
|
def template(self, req, identity):
|
||||||
"""Get the template body for an existing stack."""
|
"""Get the template body for an existing stack."""
|
||||||
|
|
||||||
|
@ -460,19 +461,19 @@ class StackController(object):
|
||||||
# TODO(zaneb): always set Content-type to application/json
|
# TODO(zaneb): always set Content-type to application/json
|
||||||
return templ
|
return templ
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def environment(self, req, identity):
|
def environment(self, req, identity):
|
||||||
"""Get the environment for an existing stack."""
|
"""Get the environment for an existing stack."""
|
||||||
env = self.rpc_client.get_environment(req.context, identity)
|
env = self.rpc_client.get_environment(req.context, identity)
|
||||||
|
|
||||||
return env
|
return env
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def files(self, req, identity):
|
def files(self, req, identity):
|
||||||
"""Get the files for an existing stack."""
|
"""Get the files for an existing stack."""
|
||||||
return self.rpc_client.get_files(req.context, identity)
|
return self.rpc_client.get_files(req.context, identity)
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def update(self, req, identity, body):
|
def update(self, req, identity, body):
|
||||||
"""Update an existing stack with a new template and/or parameters."""
|
"""Update an existing stack with a new template and/or parameters."""
|
||||||
data = InstantiationData(body)
|
data = InstantiationData(body)
|
||||||
|
@ -489,7 +490,7 @@ class StackController(object):
|
||||||
|
|
||||||
raise exc.HTTPAccepted()
|
raise exc.HTTPAccepted()
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def update_patch(self, req, identity, body):
|
def update_patch(self, req, identity, body):
|
||||||
"""Update an existing stack with a new template.
|
"""Update an existing stack with a new template.
|
||||||
|
|
||||||
|
@ -518,7 +519,7 @@ class StackController(object):
|
||||||
if p_name in params:
|
if p_name in params:
|
||||||
return self._extract_bool_param(p_name, params[p_name])
|
return self._extract_bool_param(p_name, params[p_name])
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def preview_update(self, req, identity, body):
|
def preview_update(self, req, identity, body):
|
||||||
"""Preview update for existing stack with a new template/parameters."""
|
"""Preview update for existing stack with a new template/parameters."""
|
||||||
data = InstantiationData(body)
|
data = InstantiationData(body)
|
||||||
|
@ -538,7 +539,7 @@ class StackController(object):
|
||||||
|
|
||||||
return {'resource_changes': changes}
|
return {'resource_changes': changes}
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def preview_update_patch(self, req, identity, body):
|
def preview_update_patch(self, req, identity, body):
|
||||||
"""Preview PATCH update for existing stack."""
|
"""Preview PATCH update for existing stack."""
|
||||||
data = InstantiationData(body, patch=True)
|
data = InstantiationData(body, patch=True)
|
||||||
|
@ -558,7 +559,7 @@ class StackController(object):
|
||||||
|
|
||||||
return {'resource_changes': changes}
|
return {'resource_changes': changes}
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def delete(self, req, identity):
|
def delete(self, req, identity):
|
||||||
"""Delete the specified stack."""
|
"""Delete the specified stack."""
|
||||||
|
|
||||||
|
@ -567,7 +568,7 @@ class StackController(object):
|
||||||
cast=False)
|
cast=False)
|
||||||
raise exc.HTTPNoContent()
|
raise exc.HTTPNoContent()
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def abandon(self, req, identity):
|
def abandon(self, req, identity):
|
||||||
"""Abandons specified stack.
|
"""Abandons specified stack.
|
||||||
|
|
||||||
|
@ -577,7 +578,7 @@ class StackController(object):
|
||||||
return self.rpc_client.abandon_stack(req.context,
|
return self.rpc_client.abandon_stack(req.context,
|
||||||
identity)
|
identity)
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def export(self, req, identity):
|
def export(self, req, identity):
|
||||||
"""Export specified stack.
|
"""Export specified stack.
|
||||||
|
|
||||||
|
@ -585,7 +586,7 @@ class StackController(object):
|
||||||
"""
|
"""
|
||||||
return self.rpc_client.export_stack(req.context, identity)
|
return self.rpc_client.export_stack(req.context, identity)
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def validate_template(self, req, body):
|
def validate_template(self, req, body):
|
||||||
"""Implements the ValidateTemplate API action.
|
"""Implements the ValidateTemplate API action.
|
||||||
|
|
||||||
|
@ -623,7 +624,7 @@ class StackController(object):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def list_resource_types(self, req):
|
def list_resource_types(self, req):
|
||||||
"""Returns a resource types list which may be used in template."""
|
"""Returns a resource types list which may be used in template."""
|
||||||
support_status = req.params.get('support_status')
|
support_status = req.params.get('support_status')
|
||||||
|
@ -646,7 +647,7 @@ class StackController(object):
|
||||||
heat_version=version,
|
heat_version=version,
|
||||||
with_description=with_description)}
|
with_description=with_description)}
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def list_template_versions(self, req):
|
def list_template_versions(self, req):
|
||||||
"""Returns a list of available template versions."""
|
"""Returns a list of available template versions."""
|
||||||
return {
|
return {
|
||||||
|
@ -654,7 +655,7 @@ class StackController(object):
|
||||||
self.rpc_client.list_template_versions(req.context)
|
self.rpc_client.list_template_versions(req.context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def list_template_functions(self, req, template_version):
|
def list_template_functions(self, req, template_version):
|
||||||
"""Returns a list of available functions in a given template."""
|
"""Returns a list of available functions in a given template."""
|
||||||
if req.params.get('with_condition_func') is not None:
|
if req.params.get('with_condition_func') is not None:
|
||||||
|
@ -671,14 +672,14 @@ class StackController(object):
|
||||||
with_condition)
|
with_condition)
|
||||||
}
|
}
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def resource_schema(self, req, type_name, with_description=False):
|
def resource_schema(self, req, type_name, with_description=False):
|
||||||
"""Returns the schema of the given resource type."""
|
"""Returns the schema of the given resource type."""
|
||||||
return self.rpc_client.resource_schema(
|
return self.rpc_client.resource_schema(
|
||||||
req.context, type_name,
|
req.context, type_name,
|
||||||
self._extract_bool_param('with_description', with_description))
|
self._extract_bool_param('with_description', with_description))
|
||||||
|
|
||||||
@util.policy_enforce
|
@util.registered_policy_enforce
|
||||||
def generate_template(self, req, type_name):
|
def generate_template(self, req, type_name):
|
||||||
"""Generates a template based on the specified type."""
|
"""Generates a template based on the specified type."""
|
||||||
template_type = 'cfn'
|
template_type = 'cfn'
|
||||||
|
@ -694,42 +695,42 @@ class StackController(object):
|
||||||
type_name,
|
type_name,
|
||||||
template_type)
|
template_type)
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def snapshot(self, req, identity, body):
|
def snapshot(self, req, identity, body):
|
||||||
name = body.get('name')
|
name = body.get('name')
|
||||||
return self.rpc_client.stack_snapshot(req.context, identity, name)
|
return self.rpc_client.stack_snapshot(req.context, identity, name)
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def show_snapshot(self, req, identity, snapshot_id):
|
def show_snapshot(self, req, identity, snapshot_id):
|
||||||
snapshot = self.rpc_client.show_snapshot(
|
snapshot = self.rpc_client.show_snapshot(
|
||||||
req.context, identity, snapshot_id)
|
req.context, identity, snapshot_id)
|
||||||
return {'snapshot': snapshot}
|
return {'snapshot': snapshot}
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def delete_snapshot(self, req, identity, snapshot_id):
|
def delete_snapshot(self, req, identity, snapshot_id):
|
||||||
self.rpc_client.delete_snapshot(req.context, identity, snapshot_id)
|
self.rpc_client.delete_snapshot(req.context, identity, snapshot_id)
|
||||||
raise exc.HTTPNoContent()
|
raise exc.HTTPNoContent()
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def list_snapshots(self, req, identity):
|
def list_snapshots(self, req, identity):
|
||||||
return {
|
return {
|
||||||
'snapshots': self.rpc_client.stack_list_snapshots(
|
'snapshots': self.rpc_client.stack_list_snapshots(
|
||||||
req.context, identity)
|
req.context, identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def restore_snapshot(self, req, identity, snapshot_id):
|
def restore_snapshot(self, req, identity, snapshot_id):
|
||||||
self.rpc_client.stack_restore(req.context, identity, snapshot_id)
|
self.rpc_client.stack_restore(req.context, identity, snapshot_id)
|
||||||
raise exc.HTTPAccepted()
|
raise exc.HTTPAccepted()
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def list_outputs(self, req, identity):
|
def list_outputs(self, req, identity):
|
||||||
return {
|
return {
|
||||||
'outputs': self.rpc_client.list_outputs(
|
'outputs': self.rpc_client.list_outputs(
|
||||||
req.context, identity)
|
req.context, identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@util.identified_stack
|
@util.registered_identified_stack
|
||||||
def show_output(self, req, identity, output_key):
|
def show_output(self, req, identity, output_key):
|
||||||
return {'output': self.rpc_client.show_output(req.context,
|
return {'output': self.rpc_client.show_output(req.context,
|
||||||
identity,
|
identity,
|
||||||
|
|
|
@ -108,7 +108,8 @@ class Enforcer(object):
|
||||||
:param context: Heat request context
|
:param context: Heat request context
|
||||||
:returns: A non-False value if the user is admin according to policy
|
:returns: A non-False value if the user is admin according to policy
|
||||||
"""
|
"""
|
||||||
return self._check(context, 'context_is_admin', target={}, exc=None)
|
return self._check(context, 'context_is_admin', target={}, exc=None,
|
||||||
|
is_registered_policy=True)
|
||||||
|
|
||||||
|
|
||||||
def get_enforcer():
|
def get_enforcer():
|
||||||
|
|
|
@ -14,9 +14,11 @@
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
from heat.policies import base
|
from heat.policies import base
|
||||||
|
from heat.policies import stacks
|
||||||
|
|
||||||
|
|
||||||
def list_rules():
|
def list_rules():
|
||||||
return itertools.chain(
|
return itertools.chain(
|
||||||
base.list_rules(),
|
base.list_rules(),
|
||||||
|
stacks.list_rules(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,370 @@
|
||||||
|
# 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 heat.policies import base
|
||||||
|
|
||||||
|
POLICY_ROOT = 'stacks:%s'
|
||||||
|
|
||||||
|
stacks_policies = [
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'abandon',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Abandon stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'abandon',
|
||||||
|
'method': 'DELETE'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'create',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Create stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'delete',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Delete stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}',
|
||||||
|
'method': 'DELETE'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'detail',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List stacks in detail.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'export',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Export stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'export',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'generate_template',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Generate stack template.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'template',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'global_index',
|
||||||
|
check_str=base.RULE_DENY_EVERYBODY,
|
||||||
|
description='List stacks globally.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'index',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List stacks.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'list_resource_types',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List resource types.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/resource_types',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'list_template_versions',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List template versions.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/template_versions',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'list_template_functions',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List template functions.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/template_versions/'
|
||||||
|
'{template_version}/functions',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'lookup',
|
||||||
|
check_str=base.RULE_ALLOW_EVERYBODY,
|
||||||
|
description='Find stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_identity}',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'preview',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Preview stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/preview',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'resource_schema',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Show resource type schema.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/resource_types/{type_name}',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'show',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Show stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_identity}',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'template',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Get stack template.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'template',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'environment',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Get stack environment.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'environment',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'files',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Get stack files.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'files',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'update',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Update stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}',
|
||||||
|
'method': 'PUT'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'update_patch',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Update stack (PATCH).',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}',
|
||||||
|
'method': 'PATCH'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'preview_update',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Preview update stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'preview',
|
||||||
|
'method': 'PUT'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'preview_update_patch',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Preview update stack (PATCH).',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'preview',
|
||||||
|
'method': 'PATCH'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'validate_template',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Validate template.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/validate',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'snapshot',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Snapshot Stack.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'snapshots',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'show_snapshot',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Show snapshot.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'snapshots/{snapshot_id}',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'delete_snapshot',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Delete snapshot.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'snapshots/{snapshot_id}',
|
||||||
|
'method': 'DELETE'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'list_snapshots',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List snapshots.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'snapshots',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'restore_snapshot',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Restore snapshot.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'snapshots/{snapshot_id}/restore',
|
||||||
|
'method': 'POST'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'list_outputs',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='List outputs.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'outputs',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
policy.DocumentedRuleDefault(
|
||||||
|
name=POLICY_ROOT % 'show_output',
|
||||||
|
check_str=base.RULE_DENY_STACK_USER,
|
||||||
|
description='Show outputs.',
|
||||||
|
operations=[
|
||||||
|
{
|
||||||
|
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
|
||||||
|
'outputs/{output_key}',
|
||||||
|
'method': 'GET'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def list_rules():
|
||||||
|
return stacks_policies
|
|
@ -473,7 +473,7 @@ class StackControllerTest(tools.ControllerTest, common.HeatTestCase):
|
||||||
self.controller.index(req, tenant_id=self.tenant)
|
self.controller.index(req, tenant_id=self.tenant)
|
||||||
mock_enforce.assert_called_with(action='global_index',
|
mock_enforce.assert_called_with(action='global_index',
|
||||||
scope=self.controller.REQUEST_SCOPE,
|
scope=self.controller.REQUEST_SCOPE,
|
||||||
is_registered_policy=False,
|
is_registered_policy=True,
|
||||||
context=self.context)
|
context=self.context)
|
||||||
|
|
||||||
def test_global_index_uses_admin_context(self, mock_enforce):
|
def test_global_index_uses_admin_context(self, mock_enforce):
|
||||||
|
|
|
@ -159,8 +159,7 @@ class TestPolicyEnforcer(common.HeatTestCase):
|
||||||
self.assertFalse(enforcer.enforce(ctx, action))
|
self.assertFalse(enforcer.enforce(ctx, action))
|
||||||
|
|
||||||
def test_check_admin(self):
|
def test_check_admin(self):
|
||||||
enforcer = policy.Enforcer(
|
enforcer = policy.Enforcer()
|
||||||
policy_file=self.get_policy_file('check_admin.json'))
|
|
||||||
|
|
||||||
ctx = utils.dummy_context(roles=[])
|
ctx = utils.dummy_context(roles=[])
|
||||||
self.assertFalse(enforcer.check_is_admin(ctx))
|
self.assertFalse(enforcer.check_is_admin(ctx))
|
||||||
|
@ -174,11 +173,6 @@ class TestPolicyEnforcer(common.HeatTestCase):
|
||||||
def test_enforce_creds(self):
|
def test_enforce_creds(self):
|
||||||
enforcer = policy.Enforcer()
|
enforcer = policy.Enforcer()
|
||||||
ctx = utils.dummy_context(roles=['admin'])
|
ctx = utils.dummy_context(roles=['admin'])
|
||||||
self.m.StubOutWithMock(base_policy.Enforcer, 'enforce')
|
|
||||||
base_policy.Enforcer.enforce('context_is_admin', {},
|
|
||||||
ctx.to_policy_values(),
|
|
||||||
False, exc=None).AndReturn(True)
|
|
||||||
self.m.ReplayAll()
|
|
||||||
self.assertTrue(enforcer.check_is_admin(ctx))
|
self.assertTrue(enforcer.check_is_admin(ctx))
|
||||||
|
|
||||||
def test_resource_default_rule(self):
|
def test_resource_default_rule(self):
|
||||||
|
|
Loading…
Reference in New Issue