Public Dashboards: Can toggle annotations in modal (#57312)

adds toggle for pubdash annotations
This commit is contained in:
owensmallwood
2022-10-21 13:42:14 -06:00
committed by GitHub
parent 7f3b567657
commit 0b8fb543fc
14 changed files with 176 additions and 83 deletions

View File

@@ -241,8 +241,9 @@ func (d *PublicDashboardStoreImpl) UpdatePublicDashboardConfig(ctx context.Conte
return err
}
_, err = sess.Exec("UPDATE dashboard_public SET is_enabled = ?, time_settings = ?, updated_by = ?, updated_at = ? WHERE uid = ?",
_, err = sess.Exec("UPDATE dashboard_public SET is_enabled = ?, annotations_enabled = ?, time_settings = ?, updated_by = ?, updated_at = ? WHERE uid = ?",
cmd.PublicDashboard.IsEnabled,
cmd.PublicDashboard.AnnotationsEnabled,
string(timeSettingsJSON),
cmd.PublicDashboard.UpdatedBy,
cmd.PublicDashboard.UpdatedAt.UTC().Format("2006-01-02 15:04:05"),

View File

@@ -233,14 +233,15 @@ func TestIntegrationGetPublicDashboard(t *testing.T) {
setup()
cmd := SavePublicDashboardConfigCommand{
PublicDashboard: PublicDashboard{
IsEnabled: true,
Uid: "abc1234",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
IsEnabled: true,
AnnotationsEnabled: true,
Uid: "abc1234",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
},
}
@@ -359,14 +360,15 @@ func TestIntegrationSavePublicDashboardConfig(t *testing.T) {
setup()
err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
PublicDashboard: PublicDashboard{
IsEnabled: true,
Uid: "pubdash-uid",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
IsEnabled: true,
AnnotationsEnabled: true,
Uid: "pubdash-uid",
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
TimeSettings: DefaultTimeSettings,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
},
})
require.NoError(t, err)
@@ -424,13 +426,14 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
pdUid := "asdf1234"
err := publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
PublicDashboard: PublicDashboard{
Uid: pdUid,
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
IsEnabled: true,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
Uid: pdUid,
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
IsEnabled: false,
AnnotationsEnabled: true,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "NOTAREALUUID",
},
})
require.NoError(t, err)
@@ -439,25 +442,27 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
anotherPdUid := "anotherUid"
err = publicdashboardStore.SavePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
PublicDashboard: PublicDashboard{
Uid: anotherPdUid,
DashboardUid: anotherSavedDashboard.Uid,
OrgId: anotherSavedDashboard.OrgId,
IsEnabled: true,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "fakeaccesstoken",
Uid: anotherPdUid,
DashboardUid: anotherSavedDashboard.Uid,
OrgId: anotherSavedDashboard.OrgId,
IsEnabled: true,
AnnotationsEnabled: false,
CreatedAt: DefaultTime,
CreatedBy: 7,
AccessToken: "fakeaccesstoken",
},
})
require.NoError(t, err)
updatedPublicDashboard := PublicDashboard{
Uid: pdUid,
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
IsEnabled: false,
TimeSettings: &TimeSettings{From: "now-8", To: "now"},
UpdatedAt: time.Now().UTC().Round(time.Second),
UpdatedBy: 8,
Uid: pdUid,
DashboardUid: savedDashboard.Uid,
OrgId: savedDashboard.OrgId,
IsEnabled: false,
AnnotationsEnabled: true,
TimeSettings: &TimeSettings{From: "now-8", To: "now"},
UpdatedAt: time.Now().UTC().Round(time.Second),
UpdatedBy: 8,
}
// update initial record
err = publicdashboardStore.UpdatePublicDashboardConfig(context.Background(), SavePublicDashboardConfigCommand{
@@ -473,12 +478,14 @@ func TestIntegrationUpdatePublicDashboard(t *testing.T) {
// make sure we're correctly updated IsEnabled because we have to call
// UseBool with xorm
assert.Equal(t, updatedPublicDashboard.IsEnabled, pdRetrieved.IsEnabled)
assert.Equal(t, updatedPublicDashboard.AnnotationsEnabled, pdRetrieved.AnnotationsEnabled)
// not updated dashboard shouldn't have changed
pdNotUpdatedRetrieved, err := publicdashboardStore.GetPublicDashboardConfig(context.Background(), anotherSavedDashboard.OrgId, anotherSavedDashboard.Uid)
require.NoError(t, err)
assert.NotEqual(t, updatedPublicDashboard.UpdatedAt, pdNotUpdatedRetrieved.UpdatedAt)
assert.NotEqual(t, updatedPublicDashboard.IsEnabled, pdNotUpdatedRetrieved.IsEnabled)
assert.NotEqual(t, updatedPublicDashboard.AnnotationsEnabled, pdNotUpdatedRetrieved.AnnotationsEnabled)
})
}

View File

@@ -64,12 +64,13 @@ var (
)
type PublicDashboard struct {
Uid string `json:"uid" xorm:"pk uid"`
DashboardUid string `json:"dashboardUid" xorm:"dashboard_uid"`
OrgId int64 `json:"-" xorm:"org_id"` // Don't ever marshal orgId to Json
TimeSettings *TimeSettings `json:"timeSettings" xorm:"time_settings"`
IsEnabled bool `json:"isEnabled" xorm:"is_enabled"`
AccessToken string `json:"accessToken" xorm:"access_token"`
Uid string `json:"uid" xorm:"pk uid"`
DashboardUid string `json:"dashboardUid" xorm:"dashboard_uid"`
OrgId int64 `json:"-" xorm:"org_id"` // Don't ever marshal orgId to Json
TimeSettings *TimeSettings `json:"timeSettings" xorm:"time_settings"`
IsEnabled bool `json:"isEnabled" xorm:"is_enabled"`
AccessToken string `json:"accessToken" xorm:"access_token"`
AnnotationsEnabled bool `json:"annotationsEnabled" xorm:"annotations_enabled"`
CreatedBy int64 `json:"createdBy" xorm:"created_by"`
UpdatedBy int64 `json:"updatedBy" xorm:"updated_by"`

View File

@@ -19,11 +19,15 @@ import (
// GetAnnotations returns annotations for a public dashboard
func (pd *PublicDashboardServiceImpl) GetAnnotations(ctx context.Context, reqDTO models.AnnotationsQueryDTO, accessToken string) ([]models.AnnotationEvent, error) {
_, dash, err := pd.GetPublicDashboard(ctx, accessToken)
pub, dash, err := pd.GetPublicDashboard(ctx, accessToken)
if err != nil {
return nil, err
}
if !pub.AnnotationsEnabled {
return []models.AnnotationEvent{}, nil
}
annoDto, err := UnmarshalDashboardAnnotations(dash.Data)
if err != nil {
return nil, err

View File

@@ -408,6 +408,8 @@ func TestGetQueryDataResponse(t *testing.T) {
}
func TestGetAnnotations(t *testing.T) {
color := "red"
name := "annoName"
t.Run("will build anonymous user with correct permissions to get annotations", func(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
config := setting.NewCfg()
@@ -436,8 +438,6 @@ func TestGetAnnotations(t *testing.T) {
t.Run("Test events from tag queries overwrite built-in annotation queries and duplicate events are not returned", func(t *testing.T) {
dash := grafanamodels.NewDashboard("test")
color := "red"
name := "annoName"
grafanaAnnotation := DashAnnotation{
Datasource: CreateDatasource("grafana", "grafana"),
Enable: true,
@@ -473,7 +473,7 @@ func TestGetAnnotations(t *testing.T) {
store: &fakeStore,
AnnotationsRepo: &annotationsRepo,
}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{
{
@@ -508,8 +508,6 @@ func TestGetAnnotations(t *testing.T) {
t.Run("Test panelId set to zero when annotation event is for a tags query", func(t *testing.T) {
dash := grafanamodels.NewDashboard("test")
color := "red"
name := "annoName"
grafanaAnnotation := DashAnnotation{
Datasource: CreateDatasource("grafana", "grafana"),
Enable: true,
@@ -532,7 +530,7 @@ func TestGetAnnotations(t *testing.T) {
store: &fakeStore,
AnnotationsRepo: &annotationsRepo,
}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{
{
@@ -567,8 +565,6 @@ func TestGetAnnotations(t *testing.T) {
t.Run("Test can get grafana annotations and will skip annotation queries and disabled annotations", func(t *testing.T) {
dash := grafanamodels.NewDashboard("test")
color := "red"
name := "annoName"
disabledGrafanaAnnotation := DashAnnotation{
Datasource: CreateDatasource("grafana", "grafana"),
Enable: false,
@@ -603,7 +599,7 @@ func TestGetAnnotations(t *testing.T) {
store: &fakeStore,
AnnotationsRepo: &annotationsRepo,
}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return([]*annotations.ItemDTO{
{
@@ -645,7 +641,40 @@ func TestGetAnnotations(t *testing.T) {
AnnotationsRepo: &annotationsRepo,
}
dashboard := grafanamodels.NewDashboard("dashWithNoAnnotations")
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: true}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
items, err := service.GetAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123")
require.NoError(t, err)
assert.Empty(t, items)
})
t.Run("test will return nothing when pubdash annotations are disabled", func(t *testing.T) {
annotationsRepo := annotations.FakeAnnotationsRepo{}
fakeStore := FakePublicDashboardStore{}
service := &PublicDashboardServiceImpl{
log: log.New("test.logger"),
store: &fakeStore,
AnnotationsRepo: &annotationsRepo,
}
dash := grafanamodels.NewDashboard("test")
grafanaAnnotation := DashAnnotation{
Datasource: CreateDatasource("grafana", "grafana"),
Enable: true,
Name: &name,
IconColor: &color,
Target: &dashboard2.AnnotationTarget{
Limit: 100,
MatchAny: false,
Tags: nil,
Type: "dashboard",
},
Type: "dashboard",
}
annos := []DashAnnotation{grafanaAnnotation}
dashboard := AddAnnotationsToDashboard(t, dash, annos)
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dashboard.Uid, AnnotationsEnabled: false}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dashboard, nil)
items, err := service.GetAnnotations(context.Background(), AnnotationsQueryDTO{}, "abc123")
@@ -663,8 +692,6 @@ func TestGetAnnotations(t *testing.T) {
AnnotationsRepo: &annotationsRepo,
}
dash := grafanamodels.NewDashboard("test")
color := "red"
name := "annoName"
grafanaAnnotation := DashAnnotation{
Datasource: CreateDatasource("grafana", "grafana"),
Enable: true,
@@ -679,7 +706,7 @@ func TestGetAnnotations(t *testing.T) {
}
annos := []DashAnnotation{grafanaAnnotation}
dash = AddAnnotationsToDashboard(t, dash, annos)
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dash.Uid}
pubdash := &PublicDashboard{Uid: "uid1", IsEnabled: true, OrgId: 1, DashboardUid: dash.Uid, AnnotationsEnabled: true}
fakeStore.On("GetPublicDashboard", mock.Anything, mock.AnythingOfType("string")).Return(pubdash, dash, nil)
annotationsRepo.On("Find", mock.Anything, mock.Anything).Return(nil, errors.New("failed")).Maybe()

View File

@@ -168,14 +168,15 @@ func (pd *PublicDashboardServiceImpl) savePublicDashboardConfig(ctx context.Cont
cmd := SavePublicDashboardConfigCommand{
PublicDashboard: PublicDashboard{
Uid: uid,
DashboardUid: dto.DashboardUid,
OrgId: dto.OrgId,
IsEnabled: dto.PublicDashboard.IsEnabled,
TimeSettings: dto.PublicDashboard.TimeSettings,
CreatedBy: dto.UserId,
CreatedAt: time.Now(),
AccessToken: accessToken,
Uid: uid,
DashboardUid: dto.DashboardUid,
OrgId: dto.OrgId,
IsEnabled: dto.PublicDashboard.IsEnabled,
AnnotationsEnabled: dto.PublicDashboard.AnnotationsEnabled,
TimeSettings: dto.PublicDashboard.TimeSettings,
CreatedBy: dto.UserId,
CreatedAt: time.Now(),
AccessToken: accessToken,
},
}
@@ -192,11 +193,12 @@ func (pd *PublicDashboardServiceImpl) savePublicDashboardConfig(ctx context.Cont
func (pd *PublicDashboardServiceImpl) updatePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (string, error) {
cmd := SavePublicDashboardConfigCommand{
PublicDashboard: PublicDashboard{
Uid: dto.PublicDashboard.Uid,
IsEnabled: dto.PublicDashboard.IsEnabled,
TimeSettings: dto.PublicDashboard.TimeSettings,
UpdatedBy: dto.UserId,
UpdatedAt: time.Now(),
Uid: dto.PublicDashboard.Uid,
IsEnabled: dto.PublicDashboard.IsEnabled,
AnnotationsEnabled: dto.PublicDashboard.AnnotationsEnabled,
TimeSettings: dto.PublicDashboard.TimeSettings,
UpdatedBy: dto.UserId,
UpdatedAt: time.Now(),
},
}

View File

@@ -135,10 +135,11 @@ func TestSavePublicDashboard(t *testing.T) {
OrgId: dashboard.OrgId,
UserId: 7,
PublicDashboard: &PublicDashboard{
IsEnabled: true,
DashboardUid: "NOTTHESAME",
OrgId: 9999999,
TimeSettings: timeSettings,
IsEnabled: true,
AnnotationsEnabled: false,
DashboardUid: "NOTTHESAME",
OrgId: 9999999,
TimeSettings: timeSettings,
},
}
@@ -152,6 +153,7 @@ func TestSavePublicDashboard(t *testing.T) {
assert.Equal(t, dashboard.Uid, pubdash.DashboardUid)
assert.Equal(t, dashboard.OrgId, pubdash.OrgId)
assert.Equal(t, dto.UserId, pubdash.CreatedBy)
assert.Equal(t, dto.PublicDashboard.AnnotationsEnabled, pubdash.AnnotationsEnabled)
// IsEnabled set by parameters
assert.Equal(t, dto.PublicDashboard.IsEnabled, pubdash.IsEnabled)
// CreatedAt set to non-zero time
@@ -270,8 +272,9 @@ func TestUpdatePublicDashboard(t *testing.T) {
OrgId: dashboard.OrgId,
UserId: 7,
PublicDashboard: &PublicDashboard{
IsEnabled: true,
TimeSettings: timeSettings,
AnnotationsEnabled: false,
IsEnabled: true,
TimeSettings: timeSettings,
},
}
@@ -290,9 +293,10 @@ func TestUpdatePublicDashboard(t *testing.T) {
CreatedBy: 9,
CreatedAt: time.Time{},
IsEnabled: true,
TimeSettings: timeSettings,
AccessToken: "NOTAREALUUID",
IsEnabled: true,
AnnotationsEnabled: true,
TimeSettings: timeSettings,
AccessToken: "NOTAREALUUID",
},
}
@@ -310,6 +314,7 @@ func TestUpdatePublicDashboard(t *testing.T) {
// gets updated
assert.Equal(t, dto.PublicDashboard.IsEnabled, updatedPubdash.IsEnabled)
assert.Equal(t, dto.PublicDashboard.AnnotationsEnabled, updatedPubdash.AnnotationsEnabled)
assert.Equal(t, dto.PublicDashboard.TimeSettings, updatedPubdash.TimeSettings)
assert.Equal(t, dto.UserId, updatedPubdash.UpdatedBy)
assert.NotEqual(t, &time.Time{}, updatedPubdash.UpdatedAt)

View File

@@ -65,4 +65,13 @@ func addPublicDashboardMigration(mg *Migrator) {
// rename table
addTableRenameMigration(mg, "dashboard_public_config", "dashboard_public", "v2")
// some migrations (like AddColumn) need the table object to be passed in. So we need to make sure its updated.
dashboardPublicCfgV2.Name = "dashboard_public"
mg.AddMigration("add annotations_enabled column", NewAddColumnMigration(dashboardPublicCfgV2, &Column{
Name: "annotations_enabled",
Type: DB_Bool,
Nullable: false,
Default: "0",
}))
}