mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
dashboards: reject updates of provisioned dashboards
This commit is contained in:
parent
d6faa3d06f
commit
627df67992
@ -235,7 +235,8 @@ func PostDashboard(c *m.ReqContext, cmd m.SaveDashboardCommand) Response {
|
|||||||
err == m.ErrDashboardWithSameUIDExists ||
|
err == m.ErrDashboardWithSameUIDExists ||
|
||||||
err == m.ErrFolderNotFound ||
|
err == m.ErrFolderNotFound ||
|
||||||
err == m.ErrDashboardFolderCannotHaveParent ||
|
err == m.ErrDashboardFolderCannotHaveParent ||
|
||||||
err == m.ErrDashboardFolderNameExists {
|
err == m.ErrDashboardFolderNameExists ||
|
||||||
|
err == m.ErrDashboardCannotSaveProvisionedDashboard {
|
||||||
return Error(400, err.Error(), nil)
|
return Error(400, err.Error(), nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,6 +720,7 @@ func TestDashboardApiEndpoint(t *testing.T) {
|
|||||||
{SaveError: m.ErrDashboardUpdateAccessDenied, ExpectedStatusCode: 403},
|
{SaveError: m.ErrDashboardUpdateAccessDenied, ExpectedStatusCode: 403},
|
||||||
{SaveError: m.ErrDashboardInvalidUid, ExpectedStatusCode: 400},
|
{SaveError: m.ErrDashboardInvalidUid, ExpectedStatusCode: 400},
|
||||||
{SaveError: m.ErrDashboardUidToLong, ExpectedStatusCode: 400},
|
{SaveError: m.ErrDashboardUidToLong, ExpectedStatusCode: 400},
|
||||||
|
{SaveError: m.ErrDashboardCannotSaveProvisionedDashboard, ExpectedStatusCode: 400},
|
||||||
{SaveError: m.UpdatePluginDashboardError{PluginId: "plug"}, ExpectedStatusCode: 412},
|
{SaveError: m.UpdatePluginDashboardError{PluginId: "plug"}, ExpectedStatusCode: 412},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ var (
|
|||||||
ErrDashboardUpdateAccessDenied = errors.New("Access denied to save dashboard")
|
ErrDashboardUpdateAccessDenied = errors.New("Access denied to save dashboard")
|
||||||
ErrDashboardInvalidUid = errors.New("uid contains illegal characters")
|
ErrDashboardInvalidUid = errors.New("uid contains illegal characters")
|
||||||
ErrDashboardUidToLong = errors.New("uid to long. max 40 characters")
|
ErrDashboardUidToLong = errors.New("uid to long. max 40 characters")
|
||||||
|
ErrDashboardCannotSaveProvisionedDashboard = errors.New("Cannot save provisioned dashboards")
|
||||||
|
ErrDashboardProvisioningDoesNotExist = errors.New("Dashboard provisioning does not exist")
|
||||||
RootFolderName = "General"
|
RootFolderName = "General"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -111,6 +111,11 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO,
|
|||||||
return nil, models.ErrDashboardUpdateAccessDenied
|
return nil, models.ErrDashboardUpdateAccessDenied
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := dr.validateDashboardIsNotProvisioned(dash.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
cmd := &models.SaveDashboardCommand{
|
cmd := &models.SaveDashboardCommand{
|
||||||
Dashboard: dash.Data,
|
Dashboard: dash.Data,
|
||||||
Message: dto.Message,
|
Message: dto.Message,
|
||||||
@ -129,6 +134,23 @@ func (dr *dashboardServiceImpl) buildSaveDashboardCommand(dto *SaveDashboardDTO,
|
|||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dr *dashboardServiceImpl) validateDashboardIsNotProvisioned(dashboardId int64) error {
|
||||||
|
dpQuery := &models.GetProvisionedDashboardByDashboardId{DashboardId: dashboardId}
|
||||||
|
err := bus.Dispatch(dpQuery)
|
||||||
|
|
||||||
|
// provisioned dashboards cannot be saved. So we can only save
|
||||||
|
// this dashboard if ErrDashboardProvisioningDoesNotExist is returned
|
||||||
|
if err != nil && err != models.ErrDashboardProvisioningDoesNotExist {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return models.ErrDashboardCannotSaveProvisionedDashboard
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (dr *dashboardServiceImpl) updateAlerting(cmd *models.SaveDashboardCommand, dto *SaveDashboardDTO) error {
|
func (dr *dashboardServiceImpl) updateAlerting(cmd *models.SaveDashboardCommand, dto *SaveDashboardDTO) error {
|
||||||
alertCmd := models.UpdateDashboardAlertsCommand{
|
alertCmd := models.UpdateDashboardAlertsCommand{
|
||||||
OrgId: dto.OrgId,
|
OrgId: dto.OrgId,
|
||||||
|
@ -14,7 +14,9 @@ import (
|
|||||||
|
|
||||||
func TestDashboardService(t *testing.T) {
|
func TestDashboardService(t *testing.T) {
|
||||||
Convey("Dashboard service tests", t, func() {
|
Convey("Dashboard service tests", t, func() {
|
||||||
service := dashboardServiceImpl{}
|
bus.ClearBusHandlers()
|
||||||
|
|
||||||
|
service := &dashboardServiceImpl{}
|
||||||
|
|
||||||
origNewDashboardGuardian := guardian.New
|
origNewDashboardGuardian := guardian.New
|
||||||
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true})
|
guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true})
|
||||||
@ -54,6 +56,10 @@ func TestDashboardService(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
bus.AddHandler("test", func(cmd *models.GetProvisionedDashboardByDashboardId) error {
|
||||||
|
return models.ErrDashboardProvisioningDoesNotExist
|
||||||
|
})
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
Uid string
|
Uid string
|
||||||
Error error
|
Error error
|
||||||
@ -77,7 +83,32 @@ func TestDashboardService(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("Should return validation error if dashboard is provisioned", func() {
|
||||||
|
bus.AddHandler("test", func(cmd *models.GetProvisionedDashboardByDashboardId) error {
|
||||||
|
cmd.Result = &models.DashboardProvisioning{}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
bus.AddHandler("test", func(cmd *models.ValidateDashboardAlertsCommand) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
bus.AddHandler("test", func(cmd *models.ValidateDashboardBeforeSaveCommand) error {
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
dto.Dashboard = models.NewDashboard("Dash")
|
||||||
|
dto.Dashboard.SetId(3)
|
||||||
|
dto.User = &models.SignedInUser{UserId: 1}
|
||||||
|
_, err := service.buildSaveDashboardCommand(dto, false)
|
||||||
|
So(err, ShouldEqual, models.ErrDashboardCannotSaveProvisionedDashboard)
|
||||||
|
})
|
||||||
|
|
||||||
Convey("Should return validation error if alert data is invalid", func() {
|
Convey("Should return validation error if alert data is invalid", func() {
|
||||||
|
bus.AddHandler("test", func(cmd *models.GetProvisionedDashboardByDashboardId) error {
|
||||||
|
return models.ErrDashboardProvisioningDoesNotExist
|
||||||
|
})
|
||||||
|
|
||||||
bus.AddHandler("test", func(cmd *models.ValidateDashboardAlertsCommand) error {
|
bus.AddHandler("test", func(cmd *models.ValidateDashboardAlertsCommand) error {
|
||||||
return errors.New("error")
|
return errors.New("error")
|
||||||
})
|
})
|
||||||
|
@ -21,12 +21,17 @@ type DashboardExtras struct {
|
|||||||
func GetProvisionedDataByDashboardId(cmd *models.GetProvisionedDashboardByDashboardId) error {
|
func GetProvisionedDataByDashboardId(cmd *models.GetProvisionedDashboardByDashboardId) error {
|
||||||
result := &models.DashboardProvisioning{}
|
result := &models.DashboardProvisioning{}
|
||||||
|
|
||||||
_, err := x.Where("dashboard_id = ?", cmd.DashboardId).Get(result)
|
exist, err := x.Where("dashboard_id = ?", cmd.DashboardId).Get(result)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !exist {
|
||||||
|
return models.ErrDashboardProvisioningDoesNotExist
|
||||||
|
}
|
||||||
|
|
||||||
cmd.Result = result
|
cmd.Result = result
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,13 @@ func TestDashboardProvisioningTest(t *testing.T) {
|
|||||||
So(query.Result.DashboardId, ShouldEqual, cmd.Result.Id)
|
So(query.Result.DashboardId, ShouldEqual, cmd.Result.Id)
|
||||||
So(query.Result.Updated, ShouldEqual, now.Unix())
|
So(query.Result.Updated, ShouldEqual, now.Unix())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Convey("Can query for one provisioned dashboard2", func() {
|
||||||
|
query := &models.GetProvisionedDashboardByDashboardId{DashboardId: 3000}
|
||||||
|
|
||||||
|
err := GetProvisionedDataByDashboardId(query)
|
||||||
|
So(err, ShouldEqual, models.ErrDashboardProvisioningDoesNotExist)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ func TestIntegratedDashboardService(t *testing.T) {
|
|||||||
var testOrgId int64 = 1
|
var testOrgId int64 = 1
|
||||||
|
|
||||||
Convey("Given saved folders and dashboards in organization A", func() {
|
Convey("Given saved folders and dashboards in organization A", func() {
|
||||||
|
|
||||||
bus.AddHandler("test", func(cmd *models.ValidateDashboardAlertsCommand) error {
|
bus.AddHandler("test", func(cmd *models.ValidateDashboardAlertsCommand) error {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@ -28,6 +27,10 @@ func TestIntegratedDashboardService(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
bus.AddHandler("test", func(cmd *models.GetProvisionedDashboardByDashboardId) error {
|
||||||
|
return models.ErrDashboardProvisioningDoesNotExist
|
||||||
|
})
|
||||||
|
|
||||||
savedFolder := saveTestFolder("Saved folder", testOrgId)
|
savedFolder := saveTestFolder("Saved folder", testOrgId)
|
||||||
savedDashInFolder := saveTestDashboard("Saved dash in folder", testOrgId, savedFolder.Id)
|
savedDashInFolder := saveTestDashboard("Saved dash in folder", testOrgId, savedFolder.Id)
|
||||||
saveTestDashboard("Other saved dash in folder", testOrgId, savedFolder.Id)
|
saveTestDashboard("Other saved dash in folder", testOrgId, savedFolder.Id)
|
||||||
|
Loading…
Reference in New Issue
Block a user