2021-12-27 17:01:17 -06:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2023-08-08 11:29:34 -05:00
|
|
|
"context"
|
2022-03-09 12:20:29 -06:00
|
|
|
"fmt"
|
|
|
|
"sync"
|
2021-12-27 17:01:17 -06:00
|
|
|
"testing"
|
2022-03-09 12:20:29 -06:00
|
|
|
"time"
|
2021-12-27 17:01:17 -06:00
|
|
|
|
2023-01-30 02:55:35 -06:00
|
|
|
"github.com/grafana/grafana-plugin-sdk-go/data"
|
|
|
|
|
2023-08-08 11:29:34 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
2023-08-09 04:27:14 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/auth/identity"
|
2022-03-09 12:20:29 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/eval"
|
2023-11-15 10:54:54 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/models"
|
2022-03-09 12:20:29 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/state"
|
2023-11-15 10:54:54 -06:00
|
|
|
"github.com/grafana/grafana/pkg/services/ngalert/store"
|
2023-08-08 11:29:34 -05:00
|
|
|
"github.com/grafana/grafana/pkg/services/user"
|
2021-12-27 17:01:17 -06:00
|
|
|
)
|
|
|
|
|
2022-03-09 12:20:29 -06:00
|
|
|
type fakeAlertInstanceManager struct {
|
|
|
|
mtx sync.Mutex
|
|
|
|
// orgID -> RuleID -> States
|
|
|
|
states map[int64]map[string][]*state.State
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewFakeAlertInstanceManager(t *testing.T) *fakeAlertInstanceManager {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
return &fakeAlertInstanceManager{
|
|
|
|
states: map[int64]map[string][]*state.State{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *fakeAlertInstanceManager) GetAll(orgID int64) []*state.State {
|
|
|
|
f.mtx.Lock()
|
|
|
|
defer f.mtx.Unlock()
|
|
|
|
var s []*state.State
|
|
|
|
|
|
|
|
for orgID := range f.states {
|
|
|
|
for _, states := range f.states[orgID] {
|
|
|
|
s = append(s, states...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *fakeAlertInstanceManager) GetStatesForRuleUID(orgID int64, alertRuleUID string) []*state.State {
|
|
|
|
f.mtx.Lock()
|
|
|
|
defer f.mtx.Unlock()
|
|
|
|
return f.states[orgID][alertRuleUID]
|
|
|
|
}
|
|
|
|
|
2022-03-14 05:39:20 -05:00
|
|
|
// forEachState represents the callback used when generating alert instances that allows us to modify the generated result
|
|
|
|
type forEachState func(s *state.State) *state.State
|
|
|
|
|
|
|
|
func (f *fakeAlertInstanceManager) GenerateAlertInstances(orgID int64, alertRuleUID string, count int, callbacks ...forEachState) {
|
2022-03-09 12:20:29 -06:00
|
|
|
f.mtx.Lock()
|
|
|
|
defer f.mtx.Unlock()
|
|
|
|
|
2022-03-14 05:39:20 -05:00
|
|
|
evaluationTime := timeNow()
|
2022-03-09 12:20:29 -06:00
|
|
|
evaluationDuration := 1 * time.Minute
|
|
|
|
|
|
|
|
for i := 0; i < count; i++ {
|
|
|
|
_, ok := f.states[orgID]
|
|
|
|
if !ok {
|
|
|
|
f.states[orgID] = map[string][]*state.State{}
|
|
|
|
}
|
|
|
|
_, ok = f.states[orgID][alertRuleUID]
|
|
|
|
if !ok {
|
|
|
|
f.states[orgID][alertRuleUID] = []*state.State{}
|
|
|
|
}
|
|
|
|
|
2022-03-14 05:39:20 -05:00
|
|
|
newState := &state.State{
|
|
|
|
AlertRuleUID: alertRuleUID,
|
2022-03-09 12:20:29 -06:00
|
|
|
OrgID: 1,
|
|
|
|
Labels: data.Labels{
|
|
|
|
"__alert_rule_namespace_uid__": "test_namespace_uid",
|
|
|
|
"__alert_rule_uid__": fmt.Sprintf("test_alert_rule_uid_%v", i),
|
|
|
|
"alertname": fmt.Sprintf("test_title_%v", i),
|
|
|
|
"label": "test",
|
|
|
|
"instance_label": "test",
|
|
|
|
},
|
|
|
|
State: eval.Normal,
|
|
|
|
Results: []state.Evaluation{
|
|
|
|
{
|
|
|
|
EvaluationTime: evaluationTime,
|
|
|
|
EvaluationState: eval.Normal,
|
|
|
|
Values: make(map[string]*float64),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
EvaluationTime: evaluationTime.Add(1 * time.Minute),
|
|
|
|
EvaluationState: eval.Normal,
|
|
|
|
Values: make(map[string]*float64),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
LastEvaluationTime: evaluationTime.Add(1 * time.Minute),
|
|
|
|
EvaluationDuration: evaluationDuration,
|
|
|
|
Annotations: map[string]string{"annotation": "test"},
|
2022-03-14 05:39:20 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if len(callbacks) != 0 {
|
|
|
|
for _, cb := range callbacks {
|
|
|
|
newState = cb(newState)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
f.states[orgID][alertRuleUID] = append(f.states[orgID][alertRuleUID], newState)
|
2022-03-09 12:20:29 -06:00
|
|
|
}
|
|
|
|
}
|
2023-08-08 11:29:34 -05:00
|
|
|
|
|
|
|
type recordingAccessControlFake struct {
|
|
|
|
Disabled bool
|
|
|
|
EvaluateRecordings []struct {
|
|
|
|
User *user.SignedInUser
|
|
|
|
Evaluator accesscontrol.Evaluator
|
|
|
|
}
|
|
|
|
Callback func(user *user.SignedInUser, evaluator accesscontrol.Evaluator) (bool, error)
|
|
|
|
}
|
|
|
|
|
2023-08-09 04:27:14 -05:00
|
|
|
func (a *recordingAccessControlFake) Evaluate(ctx context.Context, ur identity.Requester, evaluator accesscontrol.Evaluator) (bool, error) {
|
|
|
|
u := ur.(*user.SignedInUser)
|
2023-08-08 11:29:34 -05:00
|
|
|
a.EvaluateRecordings = append(a.EvaluateRecordings, struct {
|
|
|
|
User *user.SignedInUser
|
|
|
|
Evaluator accesscontrol.Evaluator
|
|
|
|
}{User: u, Evaluator: evaluator})
|
|
|
|
if a.Callback == nil {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
return a.Callback(u, evaluator)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *recordingAccessControlFake) RegisterScopeAttributeResolver(prefix string, resolver accesscontrol.ScopeAttributeResolver) {
|
|
|
|
// TODO implement me
|
|
|
|
panic("implement me")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *recordingAccessControlFake) IsDisabled() bool {
|
|
|
|
return a.Disabled
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ accesscontrol.AccessControl = &recordingAccessControlFake{}
|
2023-11-15 10:54:54 -06:00
|
|
|
|
|
|
|
type fakeRuleAccessControlService struct {
|
|
|
|
}
|
|
|
|
|
2023-12-01 17:42:11 -06:00
|
|
|
func (f fakeRuleAccessControlService) HasAccessToRuleGroup(ctx context.Context, user identity.Requester, rules models.RulesGroup) (bool, error) {
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f fakeRuleAccessControlService) AuthorizeAccessToRuleGroup(ctx context.Context, user identity.Requester, rules models.RulesGroup) error {
|
|
|
|
return nil
|
2023-11-15 10:54:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f fakeRuleAccessControlService) AuthorizeRuleChanges(ctx context.Context, user identity.Requester, change *store.GroupDelta) error {
|
|
|
|
return nil
|
|
|
|
}
|
2023-12-01 17:42:11 -06:00
|
|
|
|
|
|
|
func (f fakeRuleAccessControlService) AuthorizeDatasourceAccessForRule(ctx context.Context, user identity.Requester, rule *models.AlertRule) error {
|
|
|
|
return nil
|
|
|
|
}
|