move GetDashboardUIDById out of sqlstore and into dashboard service (#49170)

* sqlstore: move GetDashboardUIDById to dashboard service
* winding change through the rest of the codebase
This commit is contained in:
Kristin Laemmert
2022-05-19 10:13:02 -04:00
committed by GitHub
parent 0bad187a60
commit 2b8909a9c6
26 changed files with 154 additions and 117 deletions

View File

@@ -443,7 +443,7 @@ func (hs *HTTPServer) GetHomeDashboard(c *models.ReqContext) response.Response {
if preference.HomeDashboardID != 0 {
slugQuery := models.GetDashboardRefByIdQuery{Id: preference.HomeDashboardID}
err := hs.SQLStore.GetDashboardUIDById(c.Req.Context(), &slugQuery)
err := hs.dashboardService.GetDashboardUIDById(c.Req.Context(), &slugQuery)
if err == nil {
url := models.GetDashboardUrl(slugQuery.Result.Uid, slugQuery.Result.Slug)
dashRedirect := dtos.DashboardRedirect{RedirectUri: url}
@@ -783,7 +783,7 @@ func (hs *HTTPServer) GetDashboardUIDs(c *models.ReqContext) {
continue
}
q.Id = id
err = hs.SQLStore.GetDashboardUIDById(c.Req.Context(), q)
err = hs.dashboardService.GetDashboardUIDById(c.Req.Context(), q)
if err != nil {
continue
}

View File

@@ -16,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting/metrics"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/encryption"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/rendering"
@@ -28,7 +29,6 @@ import (
type AlertStore interface {
GetAllAlertQueryHandler(context.Context, *models.GetAllAlertsQuery) error
GetDataSource(context.Context, *models.GetDataSourceQuery) error
GetDashboardUIDById(context.Context, *models.GetDashboardRefByIdQuery) error
SetAlertNotificationStateToCompleteCommand(context.Context, *models.SetAlertNotificationStateToCompleteCommand) error
SetAlertNotificationStateToPendingCommand(context.Context, *models.SetAlertNotificationStateToPendingCommand) error
GetAlertNotificationUidWithId(context.Context, *models.GetAlertNotificationUidQuery) error
@@ -57,6 +57,7 @@ type AlertEngine struct {
tracer tracing.Tracer
sqlStore AlertStore
dashAlertExtractor DashAlertExtractor
dashboardService dashboards.DashboardService
}
// IsDisabled returns true if the alerting service is disabled for this instance.
@@ -68,7 +69,7 @@ func (e *AlertEngine) IsDisabled() bool {
func ProvideAlertEngine(renderer rendering.Service, requestValidator models.PluginRequestValidator,
dataService legacydata.RequestHandler, usageStatsService usagestats.Service, encryptionService encryption.Internal,
notificationService *notifications.NotificationService, tracer tracing.Tracer, sqlStore AlertStore, cfg *setting.Cfg,
dashAlertExtractor DashAlertExtractor) *AlertEngine {
dashAlertExtractor DashAlertExtractor, dashboardService dashboards.DashboardService) *AlertEngine {
e := &AlertEngine{
Cfg: cfg,
RenderService: renderer,
@@ -78,6 +79,7 @@ func ProvideAlertEngine(renderer rendering.Service, requestValidator models.Plug
tracer: tracer,
sqlStore: sqlStore,
dashAlertExtractor: dashAlertExtractor,
dashboardService: dashboardService,
}
e.execQueue = make(chan *Job, 1000)
e.scheduler = newScheduler()
@@ -199,7 +201,7 @@ func (e *AlertEngine) processJob(attemptID int, attemptChan chan int, cancelChan
alertCtx, cancelFn := context.WithTimeout(context.Background(), setting.AlertingEvaluationTimeout)
cancelChan <- cancelFn
alertCtx, span := e.tracer.Start(alertCtx, "alert execution")
evalContext := NewEvalContext(alertCtx, job.Rule, e.RequestValidator, e.sqlStore)
evalContext := NewEvalContext(alertCtx, job.Rule, e.RequestValidator, e.sqlStore, e.dashboardService)
evalContext.Ctx = alertCtx
go func() {

View File

@@ -24,7 +24,7 @@ func TestEngineTimeouts(t *testing.T) {
usMock := &usagestats.UsageStatsMock{T: t}
tracer, err := tracing.InitializeTracerForTest()
require.NoError(t, err)
engine := ProvideAlertEngine(nil, nil, nil, usMock, ossencryption.ProvideService(), nil, tracer, nil, setting.NewCfg(), nil)
engine := ProvideAlertEngine(nil, nil, nil, usMock, ossencryption.ProvideService(), nil, tracer, nil, setting.NewCfg(), nil, nil)
setting.AlertingNotificationTimeout = 30 * time.Second
setting.AlertingMaxAttempts = 3
engine.resultHandler = &FakeResultHandler{}

View File

@@ -104,7 +104,7 @@ func TestEngineProcessJob(t *testing.T) {
require.NoError(t, err)
store := &AlertStoreMock{}
engine := ProvideAlertEngine(nil, nil, nil, usMock, ossencryption.ProvideService(), nil, tracer, store, setting.NewCfg(), nil)
engine := ProvideAlertEngine(nil, nil, nil, usMock, ossencryption.ProvideService(), nil, tracer, store, setting.NewCfg(), nil, nil)
setting.AlertingEvaluationTimeout = 30 * time.Second
setting.AlertingNotificationTimeout = 30 * time.Second
setting.AlertingMaxAttempts = 3

View File

@@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/setting"
)
@@ -37,11 +38,13 @@ type EvalContext struct {
Ctx context.Context
Store AlertStore
Store AlertStore
dashboardService dashboards.DashboardService
}
// NewEvalContext is the EvalContext constructor.
func NewEvalContext(alertCtx context.Context, rule *Rule, requestValidator models.PluginRequestValidator, sqlStore AlertStore) *EvalContext {
func NewEvalContext(alertCtx context.Context, rule *Rule, requestValidator models.PluginRequestValidator,
sqlStore AlertStore, dashboardService dashboards.DashboardService) *EvalContext {
return &EvalContext{
Ctx: alertCtx,
StartTime: time.Now(),
@@ -53,6 +56,7 @@ func NewEvalContext(alertCtx context.Context, rule *Rule, requestValidator model
PrevAlertState: rule.State,
RequestValidator: requestValidator,
Store: sqlStore,
dashboardService: dashboardService,
}
}
@@ -112,7 +116,7 @@ func (c *EvalContext) GetDashboardUID() (*models.DashboardRef, error) {
}
uidQuery := &models.GetDashboardRefByIdQuery{Id: c.Rule.DashboardID}
if err := c.Store.GetDashboardUIDById(c.Ctx, uidQuery); err != nil {
if err := c.dashboardService.GetDashboardUIDById(c.Ctx, uidQuery); err != nil {
return nil, err
}

View File

@@ -6,16 +6,15 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/models"
"github.com/stretchr/testify/assert"
"github.com/grafana/grafana/pkg/services/validations"
)
func TestStateIsUpdatedWhenNeeded(t *testing.T) {
ctx := NewEvalContext(context.Background(), &Rule{Conditions: []Condition{&conditionStub{firing: true}}}, &validations.OSSPluginRequestValidator{}, nil)
ctx := NewEvalContext(context.Background(), &Rule{Conditions: []Condition{&conditionStub{firing: true}}}, &validations.OSSPluginRequestValidator{}, nil, nil)
t.Run("ok -> alerting", func(t *testing.T) {
ctx.PrevAlertState = models.AlertStateOK
@@ -200,7 +199,7 @@ func TestGetStateFromEvalContext(t *testing.T) {
}
for _, tc := range tcs {
evalContext := NewEvalContext(context.Background(), &Rule{Conditions: []Condition{&conditionStub{firing: true}}}, &validations.OSSPluginRequestValidator{}, nil)
evalContext := NewEvalContext(context.Background(), &Rule{Conditions: []Condition{&conditionStub{firing: true}}}, &validations.OSSPluginRequestValidator{}, nil, nil)
tc.applyFn(evalContext)
newState := evalContext.GetNewState()
@@ -391,7 +390,8 @@ func TestEvaluateNotificationTemplateFields(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(tt *testing.T) {
evalContext := NewEvalContext(context.Background(), &Rule{Name: "Rule name: ${value1}", Message: "Rule message: ${value2}", Conditions: []Condition{&conditionStub{firing: true}}}, &validations.OSSPluginRequestValidator{}, nil)
evalContext := NewEvalContext(context.Background(), &Rule{Name: "Rule name: ${value1}", Message: "Rule message: ${value2}",
Conditions: []Condition{&conditionStub{firing: true}}}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.EvalMatches = test.evalMatches
evalContext.AllMatches = test.allMatches

View File

@@ -29,7 +29,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
Conditions: []Condition{&conditionStub{
firing: true,
}},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, true, context.Firing)
@@ -39,7 +39,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
t.Run("Show return triggered with single passing condition2", func(t *testing.T) {
context := NewEvalContext(context.Background(), &Rule{
Conditions: []Condition{&conditionStub{firing: true, operator: "and"}},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, true, context.Firing)
@@ -52,7 +52,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: true, operator: "and", matches: []*EvalMatch{{}, {}}},
&conditionStub{firing: false, operator: "and"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, false, context.Firing)
@@ -65,7 +65,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: true, operator: "and"},
&conditionStub{firing: false, operator: "or"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, true, context.Firing)
@@ -78,7 +78,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: true, operator: "and"},
&conditionStub{firing: false, operator: "and"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, false, context.Firing)
@@ -92,7 +92,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: true, operator: "and"},
&conditionStub{firing: false, operator: "or"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, true, context.Firing)
@@ -106,7 +106,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: false, operator: "and"},
&conditionStub{firing: false, operator: "or"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, false, context.Firing)
@@ -120,7 +120,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: false, operator: "and"},
&conditionStub{firing: true, operator: "and"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, false, context.Firing)
@@ -134,7 +134,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: false, operator: "or"},
&conditionStub{firing: true, operator: "or"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, true, context.Firing)
@@ -148,7 +148,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{firing: false, operator: "or"},
&conditionStub{firing: false, operator: "or"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, false, context.Firing)
@@ -163,7 +163,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{operator: "or", noData: false},
&conditionStub{operator: "or", noData: false},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.False(t, context.NoDataFound)
@@ -174,7 +174,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
Conditions: []Condition{
&conditionStub{operator: "and", noData: true},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.Equal(t, false, context.Firing)
@@ -187,7 +187,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{operator: "and", noData: true},
&conditionStub{operator: "and", noData: false},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.True(t, context.NoDataFound)
@@ -199,7 +199,7 @@ func TestAlertingEvaluationHandler(t *testing.T) {
&conditionStub{operator: "or", noData: true},
&conditionStub{operator: "or", noData: false},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
handler.Eval(context)
require.True(t, context.NoDataFound)

View File

@@ -5,35 +5,33 @@ import (
"testing"
"time"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/components/imguploader"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/validations"
"github.com/grafana/grafana/pkg/setting"
)
func TestNotificationService(t *testing.T) {
testRule := &Rule{Name: "Test", Message: "Something is bad"}
store := &AlertStoreMock{}
evalCtx := NewEvalContext(context.Background(), testRule, &validations.OSSPluginRequestValidator{}, store)
evalCtx := NewEvalContext(context.Background(), testRule, &validations.OSSPluginRequestValidator{}, store, nil)
testRuleTemplated := &Rule{Name: "Test latency ${quantile}", Message: "Something is bad on instance ${instance}"}
evalCtxWithMatch := NewEvalContext(context.Background(), testRuleTemplated, &validations.OSSPluginRequestValidator{}, store)
evalCtxWithMatch := NewEvalContext(context.Background(), testRuleTemplated, &validations.OSSPluginRequestValidator{}, store, nil)
evalCtxWithMatch.EvalMatches = []*EvalMatch{{
Tags: map[string]string{
"instance": "localhost:3000",
"quantile": "0.99",
},
}}
evalCtxWithoutMatch := NewEvalContext(context.Background(), testRuleTemplated, &validations.OSSPluginRequestValidator{}, store)
evalCtxWithoutMatch := NewEvalContext(context.Background(), testRuleTemplated, &validations.OSSPluginRequestValidator{}, store, nil)
notificationServiceScenario(t, "Given alert rule with upload image enabled should render and upload image and send notification",
evalCtx, true, func(sc *scenarioContext) {

View File

@@ -68,7 +68,7 @@ func TestWhenAlertManagerShouldNotify(t *testing.T) {
am := &AlertmanagerNotifier{log: log.New("test.logger")}
evalContext := alerting.NewEvalContext(context.Background(), &alerting.Rule{
State: tc.prevState,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.Rule.State = tc.newState

View File

@@ -170,7 +170,7 @@ func TestShouldSendAlertNotification(t *testing.T) {
for _, tc := range tcs {
evalContext := alerting.NewEvalContext(context.Background(), &alerting.Rule{
State: tc.prevState,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
if tc.state == nil {
tc.state = &models.AlertNotificationState{}

View File

@@ -50,7 +50,7 @@ func TestDingDingNotifier(t *testing.T) {
&alerting.Rule{
State: models.AlertStateAlerting,
Message: `{host="localhost"}`,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
_, err = notifier.genBody(evalContext, "")
require.Nil(t, err)
})

View File

@@ -103,7 +103,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: tagPairs,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.IsTestRun = true
tags := make([]string, 0)
@@ -152,7 +152,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: tagPairs,
}, nil, nil)
}, nil, nil, nil)
evalContext.IsTestRun = true
tags := make([]string, 0)
@@ -201,7 +201,7 @@ func TestOpsGenieNotifier(t *testing.T) {
Message: "someMessage",
State: models.AlertStateAlerting,
AlertRuleTags: tagPairs,
}, nil, nil)
}, nil, nil, nil)
evalContext.IsTestRun = true
tags := make([]string, 0)

View File

@@ -6,6 +6,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana/pkg/components/null"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
@@ -139,7 +140,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateAlerting,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.IsTestRun = true
payloadJSON, err := pagerdutyNotifier.buildEventPayload(evalContext)
@@ -195,7 +196,7 @@ func TestPagerdutyNotifier(t *testing.T) {
ID: 0,
Name: "someRule",
State: models.AlertStateAlerting,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.IsTestRun = true
payloadJSON, err := pagerdutyNotifier.buildEventPayload(evalContext)
@@ -253,7 +254,7 @@ func TestPagerdutyNotifier(t *testing.T) {
Name: "someRule",
Message: "someMessage",
State: models.AlertStateAlerting,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.IsTestRun = true
evalContext.EvalMatches = []*alerting.EvalMatch{
{
@@ -332,7 +333,7 @@ func TestPagerdutyNotifier(t *testing.T) {
{Key: "severity", Value: "warning"},
{Key: "dedup_key", Value: "key-" + strings.Repeat("x", 260)},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.ImagePublicURL = "http://somewhere.com/omg_dont_panic.png"
evalContext.IsTestRun = true
@@ -411,7 +412,7 @@ func TestPagerdutyNotifier(t *testing.T) {
{Key: "component", Value: "aComponent"},
{Key: "severity", Value: "info"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.ImagePublicURL = "http://somewhere.com/omg_dont_panic.png"
evalContext.IsTestRun = true
@@ -490,7 +491,7 @@ func TestPagerdutyNotifier(t *testing.T) {
{Key: "component", Value: "aComponent"},
{Key: "severity", Value: "llama"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.ImagePublicURL = "http://somewhere.com/omg_dont_panic.png"
evalContext.IsTestRun = true

View File

@@ -74,7 +74,7 @@ func TestGenPushoverBody(t *testing.T) {
evalContext := alerting.NewEvalContext(context.Background(),
&alerting.Rule{
State: models.AlertStateAlerting,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
_, pushoverBody, err := notifier.genPushoverBody(evalContext, "", "")
require.Nil(t, err)
@@ -85,7 +85,7 @@ func TestGenPushoverBody(t *testing.T) {
evalContext := alerting.NewEvalContext(context.Background(),
&alerting.Rule{
State: models.AlertStateOK,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
_, pushoverBody, err := notifier.genPushoverBody(evalContext, "", "")
require.Nil(t, err)

View File

@@ -59,7 +59,7 @@ func TestTelegramNotifier(t *testing.T) {
Name: "This is an alarm",
Message: "Some kind of message.",
State: models.AlertStateOK,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
caption := generateImageCaption(evalContext, "http://grafa.url/abcdef", "")
require.LessOrEqual(t, len(caption), 1024)
@@ -75,7 +75,7 @@ func TestTelegramNotifier(t *testing.T) {
Name: "This is an alarm",
Message: "Some kind of message.",
State: models.AlertStateOK,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
caption := generateImageCaption(evalContext,
"http://grafa.url/abcdefaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
@@ -93,7 +93,7 @@ func TestTelegramNotifier(t *testing.T) {
Name: "This is an alarm",
Message: "Some kind of message that is too long for appending to our pretty little message, this line is actually exactly 197 chars long and I will get there in the end I promise I will. Yes siree that's it. But suddenly Telegram increased the length so now we need some lorem ipsum to fix this test. Here we go: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur molestie cursus. Donec suscipit egestas nisi. Proin ut efficitur ex. Mauris mi augue, volutpat a nisi vel, euismod dictum arcu. Sed quis tempor eros, sed malesuada dolor. Ut orci augue, viverra sit amet blandit quis, faucibus sit amet ex. Duis condimentum efficitur lectus, id dignissim quam tempor id. Morbi sollicitudin rhoncus diam, id tincidunt lectus scelerisque vitae. Etiam imperdiet semper sem, vel eleifend ligula mollis eget. Etiam ultrices fringilla lacus, sit amet pharetra ex blandit quis. Suspendisse in egestas neque, et posuere lectus. Vestibulum eu ex dui. Sed molestie nulla a lobortis scelerisque. Nulla ipsum ex, iaculis vitae vehicula sit amet, fermentum eu eros.",
State: models.AlertStateOK,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
caption := generateImageCaption(evalContext,
"http://grafa.url/foo",
@@ -110,7 +110,7 @@ func TestTelegramNotifier(t *testing.T) {
Name: "This is an alarm",
Message: "Some kind of message that is too long for appending to our pretty little message, this line is actually exactly 197 chars long and I will get there in the end I promise I will. Yes siree that's it. But suddenly Telegram increased the length so now we need some lorem ipsum to fix this test. Here we go: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus consectetur molestie cursus. Donec suscipit egestas nisi. Proin ut efficitur ex. Mauris mi augue, volutpat a nisi vel, euismod dictum arcu. Sed quis tempor eros, sed malesuada dolor. Ut orci augue, viverra sit amet blandit quis, faucibus sit amet ex. Duis condimentum efficitur lectus, id dignissim quam tempor id. Morbi sollicitudin rhoncus diam, id tincidunt lectus scelerisque vitae. Etiam imperdiet semper sem, vel eleifend ligula mollis eget. Etiam ultrices fringilla lacus, sit amet pharetra ex blandit quis. Suspendisse in egestas neque, et posuere lectus. Vestibulum eu ex dui. Sed molestie nulla a lobortis sceleri",
State: models.AlertStateOK,
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
caption := generateImageCaption(evalContext,
"http://grafa.url/foo",

View File

@@ -5,6 +5,7 @@ import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/alerting"
@@ -90,7 +91,7 @@ func TestVictoropsNotifier(t *testing.T) {
{Key: "keyOnly"},
{Key: "severity", Value: "warning"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.IsTestRun = true
payload, err := victoropsNotifier.buildEventPayload(evalContext)
@@ -138,7 +139,7 @@ func TestVictoropsNotifier(t *testing.T) {
{Key: "keyOnly"},
{Key: "severity", Value: "warning"},
},
}, &validations.OSSPluginRequestValidator{}, nil)
}, &validations.OSSPluginRequestValidator{}, nil, nil)
evalContext.IsTestRun = true
payload, err := victoropsNotifier.buildEventPayload(evalContext)

View File

@@ -57,7 +57,7 @@ func createTestEvalContext(cmd *NotificationTestCommand) *EvalContext {
ID: rand.Int63(),
}
ctx := NewEvalContext(context.Background(), testRule, fakeRequestValidator{}, nil)
ctx := NewEvalContext(context.Background(), testRule, fakeRequestValidator{}, nil, nil)
if cmd.Settings.Get("uploadImage").MustBool(true) {
ctx.ImagePublicURL = "https://grafana.com/assets/img/blog/mixed_styles.png"
}

View File

@@ -32,7 +32,7 @@ func (e *AlertEngine) AlertTest(orgID int64, dashboard *simplejson.Json, panelID
handler := NewEvalHandler(e.DataService)
context := NewEvalContext(context.Background(), rule, fakeRequestValidator{}, e.sqlStore)
context := NewEvalContext(context.Background(), rule, fakeRequestValidator{}, e.sqlStore, nil)
context.IsTestRun = true
context.IsDebug = true

View File

@@ -15,15 +15,16 @@ import (
// DashboardService is a service for operating on dashboards.
type DashboardService interface {
SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error)
GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error)
SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error)
ImportDashboard(ctx context.Context, dto *SaveDashboardDTO) (*models.Dashboard, error)
DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error
MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
BuildSaveDashboardCommand(ctx context.Context, dto *SaveDashboardDTO, shouldValidateAlerts bool, validateProvisionedDashboard bool) (*models.SaveDashboardCommand, error)
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
DeleteDashboard(ctx context.Context, dashboardId int64, orgId int64) error
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
GetPublicDashboardConfig(ctx context.Context, orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error)
ImportDashboard(ctx context.Context, dto *SaveDashboardDTO) (*models.Dashboard, error)
MakeUserAdmin(ctx context.Context, orgID int64, userID, dashboardID int64, setViewAndEditPermissions bool) error
SaveDashboard(ctx context.Context, dto *SaveDashboardDTO, allowUiUpdate bool) (*models.Dashboard, error)
SavePublicDashboardConfig(ctx context.Context, dto *SavePublicDashboardConfigDTO) (*models.PublicDashboardConfig, error)
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
}
// PluginService is a service for operating on plugin dashboards.
@@ -34,37 +35,39 @@ type PluginService interface {
//go:generate mockery --name DashboardProvisioningService --structname FakeDashboardProvisioning --inpackage --filename dashboard_provisioning_mock.go
// DashboardProvisioningService is a service for operating on provisioned dashboards.
type DashboardProvisioningService interface {
SaveProvisionedDashboard(ctx context.Context, dto *SaveDashboardDTO, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
SaveFolderForProvisionedDashboards(context.Context, *SaveDashboardDTO) (*models.Dashboard, error)
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
UnprovisionDashboard(ctx context.Context, dashboardID int64) error
DeleteProvisionedDashboard(ctx context.Context, dashboardID int64, orgID int64) error
DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *models.DeleteOrphanedProvisionedDashboardsCommand) error
DeleteProvisionedDashboard(ctx context.Context, dashboardID int64, orgID int64) error
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDashboardDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
SaveFolderForProvisionedDashboards(context.Context, *SaveDashboardDTO) (*models.Dashboard, error)
SaveProvisionedDashboard(ctx context.Context, dto *SaveDashboardDTO, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
UnprovisionDashboard(ctx context.Context, dashboardID int64) error
}
//go:generate mockery --name Store --structname FakeDashboardStore --inpackage --filename database_mock.go
// Store is a dashboard store.
type Store interface {
// ValidateDashboardBeforeSave validates a dashboard before save.
ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error)
GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
SavePublicDashboardConfig(cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboardConfig, error)
GetPublicDashboardConfig(orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error)
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error
DeleteOrphanedProvisionedDashboards(ctx context.Context, cmd *models.DeleteOrphanedProvisionedDashboardsCommand) error
// SaveAlerts saves dashboard alerts.
SaveAlerts(ctx context.Context, dashID int64, alerts []*models.Alert) error
UnprovisionDashboard(ctx context.Context, id int64) error
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
// GetDashboardsByPluginID retrieves dashboards identified by plugin.
GetDashboardsByPluginID(ctx context.Context, query *models.GetDashboardsByPluginIdQuery) error
GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error
DeleteDashboard(ctx context.Context, cmd *models.DeleteDashboardCommand) error
GetProvisionedDashboardData(name string) ([]*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardID(dashboardID int64) (*models.DashboardProvisioning, error)
GetProvisionedDataByDashboardUID(orgID int64, dashboardUID string) (*models.DashboardProvisioning, error)
GetPublicDashboardConfig(orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error)
// SaveAlerts saves dashboard alerts.
SaveAlerts(ctx context.Context, dashID int64, alerts []*models.Alert) error
SaveDashboard(cmd models.SaveDashboardCommand) (*models.Dashboard, error)
SaveProvisionedDashboard(cmd models.SaveDashboardCommand, provisioning *models.DashboardProvisioning) (*models.Dashboard, error)
SavePublicDashboardConfig(cmd models.SavePublicDashboardConfigCommand) (*models.PublicDashboardConfig, error)
UnprovisionDashboard(ctx context.Context, id int64) error
UpdateDashboardACL(ctx context.Context, uid int64, items []*models.DashboardAcl) error
// ValidateDashboardBeforeSave validates a dashboard before save.
ValidateDashboardBeforeSave(dashboard *models.Dashboard, overwrite bool) (bool, error)
FolderStore
}

View File

@@ -69,3 +69,7 @@ func (s *FakeDashboardService) GetDashboard(ctx context.Context, cmd *models.Get
cmd.Result = d
return nil
}
func (s *FakeDashboardService) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
return nil
}

View File

@@ -889,3 +889,18 @@ func (d *DashboardStore) GetDashboard(ctx context.Context, query *models.GetDash
return nil
})
}
func (d *DashboardStore) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
return d.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
var rawSQL = `SELECT uid, slug from dashboard WHERE Id=?`
us := &models.DashboardRef{}
exists, err := sess.SQL(rawSQL, query.Id).Get(us)
if err != nil {
return err
} else if !exists {
return models.ErrDashboardNotFound
}
query.Result = us
return nil
})
}

View File

@@ -109,6 +109,14 @@ func TestDashboardDataAccess(t *testing.T) {
require.False(t, query.Result.IsFolder)
})
t.Run("Should be able to get a dashboard UID by ID", func(t *testing.T) {
setup()
query := models.GetDashboardRefByIdQuery{Id: savedDash.Id}
err := dashboardStore.GetDashboardUIDById(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.Uid, savedDash.Uid)
})
t.Run("Shouldn't be able to get a dashboard with just an OrgID", func(t *testing.T) {
setup()
query := models.GetDashboardQuery{

View File

@@ -58,6 +58,20 @@ func (_m *FakeDashboardStore) GetDashboard(ctx context.Context, query *models.Ge
return r0
}
// GetDashboardUIDById provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
ret := _m.Called(ctx, query)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.GetDashboardRefByIdQuery) error); ok {
r0 = rf(ctx, query)
} else {
r0 = ret.Error(0)
}
return r0
}
// GetDashboardsByPluginID provides a mock function with given fields: ctx, query
func (_m *FakeDashboardStore) GetDashboardsByPluginID(ctx context.Context, query *models.GetDashboardsByPluginIdQuery) error {
ret := _m.Called(ctx, query)
@@ -210,13 +224,13 @@ func (_m *FakeDashboardStore) GetProvisionedDataByDashboardUID(orgID int64, dash
return r0, r1
}
// GetPublicDashboardConfig provides a mock function with given fields: dashboardUid
// GetPublicDashboardConfig provides a mock function with given fields: orgId, dashboardUid
func (_m *FakeDashboardStore) GetPublicDashboardConfig(orgId int64, dashboardUid string) (*models.PublicDashboardConfig, error) {
ret := _m.Called(dashboardUid)
ret := _m.Called(orgId, dashboardUid)
var r0 *models.PublicDashboardConfig
if rf, ok := ret.Get(0).(func(string) *models.PublicDashboardConfig); ok {
r0 = rf(dashboardUid)
if rf, ok := ret.Get(0).(func(int64, string) *models.PublicDashboardConfig); ok {
r0 = rf(orgId, dashboardUid)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*models.PublicDashboardConfig)
@@ -224,8 +238,8 @@ func (_m *FakeDashboardStore) GetPublicDashboardConfig(orgId int64, dashboardUid
}
var r1 error
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(dashboardUid)
if rf, ok := ret.Get(1).(func(int64, string) error); ok {
r1 = rf(orgId, dashboardUid)
} else {
r1 = ret.Error(1)
}

View File

@@ -7,6 +7,7 @@ import (
"time"
"github.com/grafana/grafana-plugin-sdk-go/backend/gtime"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
@@ -26,6 +27,8 @@ var (
m.ActionDashboardsCreate: {m.ScopeFoldersAll},
m.ActionDashboardsWrite: {m.ScopeFoldersAll},
}
// DashboardServiceImpl implements the DashboardService interface
_ m.DashboardService = (*DashboardServiceImpl)(nil)
)
type DashboardServiceImpl struct {
@@ -511,3 +514,7 @@ func (dr *DashboardServiceImpl) setDefaultPermissions(ctx context.Context, dto *
func (dr *DashboardServiceImpl) GetDashboard(ctx context.Context, query *models.GetDashboardQuery) error {
return dr.dashboardStore.GetDashboard(ctx, query)
}
func (dr *DashboardServiceImpl) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
return dr.dashboardStore.GetDashboardUIDById(ctx, query)
}

View File

@@ -293,25 +293,6 @@ func (ss *SQLStore) GetDashboardPermissionsForUser(ctx context.Context, query *m
})
}
func (ss *SQLStore) GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error {
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {
var rawSQL = `SELECT uid, slug from dashboard WHERE Id=?`
us := &models.DashboardRef{}
exists, err := dbSession.SQL(rawSQL, query.Id).Get(us)
if err != nil {
return err
} else if !exists {
return models.ErrDashboardNotFound
}
query.Result = us
return nil
})
}
// HasEditPermissionInFolders validates that an user have access to a certain folder
func (ss *SQLStore) HasEditPermissionInFolders(ctx context.Context, query *models.HasEditPermissionInFoldersQuery) error {
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {

View File

@@ -99,7 +99,6 @@ type Store interface {
GetDashboardTags(ctx context.Context, query *models.GetDashboardTagsQuery) error
SearchDashboards(ctx context.Context, query *models.FindPersistedDashboardsQuery) error
GetDashboards(ctx context.Context, query *models.GetDashboardsQuery) error
GetDashboardUIDById(ctx context.Context, query *models.GetDashboardRefByIdQuery) error
GetDataSource(ctx context.Context, query *models.GetDataSourceQuery) error
GetDataSources(ctx context.Context, query *models.GetDataSourcesQuery) error
GetDataSourcesByType(ctx context.Context, query *models.GetDataSourcesByTypeQuery) error