Add a ton of policy checks

In some cases there isn't a perfect relationship between
UI widgets and API endpoints but this should be pretty close.

Story: 2008897
Task: 42463
Change-Id: I8966035fe8e754bf31367535b08dc46856f5afac
This commit is contained in:
Andrew Bogott
2021-05-04 21:06:13 -05:00
committed by Lingxian Kong
parent 055a1a819f
commit 083bf79107
7 changed files with 62 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
---
features:
- |
Dashboard features now check the 'databases' policy file. If the
corresponding API is not available to the current user, this UI element
will not display or will appear disabled.

View File

@@ -26,9 +26,12 @@ class CreateBackupStrategy(tables.LinkAction):
url = "horizon:project:backup_strategies:create"
classes = ("ajax-modal", "btn-create")
icon = "camera"
policy_rules = (("database", "backup_strategy:create"), )
class DeleteBackupStrategy(tables.DeleteAction):
policy_rules = (("database", "backup_strategy:delete"), )
@staticmethod
def action_present(count):
return ngettext_lazy(

View File

@@ -58,6 +58,7 @@ class LaunchLink(tables.LinkAction):
url = "horizon:project:database_backups:create"
classes = ("ajax-modal", "btn-create")
icon = "camera"
policy_rules = (("database", "backup:create"), )
class RestoreLink(tables.LinkAction):
@@ -66,6 +67,7 @@ class RestoreLink(tables.LinkAction):
url = "horizon:project:databases:launch"
classes = ("ajax-modal",)
icon = "cloud-upload"
policy_rules = (("database", "backup:show"), )
def allowed(self, request, backup=None):
return backup.status in ['COMPLETED', 'RESTORED']
@@ -80,6 +82,7 @@ class DownloadBackup(tables.LinkAction):
verbose_name = _("Download Backup")
url = 'horizon:project:containers:object_download'
classes = ("btn-download",)
policy_rules = (("database", "backup:show"), )
def get_link_url(self, datum):
ref = datum.locationRef.split('/')
@@ -99,6 +102,8 @@ class DownloadBackup(tables.LinkAction):
class DeleteBackup(tables.DeleteAction):
policy_rules = (("database", "backup:delete"), )
@staticmethod
def action_present(count):
return ngettext_lazy(

View File

@@ -42,6 +42,7 @@ class DeleteCluster(tables.BatchAction):
icon = "remove"
classes = ('btn-danger',)
help_text = _("Deleted cluster is not recoverable.")
policy_rules = (("database", "cluster:delete"), )
@staticmethod
def action_present(count):
@@ -69,12 +70,14 @@ class LaunchLink(tables.LinkAction):
url = "horizon:project:database_clusters:launch"
classes = ("btn-launch", "ajax-modal")
icon = "cloud-upload"
policy_rules = (("database", "cluster:create"), )
class ClusterGrow(tables.LinkAction):
name = "cluster_grow"
verbose_name = _("Grow Cluster")
url = "horizon:project:database_clusters:cluster_grow_details"
policy_rules = (("database", "cluster:action"), )
def allowed(self, request, cluster=None):
if (cluster and cluster.task["name"] == 'NONE' and
@@ -87,6 +90,7 @@ class ClusterShrink(tables.LinkAction):
name = "cluster_shrink"
verbose_name = _("Shrink Cluster")
url = "horizon:project:database_clusters:cluster_shrink_details"
policy_rules = (("database", "cluster:action"), )
def allowed(self, request, cluster=None):
if (cluster and cluster.task["name"] == 'NONE' and
@@ -100,6 +104,7 @@ class ResetPassword(tables.LinkAction):
verbose_name = _("Reset Root Password")
url = "horizon:project:database_clusters:reset_password"
classes = ("ajax-modal",)
policy_rules = (("database", "cluster:action"), )
def allowed(self, request, cluster=None):
if (cluster and cluster.task["name"] == 'NONE' and
@@ -241,6 +246,7 @@ class ClusterShrinkAction(tables.BatchAction):
classes = ('btn-danger',)
success_url = 'horizon:project:database_clusters:index'
help_text = _("Shrinking a cluster is not recoverable.")
policy_rules = (("database", "cluster:delete"), )
@staticmethod
def action_present(count):
@@ -305,6 +311,7 @@ class ClusterGrowAddInstance(tables.LinkAction):
verbose_name = _("Add Instance")
url = "horizon:project:database_clusters:add_instance"
classes = ("ajax-modal",)
policy_rules = (("database", "cluster:action"), )
def get_link_url(self):
return urls.reverse(
@@ -313,6 +320,7 @@ class ClusterGrowAddInstance(tables.LinkAction):
class ClusterGrowRemoveInstance(tables.BatchAction):
name = "cluster_grow_remove_instance"
policy_rules = (("database", "cluster:action"), )
@staticmethod
def action_present(count):
@@ -387,6 +395,7 @@ class ClusterGrowAction(tables.Action):
verbose_name_plural = _("Grow Cluster")
requires_input = False
icon = "plus"
policy_rules = (("database", "cluster:action"), )
def handle(self, table, request, obj_ids):
if not table.data:

View File

@@ -33,11 +33,13 @@ class CreateConfiguration(tables.LinkAction):
url = "horizon:project:database_configurations:create"
classes = ('ajax-modal', )
icon = "plus"
policy_rules = (("database", "configuration:create"),)
class DeleteConfiguration(tables.DeleteAction):
data_type_singular = _("Configuration Group")
data_type_plural = _("Configuration Groups")
policy_rules = (("database", "configuration:delete"),)
@staticmethod
def action_present(count):
@@ -87,6 +89,7 @@ class AddParameter(tables.LinkAction):
url = "horizon:project:database_configurations:add"
classes = ('ajax-modal', )
icon = "plus"
policy_rules = (("database", "configuration:edit"),)
def get_link_url(self, datum=None):
configuration_id = self.table.kwargs['configuration_id']
@@ -98,6 +101,7 @@ class ApplyChanges(tables.Action):
verbose_name = _("Apply Changes")
verbose_name_plural = _("Apply Changes")
icon = "pencil"
policy_rules = (("database", "configuration:edit"),)
def __init__(self, **kwargs):
super(ApplyChanges, self).__init__(**kwargs)

View File

@@ -39,6 +39,7 @@ class PublishLog(tables.BatchAction):
)
name = "publish_log"
policy_rules = (("database", "instance:guest_log_list"),)
def action(self, request, obj_id):
instance_id = self.table.kwargs['instance_id']
@@ -63,6 +64,7 @@ class DiscardLog(tables.BatchAction):
)
name = "discard_log"
policy_rules = (("database", "instance:guest_log_list"),)
def action(self, request, obj_id):
instance_id = self.table.kwargs['instance_id']
@@ -87,6 +89,7 @@ class EnableLog(tables.BatchAction):
)
name = "enable_log"
policy_rules = (("database", "instance:guest_log_list"),)
def action(self, request, obj_id):
instance_id = self.table.kwargs['instance_id']
@@ -111,6 +114,7 @@ class DisableLog(tables.BatchAction):
)
name = "disable_log"
policy_rules = (("database", "instance:guest_log_list"),)
def action(self, request, obj_id):
instance_id = self.table.kwargs['instance_id']
@@ -126,6 +130,7 @@ class ViewLog(tables.LinkAction):
name = "view_log"
verbose_name = _("View Log")
url = "horizon:project:databases:logs:log_contents"
policy_rules = (("database", "instance:guest_log_list"),)
def get_link_url(self, datum):
instance_id = self.table.kwargs['instance_id']

View File

@@ -42,6 +42,7 @@ ACTIVE_STATES = ("ACTIVE", "HEALTHY",)
class DeleteInstance(tables.DeleteAction):
help_text = _("Deleted instances are not recoverable.")
policy_rules = (("database", "instance:delete"),)
@staticmethod
def action_present(count):
@@ -66,6 +67,7 @@ class DeleteInstance(tables.DeleteAction):
class RestartInstance(tables.BatchAction):
help_text = _("Restarted instances will lose any data not"
" saved in persistent storage.")
policy_rules = (("database", "instance:restart"),)
@staticmethod
def action_present(count):
@@ -103,6 +105,7 @@ class DetachReplica(tables.BatchAction):
u"Detach Replicas",
count
)
policy_rules = (("database", "instance:eject_replica_source"),)
@staticmethod
def action_past(count):
@@ -128,6 +131,7 @@ class PromoteToReplicaSource(tables.LinkAction):
verbose_name = _("Promote to Replica Source")
url = "horizon:project:databases:promote_to_replica_source"
classes = ("ajax-modal", "btn-promote-to-replica-source")
policy_rules = (("database", "instance:promote_to_replica_source"),)
def allowed(self, request, instance=None):
return (instance.status in ACTIVE_STATES and
@@ -157,6 +161,7 @@ class EjectReplicaSource(tables.BatchAction):
name = "eject_replica_source"
classes = ('btn-danger', 'btn-eject-replica-source')
policy_rules = (("database", "instance:eject_replica_source"),)
def _allowed(self, request, instance=None):
return (instance.status != 'PROMOTE' and
@@ -185,6 +190,7 @@ class GrantAccess(tables.BatchAction):
name = "grant_access"
classes = ('btn-grant-access')
policy_rules = (("database", "instance:extension:user_access:update"),)
def allowed(self, request, instance=None):
if instance:
@@ -219,6 +225,7 @@ class RevokeAccess(tables.BatchAction):
name = "revoke_access"
classes = ('btn-revoke-access')
policy_rules = (("database", "instance:extension:user_access:delete"),)
def allowed(self, request, instance=None):
if instance:
@@ -246,6 +253,7 @@ def parse_host_param(request):
class AccessTable(tables.DataTable):
dbname = tables.Column("name", verbose_name=_("Name"))
access = tables.Column(
"access",
verbose_name=_("Accessible"),
@@ -265,6 +273,7 @@ class ManageAccess(tables.LinkAction):
verbose_name = _("Manage Access")
url = "horizon:project:databases:access_detail"
icon = "pencil"
policy_rules = (("database", "instance:extension:user_access:update"),)
def allowed(self, request, instance=None):
instance = self.table.kwargs['instance']
@@ -284,6 +293,7 @@ class CreateUser(tables.LinkAction):
url = "horizon:project:databases:create_user"
classes = ("ajax-modal",)
icon = "plus"
policy_rules = (("database", "instance:extension:user:create"),)
def allowed(self, request, instance=None):
instance = self.table.kwargs['instance']
@@ -301,6 +311,7 @@ class EditUser(tables.LinkAction):
url = "horizon:project:databases:edit_user"
classes = ("ajax-modal",)
icon = "pencil"
policy_rules = (("database", "instance:extension:user:update"),)
def allowed(self, request, instance=None):
instance = self.table.kwargs['instance']
@@ -322,6 +333,8 @@ def has_user_add_perm(request):
class DeleteUser(tables.DeleteAction):
policy_rules = (("database", "instance:extension:user:delete"),)
@staticmethod
def action_present(count):
return ngettext_lazy(
@@ -350,6 +363,7 @@ class CreateDatabase(tables.LinkAction):
url = "horizon:project:databases:create_database"
classes = ("ajax-modal",)
icon = "plus"
policy_rules = (("database", "instance:extension:database:create"),)
def allowed(self, request, database=None):
instance = self.table.kwargs['instance']
@@ -369,6 +383,8 @@ def has_database_add_perm(request):
class DeleteDatabase(tables.DeleteAction):
policy_rules = (("database", "instance:extension:database:delete"),)
@staticmethod
def action_present(count):
return ngettext_lazy(
@@ -400,6 +416,7 @@ class LaunchLink(tables.LinkAction):
url = "horizon:project:databases:launch"
classes = ("ajax-modal", "btn-launch")
icon = "cloud-upload"
policy_rules = (("database", "instance:create"),)
class CreateBackup(tables.LinkAction):
@@ -408,6 +425,7 @@ class CreateBackup(tables.LinkAction):
url = "horizon:project:database_backups:create"
classes = ("ajax-modal",)
icon = "camera"
policy_rules = (("database", "backup:create"),)
def allowed(self, request, instance=None):
return (instance.status in ACTIVE_STATES and
@@ -423,6 +441,7 @@ class ResizeVolume(tables.LinkAction):
verbose_name = _("Resize Volume")
url = "horizon:project:databases:resize_volume"
classes = ("ajax-modal", "btn-resize")
policy_rules = (("database", "instance:resize_volume"),)
def allowed(self, request, instance=None):
return instance.status in ACTIVE_STATES
@@ -437,6 +456,7 @@ class ResizeInstance(tables.LinkAction):
verbose_name = _("Resize Instance")
url = "horizon:project:databases:resize_instance"
classes = ("ajax-modal", "btn-resize")
policy_rules = (("database", "instance:resize_flavor"),)
def allowed(self, request, instance=None):
return ((instance.status in ACTIVE_STATES or
@@ -452,6 +472,7 @@ class AttachConfiguration(tables.LinkAction):
verbose_name = _("Attach Configuration Group")
url = "horizon:project:databases:attach_config"
classes = ("btn-attach-config", "ajax-modal")
policy_rules = (("database", "instance:update"),)
def allowed(self, request, instance=None):
return (instance.status in ACTIVE_STATES and
@@ -477,6 +498,7 @@ class DetachConfiguration(tables.BatchAction):
name = "detach_configuration"
classes = ('btn-danger', 'btn-detach-config')
policy_rules = (("database", "instance:update"),)
def allowed(self, request, instance=None):
return (instance.status in ACTIVE_STATES and
@@ -489,6 +511,7 @@ class DetachConfiguration(tables.BatchAction):
class EnableRootAction(tables.Action):
name = "enable_root_action"
verbose_name = _("Enable Root")
policy_rules = (("database", "instance:extension:root:create"),)
def handle(self, table, request, obj_ids):
try:
@@ -502,6 +525,7 @@ class EnableRootAction(tables.Action):
class DisableRootAction(tables.Action):
name = "disable_root_action"
verbose_name = _("Disable Root")
policy_rules = (("database", "instance:extension:root:delete"),)
def allowed(self, request, instance):
enabled = api.trove.root_show(request, instance.id)
@@ -521,6 +545,9 @@ class ManageRoot(tables.LinkAction):
name = "manage_root_action"
verbose_name = _("Manage Root Access")
url = "horizon:project:databases:manage_root"
policy_rules = (("database", "instance:extension:root:index"),
("database", "instance:extension:root:create"),
("database", "instance:extension:root:delete"))
def allowed(self, request, instance):
return instance.status in ACTIVE_STATES
@@ -532,6 +559,7 @@ class ManageRoot(tables.LinkAction):
class ManageRootTable(tables.DataTable):
name = tables.Column('name', verbose_name=_('Instance Name'))
policy_rules = (("database", "instance:extension:root:index"), )
enabled = tables.Column('enabled',
verbose_name=_('Has Root Ever Been Enabled'),
filters=(d_filters.yesno, d_filters.capfirst),
@@ -659,6 +687,7 @@ class StopDatabase(tables.BatchAction):
name = "stop_database"
help_text = _("Stop database service inside an instance.")
action_type = "danger"
policy_rules = (("database", "instance:extension:database:delete"), )
@staticmethod
def action_present(count):
@@ -688,6 +717,7 @@ class UpdateInstance(tables.LinkAction):
verbose_name = _("Update Instance")
url = "horizon:project:databases:edit_instance"
classes = ("btn-attach-config", "ajax-modal")
policy_rules = (("database", "instance:update"), )
def allowed(self, request, instance=None):
return (instance.status in ACTIVE_STATES)