package definitions import ( "encoding/json" "fmt" "time" "github.com/grafana/grafana-plugin-sdk-go/backend" "github.com/grafana/grafana-plugin-sdk-go/data" amv2 "github.com/prometheus/alertmanager/api/v2/models" "github.com/prometheus/alertmanager/config" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/promql" ) // swagger:route Post /v1/rule/test/grafana testing RouteTestRuleGrafanaConfig // // Test a rule against Grafana ruler // // Consumes: // - application/json // // Produces: // - application/json // // Responses: // 200: TestGrafanaRuleResponse // 400: ValidationError // 404: NotFound // swagger:route Post /v1/rule/test/{DatasourceUID} testing RouteTestRuleConfig // // Test a rule against external data source ruler // // Consumes: // - application/json // // Produces: // - application/json // // Responses: // 200: TestRuleResponse // 404: NotFound // swagger:route Post /v1/eval testing RouteEvalQueries // // Test rule // // Consumes: // - application/json // // Produces: // - application/json // // Responses: // 200: EvalQueriesResponse // swagger:route Post /v1/rule/backtest testing BacktestConfig // // Test rule // // Consumes: // - application/json // // Produces: // - application/json // // Responses: // 200: BacktestResult // swagger:parameters RouteTestReceiverConfig type TestReceiverRequest struct { // in:body Body ExtendedReceiver } // swagger:parameters RouteTestRuleConfig type TestRuleRequest struct { // in:body Body TestRulePayload } // swagger:model type TestRulePayload struct { // Example: (node_filesystem_avail_bytes{fstype!="",job="integrations/node_exporter"} node_filesystem_size_bytes{fstype!="",job="integrations/node_exporter"} * 100 < 5 and node_filesystem_readonly{fstype!="",job="integrations/node_exporter"} == 0) Expr string `json:"expr,omitempty"` // GrafanaManagedCondition for grafana alerts GrafanaManagedCondition *EvalAlertConditionCommand `json:"grafana_condition,omitempty"` } // swagger:response TestGrafanaRuleResponse type TestGrafanaRuleResponse struct { // in:body Body []amv2.PostableAlert } // swagger:parameters RouteTestRuleGrafanaConfig type TestGrafanaRuleRequest struct { // in:body Body PostableExtendedRuleNodeExtended } // swagger:model type PostableExtendedRuleNodeExtended struct { // required: true Rule PostableExtendedRuleNode `json:"rule"` // example: okrd3I0Vz NamespaceUID string `json:"folderUid"` // example: project_x NamespaceTitle string `json:"folderTitle"` // example: eval_group_1 RuleGroup string `json:"ruleGroup"` } func (n *PostableExtendedRuleNodeExtended) UnmarshalJSON(b []byte) error { type plain PostableExtendedRuleNodeExtended if err := json.Unmarshal(b, (*plain)(n)); err != nil { return err } return nil } // swagger:parameters RouteEvalQueries type EvalQueriesRequest struct { // in:body Body EvalQueriesPayload } // swagger:model type EvalQueriesPayload struct { Condition string `json:"condition"` Data []AlertQuery `json:"data"` Now time.Time `json:"now"` } func (p *TestRulePayload) UnmarshalJSON(b []byte) error { type plain TestRulePayload if err := json.Unmarshal(b, (*plain)(p)); err != nil { return err } return p.validate() } func (p *TestRulePayload) validate() error { if p.Expr != "" && p.GrafanaManagedCondition != nil { return fmt.Errorf("cannot mix Grafana & Prometheus style expressions") } if p.Expr == "" && p.GrafanaManagedCondition == nil { return fmt.Errorf("missing either Grafana or Prometheus style expressions") } return nil } func (p *TestRulePayload) Type() (backend Backend) { if p.Expr != "" { return LoTexRulerBackend } if p.GrafanaManagedCondition != nil { return GrafanaBackend } return } // swagger:model type TestRuleResponse struct { Alerts promql.Vector `json:"alerts"` GrafanaAlertInstances AlertInstancesResponse `json:"grafana_alert_instances"` } // swagger:model type EvalQueriesResponse = backend.QueryDataResponse // swagger:model type AlertInstancesResponse struct { // Instances is an array of arrow encoded dataframes // each frame has a single row, and a column for each instance (alert identified by unique labels) with a boolean value (firing/not firing) Instances [][]byte `json:"instances"` } // swagger:model type ExtendedReceiver struct { EmailConfigs config.EmailConfig `yaml:"email_configs,omitempty" json:"email_configs,omitempty"` PagerdutyConfigs config.PagerdutyConfig `yaml:"pagerduty_configs,omitempty" json:"pagerduty_configs,omitempty"` SlackConfigs config.SlackConfig `yaml:"slack_configs,omitempty" json:"slack_configs,omitempty"` WebhookConfigs config.WebhookConfig `yaml:"webhook_configs,omitempty" json:"webhook_configs,omitempty"` OpsGenieConfigs config.OpsGenieConfig `yaml:"opsgenie_configs,omitempty" json:"opsgenie_configs,omitempty"` WechatConfigs config.WechatConfig `yaml:"wechat_configs,omitempty" json:"wechat_configs,omitempty"` PushoverConfigs config.PushoverConfig `yaml:"pushover_configs,omitempty" json:"pushover_configs,omitempty"` VictorOpsConfigs config.VictorOpsConfig `yaml:"victorops_configs,omitempty" json:"victorops_configs,omitempty"` GrafanaReceiver PostableGrafanaReceiver `yaml:"grafana_managed_receiver,omitempty" json:"grafana_managed_receiver,omitempty"` } // swagger:model type Success ResponseDetails // swagger:model type SmtpNotEnabled ResponseDetails // swagger:model type Failure ResponseDetails // swagger:model type ResponseDetails struct { Msg string `json:"msg"` } // swagger:parameters BacktestConfig type BacktestConfigRequest struct { // in:body Body BacktestConfig } // swagger:model type BacktestConfig struct { From time.Time `json:"from"` To time.Time `json:"to"` Interval model.Duration `json:"interval,omitempty"` Condition string `json:"condition"` Data []AlertQuery `json:"data"` For model.Duration `json:"for,omitempty"` Title string `json:"title"` Labels map[string]string `json:"labels,omitempty"` Annotations map[string]string `json:"annotations,omitempty"` NoDataState NoDataState `json:"no_data_state"` } // swagger:model type BacktestResult data.Frame