Alerting: Update mute timings provisioning API to support optimistic locking (#88731)

* add version to time-interval models
* set time interval fingerprint as version
* update to check provided version
* delete to check if version is provided in query parameter 'version'
* update integration tests
* update specs
This commit is contained in:
Yuri Tseretyan
2024-06-06 18:06:37 -04:00
committed by GitHub
parent a2e21d61f8
commit 003e3efce9
13 changed files with 379 additions and 22 deletions
+3 -2
View File
@@ -60,7 +60,7 @@ type MuteTimingService interface {
GetMuteTiming(ctx context.Context, name string, orgID int64) (definitions.MuteTimeInterval, error)
CreateMuteTiming(ctx context.Context, mt definitions.MuteTimeInterval, orgID int64) (definitions.MuteTimeInterval, error)
UpdateMuteTiming(ctx context.Context, mt definitions.MuteTimeInterval, orgID int64) (definitions.MuteTimeInterval, error)
DeleteMuteTiming(ctx context.Context, name string, orgID int64, provenance definitions.Provenance) error
DeleteMuteTiming(ctx context.Context, name string, orgID int64, provenance definitions.Provenance, version string) error
}
type AlertRuleService interface {
@@ -307,7 +307,8 @@ func (srv *ProvisioningSrv) RoutePutMuteTiming(c *contextmodel.ReqContext, mt de
}
func (srv *ProvisioningSrv) RouteDeleteMuteTiming(c *contextmodel.ReqContext, name string) response.Response {
err := srv.muteTimings.DeleteMuteTiming(c.Req.Context(), name, c.SignedInUser.GetOrgID(), determineProvenance(c))
version := c.Query("version")
err := srv.muteTimings.DeleteMuteTiming(c.Req.Context(), name, c.SignedInUser.GetOrgID(), determineProvenance(c), version)
if err != nil {
return response.ErrOrFallback(http.StatusInternalServerError, "failed to delete mute timing", err)
}
+23
View File
@@ -1713,6 +1713,9 @@
"$ref": "#/definitions/TimeIntervalItem"
},
"type": "array"
},
"version": {
"type": "string"
}
},
"type": "object"
@@ -2800,6 +2803,9 @@
"$ref": "#/definitions/TimeIntervalItem"
},
"type": "array"
},
"version": {
"type": "string"
}
},
"type": "object"
@@ -5780,6 +5786,17 @@
"name": "name",
"required": true,
"type": "string"
},
{
"description": "Version of mute timing to use for optimistic concurrency. Leave empty to disable validation",
"in": "query",
"name": "version",
"type": "string"
},
{
"in": "header",
"name": "X-Disable-Provenance",
"type": "string"
}
],
"responses": {
@@ -5863,6 +5880,12 @@
"schema": {
"$ref": "#/definitions/ValidationError"
}
},
"409": {
"description": "GenericPublicError",
"schema": {
"$ref": "#/definitions/GenericPublicError"
}
}
},
"summary": "Replace an existing mute timing.",
@@ -70,6 +70,7 @@ import (
// Responses:
// 202: MuteTimeInterval
// 400: ValidationError
// 409: GenericPublicError
// swagger:route DELETE /v1/provisioning/mute-timings/{name} provisioning stable RouteDeleteMuteTiming
//
@@ -84,20 +85,31 @@ import (
// swagger:model
type MuteTimings []MuteTimeInterval
// swagger:parameters RouteGetTemplate RouteGetMuteTiming RoutePutMuteTiming stable RouteDeleteMuteTiming RouteExportMuteTiming
// swagger:parameters RouteGetTemplate RouteGetMuteTiming RoutePutMuteTiming stable RouteExportMuteTiming
type RouteGetMuteTimingParam struct {
// Mute timing name
// in:path
Name string `json:"name"`
}
// swagger:parameters stable RouteDeleteMuteTiming
type RouteDeleteMuteTimingParam struct {
// Mute timing name
// in:path
Name string `json:"name"`
// Version of mute timing to use for optimistic concurrency. Leave empty to disable validation
// in:query
Version string `json:"version"`
}
// swagger:parameters RoutePostMuteTiming RoutePutMuteTiming
type MuteTimingPayload struct {
// in:body
Body MuteTimeInterval
}
// swagger:parameters RoutePostMuteTiming RoutePutMuteTiming
// swagger:parameters RoutePostMuteTiming RoutePutMuteTiming RouteDeleteMuteTiming
type MuteTimingHeaders struct {
// in:header
XDisableProvenance string `json:"X-Disable-Provenance"`
@@ -106,6 +118,7 @@ type MuteTimingHeaders struct {
// swagger:model
type MuteTimeInterval struct {
config.MuteTimeInterval `json:",inline" yaml:",inline"`
Version string `json:"version,omitempty"`
Provenance Provenance `json:"provenance,omitempty"`
}
@@ -39,6 +39,7 @@ type GetIntervalsByNameResponse struct {
// swagger:model
type PostableTimeIntervals struct {
Name string `json:"name" hcl:"name"`
Version string `json:"version,omitempty"`
TimeIntervals []TimeIntervalItem `json:"time_intervals" hcl:"intervals,block"`
}
@@ -60,5 +61,6 @@ type TimeIntervalTimeRange struct {
type GettableTimeIntervals struct {
Name string `json:"name" hcl:"name"`
TimeIntervals []TimeIntervalItem `json:"time_intervals" hcl:"intervals,block"`
Version string `json:"version,omitempty"`
Provenance Provenance `json:"provenance,omitempty"`
}
@@ -2802,6 +2802,9 @@
"$ref": "#/definitions/TimeIntervalItem"
},
"type": "array"
},
"version": {
"type": "string"
}
},
"type": "object"
@@ -7896,6 +7899,17 @@
"name": "name",
"required": true,
"type": "string"
},
{
"description": "Version of mute timing to use for optimistic concurrency. Leave empty to disable validation",
"in": "query",
"name": "version",
"type": "string"
},
{
"in": "header",
"name": "X-Disable-Provenance",
"type": "string"
}
],
"responses": {
@@ -7979,6 +7993,12 @@
"schema": {
"$ref": "#/definitions/ValidationError"
}
},
"409": {
"description": "GenericPublicError",
"schema": {
"$ref": "#/definitions/GenericPublicError"
}
}
},
"summary": "Replace an existing mute timing.",
@@ -3060,6 +3060,12 @@
"schema": {
"$ref": "#/definitions/ValidationError"
}
},
"409": {
"description": "GenericPublicError",
"schema": {
"$ref": "#/definitions/GenericPublicError"
}
}
}
},
@@ -3077,6 +3083,17 @@
"name": "name",
"in": "path",
"required": true
},
{
"type": "string",
"description": "Version of mute timing to use for optimistic concurrency. Leave empty to disable validation",
"name": "version",
"in": "query"
},
{
"type": "string",
"name": "X-Disable-Provenance",
"in": "header"
}
],
"responses": {
@@ -6316,6 +6333,9 @@
"items": {
"$ref": "#/definitions/TimeIntervalItem"
}
},
"version": {
"type": "string"
}
}
},