Browse Source

[policy in code] part 4

Add service rule, resource rules, actions rules, build_info rules,
events rules.
Partially-Implements: bp policy-in-code

Change-Id: I497f4d02b5ea8399265dedc548214e4eca6b6a35
changes/75/510075/7
ricolin 5 years ago
parent
commit
51e4f04693
  1. 14
      etc/heat/policy.json
  2. 5
      heat/api/openstack/v1/actions.py
  3. 5
      heat/api/openstack/v1/build_info.py
  4. 7
      heat/api/openstack/v1/events.py
  5. 13
      heat/api/openstack/v1/resources.py
  6. 5
      heat/api/openstack/v1/services.py
  7. 12
      heat/policies/__init__.py
  8. 37
      heat/policies/actions.py
  9. 35
      heat/policies/build_info.py
  10. 48
      heat/policies/events.py
  11. 84
      heat/policies/resource.py
  12. 27
      heat/policies/service.py

14
etc/heat/policy.json

@ -25,16 +25,6 @@
"cloudwatch:PutMetricData": "",
"cloudwatch:SetAlarmState": "rule:deny_stack_user",
"actions:action": "rule:deny_stack_user",
"build_info:build_info": "rule:deny_stack_user",
"events:index": "rule:deny_stack_user",
"events:show": "rule:deny_stack_user",
"resource:index": "rule:deny_stack_user",
"resource:metadata": "",
"resource:signal": "",
"resource:mark_unhealthy": "rule:deny_stack_user",
"resource:show": "rule:deny_stack_user",
"software_configs:global_index": "rule:deny_everybody",
"software_configs:index": "rule:deny_stack_user",
"software_configs:create": "rule:deny_stack_user",
@ -45,7 +35,5 @@
"software_deployments:show": "rule:deny_stack_user",
"software_deployments:update": "rule:deny_stack_user",
"software_deployments:delete": "rule:deny_stack_user",
"software_deployments:metadata": "",
"service:index": "rule:context_is_admin"
"software_deployments:metadata": ""
}

5
heat/api/openstack/v1/actions.py

@ -26,7 +26,8 @@ class ActionController(object):
Implements the API for stack 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 = 'actions'
ACTIONS = (
@ -41,7 +42,7 @@ class ActionController(object):
self.options = options
self.rpc_client = rpc_client.EngineClient()
@util.identified_stack
@util.registered_identified_stack
def action(self, req, identity, body=None):
"""Performs a specified action on a stack.

5
heat/api/openstack/v1/build_info.py

@ -24,14 +24,15 @@ class BuildInfoController(object):
Returns build information for current app.
"""
# 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 = 'build_info'
def __init__(self, options):
self.options = options
self.rpc_client = rpc_client.EngineClient()
@util.policy_enforce
@util.registered_policy_enforce
def build_info(self, req):
engine_revision = self.rpc_client.get_revision(req.context)
build_info = {

7
heat/api/openstack/v1/events.py

@ -84,7 +84,8 @@ class EventController(object):
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 = 'events'
def __init__(self, options):
@ -106,7 +107,7 @@ class EventController(object):
return [format_event(req, e, keys) for e in events]
@util.identified_stack
@util.registered_identified_stack
def index(self, req, identity, resource_name=None):
"""Lists summary information for all events."""
whitelist = {
@ -149,7 +150,7 @@ class EventController(object):
return {'events': events}
@util.identified_stack
@util.registered_identified_stack
def show(self, req, identity, resource_name, event_id):
"""Gets detailed information for an event."""

13
heat/api/openstack/v1/resources.py

@ -75,7 +75,8 @@ class ResourceController(object):
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 = 'resource'
def __init__(self, options):
@ -92,7 +93,7 @@ class ResourceController(object):
else:
return default
@util.identified_stack
@util.registered_identified_stack
def index(self, req, identity):
"""Lists information for all resources."""
@ -131,7 +132,7 @@ class ResourceController(object):
return {'resources': [format_resource(req, res) for res in res_list]}
@util.identified_stack
@util.registered_identified_stack
def show(self, req, identity, resource_name):
"""Gets detailed information for a resource."""
@ -146,7 +147,7 @@ class ResourceController(object):
return {'resource': format_resource(req, res)}
@util.identified_stack
@util.registered_identified_stack
def metadata(self, req, identity, resource_name):
"""Gets metadata information for a resource."""
@ -156,14 +157,14 @@ class ResourceController(object):
return {rpc_api.RES_METADATA: res[rpc_api.RES_METADATA]}
@util.identified_stack
@util.registered_identified_stack
def signal(self, req, identity, resource_name, body=None):
self.rpc_client.resource_signal(req.context,
stack_identity=identity,
resource_name=resource_name,
details=body)
@util.identified_stack
@util.registered_identified_stack
def mark_unhealthy(self, req, identity, resource_name, body):
"""Mark a resource as healthy or unhealthy."""
data = dict()

5
heat/api/openstack/v1/services.py

@ -25,14 +25,15 @@ from heat.rpc import client as rpc_client
class ServiceController(object):
"""WSGI controller for reporting the heat engine status in Heat v1 API."""
# 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 = 'service'
def __init__(self, options):
self.options = options
self.rpc_client = rpc_client.EngineClient()
@util.policy_enforce
@util.registered_policy_enforce
def index(self, req):
try:
services = self.rpc_client.list_services(req.context)

12
heat/policies/__init__.py

@ -13,14 +13,24 @@
import itertools
from heat.policies import actions
from heat.policies import base
from heat.policies import build_info
from heat.policies import events
from heat.policies import resource
from heat.policies import resource_types
from heat.policies import service
from heat.policies import stacks
def list_rules():
return itertools.chain(
base.list_rules(),
stacks.list_rules(),
actions.list_rules(),
build_info.list_rules(),
events.list_rules(),
resource.list_rules(),
resource_types.list_rules(),
service.list_rules(),
stacks.list_rules(),
)

37
heat/policies/actions.py

@ -0,0 +1,37 @@
# 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 = 'actions:%s'
actions_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'action',
check_str=base.RULE_DENY_STACK_USER,
description='Performs non-lifecycle operations on the stack '
'(Snapshot, Resume, Cancel update, or check stack resources).',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'actions',
'method': 'POST'
}
]
)
]
def list_rules():
return actions_policies

35
heat/policies/build_info.py

@ -0,0 +1,35 @@
# 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 = 'build_info:%s'
build_info_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'build_info',
check_str=base.RULE_DENY_STACK_USER,
description='Show build information.',
operations=[
{
'path': '/v1/{tenant_id}/build_info',
'method': 'GET'
}
]
)
]
def list_rules():
return build_info_policies

48
heat/policies/events.py

@ -0,0 +1,48 @@
# 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 = 'events:%s'
events_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.RULE_DENY_STACK_USER,
description='List events.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'events',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.RULE_DENY_STACK_USER,
description='Show event.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'resources/{resource_name}/events/{event_id}',
'method': 'GET'
}
]
)
]
def list_rules():
return events_policies

84
heat/policies/resource.py

@ -0,0 +1,84 @@
# 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 = 'resource:%s'
resource_policies = [
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.RULE_DENY_STACK_USER,
description='List resources.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'resources',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'metadata',
check_str=base.RULE_ALLOW_EVERYBODY,
description='Show resource metadata.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'resources/{resource_name}/metadata',
'method': 'GET'
}
]
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'signal',
check_str=base.RULE_ALLOW_EVERYBODY,
description='Signal resource.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'resources/{resource_name}/signal',
'method': 'POST'
}
]
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'mark_unhealthy',
check_str=base.RULE_DENY_STACK_USER,
description='Mark resource as unhealthy.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'resources/{resource_name_or_physical_id}',
'method': 'PATCH'
}
]
),
policy.DocumentedRuleDefault(
name=POLICY_ROOT % 'show',
check_str=base.RULE_DENY_STACK_USER,
description='Show resource.',
operations=[
{
'path': '/v1/{tenant_id}/stacks/{stack_name}/{stack_id}/'
'resources/{resource_name}',
'method': 'GET'
}
]
)
]
def list_rules():
return resource_policies

27
heat/policies/service.py

@ -0,0 +1,27 @@
# 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 = 'service:%s'
service_policies = [
policy.RuleDefault(
name=POLICY_ROOT % 'index',
check_str=base.RULE_CONTEXT_IS_ADMIN)
]
def list_rules():
return service_policies
Loading…
Cancel
Save