Dashboards / Folders: delete related data (permissions, stars, tags, versions, annotations) when deleting a dashboard or a folder (#28826)

* Dashboard: delete related data when deleting a dashboard or a folder

* fix migrations order

* apply PR feedback
This commit is contained in:
Agnès Toulet 2020-11-06 09:02:31 +01:00 committed by GitHub
parent 0cbf034483
commit f0421ed08e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 3 deletions

View File

@ -374,16 +374,16 @@ func deleteDashboard(cmd *models.DeleteDashboardCommand, sess *DBSession) error
"DELETE FROM dashboard_version WHERE dashboard_id = ?",
"DELETE FROM annotation WHERE dashboard_id = ?",
"DELETE FROM dashboard_provisioning WHERE dashboard_id = ?",
"DELETE FROM dashboard_acl WHERE dashboard_id = ?",
}
if dashboard.IsFolder {
deletes = append(deletes, "DELETE FROM dashboard_provisioning WHERE dashboard_id in (select id from dashboard where folder_id = ?)")
deletes = append(deletes, "DELETE FROM dashboard WHERE folder_id = ?")
dashIds := []struct {
Id int64
}{}
err := sess.SQL("select id from dashboard where folder_id = ?", dashboard.Id).Find(&dashIds)
err := sess.SQL("SELECT id FROM dashboard WHERE folder_id = ?", dashboard.Id).Find(&dashIds)
if err != nil {
return err
}
@ -393,6 +393,23 @@ func deleteDashboard(cmd *models.DeleteDashboardCommand, sess *DBSession) error
return err
}
}
if len(dashIds) > 0 {
childrenDeletes := []string{
"DELETE FROM dashboard_tag WHERE dashboard_id IN (SELECT id FROM dashboard WHERE org_id = ? AND folder_id = ?)",
"DELETE FROM star WHERE dashboard_id IN (SELECT id FROM dashboard WHERE org_id = ? AND folder_id = ?)",
"DELETE FROM dashboard_version WHERE dashboard_id IN (SELECT id FROM dashboard WHERE org_id = ? AND folder_id = ?)",
"DELETE FROM annotation WHERE dashboard_id IN (SELECT id FROM dashboard WHERE org_id = ? AND folder_id = ?)",
"DELETE FROM dashboard_provisioning WHERE dashboard_id IN (SELECT id FROM dashboard WHERE org_id = ? AND folder_id = ?)",
"DELETE FROM dashboard_acl WHERE dashboard_id IN (SELECT id FROM dashboard WHERE org_id = ? AND folder_id = ?)",
}
for _, sql := range childrenDeletes {
_, err := sess.Exec(sql, dashboard.OrgId, dashboard.Id)
if err != nil {
return err
}
}
}
}
if err := deleteAlertDefinition(dashboard.Id, sess); err != nil {
@ -401,7 +418,6 @@ func deleteDashboard(cmd *models.DeleteDashboardCommand, sess *DBSession) error
for _, sql := range deletes {
_, err := sess.Exec(sql, dashboard.Id)
if err != nil {
return err
}

View File

@ -201,6 +201,14 @@ func TestDashboardDataAccess(t *testing.T) {
So(query.Result.Updated.IsZero(), ShouldBeFalse)
})
Convey("Should be able to delete empty folder", func() {
emptyFolder := insertTestDashboard("2 test dash folder", 1, 0, true, "prod", "webapp")
deleteCmd := &models.DeleteDashboardCommand{Id: emptyFolder.Id}
err := DeleteDashboard(deleteCmd)
So(err, ShouldBeNil)
})
Convey("Should be able to delete a dashboard folder and its children", func() {
deleteCmd := &models.DeleteDashboardCommand{Id: savedFolder.Id}
err := DeleteDashboard(deleteCmd)

View File

@ -46,4 +46,7 @@ INSERT INTO dashboard_acl
`
mg.AddMigration("save default acl rules in dashboard_acl table", NewRawSqlMigration(rawSQL))
mg.AddMigration("delete acl rules for deleted dashboards and folders", NewRawSqlMigration(
"DELETE FROM dashboard_acl WHERE dashboard_id NOT IN (SELECT id FROM dashboard) AND dashboard_id != -1"))
}

View File

@ -219,4 +219,10 @@ func addDashboardMigration(mg *Migrator) {
Cols: []string{"title"},
Type: IndexType,
}))
mg.AddMigration("delete tags for deleted dashboards", NewRawSqlMigration(
"DELETE FROM dashboard_tag WHERE dashboard_id NOT IN (SELECT id FROM dashboard)"))
mg.AddMigration("delete stars for deleted dashboards", NewRawSqlMigration(
"DELETE FROM star WHERE dashboard_id NOT IN (SELECT id FROM dashboard)"))
}