diff --git a/openstack_dashboard/conf/heat_policy.json b/openstack_dashboard/conf/heat_policy.json new file mode 100644 index 0000000000..1a54e4a077 --- /dev/null +++ b/openstack_dashboard/conf/heat_policy.json @@ -0,0 +1,50 @@ +{ + "context_is_admin": "role:admin", + "deny_stack_user": "not role:heat_stack_user", + + "cloudformation:ListStacks": "rule:deny_stack_user", + "cloudformation:CreateStack": "rule:deny_stack_user", + "cloudformation:DescribeStacks": "rule:deny_stack_user", + "cloudformation:DeleteStack": "rule:deny_stack_user", + "cloudformation:UpdateStack": "rule:deny_stack_user", + "cloudformation:DescribeStackEvents": "rule:deny_stack_user", + "cloudformation:ValidateTemplate": "rule:deny_stack_user", + "cloudformation:GetTemplate": "rule:deny_stack_user", + "cloudformation:EstimateTemplateCost": "rule:deny_stack_user", + "cloudformation:DescribeStackResource": "", + "cloudformation:DescribeStackResources": "rule:deny_stack_user", + "cloudformation:ListStackResources": "rule:deny_stack_user", + + "cloudwatch:DeleteAlarms": "rule:deny_stack_user", + "cloudwatch:DescribeAlarmHistory": "rule:deny_stack_user", + "cloudwatch:DescribeAlarms": "rule:deny_stack_user", + "cloudwatch:DescribeAlarmsForMetric": "rule:deny_stack_user", + "cloudwatch:DisableAlarmActions": "rule:deny_stack_user", + "cloudwatch:EnableAlarmActions": "rule:deny_stack_user", + "cloudwatch:GetMetricStatistics": "rule:deny_stack_user", + "cloudwatch:ListMetrics": "rule:deny_stack_user", + "cloudwatch:PutMetricAlarm": "rule:deny_stack_user", + "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: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:generate_template": "rule:deny_stack_user", + "stacks:index": "rule:deny_stack_user", + "stacks:list_resource_types": "rule:deny_stack_user", + "stacks:lookup": "rule:deny_stack_user", + "stacks:resource_schema": "rule:deny_stack_user", + "stacks:show": "rule:deny_stack_user", + "stacks:template": "rule:deny_stack_user", + "stacks:update": "rule:deny_stack_user", + "stacks:validate_template": "rule:deny_stack_user" +} \ No newline at end of file diff --git a/openstack_dashboard/dashboards/project/stacks/tables.py b/openstack_dashboard/dashboards/project/stacks/tables.py index e5f829acd4..02da559130 100644 --- a/openstack_dashboard/dashboards/project/stacks/tables.py +++ b/openstack_dashboard/dashboards/project/stacks/tables.py @@ -33,6 +33,7 @@ class LaunchStack(tables.LinkAction): verbose_name = _("Launch Stack") url = "horizon:project:stacks:select_template" classes = ("btn-create", "ajax-modal") + policy_rules = (("orchestration", "cloudformation:CreateStack"),) class ChangeStackTemplate(tables.LinkAction): @@ -52,6 +53,7 @@ class DeleteStack(tables.BatchAction): data_type_singular = _("Stack") data_type_plural = _("Stacks") classes = ('btn-danger', 'btn-terminate') + policy_rules = (("orchestration", "cloudformation:DeleteStack"),) def action(self, request, stack_id): api.heat.stack_delete(request, stack_id) diff --git a/openstack_dashboard/dashboards/project/stacks/tabs.py b/openstack_dashboard/dashboards/project/stacks/tabs.py index c68464a365..ee3c5b3df4 100644 --- a/openstack_dashboard/dashboards/project/stacks/tabs.py +++ b/openstack_dashboard/dashboards/project/stacks/tabs.py @@ -19,6 +19,7 @@ from django.utils.translation import ugettext_lazy as _ from horizon import messages from horizon import tabs from openstack_dashboard import api +from openstack_dashboard import policy from openstack_dashboard.dashboards.project.stacks \ import api as project_api @@ -36,6 +37,12 @@ class StackTopologyTab(tabs.Tab): template_name = "project/stacks/_detail_topology.html" preload = False + def allowed(self, request): + return policy.check( + (("orchestration", "cloudformation:DescribeStacks"), + ("orchestration", "cloudformation:ListStackResources"),), + request) + def get_context_data(self, request): context = {} stack = self.tab_group.kwargs['stack'] @@ -49,6 +56,11 @@ class StackOverviewTab(tabs.Tab): slug = "overview" template_name = "project/stacks/_detail_overview.html" + def allowed(self, request): + return policy.check( + (("orchestration", "cloudformation:DescribeStacks"),), + request) + def get_context_data(self, request): return {"stack": self.tab_group.kwargs['stack']} @@ -58,6 +70,11 @@ class ResourceOverviewTab(tabs.Tab): slug = "resource_overview" template_name = "project/stacks/_resource_overview.html" + def allowed(self, request): + return policy.check( + (("orchestration", "cloudformation:DescribeStackResource"),), + request) + def get_context_data(self, request): resource = self.tab_group.kwargs['resource'] resource_url = mappings.resource_to_url(resource) @@ -73,6 +90,11 @@ class StackEventsTab(tabs.Tab): template_name = "project/stacks/_detail_events.html" preload = False + def allowed(self, request): + return policy.check( + (("orchestration", "cloudformation:DescribeStackEvents"),), + request) + def get_context_data(self, request): stack = self.tab_group.kwargs['stack'] try: @@ -93,6 +115,11 @@ class StackResourcesTab(tabs.Tab): template_name = "project/stacks/_detail_resources.html" preload = False + def allowed(self, request): + return policy.check( + (("orchestration", "cloudformation:ListStackResources"),), + request) + def get_context_data(self, request): stack = self.tab_group.kwargs['stack'] try: diff --git a/openstack_dashboard/settings.py b/openstack_dashboard/settings.py index 6392edf27b..1d305d28fd 100644 --- a/openstack_dashboard/settings.py +++ b/openstack_dashboard/settings.py @@ -206,6 +206,7 @@ POLICY_FILES = { 'compute': 'nova_policy.json', 'volume': 'cinder_policy.json', 'image': 'glance_policy.json', + 'orchestration': 'heat_policy.json', } SECRET_KEY = None