grafana/pkg/services/ngalert/limits.go
Alexander Weaver ab0ef5276f
Alerting: Decouple quota configuration logic from API interfaces and add tests (#78930)
* Separate usage reporter from API

* Extract quota registration

* Decouple from API store interface

* Move to ngalert package and add tests

* linter
2023-12-01 10:47:19 -06:00

89 lines
2.1 KiB
Go

package ngalert
import (
"context"
"github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/setting"
)
type RuleUsageReader interface {
Count(ctx context.Context, orgID int64) (int64, error)
}
func RegisterQuotas(cfg *setting.Cfg, qs quota.Service, rules RuleUsageReader) error {
defaultLimits, err := readQuotaConfig(cfg)
if err != nil {
return err
}
return qs.RegisterQuotaReporter(&quota.NewUsageReporter{
TargetSrv: models.QuotaTargetSrv,
DefaultLimits: defaultLimits,
Reporter: UsageReporter(rules),
})
}
func UsageReporter(rules RuleUsageReader) quota.UsageReporterFunc {
return func(ctx context.Context, scopeParams *quota.ScopeParameters) (*quota.Map, error) {
u := &quota.Map{}
var orgID int64 = 0
if scopeParams != nil {
orgID = scopeParams.OrgID
}
if orgUsage, err := rules.Count(ctx, orgID); err != nil {
return u, err
} else {
tag, err := quota.NewTag(models.QuotaTargetSrv, models.QuotaTarget, quota.OrgScope)
if err != nil {
return u, err
}
u.Set(tag, orgUsage)
}
if globalUsage, err := rules.Count(ctx, 0); err != nil {
return u, err
} else {
tag, err := quota.NewTag(models.QuotaTargetSrv, models.QuotaTarget, quota.GlobalScope)
if err != nil {
return u, err
}
u.Set(tag, globalUsage)
}
return u, nil
}
}
func readQuotaConfig(cfg *setting.Cfg) (*quota.Map, error) {
limits := &quota.Map{}
if cfg == nil {
return limits, nil
}
var alertOrgQuota int64
var alertGlobalQuota int64
if cfg.UnifiedAlerting.IsEnabled() {
alertOrgQuota = cfg.Quota.Org.AlertRule
alertGlobalQuota = cfg.Quota.Global.AlertRule
}
globalQuotaTag, err := quota.NewTag(models.QuotaTargetSrv, models.QuotaTarget, quota.GlobalScope)
if err != nil {
return limits, err
}
orgQuotaTag, err := quota.NewTag(models.QuotaTargetSrv, models.QuotaTarget, quota.OrgScope)
if err != nil {
return limits, err
}
limits.Set(globalQuotaTag, alertGlobalQuota)
limits.Set(orgQuotaTag, alertOrgQuota)
return limits, nil
}