This adds provisioning endpoints for downloading alert rules and alert rule groups in a
format that is compatible with file provisioning. Each endpoint supports both json and
yaml response types via Accept header as well as a query parameter
download=true/false that will set Content-Disposition to recommend initiating a download
or inline display.
This also makes some package changes to keep structs with potential to drift closer
together. Eventually, other alerting file structs should also move into this new file
package, but the rest require some refactoring that is out of scope for this PR.
@ -22,20 +22,20 @@ Details on how to set up the files and which fields are required for each object
**Note:**
Provisioning takes place during the initial set up of your Grafana system, but you can re-run it at any time using the [Grafana Alerting provisioning API](https://grafana.com/docs/grafana/latest/developers/http_api/admin/#reload-provisioning-configurations).
Provisioning takes place during the initial set up of your Grafana system, but you can re-run it at any time using the [Grafana Admin API](https://grafana.com/docs/grafana/latest/developers/http_api/admin/#reload-provisioning-configurations).
### Provision alert rules
Create or delete alert rules in your Grafana instance(s).
1. Create an alert rule in Grafana.
1. Use the [Alerting provisioning API](https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/#route-get-alert-rule) to extract the alert rule.
1. Create alert rules in Grafana.
1. Use the [Alerting provisioning API](https://grafana.com/docs/grafana/latest/developers/http_api/alerting_provisioning/#route-get-alert-rule-export) export endpoints to download a provisioning file for your alert rules.
1. Copy the contents into a YAML or JSON configuration file in the default provisioning directory or in your configured directory.
Example configuration files can be found below.
1. Ensure that your files are in the right directory on the node running the Grafana server, so that they deploy alongside your Grafana instance(s).
1. Delete the alert rule in Grafana.
1. Delete the alert rules in Grafana that will be provisioned.
"title":"AlertQuery represents a single query associated with an alert definition.",
"type":"object"
},
"AlertQueryExport":{
"properties":{
"datasourceUid":{
"type":"string"
},
"model":{
"additionalProperties":{},
"type":"object"
},
"queryType":{
"type":"string"
},
"refId":{
"type":"string"
},
"relativeTimeRange":{
"$ref":"#/definitions/RelativeTimeRange"
}
},
"title":"AlertQueryExport is the provisioned export of models.AlertQuery.",
"type":"object"
},
"AlertResponse":{
"properties":{
"data":{
@ -141,6 +163,65 @@
],
"type":"object"
},
"AlertRuleExport":{
"properties":{
"annotations":{
"additionalProperties":{
"type":"string"
},
"type":"object"
},
"condition":{
"type":"string"
},
"dasboardUid":{
"type":"string"
},
"data":{
"items":{
"$ref":"#/definitions/AlertQueryExport"
},
"type":"array"
},
"execErrState":{
"enum":[
"Alerting",
"Error",
"OK"
],
"type":"string"
},
"for":{
"$ref":"#/definitions/Duration"
},
"labels":{
"additionalProperties":{
"type":"string"
},
"type":"object"
},
"noDataState":{
"enum":[
"Alerting",
"NoData",
"OK"
],
"type":"string"
},
"panelId":{
"format":"int64",
"type":"integer"
},
"title":{
"type":"string"
},
"uid":{
"type":"string"
}
},
"title":"AlertRuleExport is the provisioned file export of models.AlertRule.",
"type":"object"
},
"AlertRuleGroup":{
"properties":{
"folderUid":{
@ -162,6 +243,31 @@
},
"type":"object"
},
"AlertRuleGroupExport":{
"properties":{
"folder":{
"type":"string"
},
"interval":{
"$ref":"#/definitions/Duration"
},
"name":{
"type":"string"
},
"orgId":{
"format":"int64",
"type":"integer"
},
"rules":{
"items":{
"$ref":"#/definitions/AlertRuleExport"
},
"type":"array"
}
},
"title":"AlertRuleGroupExport is the provisioned file export of AlertRuleGroupV1.",
"type":"object"
},
"AlertRuleGroupMetadata":{
"properties":{
"interval":{
@ -171,6 +277,22 @@
},
"type":"object"
},
"AlertingFileExport":{
"properties":{
"apiVersion":{
"format":"int64",
"type":"integer"
},
"groups":{
"items":{
"$ref":"#/definitions/AlertRuleGroupExport"
},
"type":"array"
}
},
"title":"AlertingFileExport is the full provisioned file export.",
"type":"object"
},
"AlertingRule":{
"description":"adapted from cortex",
"properties":{
@ -3155,7 +3277,6 @@
"type":"object"
},
"URL":{
"description":"The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"properties":{
"ForceQuery":{
"type":"boolean"
@ -3191,7 +3312,7 @@
"$ref":"#/definitions/Userinfo"
}
},
"title":"A URL represents a parsed URL (technically, a URI reference).",
"title":"URL is a custom URL type that allows validation at configuration load time.",
"type":"object"
},
"Userinfo":{
@ -3551,6 +3672,7 @@
"type":"object"
},
"gettableAlerts":{
"description":"GettableAlerts gettable alerts",
"items":{
"$ref":"#/definitions/gettableAlert"
},
@ -3611,7 +3733,6 @@
"type":"array"
},
"integration":{
"description":"Integration integration",
"properties":{
"lastNotifyAttempt":{
"description":"A timestamp indicating the last attempt to deliver a notification regardless of the outcome.\nFormat: date-time",
@ -3793,6 +3914,7 @@
"type":"object"
},
"receiver":{
"description":"Receiver receiver",
"properties":{
"active":{
"description":"active",
@ -3967,6 +4089,35 @@
]
}
},
"/api/v1/provisioning/alert-rules/export":{
"get":{
"operationId":"RouteGetAlertRulesExport",
"parameters":[
{
"default":false,
"description":"Whether to initiate a download of the file or not.",
"in":"query",
"name":"download",
"type":"boolean"
}
],
"responses":{
"200":{
"description":"AlertingFileExport",
"schema":{
"$ref":"#/definitions/AlertingFileExport"
}
},
"404":{
"description":" Not found."
}
},
"summary":"Export all alert rules in provisioning file format.",
"tags":[
"provisioning"
]
}
},
"/api/v1/provisioning/alert-rules/{UID}":{
"delete":{
"operationId":"RouteDeleteAlertRule",
@ -4062,6 +4213,47 @@
]
}
},
"/api/v1/provisioning/alert-rules/{UID}/export":{
"get":{
"operationId":"RouteGetAlertRuleExport",
"parameters":[
{
"description":"Alert rule UID",
"in":"path",
"name":"UID",
"required":true,
"type":"string"
},
{
"default":false,
"description":"Whether to initiate a download of the file or not.",
"in":"query",
"name":"download",
"type":"boolean"
}
],
"produces":[
"application/json",
"application/yaml",
"text/yaml"
],
"responses":{
"200":{
"description":"AlertingFileExport",
"schema":{
"$ref":"#/definitions/AlertingFileExport"
}
},
"404":{
"description":" Not found."
}
},
"summary":"Export an alert rule in provisioning file format.",
"title":"AlertQuery represents a single query associated with an alert definition.",
"type":"object"
},
"AlertQueryExport":{
"properties":{
"datasourceUid":{
"type":"string"
},
"model":{
"additionalProperties":{},
"type":"object"
},
"queryType":{
"type":"string"
},
"refId":{
"type":"string"
},
"relativeTimeRange":{
"$ref":"#/definitions/RelativeTimeRange"
}
},
"title":"AlertQueryExport is the provisioned export of models.AlertQuery.",
"type":"object"
},
"AlertResponse":{
"properties":{
"data":{
@ -141,6 +163,77 @@
],
"type":"object"
},
"AlertRuleExport":{
"properties":{
"annotations":{
"additionalProperties":{
"type":"string"
},
"type":"object"
},
"condition":{
"type":"string"
},
"dasboardUid":{
"type":"string"
},
"data":{
"items":{
"$ref":"#/definitions/AlertQueryExport"
},
"type":"array"
},
"execErrState":{
"enum":[
"Alerting",
"Error",
"OK"
],
"type":"string"
},
"for":{
"$ref":"#/definitions/Duration"
},
"labels":{
"additionalProperties":{
"type":"string"
},
"type":"object"
},
"noDataState":{
"enum":[
"Alerting",
"NoData",
"OK"
],
"type":"string"
},
"panelId":{
"format":"int64",
"type":"integer"
},
"title":{
"type":"string"
},
"uid":{
"type":"string"
}
},
"title":"AlertRuleExport is the provisioned export of models.AlertRule.",
"type":"object"
},
"AlertRuleFileExport":{
"properties":{
"groups":{
"items":{
"$ref":"#/definitions/AlertRuleGroupExport"
},
"type":"array"
}
},
"title":"AlertRuleFileExport is the provisioned export of multiple models.AlertRuleGroup.",
"type":"object"
},
"AlertRuleGroup":{
"properties":{
"folderUid":{
@ -162,6 +255,31 @@
},
"type":"object"
},
"AlertRuleGroupExport":{
"properties":{
"folder":{
"type":"string"
},
"interval":{
"$ref":"#/definitions/Duration"
},
"name":{
"type":"string"
},
"orgId":{
"format":"int64",
"type":"integer"
},
"rules":{
"items":{
"$ref":"#/definitions/AlertRuleExport"
},
"type":"array"
}
},
"title":"AlertRuleGroupExport is the provisioned export of models.AlertRuleGroup.",
"type":"object"
},
"AlertRuleGroupMetadata":{
"properties":{
"interval":{
@ -3155,6 +3273,7 @@
"type":"object"
},
"URL":{
"description":"The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"properties":{
"ForceQuery":{
"type":"boolean"
@ -3190,7 +3309,7 @@
"$ref":"#/definitions/Userinfo"
}
},
"title":"URL is a custom URL type that allows validation at configuration load time.",
"title":"A URL represents a parsed URL (technically, a URI reference).",
"type":"object"
},
"Userinfo":{
@ -3391,7 +3510,6 @@
"type":"object"
},
"alertGroups":{
"description":"AlertGroups alert groups",
"items":{
"$ref":"#/definitions/alertGroup"
},
@ -3496,7 +3614,6 @@
"type":"object"
},
"gettableAlert":{
"description":"GettableAlert gettable alert",
"properties":{
"annotations":{
"$ref":"#/definitions/labelSet"
@ -3558,6 +3675,7 @@
"type":"array"
},
"gettableSilence":{
"description":"GettableSilence gettable silence",
"properties":{
"comment":{
"description":"comment",
@ -5640,6 +5758,35 @@
]
}
},
"/api/v1/provisioning/alert-rules/export":{
"get":{
"operationId":"RouteGetAlertRulesExport",
"parameters":[
{
"default":false,
"description":"Whether to initiate a download of the file or not.",
"in":"query",
"name":"download",
"type":"boolean"
}
],
"responses":{
"200":{
"description":"AlertRuleFileExport",
"schema":{
"$ref":"#/definitions/AlertRuleFileExport"
}
},
"404":{
"description":" Not found."
}
},
"summary":"Export all alert rules in provisioning file format.",
"tags":[
"provisioning"
]
}
},
"/api/v1/provisioning/alert-rules/{UID}":{
"delete":{
"operationId":"RouteDeleteAlertRule",
@ -5735,6 +5882,47 @@
]
}
},
"/api/v1/provisioning/alert-rules/{UID}/export":{
"get":{
"operationId":"RouteGetAlertRuleExport",
"parameters":[
{
"description":"Alert rule UID",
"in":"path",
"name":"UID",
"required":true,
"type":"string"
},
{
"default":false,
"description":"Whether to initiate a download of the file or not.",
"in":"query",
"name":"download",
"type":"boolean"
}
],
"produces":[
"application/json",
"application/yaml",
"text/yaml"
],
"responses":{
"200":{
"description":"AlertRuleExport",
"schema":{
"$ref":"#/definitions/AlertRuleExport"
}
},
"404":{
"description":" Not found."
}
},
"summary":"Export an alert rule in provisioning file format.",
// We need folder titles for the provisioning file format. We do it this way instead of using GetUserVisibleNamespaces to avoid folder:read permissions that should not apply to those with alert.provisioning:read.
"summary":"Export an alert rule group in provisioning file format.",
"operationId":"RouteGetAlertRuleGroupExport",
"parameters":[
{
"type":"string",
"name":"FolderUID",
"in":"path",
"required":true
},
{
"type":"string",
"name":"Group",
"in":"path",
"required":true
},
{
"type":"boolean",
"default":false,
"description":"Whether to initiate a download of the file or not.",
"name":"download",
"in":"query"
}
],
"responses":{
"200":{
"description":"AlertingFileExport",
"schema":{
"$ref":"#/definitions/AlertingFileExport"
}
},
"404":{
"description":" Not found."
}
}
}
},
"/api/v1/provisioning/mute-timings":{
"get":{
"tags":[
@ -11044,6 +11160,28 @@
}
}
},
"AlertQueryExport":{
"type":"object",
"title":"AlertQueryExport is the provisioned export of models.AlertQuery.",
"properties":{
"datasourceUid":{
"type":"string"
},
"model":{
"type":"object",
"additionalProperties":false
},
"queryType":{
"type":"string"
},
"refId":{
"type":"string"
},
"relativeTimeRange":{
"$ref":"#/definitions/RelativeTimeRange"
}
}
},
"AlertResponse":{
"type":"object",
"required":[
@ -11064,6 +11202,65 @@
}
}
},
"AlertRuleExport":{
"type":"object",
"title":"AlertRuleExport is the provisioned file export of models.AlertRule.",
"properties":{
"annotations":{
"type":"object",
"additionalProperties":{
"type":"string"
}
},
"condition":{
"type":"string"
},
"dasboardUid":{
"type":"string"
},
"data":{
"type":"array",
"items":{
"$ref":"#/definitions/AlertQueryExport"
}
},
"execErrState":{
"type":"string",
"enum":[
"Alerting",
"Error",
"OK"
]
},
"for":{
"$ref":"#/definitions/Duration"
},
"labels":{
"type":"object",
"additionalProperties":{
"type":"string"
}
},
"noDataState":{
"type":"string",
"enum":[
"Alerting",
"NoData",
"OK"
]
},
"panelId":{
"type":"integer",
"format":"int64"
},
"title":{
"type":"string"
},
"uid":{
"type":"string"
}
}
},
"AlertRuleGroup":{
"type":"object",
"properties":{
@ -11085,6 +11282,31 @@
}
}
},
"AlertRuleGroupExport":{
"type":"object",
"title":"AlertRuleGroupExport is the provisioned file export of AlertRuleGroupV1.",
"properties":{
"folder":{
"type":"string"
},
"interval":{
"$ref":"#/definitions/Duration"
},
"name":{
"type":"string"
},
"orgId":{
"type":"integer",
"format":"int64"
},
"rules":{
"type":"array",
"items":{
"$ref":"#/definitions/AlertRuleExport"
}
}
}
},
"AlertRuleGroupMetadata":{
"type":"object",
"properties":{
@ -11174,6 +11396,22 @@
}
}
},
"AlertingFileExport":{
"type":"object",
"title":"AlertingFileExport is the full provisioned file export.",
"properties":{
"apiVersion":{
"type":"integer",
"format":"int64"
},
"groups":{
"type":"array",
"items":{
"$ref":"#/definitions/AlertRuleGroupExport"
}
}
}
},
"AlertingRule":{
"description":"adapted from cortex",
"type":"object",
@ -17824,9 +18062,8 @@
"type":"string"
},
"URL":{
"description":"The general form represented is:\n\n[scheme:][//[userinfo@]host][/]path[?query][#fragment]\n\nURLs that do not start with a slash after the scheme are interpreted as:\n\nscheme:opaque[?query][#fragment]\n\nNote that the Path field is stored in decoded form: /%47%6f%2f becomes /Go/.\nA consequence is that it is impossible to tell which slashes in the Path were\nslashes in the raw URL and which were %2f. This distinction is rarely important,\nbut when it is, the code should use RawPath, an optional field which only gets\nset if the default encoding is different from Path.\n\nURL's String method uses the EscapedPath method to obtain the path. See the\nEscapedPath method for more details.",
"type":"object",
"title":"A URL represents a parsed URL (technically, a URI reference).",
"title":"URL is a custom URL type that allows validation at configuration load time.",