New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Alerting: Handle custom dashboard permissions in migration service #74504
Conversation
3f90c83
to
72d25b2
Compare
84509f2
to
ba3d80f
Compare
72d25b2
to
8a91edd
Compare
Updated main and rebased |
8a91edd
to
4a4eb61
Compare
93473b8
to
3b23991
Compare
057bf9e
to
dbc6381
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
PanelID: &da.PanelID, | ||
RuleGroup: name, | ||
RuleGroup: fmt.Sprintf("%s - %d", info.DashboardName, da.PanelID), // Unique to this dash alert but still contains useful info. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is not related to this PR scope. Probably makes sense to address it in a follow-up PR because RuleGroup length is limited and we need to check that the concatenated name does not exceed it, and if it exceeds - the trimmed version is still unique.
if err != nil { | ||
return nil, err | ||
} | ||
l := log.New("dashboardTitle", dash.Title, "dashboardUID", dash.UID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make sure the context labels follow the guidelines. In this case it should be dashboardUid
. It can be addressed it later.
// Any dashboard that has greater read/write permissions for an orgRole/team/user compared to its folder will necessitate creating a new folder with the same permissions as the dashboard. | ||
func (om *OrgMigration) getOrCreateMigratedFolder(ctx context.Context, l log.Logger, dash *dashboards.Dashboard, parentFolder *folder.Folder) (*folder.Folder, error) { | ||
// If parentFolder does not exist then the dashboard is an orphan. We migrate the alert to the general alerting folder. | ||
if parentFolder == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's mention here in the comment that the "General Alerting" folder is available to only admins.
|
||
// Check if the dashboard has custom permissions. If it does, we need to create a new folder for it. | ||
// This folder will be cached for re-use for each dashboard in the folder with the same permissions. | ||
customFolders, ok := om.permissionsMap[parentFolder.ID] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think name "customFolders" is misleading here. It reflects the permissions of the parent folder and dashboards in this folder.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
3994d4e
to
e56e6e7
Compare
Dashboard alert permissions were determined by both its dashboard and folder scoped permissions, while UA alert rules only have folder scoped permissions. This means, when migrating an alert, we'll need to decide if the parent folder is a correct location for the newly created alert rule so that users, teams, and org roles have the same access to it as they did in legacy. To do this, we translate both the folder and dashboard resource permissions to two sets of SetResourcePermissionCommands. Each of these encapsulates a mapping of all: OrgRoles -> Viewer/Editor/Admin Teams -> Viewer/Editor/Admin Users -> Viewer/Editor/Admin When the dashboard permissions (including those inherited from the parent folder) differ from the parent folder permissions alone, we need to create a new folder to represent the access-level of the legacy dashboard. Compromises: When determining the SetResourcePermissionCommands we only take into account managed and basic roles. Fixed and custom roles introduce significant complexity and synchronicity hurdles. Instead, we log a warning they had the potential to override the newly created folder permissions. Also, we don't attempt to reconcile datasource permissions that were not necessary in legacy alerting. Users without access to the necessary datasources to edit an alert rule will need to obtain said access separate from the migration.
e56e6e7
to
dc6b396
Compare
/deploy-to-hg |
|
|
…74504) * Fix migration of custom dashboard permissions Dashboard alert permissions were determined by both its dashboard and folder scoped permissions, while UA alert rules only have folder scoped permissions. This means, when migrating an alert, we'll need to decide if the parent folder is a correct location for the newly created alert rule so that users, teams, and org roles have the same access to it as they did in legacy. To do this, we translate both the folder and dashboard resource permissions to two sets of SetResourcePermissionCommands. Each of these encapsulates a mapping of all: OrgRoles -> Viewer/Editor/Admin Teams -> Viewer/Editor/Admin Users -> Viewer/Editor/Admin When the dashboard permissions (including those inherited from the parent folder) differ from the parent folder permissions alone, we need to create a new folder to represent the access-level of the legacy dashboard. Compromises: When determining the SetResourcePermissionCommands we only take into account managed and basic roles. Fixed and custom roles introduce significant complexity and synchronicity hurdles. Instead, we log a warning they had the potential to override the newly created folder permissions. Also, we don't attempt to reconcile datasource permissions that were not necessary in legacy alerting. Users without access to the necessary datasources to edit an alert rule will need to obtain said access separate from the migration.
Followup to #72702 and #74503.
Summary
This PR replaces the obsolete and broken code that checks for custom dashboard ACLs for creating new folders during migration. The new code now uses the new RBAC permissions models / logic.
The main focus of this PR is the new permissions logic, however there are also other changes that were necessary or prudent to carry-out at the same time. I'll list them first before detailing the main logic.
Fixes: #71529, #67448
Other Changes
Included in this PR is a refactoring of the main migrationThis was moved to Alerting: Move legacy alert migration from sqlstore migration to service #72702Exec
method, heavily simplifying the logic. Enough changes were needed to incorporate the new permissions logic that it made sense to simplify the rest at the same time.This was moved to Alerting: Move legacy alert migration from sqlstore migration to service #72702uidSet
has been renamed and slightly reworked into a more genericdeduplicator
helper struct that is used to deduplicate both the UIDs the previous version did as well as alert rule titles.Permissions Migration
Background
In legacy alerting, dashboard alert permissions were determined by both their dashboard and folder scoped permissions. This was done by taking the greater permission defined between the two for each mapped
OrgRole
,User
, orTeam
.Now, alert rules only have folder scoped permissions. This can lead to a situation where simply migrating a legacy alert from panelA in dashboardA in folderA to a UA alert rule in folderA will cause the newly created alert rule to be viewable/editable/adminable by different users than in legacy.
To prevent this, we must make a determination of when this situation will occur, and instead migrate the legacy alert into a newly created folder that will ensure the same mapped permissions (or as close to as possible).
Logic
To determine when a migrated alert rule will have different mapped permissions, we calculate two sets of permissions:
These permissions include mappings of:
When the dashboard permissions differ from the parent folder permissions we need to create a new folder to represent the equivalent access-level of the legacy dashboard. To reduce folder clutter, we create one such new folder per set of unique permissions in a parent folder, instead of one per dashboard with differing permissions.
Permission Calculation
Permissions for a dashboard or folder are calculated using the
accesscontrol.ResourcePermission
s assigned to the resource. TheseResourcePermission
s are determined by roles with actions that are scoped to the dashboard or folder (or wildcard). For example, this can bemanaged:builtins:editor:permissions -> [folders:read, dashboards:write, ...]
ormanaged:users:1:permissions -> [...]
orfixed:dashboards:writer -> [...]
.We iterate over each of these
ResourcePermission
and map the set of actions (dashboardPermissions.MapActions
) to its equivalentdashboards.PermissionType
of eitherPERMISSION_VIEW
,PERMISSION_EDIT
, orPERMISSION_ADMIN
. When we have multiple sources of permission level for anOrgRole
,User
, orTeam
, we take the highest one.Included in the calculation are:
managed
roles (ex.managed:users:1:permissions
,managed:builtins:editor:permissions
,managed:teams:1:permissions
)basic
roles (ex.basic:admin
,basic:editor
)inherited
roles from the parent folder.Currently, we do not attempt to include
fixed
orcustom
roles in the calculation but do attempt to warn the user during migration if one of these roles had the potential to override the folder permissions. Note that these overrides would always be to increase permissions not decrease them, so the risk of giving users access to alerts they didn't have access to before is mitigated.Also, we don't attempt to reconcile any missing datasource permissions. Users without access to the necessary datasources to read/edit an alert rule will need to obtain said access separate from the migration.