policy checks for nova access/security actions

Adding policy rule checks for all Nova access and security actions.

Co-Authored-By: Lin Hua Cheng <lin-hua.cheng@hp.com>
Change-Id: I9f4e9209606999e5529e5ba068640d607b817f56
Implements: blueprint compute-rbac
This commit is contained in:
Brian DeHamer 2014-01-17 16:19:57 -08:00 committed by Lin Hua Cheng
parent 37f2426337
commit ee92fab510
4 changed files with 111 additions and 7 deletions

View File

@ -35,6 +35,7 @@ class DownloadEC2(tables.LinkAction):
verbose_name_plural = _("Download EC2 Credentials")
classes = ("btn-download",)
url = "horizon:project:access_and_security:api_access:ec2"
policy_rules = (("compute", "compute_extension:certificates"),)
class DownloadOpenRC(tables.LinkAction):

View File

@ -17,6 +17,7 @@
import logging
from django.conf import settings
from django.core import urlresolvers
from django import shortcuts
from django.utils.http import urlencode
@ -34,6 +35,8 @@ from openstack_dashboard.utils import filters
LOG = logging.getLogger(__name__)
POLICY_CHECK = getattr(settings, "POLICY_CHECK_FUNCTION", lambda p, r: True)
class AllocateIP(tables.LinkAction):
name = "allocate"
@ -55,7 +58,14 @@ class AllocateIP(tables.LinkAction):
self.verbose_name = _("Allocate IP To Project")
classes = [c for c in self.classes if c != "disabled"]
self.classes = classes
return True
if api.base.is_service_enabled(request, "network"):
policy = (("network", "create_floatingip"),)
else:
policy = (("compute", "compute_extension:floating_ips"),
("compute", "network:allocate_floating_ip"),)
return POLICY_CHECK(policy, request)
class ReleaseIPs(tables.BatchAction):
@ -66,6 +76,15 @@ class ReleaseIPs(tables.BatchAction):
data_type_plural = _("Floating IPs")
classes = ('btn-danger', 'btn-release')
def allowed(self, request, fip=None):
if api.base.is_service_enabled(request, "network"):
policy = (("network", "delete_floatingip"),)
else:
policy = (("compute", "compute_extension:floating_ips"),
("compute", "network:release_floating_ip"),)
return POLICY_CHECK(policy, request)
def action(self, request, obj_id):
api.network.tenant_floating_ip_release(request, obj_id)
@ -77,9 +96,13 @@ class AssociateIP(tables.LinkAction):
classes = ("ajax-modal", "btn-associate")
def allowed(self, request, fip):
if fip.port_id:
return False
return True
if api.base.is_service_enabled(request, "network"):
policy = (("network", "update_floatingip"),)
else:
policy = (("compute", "compute_extension:floating_ips"),
("compute", "network:associate_floating_ip"),)
return not fip.port_id and POLICY_CHECK(policy, request)
def get_link_url(self, datum):
base_url = urlresolvers.reverse(self.url)
@ -93,9 +116,13 @@ class DisassociateIP(tables.Action):
classes = ("btn-disassociate", "btn-danger")
def allowed(self, request, fip):
if fip.port_id:
return True
return False
if api.base.is_service_enabled(request, "network"):
policy = (("network", "update_floatingip"),)
else:
policy = (("compute", "compute_extension:floating_ips"),
("compute", "network:disassociate_floating_ip"),)
return fip.port_id and POLICY_CHECK(policy, request)
def single(self, table, request, obj_id):
try:

View File

@ -26,6 +26,7 @@ from openstack_dashboard.usage import quotas
class DeleteKeyPairs(tables.DeleteAction):
data_type_singular = _("Key Pair")
data_type_plural = _("Key Pairs")
policy_rules = (("compute", "compute_extension:keypairs:delete"),)
def delete(self, request, obj_id):
api.nova.keypair_delete(request, obj_id)
@ -36,6 +37,7 @@ class ImportKeyPair(tables.LinkAction):
verbose_name = _("Import Key Pair")
url = "horizon:project:access_and_security:keypairs:import"
classes = ("ajax-modal", "btn-upload")
policy_rules = (("compute", "compute_extension:keypairs:create"),)
class CreateKeyPair(tables.LinkAction):
@ -43,6 +45,7 @@ class CreateKeyPair(tables.LinkAction):
verbose_name = _("Create Key Pair")
url = "horizon:project:access_and_security:keypairs:create"
classes = ("ajax-modal", "btn-create")
policy_rules = (("compute", "compute_extension:keypairs:create"),)
def allowed(self, request, keypair=None):
usages = quotas.tenant_quota_usages(request)

View File

@ -24,11 +24,30 @@ from openstack_dashboard import api
from openstack_dashboard.utils import filters
POLICY_CHECK = getattr(settings, "POLICY_CHECK_FUNCTION",
lambda policy, request, target: True)
class DeleteGroup(tables.DeleteAction):
data_type_singular = _("Security Group")
data_type_plural = _("Security Groups")
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, security_group=None):
policy_target = self.get_policy_target(request, security_group)
if api.base.is_service_enabled(request, "network"):
policy = (("network", "delete_security_group"),)
else:
policy = (("compute", "compute_extension:security_groups"),)
if not POLICY_CHECK(policy, request, policy_target):
return False
if not security_group:
return True
return security_group.name != 'default'
@ -43,6 +62,14 @@ class CreateGroup(tables.LinkAction):
url = "horizon:project:access_and_security:security_groups:create"
classes = ("ajax-modal", "btn-create")
def allowed(self, request, security_group=None):
if api.base.is_service_enabled(request, "network"):
policy = (("network", "create_security_group"),)
else:
policy = (("compute", "compute_extension:security_groups"),)
return POLICY_CHECK(policy, request, target={})
class EditGroup(tables.LinkAction):
name = "edit"
@ -50,7 +77,22 @@ class EditGroup(tables.LinkAction):
url = "horizon:project:access_and_security:security_groups:update"
classes = ("ajax-modal", "btn-edit")
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, security_group=None):
policy_target = self.get_policy_target(request, security_group)
if api.base.is_service_enabled(request, "network"):
policy = (("network", "update_security_group"),)
else:
policy = (("compute", "compute_extension:security_groups"),)
if not POLICY_CHECK(policy, request, policy_target):
return False
if not security_group:
return True
return security_group.name != 'default'
@ -62,6 +104,21 @@ class ManageRules(tables.LinkAction):
url = "horizon:project:access_and_security:security_groups:detail"
classes = ("btn-edit")
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, security_group=None):
policy_target = self.get_policy_target(request, security_group)
if api.base.is_service_enabled(request, "network"):
policy = (("network", "get_security_group"),)
else:
policy = (("compute", "compute_extension:security_groups"),)
return POLICY_CHECK(policy, request, policy_target)
class SecurityGroupsTable(tables.DataTable):
name = tables.Column("name", verbose_name=_("Name"))
@ -83,6 +140,14 @@ class CreateRule(tables.LinkAction):
url = "horizon:project:access_and_security:security_groups:add_rule"
classes = ("ajax-modal", "btn-create")
def allowed(self, request, security_group_rule=None):
if api.base.is_service_enabled(request, "network"):
policy = (("network", "create_security_group_rule"),)
else:
policy = (("compute", "compute_extension:security_groups"),)
return POLICY_CHECK(policy, request, target={})
def get_link_url(self):
return reverse(self.url, args=[self.table.kwargs['security_group_id']])
@ -91,6 +156,14 @@ class DeleteRule(tables.DeleteAction):
data_type_singular = _("Rule")
data_type_plural = _("Rules")
def allowed(self, request, security_group_rule=None):
if api.base.is_service_enabled(request, "network"):
policy = (("network", "delete_security_group_rule"),)
else:
policy = (("compute", "compute_extension:security_groups"),)
return POLICY_CHECK(policy, request, target={})
def delete(self, request, obj_id):
api.network.security_group_rule_delete(request, obj_id)