mirror of
https://github.com/grafana/grafana.git
synced 2024-12-27 09:21:35 -06:00
Alerting: adds support for federated rules (#46037)
This commit is contained in:
parent
52629fbc4e
commit
a9b1a964b0
@ -208,9 +208,10 @@ func (c *PostableRuleGroupConfig) validate() error {
|
||||
|
||||
// swagger:model
|
||||
type GettableRuleGroupConfig struct {
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Interval model.Duration `yaml:"interval,omitempty" json:"interval,omitempty"`
|
||||
Rules []GettableExtendedRuleNode `yaml:"rules" json:"rules"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Interval model.Duration `yaml:"interval,omitempty" json:"interval,omitempty"`
|
||||
SourceTenants []string `yaml:"source_tenants,omitempty" json:"source_tenants,omitempty"`
|
||||
Rules []GettableExtendedRuleNode `yaml:"rules" json:"rules"`
|
||||
}
|
||||
|
||||
func (c *GettableRuleGroupConfig) UnmarshalJSON(b []byte) error {
|
||||
|
@ -98,6 +98,21 @@ func Test_Rule_Group_Marshaling(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "success federated lotex",
|
||||
input: PostableRuleGroupConfig{
|
||||
Name: "foo",
|
||||
Interval: 0,
|
||||
Rules: []PostableExtendedRuleNode{
|
||||
{
|
||||
ApiRuleNode: &ApiRuleNode{},
|
||||
},
|
||||
{
|
||||
ApiRuleNode: &ApiRuleNode{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "success grafana",
|
||||
input: PostableRuleGroupConfig{
|
||||
@ -189,6 +204,22 @@ func Test_Rule_Group_Type(t *testing.T) {
|
||||
},
|
||||
expected: LoTexRulerBackend,
|
||||
},
|
||||
{
|
||||
desc: "success federated lotex",
|
||||
input: PostableRuleGroupConfig{
|
||||
Name: "foo",
|
||||
Interval: 0,
|
||||
Rules: []PostableExtendedRuleNode{
|
||||
{
|
||||
ApiRuleNode: &ApiRuleNode{},
|
||||
},
|
||||
{
|
||||
ApiRuleNode: &ApiRuleNode{},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: LoTexRulerBackend,
|
||||
},
|
||||
{
|
||||
desc: "success grafana",
|
||||
input: PostableRuleGroupConfig{
|
||||
|
@ -980,6 +980,13 @@
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "Rules"
|
||||
},
|
||||
"source_tenants": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "SourceTenants"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
@ -2264,6 +2271,13 @@
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "Rules"
|
||||
},
|
||||
"source_tenants": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "SourceTenants"
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
@ -3233,12 +3247,11 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"type": "array",
|
||||
"x-go-name": "GettableAlerts",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
"type": "array"
|
||||
},
|
||||
"gettableSilence": {
|
||||
"description": "GettableSilence gettable silence",
|
||||
@ -3430,7 +3443,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"description": "comment",
|
||||
@ -3470,10 +3482,11 @@
|
||||
"matchers",
|
||||
"startsAt"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"x-go-name": "PostableSilence",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"properties": {
|
||||
"name": {
|
||||
"description": "name",
|
||||
@ -3484,7 +3497,9 @@
|
||||
"required": [
|
||||
"name"
|
||||
],
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"x-go-name": "Receiver",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"silence": {
|
||||
"description": "Silence silence",
|
||||
|
@ -2732,6 +2732,13 @@
|
||||
"$ref": "#/definitions/GettableExtendedRuleNode"
|
||||
},
|
||||
"x-go-name": "Rules"
|
||||
},
|
||||
"source_tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "SourceTenants"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
@ -4017,6 +4024,13 @@
|
||||
"$ref": "#/definitions/GettableExtendedRuleNode"
|
||||
},
|
||||
"x-go-name": "Rules"
|
||||
},
|
||||
"source_tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "SourceTenants"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
@ -4799,11 +4813,12 @@
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"x-go-name": "AlertGroups",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/alertGroups"
|
||||
},
|
||||
"alertStatus": {
|
||||
@ -4987,12 +5002,11 @@
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"x-go-name": "GettableAlerts",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/gettableAlerts"
|
||||
},
|
||||
"gettableSilence": {
|
||||
@ -5187,7 +5201,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"comment",
|
||||
@ -5228,10 +5241,11 @@
|
||||
"x-go-name": "StartsAt"
|
||||
}
|
||||
},
|
||||
"x-go-name": "PostableSilence",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/postableSilence"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"name"
|
||||
@ -5243,6 +5257,8 @@
|
||||
"x-go-name": "Name"
|
||||
}
|
||||
},
|
||||
"x-go-name": "Receiver",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models",
|
||||
"$ref": "#/definitions/receiver"
|
||||
},
|
||||
"silence": {
|
||||
|
@ -4494,15 +4494,15 @@
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"x-go-name": "DatasourceID",
|
||||
"name": "datasource_id",
|
||||
"x-go-name": "PermissionID",
|
||||
"name": "permissionId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"x-go-name": "PermissionID",
|
||||
"name": "permissionId",
|
||||
"x-go-name": "DatasourceID",
|
||||
"name": "datasource_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
@ -7846,14 +7846,6 @@
|
||||
"summary": "Add External Group.",
|
||||
"operationId": "addTeamGroupApi",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"x-go-name": "Body",
|
||||
"name": "body",
|
||||
@ -7862,6 +7854,14 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/TeamGroupMapping"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -7895,16 +7895,16 @@
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"x-go-name": "GroupID",
|
||||
"name": "groupId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "GroupID",
|
||||
"name": "groupId",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
@ -10143,7 +10143,7 @@
|
||||
},
|
||||
"x-go-package": "github.com/prometheus/common/config"
|
||||
},
|
||||
"BrandingOptions": {
|
||||
"BrandingOptionsDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"emailFooterLink": {
|
||||
@ -10280,7 +10280,7 @@
|
||||
"x-go-name": "Name"
|
||||
},
|
||||
"options": {
|
||||
"$ref": "#/definitions/ReportOptions"
|
||||
"$ref": "#/definitions/ReportOptionsDTO"
|
||||
},
|
||||
"orgId": {
|
||||
"type": "integer",
|
||||
@ -10296,10 +10296,11 @@
|
||||
"x-go-name": "ReplyTo"
|
||||
},
|
||||
"schedule": {
|
||||
"$ref": "#/definitions/Schedule"
|
||||
"$ref": "#/definitions/ScheduleDTO"
|
||||
},
|
||||
"state": {
|
||||
"$ref": "#/definitions/State"
|
||||
"type": "string",
|
||||
"x-go-name": "State"
|
||||
},
|
||||
"templateVars": {
|
||||
"type": "object",
|
||||
@ -10480,7 +10481,7 @@
|
||||
"x-go-name": "Name"
|
||||
},
|
||||
"options": {
|
||||
"$ref": "#/definitions/ReportOptions"
|
||||
"$ref": "#/definitions/ReportOptionsDTO"
|
||||
},
|
||||
"recipients": {
|
||||
"type": "string",
|
||||
@ -10491,7 +10492,7 @@
|
||||
"x-go-name": "ReplyTo"
|
||||
},
|
||||
"schedule": {
|
||||
"$ref": "#/definitions/Schedule"
|
||||
"$ref": "#/definitions/ScheduleDTO"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
@ -10762,6 +10763,10 @@
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanAdmin"
|
||||
},
|
||||
"canDelete": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanDelete"
|
||||
},
|
||||
"canEdit": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanEdit"
|
||||
@ -11723,6 +11728,10 @@
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanAdmin"
|
||||
},
|
||||
"canDelete": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanDelete"
|
||||
},
|
||||
"canEdit": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanEdit"
|
||||
@ -12068,8 +12077,8 @@
|
||||
},
|
||||
"exec_err_state": {
|
||||
"type": "string",
|
||||
"enum": ["Alerting", "Error"],
|
||||
"x-go-enum-desc": "Alerting AlertingErrState\nError ErrorErrState",
|
||||
"enum": ["OK", "Alerting", "Error"],
|
||||
"x-go-enum-desc": "OK OkErrState\nAlerting AlertingErrState\nError ErrorErrState",
|
||||
"x-go-name": "ExecErrState"
|
||||
},
|
||||
"id": {
|
||||
@ -12162,6 +12171,13 @@
|
||||
"$ref": "#/definitions/GettableExtendedRuleNode"
|
||||
},
|
||||
"x-go-name": "Rules"
|
||||
},
|
||||
"source_tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "SourceTenants"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
@ -13906,8 +13922,8 @@
|
||||
},
|
||||
"exec_err_state": {
|
||||
"type": "string",
|
||||
"enum": ["Alerting", "Error"],
|
||||
"x-go-enum-desc": "Alerting AlertingErrState\nError ErrorErrState",
|
||||
"enum": ["OK", "Alerting", "Error"],
|
||||
"x-go-enum-desc": "OK OkErrState\nAlerting AlertingErrState\nError ErrorErrState",
|
||||
"x-go-name": "ExecErrState"
|
||||
},
|
||||
"no_data_state": {
|
||||
@ -14266,7 +14282,7 @@
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report"
|
||||
},
|
||||
"ReportOptions": {
|
||||
"ReportOptionsDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"layout": {
|
||||
@ -14539,6 +14555,13 @@
|
||||
"$ref": "#/definitions/GettableExtendedRuleNode"
|
||||
},
|
||||
"x-go-name": "Rules"
|
||||
},
|
||||
"source_tenants": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"x-go-name": "SourceTenants"
|
||||
}
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
|
||||
@ -14673,7 +14696,7 @@
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
||||
},
|
||||
"Schedule": {
|
||||
"ScheduleDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"day": {
|
||||
@ -14824,7 +14847,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branding": {
|
||||
"$ref": "#/definitions/BrandingOptions"
|
||||
"$ref": "#/definitions/BrandingOptionsDTO"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer",
|
||||
@ -15054,10 +15077,6 @@
|
||||
"SmtpNotEnabled": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
"State": {
|
||||
"type": "string",
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report"
|
||||
},
|
||||
"Status": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -16772,12 +16791,11 @@
|
||||
}
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"x-go-name": "GettableAlerts",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
}
|
||||
},
|
||||
"gettableSilence": {
|
||||
"description": "GettableSilence gettable silence",
|
||||
@ -16951,7 +16969,6 @@
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"postableSilence": {
|
||||
"description": "PostableSilence postable silence",
|
||||
"type": "object",
|
||||
"required": ["comment", "createdBy", "endsAt", "matchers", "startsAt"],
|
||||
"properties": {
|
||||
@ -16985,10 +17002,11 @@
|
||||
"format": "date-time",
|
||||
"x-go-name": "StartsAt"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-go-name": "PostableSilence",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"type": "object",
|
||||
"required": ["name"],
|
||||
"properties": {
|
||||
@ -16997,7 +17015,9 @@
|
||||
"type": "string",
|
||||
"x-go-name": "Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-go-name": "Receiver",
|
||||
"x-go-package": "github.com/prometheus/alertmanager/api/v2/models"
|
||||
},
|
||||
"silence": {
|
||||
"description": "Silence silence",
|
||||
|
@ -3544,15 +3544,15 @@
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"x-go-name": "DatasourceID",
|
||||
"name": "datasource_id",
|
||||
"x-go-name": "PermissionID",
|
||||
"name": "permissionId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"x-go-name": "PermissionID",
|
||||
"name": "permissionId",
|
||||
"x-go-name": "DatasourceID",
|
||||
"name": "datasource_id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
@ -6424,14 +6424,6 @@
|
||||
"summary": "Add External Group.",
|
||||
"operationId": "addTeamGroupApi",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"x-go-name": "Body",
|
||||
"name": "body",
|
||||
@ -6440,6 +6432,14 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/TeamGroupMapping"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -6473,16 +6473,16 @@
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"x-go-name": "GroupID",
|
||||
"name": "groupId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "integer",
|
||||
"format": "int64",
|
||||
"x-go-name": "GroupID",
|
||||
"name": "groupId",
|
||||
"x-go-name": "TeamID",
|
||||
"name": "teamId",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
@ -8333,7 +8333,7 @@
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
||||
},
|
||||
"BrandingOptions": {
|
||||
"BrandingOptionsDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"emailFooterLink": {
|
||||
@ -8436,7 +8436,7 @@
|
||||
"x-go-name": "Name"
|
||||
},
|
||||
"options": {
|
||||
"$ref": "#/definitions/ReportOptions"
|
||||
"$ref": "#/definitions/ReportOptionsDTO"
|
||||
},
|
||||
"orgId": {
|
||||
"type": "integer",
|
||||
@ -8452,10 +8452,11 @@
|
||||
"x-go-name": "ReplyTo"
|
||||
},
|
||||
"schedule": {
|
||||
"$ref": "#/definitions/Schedule"
|
||||
"$ref": "#/definitions/ScheduleDTO"
|
||||
},
|
||||
"state": {
|
||||
"$ref": "#/definitions/State"
|
||||
"type": "string",
|
||||
"x-go-name": "State"
|
||||
},
|
||||
"templateVars": {
|
||||
"type": "object",
|
||||
@ -8636,7 +8637,7 @@
|
||||
"x-go-name": "Name"
|
||||
},
|
||||
"options": {
|
||||
"$ref": "#/definitions/ReportOptions"
|
||||
"$ref": "#/definitions/ReportOptionsDTO"
|
||||
},
|
||||
"recipients": {
|
||||
"type": "string",
|
||||
@ -8647,7 +8648,7 @@
|
||||
"x-go-name": "ReplyTo"
|
||||
},
|
||||
"schedule": {
|
||||
"$ref": "#/definitions/Schedule"
|
||||
"$ref": "#/definitions/ScheduleDTO"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
@ -8918,6 +8919,10 @@
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanAdmin"
|
||||
},
|
||||
"canDelete": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanDelete"
|
||||
},
|
||||
"canEdit": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanEdit"
|
||||
@ -9695,6 +9700,10 @@
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanAdmin"
|
||||
},
|
||||
"canDelete": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanDelete"
|
||||
},
|
||||
"canEdit": {
|
||||
"type": "boolean",
|
||||
"x-go-name": "CanEdit"
|
||||
@ -10839,7 +10848,7 @@
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report"
|
||||
},
|
||||
"ReportOptions": {
|
||||
"ReportOptionsDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"layout": {
|
||||
@ -10971,7 +10980,7 @@
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/models"
|
||||
},
|
||||
"Schedule": {
|
||||
"ScheduleDTO": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"day": {
|
||||
@ -11113,7 +11122,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"branding": {
|
||||
"$ref": "#/definitions/BrandingOptions"
|
||||
"$ref": "#/definitions/BrandingOptionsDTO"
|
||||
},
|
||||
"id": {
|
||||
"type": "integer",
|
||||
@ -11133,10 +11142,6 @@
|
||||
},
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report"
|
||||
},
|
||||
"State": {
|
||||
"type": "string",
|
||||
"x-go-package": "github.com/grafana/grafana/pkg/extensions/report"
|
||||
},
|
||||
"Status": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -9,6 +9,8 @@ import {
|
||||
LoadingPlaceholder,
|
||||
PanelChromeLoadingIndicator,
|
||||
Icon,
|
||||
Button,
|
||||
VerticalGroup,
|
||||
} from '@grafana/ui';
|
||||
import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
|
||||
import { AlertingQueryRunner } from './state/AlertingQueryRunner';
|
||||
@ -28,6 +30,8 @@ import { RuleDetailsExpression } from './components/rules/RuleDetailsExpression'
|
||||
import { RuleDetailsAnnotations } from './components/rules/RuleDetailsAnnotations';
|
||||
import * as ruleId from './utils/rule-id';
|
||||
import { AlertQuery } from '../../../types/unified-alerting-dto';
|
||||
import { RuleDetailsFederatedSources } from './components/rules/RuleDetailsFederatedSources';
|
||||
import { isFederatedRuleGroup } from './utils/rules';
|
||||
|
||||
type RuleViewerProps = GrafanaRouteComponentProps<{ id?: string; sourceName?: string }>;
|
||||
|
||||
@ -115,9 +119,24 @@ export function RuleViewer({ match }: RuleViewerProps) {
|
||||
</RuleViewerLayout>
|
||||
);
|
||||
}
|
||||
|
||||
const annotations = Object.entries(rule.annotations).filter(([_, value]) => !!value.trim());
|
||||
const isFederatedRule = isFederatedRuleGroup(rule.group);
|
||||
|
||||
return (
|
||||
<RuleViewerLayout wrapInContent={false} title={pageTitle}>
|
||||
{isFederatedRule && (
|
||||
<Alert severity="info" title="This rule is part of a federated rule group.">
|
||||
<VerticalGroup>
|
||||
Federated rule groups are currently an experimental feature.
|
||||
<Button fill="text" icon="book">
|
||||
<a href="https://grafana.com/docs/metrics-enterprise/latest/tenant-management/tenant-federation/#cross-tenant-alerting-and-recording-rule-federation">
|
||||
Read documentation
|
||||
</a>
|
||||
</Button>
|
||||
</VerticalGroup>
|
||||
</Alert>
|
||||
)}
|
||||
<RuleViewerLayoutContent>
|
||||
<div>
|
||||
<h4>
|
||||
@ -143,6 +162,7 @@ export function RuleViewer({ match }: RuleViewerProps) {
|
||||
</div>
|
||||
<div className={styles.rightSide}>
|
||||
<RuleDetailsDataSources rule={rule} rulesSource={rulesSource} />
|
||||
{isFederatedRule && <RuleDetailsFederatedSources group={rule.group} />}
|
||||
<DetailsField label="Namespace / Group">{`${rule.namespace.name} / ${rule.group.name}`}</DetailsField>
|
||||
</div>
|
||||
</div>
|
||||
@ -150,7 +170,7 @@ export function RuleViewer({ match }: RuleViewerProps) {
|
||||
<RuleDetailsMatchingInstances promRule={rule.promRule} />
|
||||
</div>
|
||||
</RuleViewerLayoutContent>
|
||||
{data && Object.keys(data).length > 0 && (
|
||||
{!isFederatedRule && data && Object.keys(data).length > 0 && (
|
||||
<>
|
||||
<div className={styles.queriesTitle}>
|
||||
Query results <PanelChromeLoadingIndicator loading={isLoading(data)} onCancel={() => runner.cancel()} />
|
||||
|
@ -17,6 +17,7 @@ import { CombinedRule, RulesSource } from 'app/types/unified-alerting';
|
||||
import { getAlertmanagerByUid } from '../../utils/alertmanager';
|
||||
import { useStateHistoryModal } from '../../hooks/useStateHistoryModal';
|
||||
import { RulerGrafanaRuleDTO, RulerRuleDTO } from 'app/types/unified-alerting-dto';
|
||||
import { isFederatedRuleGroup } from '../../utils/rules';
|
||||
|
||||
interface Props {
|
||||
rule: CombinedRule;
|
||||
@ -40,6 +41,7 @@ export const RuleDetailsActionButtons: FC<Props> = ({ rule, rulesSource }) => {
|
||||
const leftButtons: JSX.Element[] = [];
|
||||
const rightButtons: JSX.Element[] = [];
|
||||
|
||||
const isFederated = isFederatedRuleGroup(group);
|
||||
const { isEditable } = useIsRuleEditable(getRulesSourceName(rulesSource), rulerRule);
|
||||
const returnTo = location.pathname + location.search;
|
||||
const isViewMode = inViewMode(location.pathname);
|
||||
@ -68,7 +70,8 @@ export const RuleDetailsActionButtons: FC<Props> = ({ rule, rulesSource }) => {
|
||||
};
|
||||
|
||||
// explore does not support grafana rule queries atm
|
||||
if (isCloudRulesSource(rulesSource) && contextSrv.isEditor) {
|
||||
// neither do "federated rules"
|
||||
if (isCloudRulesSource(rulesSource) && contextSrv.isEditor && !isFederated) {
|
||||
leftButtons.push(
|
||||
<LinkButton
|
||||
className={style.button}
|
||||
@ -174,7 +177,7 @@ export const RuleDetailsActionButtons: FC<Props> = ({ rule, rulesSource }) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (isEditable && rulerRule) {
|
||||
if (isEditable && rulerRule && !isFederated) {
|
||||
const sourceName = getRulesSourceName(rulesSource);
|
||||
const identifier = ruleId.fromRulerRule(sourceName, namespace.name, group.name, rulerRule);
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { CombinedRuleGroup } from 'app/types/unified-alerting';
|
||||
import React, { FC } from 'react';
|
||||
import { DetailsField } from '../DetailsField';
|
||||
|
||||
interface Props {
|
||||
group: CombinedRuleGroup;
|
||||
}
|
||||
|
||||
const RuleDetailsFederatedSources: FC<Props> = ({ group }) => {
|
||||
const sourceTenants = group.source_tenants ?? [];
|
||||
|
||||
return (
|
||||
<DetailsField label="Tenant sources">
|
||||
<>
|
||||
{sourceTenants.map((tenant) => (
|
||||
<div key={tenant}>{tenant}</div>
|
||||
))}
|
||||
</>
|
||||
</DetailsField>
|
||||
);
|
||||
};
|
||||
|
||||
export { RuleDetailsFederatedSources };
|
@ -1,6 +1,6 @@
|
||||
import { css } from '@emotion/css';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { ConfirmModal, HorizontalGroup, Icon, Spinner, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import { Badge, ConfirmModal, HorizontalGroup, Icon, Spinner, Tooltip, useStyles2 } from '@grafana/ui';
|
||||
import kbn from 'app/core/utils/kbn';
|
||||
import { CombinedRuleGroup, CombinedRuleNamespace } from 'app/types/unified-alerting';
|
||||
import pluralize from 'pluralize';
|
||||
@ -10,7 +10,7 @@ import { useFolder } from '../../hooks/useFolder';
|
||||
import { useHasRuler } from '../../hooks/useHasRuler';
|
||||
import { deleteRulesGroupAction } from '../../state/actions';
|
||||
import { GRAFANA_RULES_SOURCE_NAME, isCloudRulesSource } from '../../utils/datasource';
|
||||
import { isGrafanaRulerRule } from '../../utils/rules';
|
||||
import { isFederatedRuleGroup, isGrafanaRulerRule } from '../../utils/rules';
|
||||
import { CollapseToggle } from '../CollapseToggle';
|
||||
import { ActionIcon } from './ActionIcon';
|
||||
import { EditCloudGroupModal } from './EditCloudGroupModal';
|
||||
@ -43,6 +43,7 @@ export const RulesGroup: FC<Props> = React.memo(({ group, namespace, expandAll }
|
||||
|
||||
// group "is deleting" if rules source has ruler, but this group has no rules that are in ruler
|
||||
const isDeleting = hasRuler(rulesSource) && !group.rules.find((rule) => !!rule.rulerRule);
|
||||
const isFederated = isFederatedRuleGroup(group);
|
||||
|
||||
const deleteGroup = () => {
|
||||
dispatch(deleteRulesGroupAction(namespace, group));
|
||||
@ -88,16 +89,18 @@ export const RulesGroup: FC<Props> = React.memo(({ group, namespace, expandAll }
|
||||
}
|
||||
}
|
||||
} else if (hasRuler(rulesSource)) {
|
||||
actionIcons.push(
|
||||
<ActionIcon
|
||||
aria-label="edit rule group"
|
||||
data-testid="edit-group"
|
||||
key="edit"
|
||||
icon="pen"
|
||||
tooltip="edit rule group"
|
||||
onClick={() => setIsEditingGroup(true)}
|
||||
/>
|
||||
);
|
||||
if (!isFederated) {
|
||||
actionIcons.push(
|
||||
<ActionIcon
|
||||
aria-label="edit rule group"
|
||||
data-testid="edit-group"
|
||||
key="edit"
|
||||
icon="pen"
|
||||
tooltip="edit rule group"
|
||||
onClick={() => setIsEditingGroup(true)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
actionIcons.push(
|
||||
<ActionIcon
|
||||
@ -132,7 +135,9 @@ export const RulesGroup: FC<Props> = React.memo(({ group, namespace, expandAll }
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
<h6 className={styles.heading}>{groupName}</h6>
|
||||
<h6 className={styles.heading}>
|
||||
{isFederated && <Badge color="purple" text="Federated" />} {groupName}
|
||||
</h6>
|
||||
<div className={styles.spacer} />
|
||||
<div className={styles.headerStats}>
|
||||
<RuleStats showInactive={false} group={group} />
|
||||
|
@ -105,6 +105,7 @@ function addRulerGroupsToCombinedNamespace(namespace: CombinedRuleNamespace, gro
|
||||
const combinedGroup: CombinedRuleGroup = {
|
||||
name: group.name,
|
||||
interval: group.interval,
|
||||
source_tenants: group.source_tenants,
|
||||
rules: [],
|
||||
};
|
||||
combinedGroup.rules = group.rules.map((rule) => rulerRuleToCombinedRule(rule, namespace, combinedGroup));
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
Alert,
|
||||
AlertingRule,
|
||||
CloudRuleIdentifier,
|
||||
CombinedRuleGroup,
|
||||
GrafanaRuleIdentifier,
|
||||
PrometheusRuleIdentifier,
|
||||
PromRuleWithLocation,
|
||||
@ -116,3 +117,13 @@ export function getFirstActiveAt(promRule: AlertingRule) {
|
||||
return prev;
|
||||
}, null as Date | null);
|
||||
}
|
||||
|
||||
/**
|
||||
* A rule group is "federated" when it has at least one "source_tenants" entry, federated rule groups will evaluate rules in multiple tenants
|
||||
* Non-federated rules do not have this property
|
||||
*
|
||||
* see https://grafana.com/docs/metrics-enterprise/latest/tenant-management/tenant-federation/#cross-tenant-alerting-and-recording-rule-federation
|
||||
*/
|
||||
export function isFederatedRuleGroup(group: CombinedRuleGroup) {
|
||||
return Array.isArray(group.source_tenants);
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ export type PostableRuleDTO = RulerAlertingRuleDTO | RulerRecordingRuleDTO | Pos
|
||||
export type RulerRuleGroupDTO<R = RulerRuleDTO> = {
|
||||
name: string;
|
||||
interval?: string;
|
||||
source_tenants?: string[];
|
||||
rules: R[];
|
||||
};
|
||||
|
||||
|
@ -86,6 +86,7 @@ export interface CombinedRule {
|
||||
export interface CombinedRuleGroup {
|
||||
name: string;
|
||||
interval?: string;
|
||||
source_tenants?: string[];
|
||||
rules: CombinedRule[];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user