mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Alerting: Allow none provenance alert rule creation from provisioning API (#58410)
This commit is contained in:
parent
79142340e0
commit
78bb8c10ce
@ -15,6 +15,8 @@ import (
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
)
|
||||
|
||||
const disableProvenanceHeaderName = "X-Disable-Provenance"
|
||||
|
||||
type ProvisioningSrv struct {
|
||||
log log.Logger
|
||||
policies NotificationPolicyService
|
||||
@ -259,7 +261,8 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *models.ReqContext, ar definiti
|
||||
if err != nil {
|
||||
return ErrResp(http.StatusBadRequest, err, "")
|
||||
}
|
||||
createdAlertRule, err := srv.alertRules.CreateAlertRule(c.Req.Context(), upstreamModel, alerting_models.ProvenanceAPI, c.UserID)
|
||||
provenance := determineProvenance(c)
|
||||
createdAlertRule, err := srv.alertRules.CreateAlertRule(c.Req.Context(), upstreamModel, provenance, c.UserID)
|
||||
if errors.Is(err, alerting_models.ErrAlertRuleFailedValidation) {
|
||||
return ErrResp(http.StatusBadRequest, err, "")
|
||||
}
|
||||
@ -273,7 +276,7 @@ func (srv *ProvisioningSrv) RoutePostAlertRule(c *models.ReqContext, ar definiti
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
|
||||
resp := definitions.NewAlertRule(createdAlertRule, alerting_models.ProvenanceAPI)
|
||||
resp := definitions.NewAlertRule(createdAlertRule, provenance)
|
||||
return response.JSON(http.StatusCreated, resp)
|
||||
}
|
||||
|
||||
@ -284,7 +287,8 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *models.ReqContext, ar definitio
|
||||
}
|
||||
updated.OrgID = c.OrgID
|
||||
updated.UID = UID
|
||||
updatedAlertRule, err := srv.alertRules.UpdateAlertRule(c.Req.Context(), updated, alerting_models.ProvenanceAPI)
|
||||
provenance := determineProvenance(c)
|
||||
updatedAlertRule, err := srv.alertRules.UpdateAlertRule(c.Req.Context(), updated, provenance)
|
||||
if errors.Is(err, alerting_models.ErrAlertRuleNotFound) {
|
||||
return response.Empty(http.StatusNotFound)
|
||||
}
|
||||
@ -298,7 +302,7 @@ func (srv *ProvisioningSrv) RoutePutAlertRule(c *models.ReqContext, ar definitio
|
||||
return ErrResp(http.StatusInternalServerError, err, "")
|
||||
}
|
||||
|
||||
resp := definitions.NewAlertRule(updatedAlertRule, alerting_models.ProvenanceAPI)
|
||||
resp := definitions.NewAlertRule(updatedAlertRule, provenance)
|
||||
return response.JSON(http.StatusOK, resp)
|
||||
}
|
||||
|
||||
@ -340,3 +344,10 @@ func (srv *ProvisioningSrv) RoutePutAlertRuleGroup(c *models.ReqContext, ag defi
|
||||
}
|
||||
return response.JSON(http.StatusOK, ag)
|
||||
}
|
||||
|
||||
func determineProvenance(ctx *models.ReqContext) alerting_models.Provenance {
|
||||
if _, disabled := ctx.Req.Header[disableProvenanceHeaderName]; disabled {
|
||||
return alerting_models.ProvenanceNone
|
||||
}
|
||||
return alerting_models.ProvenanceAPI
|
||||
}
|
||||
|
@ -229,7 +229,7 @@ func TestProvisioningApi(t *testing.T) {
|
||||
|
||||
t.Run("alert rules", func(t *testing.T) {
|
||||
t.Run("are invalid", func(t *testing.T) {
|
||||
t.Run("POST returns 400", func(t *testing.T) {
|
||||
t.Run("POST returns 400 on wrong body params", func(t *testing.T) {
|
||||
sut := createProvisioningSrvSut(t)
|
||||
rc := createTestRequestCtx()
|
||||
rule := createInvalidAlertRule()
|
||||
@ -241,7 +241,7 @@ func TestProvisioningApi(t *testing.T) {
|
||||
require.Contains(t, string(response.Body()), "invalid alert rule")
|
||||
})
|
||||
|
||||
t.Run("PUT returns 400", func(t *testing.T) {
|
||||
t.Run("PUT returns 400 on wrong body params", func(t *testing.T) {
|
||||
sut := createProvisioningSrvSut(t)
|
||||
rc := createTestRequestCtx()
|
||||
uid := "123123"
|
||||
@ -258,9 +258,10 @@ func TestProvisioningApi(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("exist in non-default orgs", func(t *testing.T) {
|
||||
t.Run("POST sets expected fields", func(t *testing.T) {
|
||||
t.Run("POST sets expected fields with no provenance", func(t *testing.T) {
|
||||
sut := createProvisioningSrvSut(t)
|
||||
rc := createTestRequestCtx()
|
||||
rc.Req.Header = map[string][]string{"X-Disable-Provenance": {"true"}}
|
||||
rc.OrgID = 3
|
||||
rule := createTestAlertRule("rule", 1)
|
||||
|
||||
@ -269,15 +270,17 @@ func TestProvisioningApi(t *testing.T) {
|
||||
require.Equal(t, 201, response.Status())
|
||||
created := deserializeRule(t, response.Body())
|
||||
require.Equal(t, int64(3), created.OrgID)
|
||||
require.Equal(t, models.ProvenanceNone, created.Provenance)
|
||||
})
|
||||
|
||||
t.Run("PUT sets expected fields", func(t *testing.T) {
|
||||
t.Run("PUT sets expected fields with no provenance", func(t *testing.T) {
|
||||
sut := createProvisioningSrvSut(t)
|
||||
uid := t.Name()
|
||||
rule := createTestAlertRule("rule", 1)
|
||||
rule.UID = uid
|
||||
insertRuleInOrg(t, sut, rule, 3)
|
||||
rc := createTestRequestCtx()
|
||||
rc.Req.Header = map[string][]string{"X-Disable-Provenance": {"hello"}}
|
||||
rc.OrgID = 3
|
||||
rule.OrgID = 1 // Set the org back to something wrong, we should still prefer the value from the req context.
|
||||
|
||||
@ -286,6 +289,7 @@ func TestProvisioningApi(t *testing.T) {
|
||||
require.Equal(t, 200, response.Status())
|
||||
created := deserializeRule(t, response.Body())
|
||||
require.Equal(t, int64(3), created.OrgID)
|
||||
require.Equal(t, models.ProvenanceNone, created.Provenance)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -364,11 +364,14 @@
|
||||
"description": "A map of RefIDs (unique query identifiers) to this type makes up the Responses property of a QueryDataResponse.\nThe Error property is used to allow for partial success responses from the containing QueryDataResponse.",
|
||||
"properties": {
|
||||
"Error": {
|
||||
"description": "Error is a property to be set if the the corresponding DataQuery has an error.",
|
||||
"description": "Error is a property to be set if the corresponding DataQuery has an error.",
|
||||
"type": "string"
|
||||
},
|
||||
"Frames": {
|
||||
"$ref": "#/definitions/Frames"
|
||||
},
|
||||
"Status": {
|
||||
"$ref": "#/definitions/Status"
|
||||
}
|
||||
},
|
||||
"title": "DataResponse contains the results from a DataQuery.",
|
||||
@ -2816,6 +2819,10 @@
|
||||
"SmtpNotEnabled": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
"Status": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"Success": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
@ -3070,6 +3077,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"
|
||||
@ -3102,7 +3110,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": {
|
||||
@ -3258,6 +3266,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"alertGroup": {
|
||||
"description": "AlertGroup alert group",
|
||||
"properties": {
|
||||
"alerts": {
|
||||
"description": "alerts",
|
||||
@ -3281,6 +3290,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
@ -3385,7 +3395,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlert": {
|
||||
"description": "GettableAlert gettable alert",
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"$ref": "#/definitions/labelSet"
|
||||
@ -3441,12 +3450,14 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"gettableSilence": {
|
||||
"description": "GettableSilence gettable silence",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"description": "comment",
|
||||
@ -3495,6 +3506,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableSilences": {
|
||||
"description": "GettableSilences gettable silences",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableSilence"
|
||||
},
|
||||
@ -3683,7 +3695,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"properties": {
|
||||
"active": {
|
||||
"description": "active",
|
||||
@ -3816,6 +3827,11 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ProvisionedAlertRule"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "header",
|
||||
"name": "X-Disable-Provenance",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -3906,6 +3922,11 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ProvisionedAlertRule"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "header",
|
||||
"name": "X-Disable-Provenance",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -57,6 +57,12 @@ type AlertRulePayload struct {
|
||||
Body ProvisionedAlertRule
|
||||
}
|
||||
|
||||
// swagger:parameters RoutePostAlertRule RoutePutAlertRule
|
||||
type AlertRuleHeaders struct {
|
||||
// in:header
|
||||
XDisableProvenance string `json:"X-Disable-Provenance"`
|
||||
}
|
||||
|
||||
type ProvisionedAlertRule struct {
|
||||
ID int64 `json:"id"`
|
||||
UID string `json:"uid"`
|
||||
|
@ -364,11 +364,14 @@
|
||||
"description": "A map of RefIDs (unique query identifiers) to this type makes up the Responses property of a QueryDataResponse.\nThe Error property is used to allow for partial success responses from the containing QueryDataResponse.",
|
||||
"properties": {
|
||||
"Error": {
|
||||
"description": "Error is a property to be set if the the corresponding DataQuery has an error.",
|
||||
"description": "Error is a property to be set if the corresponding DataQuery has an error.",
|
||||
"type": "string"
|
||||
},
|
||||
"Frames": {
|
||||
"$ref": "#/definitions/Frames"
|
||||
},
|
||||
"Status": {
|
||||
"$ref": "#/definitions/Status"
|
||||
}
|
||||
},
|
||||
"title": "DataResponse contains the results from a DataQuery.",
|
||||
@ -2816,6 +2819,10 @@
|
||||
"SmtpNotEnabled": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
"Status": {
|
||||
"format": "int64",
|
||||
"type": "integer"
|
||||
},
|
||||
"Success": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
@ -3283,7 +3290,6 @@
|
||||
"type": "object"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
@ -3443,6 +3449,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
@ -3685,6 +3692,7 @@
|
||||
"type": "object"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"properties": {
|
||||
"active": {
|
||||
"description": "active",
|
||||
@ -5489,6 +5497,11 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ProvisionedAlertRule"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "header",
|
||||
"name": "X-Disable-Provenance",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -5579,6 +5592,11 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ProvisionedAlertRule"
|
||||
}
|
||||
},
|
||||
{
|
||||
"in": "header",
|
||||
"name": "X-Disable-Provenance",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
@ -1707,6 +1707,11 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ProvisionedAlertRule"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "X-Disable-Provenance",
|
||||
"in": "header"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -1778,6 +1783,11 @@
|
||||
"schema": {
|
||||
"$ref": "#/definitions/ProvisionedAlertRule"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"name": "X-Disable-Provenance",
|
||||
"in": "header"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
@ -2799,11 +2809,14 @@
|
||||
"title": "DataResponse contains the results from a DataQuery.",
|
||||
"properties": {
|
||||
"Error": {
|
||||
"description": "Error is a property to be set if the the corresponding DataQuery has an error.",
|
||||
"description": "Error is a property to be set if the corresponding DataQuery has an error.",
|
||||
"type": "string"
|
||||
},
|
||||
"Frames": {
|
||||
"$ref": "#/definitions/Frames"
|
||||
},
|
||||
"Status": {
|
||||
"$ref": "#/definitions/Status"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -5253,6 +5266,10 @@
|
||||
"SmtpNotEnabled": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
"Status": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"Success": {
|
||||
"$ref": "#/definitions/ResponseDetails"
|
||||
},
|
||||
@ -5721,7 +5738,6 @@
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
},
|
||||
"alertGroups": {
|
||||
"description": "AlertGroups alert groups",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/alertGroup"
|
||||
@ -5883,6 +5899,7 @@
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
},
|
||||
"gettableAlerts": {
|
||||
"description": "GettableAlerts gettable alerts",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/gettableAlert"
|
||||
@ -6130,6 +6147,7 @@
|
||||
"$ref": "#/definitions/postableSilence"
|
||||
},
|
||||
"receiver": {
|
||||
"description": "Receiver receiver",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"active",
|
||||
|
Loading…
Reference in New Issue
Block a user