adding policy checks for nova instance actions
Adding policy rule checks for all Nova instance actions (on both the project and admin dashboards). Change-Id: Ibf419ecf6624cf3315ddb10daee0542f7d8d2c3e Implements: blueprint compute-rbac
This commit is contained in:
parent
6a52b59c29
commit
4d8c573b1d
@ -9,11 +9,22 @@
|
||||
"compute:create:attach_network": "",
|
||||
"compute:create:attach_volume": "",
|
||||
"compute:create:forced_host": "is_admin:True",
|
||||
"compute:delete": "rule:default",
|
||||
"compute:get_all": "",
|
||||
"compute:get_all_tenants": "",
|
||||
"compute:reboot": "rule:default",
|
||||
"compute:rebuild": "rule:default",
|
||||
"compute:snapshot": "rule:default",
|
||||
"compute:start": "rule:default",
|
||||
"compute:stop": "rule:default",
|
||||
"compute:unlock_override": "rule:admin_api",
|
||||
"compute:attach_volume" : "rule:default",
|
||||
"compute:detach_volume" : "rule:default",
|
||||
"compute:update": "rule:default",
|
||||
|
||||
"compute:resize": "rule:default",
|
||||
"compute:confirm_resize": "rule:default",
|
||||
"compute:revert_resize": "rule:default",
|
||||
|
||||
"compute:shelve": "",
|
||||
"compute:shelve_offload": "",
|
||||
|
@ -37,6 +37,13 @@ class MigrateInstance(tables.BatchAction):
|
||||
data_type_singular = _("Instance")
|
||||
data_type_plural = _("Instances")
|
||||
classes = ("btn-migrate", "btn-danger")
|
||||
policy_rules = (("compute", "compute_extension:admin_actions:migrate"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return ((instance.status in project_tables.ACTIVE_STATES
|
||||
@ -52,6 +59,14 @@ class LiveMigrateInstance(tables.LinkAction):
|
||||
verbose_name = _("Live Migrate Instance")
|
||||
url = "horizon:admin:instances:live_migrate"
|
||||
classes = ("ajax-modal", "btn-migrate", "btn-danger")
|
||||
policy_rules = (
|
||||
("compute", "compute_extension:admin_actions:migrateLive"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return ((instance.status in project_tables.ACTIVE_STATES)
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
from django.conf import settings # noqa
|
||||
from django.core import urlresolvers
|
||||
from django import shortcuts
|
||||
from django import template
|
||||
@ -77,6 +78,13 @@ class TerminateInstance(tables.BatchAction):
|
||||
data_type_singular = _("Instance")
|
||||
data_type_plural = _("Instances")
|
||||
classes = ('btn-danger', 'btn-terminate')
|
||||
policy_rules = (("compute", "compute:delete"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance=None):
|
||||
return True
|
||||
@ -92,6 +100,13 @@ class RebootInstance(tables.BatchAction):
|
||||
data_type_singular = _("Instance")
|
||||
data_type_plural = _("Instances")
|
||||
classes = ('btn-danger', 'btn-reboot')
|
||||
policy_rules = (("compute", "compute:reboot"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance=None):
|
||||
if instance is not None:
|
||||
@ -132,9 +147,19 @@ class TogglePause(tables.BatchAction):
|
||||
self.paused = instance.status == "PAUSED"
|
||||
if self.paused:
|
||||
self.current_present_action = UNPAUSE
|
||||
policy = (("compute", "compute_extension:admin_actions:unpause"),)
|
||||
else:
|
||||
self.current_present_action = PAUSE
|
||||
return ((instance.status in ACTIVE_STATES or self.paused)
|
||||
policy = (("compute", "compute_extension:admin_actions:pause"),)
|
||||
|
||||
has_permission = True
|
||||
policy_check = getattr(settings, "POLICY_CHECK_FUNCTION", None)
|
||||
if policy_check:
|
||||
has_permission = policy_check(policy, request,
|
||||
target={'project_id': getattr(instance, 'tenant_id', None)})
|
||||
|
||||
return (has_permission
|
||||
and (instance.status in ACTIVE_STATES or self.paused)
|
||||
and not is_deleting(instance))
|
||||
|
||||
def action(self, request, obj_id):
|
||||
@ -164,9 +189,19 @@ class ToggleSuspend(tables.BatchAction):
|
||||
self.suspended = instance.status == "SUSPENDED"
|
||||
if self.suspended:
|
||||
self.current_present_action = RESUME
|
||||
policy = (("compute", "compute_extension:admin_actions:resume"),)
|
||||
else:
|
||||
self.current_present_action = SUSPEND
|
||||
return ((instance.status in ACTIVE_STATES or self.suspended)
|
||||
policy = (("compute", "compute_extension:admin_actions:suspend"),)
|
||||
|
||||
has_permission = True
|
||||
policy_check = getattr(settings, "POLICY_CHECK_FUNCTION", None)
|
||||
if policy_check:
|
||||
has_permission = policy_check(policy, request,
|
||||
target={'project_id': getattr(instance, 'tenant_id', None)})
|
||||
|
||||
return (has_permission
|
||||
and (instance.status in ACTIVE_STATES or self.suspended)
|
||||
and not is_deleting(instance))
|
||||
|
||||
def action(self, request, obj_id):
|
||||
@ -183,6 +218,7 @@ class LaunchLink(tables.LinkAction):
|
||||
verbose_name = _("Launch Instance")
|
||||
url = "horizon:project:instances:launch"
|
||||
classes = ("btn-launch", "ajax-modal")
|
||||
policy_rules = (("compute", "compute:create"),)
|
||||
|
||||
def allowed(self, request, datum):
|
||||
try:
|
||||
@ -217,6 +253,13 @@ class EditInstance(tables.LinkAction):
|
||||
verbose_name = _("Edit Instance")
|
||||
url = "horizon:project:instances:update"
|
||||
classes = ("ajax-modal", "btn-edit")
|
||||
policy_rules = (("compute", "compute:update"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def get_link_url(self, project):
|
||||
return self._get_link_url(project, 'instance_info')
|
||||
@ -248,6 +291,13 @@ class CreateSnapshot(tables.LinkAction):
|
||||
verbose_name = _("Create Snapshot")
|
||||
url = "horizon:project:images_and_snapshots:snapshots:create"
|
||||
classes = ("ajax-modal", "btn-camera")
|
||||
policy_rules = (("compute", "compute:snapshot"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance=None):
|
||||
return instance.status in SNAPSHOT_READY_STATES \
|
||||
@ -259,6 +309,13 @@ class ConsoleLink(tables.LinkAction):
|
||||
verbose_name = _("Console")
|
||||
url = "horizon:project:instances:detail"
|
||||
classes = ("btn-console",)
|
||||
policy_rules = (("compute", "compute_extension:consoles"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance=None):
|
||||
return instance.status in ACTIVE_STATES and not is_deleting(instance)
|
||||
@ -275,6 +332,13 @@ class LogLink(tables.LinkAction):
|
||||
verbose_name = _("View Log")
|
||||
url = "horizon:project:instances:detail"
|
||||
classes = ("btn-log",)
|
||||
policy_rules = (("compute", "compute_extension:console_output"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance=None):
|
||||
return instance.status in ACTIVE_STATES and not is_deleting(instance)
|
||||
@ -291,6 +355,13 @@ class ResizeLink(tables.LinkAction):
|
||||
verbose_name = _("Resize Instance")
|
||||
url = "horizon:project:instances:resize"
|
||||
classes = ("ajax-modal", "btn-resize")
|
||||
policy_rules = (("compute", "compute:resize"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def get_link_url(self, project):
|
||||
return self._get_link_url(project, 'flavor_choice')
|
||||
@ -310,6 +381,13 @@ class ConfirmResize(tables.Action):
|
||||
name = "confirm"
|
||||
verbose_name = _("Confirm Resize/Migrate")
|
||||
classes = ("btn-confirm", "btn-action-required")
|
||||
policy_rules = (("compute", "compute:confirm_resize"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return instance.status == 'VERIFY_RESIZE'
|
||||
@ -322,6 +400,13 @@ class RevertResize(tables.Action):
|
||||
name = "revert"
|
||||
verbose_name = _("Revert Resize/Migrate")
|
||||
classes = ("btn-revert", "btn-action-required")
|
||||
policy_rules = (("compute", "compute:revert_resize"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return instance.status == 'VERIFY_RESIZE'
|
||||
@ -335,6 +420,13 @@ class RebuildInstance(tables.LinkAction):
|
||||
verbose_name = _("Rebuild Instance")
|
||||
classes = ("btn-rebuild", "ajax-modal")
|
||||
url = "horizon:project:instances:rebuild"
|
||||
policy_rules = (("compute", "compute:rebuild"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return ((instance.status in ACTIVE_STATES
|
||||
@ -351,6 +443,13 @@ class AssociateIP(tables.LinkAction):
|
||||
verbose_name = _("Associate Floating IP")
|
||||
url = "horizon:project:access_and_security:floating_ips:associate"
|
||||
classes = ("ajax-modal", "btn-associate")
|
||||
policy_rules = (("compute", "network:associate_floating_ip"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
if api.network.floating_ip_simple_associate_supported(request):
|
||||
@ -370,6 +469,13 @@ class SimpleAssociateIP(tables.Action):
|
||||
name = "associate-simple"
|
||||
verbose_name = _("Associate Floating IP")
|
||||
classes = ("btn-associate-simple",)
|
||||
policy_rules = (("compute", "network:associate_floating_ip"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
if not api.network.floating_ip_simple_associate_supported(request):
|
||||
@ -398,6 +504,13 @@ class SimpleDisassociateIP(tables.Action):
|
||||
name = "disassociate"
|
||||
verbose_name = _("Disassociate Floating IP")
|
||||
classes = ("btn-danger", "btn-disassociate",)
|
||||
policy_rules = (("compute", "network:disassociate_floating_ip"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
if not conf.HORIZON_CONFIG["simple_ip_management"]:
|
||||
@ -472,6 +585,13 @@ class StartInstance(tables.BatchAction):
|
||||
action_past = _("Started")
|
||||
data_type_singular = _("Instance")
|
||||
data_type_plural = _("Instances")
|
||||
policy_rules = (("compute", "compute:start"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return instance.status in ("SHUTDOWN", "SHUTOFF", "CRASHED")
|
||||
@ -487,6 +607,13 @@ class StopInstance(tables.BatchAction):
|
||||
data_type_singular = _("Instance")
|
||||
data_type_plural = _("Instances")
|
||||
classes = ('btn-danger',)
|
||||
policy_rules = (("compute", "compute:stop"),)
|
||||
|
||||
def get_policy_target(self, request, datum=None):
|
||||
project_id = None
|
||||
if datum:
|
||||
project_id = getattr(datum, 'tenant_id', None)
|
||||
return {"project_id": project_id}
|
||||
|
||||
def allowed(self, request, instance):
|
||||
return ((get_power_state(instance)
|
||||
|
Loading…
Reference in New Issue
Block a user