Alerting: Add export of mute timings to file provisioning formats (#79225)

* add export of mute timings to file provisioning formats
* support export of mute timings to HCL
pull/79499/head
Yuri Tseretyan 1 year ago committed by GitHub
parent bf8be46e6f
commit 8af08d0df2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 94
      pkg/services/ngalert/api/api_provisioning.go
  2. 160
      pkg/services/ngalert/api/api_provisioning_test.go
  3. 4
      pkg/services/ngalert/api/authorization.go
  4. 2
      pkg/services/ngalert/api/authorization_test.go
  5. 31
      pkg/services/ngalert/api/compat.go
  6. 34
      pkg/services/ngalert/api/generated_base_api_provisioning.go
  7. 8
      pkg/services/ngalert/api/provisioning.go
  8. 20
      pkg/services/ngalert/api/test-data/alertmanager_default_mutetimings-export.hcl
  9. 1
      pkg/services/ngalert/api/test-data/alertmanager_default_mutetimings-export.json
  10. 16
      pkg/services/ngalert/api/test-data/alertmanager_default_mutetimings-export.yaml
  11. 110
      pkg/services/ngalert/api/tooling/api.json
  12. 3
      pkg/services/ngalert/api/tooling/definitions/provisioning.go
  13. 45
      pkg/services/ngalert/api/tooling/definitions/provisioning_mute_timings.go
  14. 115
      pkg/services/ngalert/api/tooling/post.json
  15. 117
      pkg/services/ngalert/api/tooling/spec.json
  16. 110
      public/api-merged.json
  17. 136
      public/openapi3.json

@ -255,6 +255,20 @@ func (srv *ProvisioningSrv) RouteGetMuteTiming(c *contextmodel.ReqContext, name
return response.Empty(http.StatusNotFound)
}
func (srv *ProvisioningSrv) RouteGetMuteTimingExport(c *contextmodel.ReqContext, name string) response.Response {
timings, err := srv.muteTimings.GetMuteTimings(c.Req.Context(), c.SignedInUser.GetOrgID())
if err != nil {
return ErrResp(http.StatusInternalServerError, err, "")
}
for _, timing := range timings {
if name == timing.Name {
e := AlertingFileExportFromMuteTimings(c.SignedInUser.GetOrgID(), []definitions.MuteTimeInterval{timing})
return exportResponse(c, e)
}
}
return response.Empty(http.StatusNotFound)
}
func (srv *ProvisioningSrv) RouteGetMuteTimings(c *contextmodel.ReqContext) response.Response {
timings, err := srv.muteTimings.GetMuteTimings(c.Req.Context(), c.SignedInUser.GetOrgID())
if err != nil {
@ -263,6 +277,15 @@ func (srv *ProvisioningSrv) RouteGetMuteTimings(c *contextmodel.ReqContext) resp
return response.JSON(http.StatusOK, timings)
}
func (srv *ProvisioningSrv) RouteGetMuteTimingsExport(c *contextmodel.ReqContext) response.Response {
timings, err := srv.muteTimings.GetMuteTimings(c.Req.Context(), c.SignedInUser.GetOrgID())
if err != nil {
return ErrResp(http.StatusInternalServerError, err, "")
}
e := AlertingFileExportFromMuteTimings(c.SignedInUser.GetOrgID(), timings)
return exportResponse(c, e)
}
func (srv *ProvisioningSrv) RoutePostMuteTiming(c *contextmodel.ReqContext, mt definitions.MuteTimeInterval) response.Response {
mt.Provenance = determineProvenance(c)
created, err := srv.muteTimings.CreateMuteTiming(c.Req.Context(), mt, c.SignedInUser.GetOrgID())
@ -551,36 +574,53 @@ func exportResponse(c *contextmodel.ReqContext, body definitions.AlertingFileExp
}
func exportHcl(download bool, body definitions.AlertingFileExport) response.Response {
resources := make([]hcl.Resource, 0, len(body.Groups)+len(body.ContactPoints)+len(body.Policies))
for idx, group := range body.Groups {
gr := group
resources = append(resources, hcl.Resource{
Type: "grafana_rule_group",
Name: fmt.Sprintf("rule_group_%04d", idx),
Body: &gr,
})
}
for idx, cp := range body.ContactPoints {
upd, err := ContactPointFromContactPointExport(cp)
if err != nil {
return response.Error(http.StatusInternalServerError, "failed to convert contact points to HCL", err)
resources := make([]hcl.Resource, 0, len(body.Groups)+len(body.ContactPoints)+len(body.Policies)+len(body.MuteTimings))
convertToResources := func() error {
for idx, group := range body.Groups {
gr := group
resources = append(resources, hcl.Resource{
Type: "grafana_rule_group",
Name: fmt.Sprintf("rule_group_%04d", idx),
Body: &gr,
})
}
for idx, cp := range body.ContactPoints {
upd, err := ContactPointFromContactPointExport(cp)
if err != nil {
return fmt.Errorf("failed to convert contact points to HCL:%w", err)
}
resources = append(resources, hcl.Resource{
Type: "grafana_contact_point",
Name: fmt.Sprintf("contact_point_%d", idx),
Body: &upd,
})
}
resources = append(resources, hcl.Resource{
Type: "grafana_contact_point",
Name: fmt.Sprintf("contact_point_%d", idx),
Body: &upd,
})
}
for idx, cp := range body.Policies {
policy := cp.RouteExport
resources = append(resources, hcl.Resource{
Type: "grafana_notification_policy",
Name: fmt.Sprintf("notification_policy_%d", idx+1),
Body: policy,
})
}
for idx, cp := range body.Policies {
policy := cp.RouteExport
resources = append(resources, hcl.Resource{
Type: "grafana_notification_policy",
Name: fmt.Sprintf("notification_policy_%d", idx+1),
Body: policy,
})
}
for idx, mt := range body.MuteTimings {
mthcl, err := MuteTimingIntervalToMuteTimeIntervalHclExport(mt)
if err != nil {
return fmt.Errorf("failed to convert mute timing [%s] to HCL:%w", mt.Name, err)
}
resources = append(resources, hcl.Resource{
Type: "grafana_mute_timing",
Name: fmt.Sprintf("mute_timing_%d", idx+1),
Body: mthcl,
})
}
return nil
}
if err := convertToResources(); err != nil {
return response.Error(500, "failed to convert to HCL resources", err)
}
hclBody, err := hcl.Encode(resources...)
if err != nil {
return response.Error(500, "body hcl encode", err)

@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"path"
"testing"
"time"
@ -1150,6 +1151,132 @@ func TestProvisioningApi(t *testing.T) {
require.Equal(t, expectedResponse, string(response.Body()))
})
})
t.Run("mute timings", func(t *testing.T) {
t.Run("are present, GET returns 200", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
response := sut.RouteGetMuteTimingsExport(&rc)
require.Equal(t, 200, response.Status())
})
t.Run("accept header contains yaml, GET returns text yaml", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
rc.Context.Req.Header.Add("Accept", "application/yaml")
response := sut.RouteGetMuteTimingsExport(&rc)
response.WriteTo(&rc)
require.Equal(t, 200, response.Status())
require.Equal(t, "text/yaml", rc.Context.Resp.Header().Get("Content-Type"))
})
t.Run("accept header contains json, GET returns json", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
rc.Context.Req.Header.Add("Accept", "application/json")
response := sut.RouteGetMuteTimingsExport(&rc)
response.WriteTo(&rc)
require.Equal(t, 200, response.Status())
require.Equal(t, "application/json", rc.Context.Resp.Header().Get("Content-Type"))
})
t.Run("accept header contains json and yaml, GET returns json", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
rc.Context.Req.Header.Add("Accept", "application/json, application/yaml")
response := sut.RouteGetMuteTimingsExport(&rc)
response.WriteTo(&rc)
require.Equal(t, 200, response.Status())
require.Equal(t, "application/json", rc.Context.Resp.Header().Get("Content-Type"))
})
t.Run("query param download=true, GET returns content disposition attachment", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
rc.Context.Req.Form.Set("download", "true")
response := sut.RouteGetMuteTimingsExport(&rc)
response.WriteTo(&rc)
require.Equal(t, 200, response.Status())
require.Contains(t, rc.Context.Resp.Header().Get("Content-Disposition"), "attachment")
})
t.Run("query param download=false, GET returns empty content disposition", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
rc.Context.Req.Form.Set("download", "false")
response := sut.RouteGetMuteTimingsExport(&rc)
response.WriteTo(&rc)
require.Equal(t, 200, response.Status())
require.Equal(t, "", rc.Context.Resp.Header().Get("Content-Disposition"))
})
t.Run("query param download not set, GET returns empty content disposition", func(t *testing.T) {
sut := createProvisioningSrvSut(t)
rc := createTestRequestCtx()
response := sut.RouteGetMuteTimingsExport(&rc)
response.WriteTo(&rc)
require.Equal(t, 200, response.Status())
require.Equal(t, "", rc.Context.Resp.Header().Get("Content-Disposition"))
})
t.Run("json body content is as expected", func(t *testing.T) {
expectedResponse, err := testData.ReadFile(path.Join("test-data", "alertmanager_default_mutetimings-export.json"))
require.NoError(t, err)
sut := createProvisioningSrvSut(t)
sut.policies = createFakeNotificationPolicyService()
rc := createTestRequestCtx()
rc.Context.Req.Header.Add("Accept", "application/json")
response := sut.RouteGetMuteTimingsExport(&rc)
require.Equal(t, 200, response.Status())
require.JSONEq(t, string(expectedResponse), string(response.Body()))
})
t.Run("yaml body content is as expected", func(t *testing.T) {
expectedResponse, err := testData.ReadFile(path.Join("test-data", "alertmanager_default_mutetimings-export.yaml"))
require.NoError(t, err)
sut := createProvisioningSrvSut(t)
sut.policies = createFakeNotificationPolicyService()
rc := createTestRequestCtx()
rc.Context.Req.Header.Add("Accept", "application/yaml")
response := sut.RouteGetMuteTimingsExport(&rc)
require.Equal(t, 200, response.Status())
require.Equal(t, string(expectedResponse), string(response.Body()))
})
t.Run("hcl body content is as expected", func(t *testing.T) {
expectedResponse, err := testData.ReadFile(path.Join("test-data", "alertmanager_default_mutetimings-export.hcl"))
require.NoError(t, err)
sut := createProvisioningSrvSut(t)
sut.policies = createFakeNotificationPolicyService()
rc := createTestRequestCtx()
rc.Context.Req.Form.Add("format", "hcl")
response := sut.RouteGetMuteTimingsExport(&rc)
t.Log(string(response.Body()))
require.Equal(t, 200, response.Status())
require.Equal(t, string(expectedResponse), string(response.Body()))
})
})
})
}
@ -1765,7 +1892,38 @@ var testConfig = `
"mute_time_intervals": [{
"name": "interval",
"time_intervals": []
}]
}, {
"name": "full-interval",
"time_intervals": [
{
"times": [
{
"start_time": "10:00",
"end_time": "12:00"
}
],
"weekdays": [
"monday",
"wednesday",
"friday"
],
"days_of_month": [
"1",
"14:16",
"20"
],
"months": [
"1:3",
"7",
"12"
],
"years": [
"2023:2025"
],
"location": "America/New_York"
}
]
}]
}
}
`

@ -182,7 +182,9 @@ func (api *API) authorize(method, path string) web.Handler {
// Grafana-only Provisioning Read Paths
case http.MethodGet + "/api/v1/provisioning/policies/export",
http.MethodGet + "/api/v1/provisioning/contact-points/export":
http.MethodGet + "/api/v1/provisioning/contact-points/export",
http.MethodGet + "/api/v1/provisioning/mute-timings/export",
http.MethodGet + "/api/v1/provisioning/mute-timings/{name}/export":
eval = ac.EvalAny(
ac.EvalPermission(ac.ActionAlertingNotificationsRead), // organization scope
ac.EvalPermission(ac.ActionAlertingProvisioningRead), // organization scope

@ -40,7 +40,7 @@ func TestAuthorize(t *testing.T) {
}
paths[p] = methods
}
require.Len(t, paths, 52)
require.Len(t, paths, 54)
ac := acmock.New()
api := &API{AccessControl: ac}

@ -4,6 +4,7 @@ import (
"encoding/json"
"time"
jsoniter "github.com/json-iterator/go"
"github.com/prometheus/common/model"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
@ -342,3 +343,33 @@ func NilIfEmpty[T any](v *[]T) *[]T {
}
return v
}
func AlertingFileExportFromMuteTimings(orgID int64, m []definitions.MuteTimeInterval) definitions.AlertingFileExport {
f := definitions.AlertingFileExport{
APIVersion: 1,
MuteTimings: make([]definitions.MuteTimeIntervalExport, 0, len(m)),
}
for _, mi := range m {
f.MuteTimings = append(f.MuteTimings, MuteTimeIntervalExportFromMuteTiming(orgID, mi))
}
return f
}
func MuteTimeIntervalExportFromMuteTiming(orgID int64, m definitions.MuteTimeInterval) definitions.MuteTimeIntervalExport {
return definitions.MuteTimeIntervalExport{
OrgID: orgID,
MuteTimeInterval: m.MuteTimeInterval,
}
}
// Converts definitions.MuteTimeIntervalExport to definitions.MuteTimeIntervalExportHcl using JSON marshalling. Returns error if structure could not be marshalled\unmarshalled
func MuteTimingIntervalToMuteTimeIntervalHclExport(m definitions.MuteTimeIntervalExport) (definitions.MuteTimeIntervalExportHcl, error) {
result := definitions.MuteTimeIntervalExportHcl{}
j := jsoniter.ConfigCompatibleWithStandardLibrary
mdata, err := j.Marshal(m)
if err != nil {
return result, err
}
err = j.Unmarshal(mdata, &result)
return result, err
}

@ -24,6 +24,8 @@ type ProvisioningApi interface {
RouteDeleteContactpoints(*contextmodel.ReqContext) response.Response
RouteDeleteMuteTiming(*contextmodel.ReqContext) response.Response
RouteDeleteTemplate(*contextmodel.ReqContext) response.Response
RouteExportMuteTiming(*contextmodel.ReqContext) response.Response
RouteExportMuteTimings(*contextmodel.ReqContext) response.Response
RouteGetAlertRule(*contextmodel.ReqContext) response.Response
RouteGetAlertRuleExport(*contextmodel.ReqContext) response.Response
RouteGetAlertRuleGroup(*contextmodel.ReqContext) response.Response
@ -70,6 +72,14 @@ func (f *ProvisioningApiHandler) RouteDeleteTemplate(ctx *contextmodel.ReqContex
nameParam := web.Params(ctx.Req)[":name"]
return f.handleRouteDeleteTemplate(ctx, nameParam)
}
func (f *ProvisioningApiHandler) RouteExportMuteTiming(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
nameParam := web.Params(ctx.Req)[":name"]
return f.handleRouteExportMuteTiming(ctx, nameParam)
}
func (f *ProvisioningApiHandler) RouteExportMuteTimings(ctx *contextmodel.ReqContext) response.Response {
return f.handleRouteExportMuteTimings(ctx)
}
func (f *ProvisioningApiHandler) RouteGetAlertRule(ctx *contextmodel.ReqContext) response.Response {
// Parse Path Parameters
uIDParam := web.Params(ctx.Req)[":UID"]
@ -263,6 +273,30 @@ func (api *API) RegisterProvisioningApiEndpoints(srv ProvisioningApi, m *metrics
m,
),
)
group.Get(
toMacaronPath("/api/v1/provisioning/mute-timings/{name}/export"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodGet, "/api/v1/provisioning/mute-timings/{name}/export"),
metrics.Instrument(
http.MethodGet,
"/api/v1/provisioning/mute-timings/{name}/export",
api.Hooks.Wrap(srv.RouteExportMuteTiming),
m,
),
)
group.Get(
toMacaronPath("/api/v1/provisioning/mute-timings/export"),
requestmeta.SetOwner(requestmeta.TeamAlerting),
requestmeta.SetSLOGroup(requestmeta.SLOGroupHighSlow),
api.authorize(http.MethodGet, "/api/v1/provisioning/mute-timings/export"),
metrics.Instrument(
http.MethodGet,
"/api/v1/provisioning/mute-timings/export",
api.Hooks.Wrap(srv.RouteExportMuteTimings),
m,
),
)
group.Get(
toMacaronPath("/api/v1/provisioning/alert-rules/{UID}"),
requestmeta.SetOwner(requestmeta.TeamAlerting),

@ -127,3 +127,11 @@ func (f *ProvisioningApiHandler) handleRouteGetAlertRuleGroupExport(ctx *context
func (f *ProvisioningApiHandler) handleRoutePutAlertRuleGroup(ctx *contextmodel.ReqContext, ag apimodels.AlertRuleGroup, folder, group string) response.Response {
return f.svc.RoutePutAlertRuleGroup(ctx, ag, folder, group)
}
func (f *ProvisioningApiHandler) handleRouteExportMuteTiming(ctx *contextmodel.ReqContext, name string) response.Response {
return f.svc.RouteGetMuteTimingExport(ctx, name)
}
func (f *ProvisioningApiHandler) handleRouteExportMuteTimings(ctx *contextmodel.ReqContext) response.Response {
return f.svc.RouteGetMuteTimingsExport(ctx)
}

@ -0,0 +1,20 @@
resource "grafana_mute_timing" "mute_timing_1" {
name = "interval"
}
resource "grafana_mute_timing" "mute_timing_2" {
name = "full-interval"
intervals {
times {
start = "10:00"
end = "12:00"
}
weekdays = ["monday", "wednesday", "friday"]
days_of_month = ["1", "14:16", "20"]
months = ["1:3", "7", "12"]
years = ["2023:2025"]
location = "America/New_York"
}
}

@ -0,0 +1 @@
{"apiVersion":1,"muteTimes":[{"orgId":1,"name":"interval","time_intervals":[]},{"orgId":1,"name":"full-interval","time_intervals":[{"times":[{"start_time":"10:00","end_time":"12:00"}],"weekdays":["monday","wednesday","friday"],"days_of_month":["1","14:16","20"],"months":["1:3","7","12"],"years":["2023:2025"],"location":"America/New_York"}]}]}

@ -0,0 +1,16 @@
apiVersion: 1
muteTimes:
- orgId: 1
name: interval
time_intervals: []
- orgId: 1
name: full-interval
time_intervals:
- times:
- start_time: "10:00"
end_time: "12:00"
weekdays: [monday, wednesday, friday]
days_of_month: ["1", "14:16", "20"]
months: ["1:3", "7", "12"]
years: ['2023:2025']
location: America/New_York

@ -298,6 +298,12 @@
},
"type": "array"
},
"muteTimes": {
"items": {
"$ref": "#/definitions/MuteTimeIntervalExport"
},
"type": "array"
},
"policies": {
"items": {
"$ref": "#/definitions/NotificationPolicyExport"
@ -1920,6 +1926,24 @@
"title": "MuteTimeInterval represents a named set of time intervals for which a route should be muted.",
"type": "object"
},
"MuteTimeIntervalExport": {
"properties": {
"OrgID": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"time_intervals": {
"items": {
"$ref": "#/definitions/TimeInterval"
},
"type": "array"
}
},
"type": "object"
},
"MuteTimings": {
"items": {
"$ref": "#/definitions/MuteTimeInterval"
@ -4228,7 +4252,6 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup"
},
@ -5365,6 +5388,45 @@
]
}
},
"/api/v1/provisioning/mute-timings/export": {
"get": {
"operationId": "RouteExportMuteTimings",
"parameters": [
{
"default": false,
"description": "Whether to initiate a download of the file or not.",
"in": "query",
"name": "download",
"type": "boolean"
},
{
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"in": "query",
"name": "format",
"type": "string"
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
},
"summary": "Export all mute timings in provisioning format.",
"tags": [
"provisioning"
]
}
},
"/api/v1/provisioning/mute-timings/{name}": {
"delete": {
"operationId": "RouteDeleteMuteTiming",
@ -5455,6 +5517,52 @@
]
}
},
"/api/v1/provisioning/mute-timings/{name}/export": {
"get": {
"operationId": "RouteExportMuteTiming",
"parameters": [
{
"default": false,
"description": "Whether to initiate a download of the file or not.",
"in": "query",
"name": "download",
"type": "boolean"
},
{
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"in": "query",
"name": "format",
"type": "string"
},
{
"description": "Mute timing name",
"in": "path",
"name": "name",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
},
"summary": "Export a mute timing in provisioning format.",
"tags": [
"provisioning"
]
}
},
"/api/v1/provisioning/policies": {
"delete": {
"consumes": [

@ -7,9 +7,10 @@ type AlertingFileExport struct {
Groups []AlertRuleGroupExport `json:"groups,omitempty" yaml:"groups,omitempty"`
ContactPoints []ContactPointExport `json:"contactPoints,omitempty" yaml:"contactPoints,omitempty"`
Policies []NotificationPolicyExport `json:"policies,omitempty" yaml:"policies,omitempty"`
MuteTimings []MuteTimeIntervalExport `json:"muteTimes,omitempty" yaml:"muteTimes,omitempty"`
}
// swagger:parameters RouteGetAlertRuleGroupExport RouteGetAlertRuleExport RouteGetContactpointsExport RouteGetContactpointExport RoutePostRulesGroupForExport
// swagger:parameters RouteGetAlertRuleGroupExport RouteGetAlertRuleExport RouteGetContactpointsExport RouteGetContactpointExport RoutePostRulesGroupForExport RouteExportMuteTimings RouteExportMuteTiming
type ExportQueryParams struct {
// Whether to initiate a download of the file or not.
// in: query

@ -11,6 +11,14 @@ import (
// Responses:
// 200: MuteTimings
// swagger:route GET /api/v1/provisioning/mute-timings/export provisioning stable RouteExportMuteTimings
//
// Export all mute timings in provisioning format.
//
// Responses:
// 200: AlertingFileExport
// 403: PermissionDenied
// swagger:route GET /api/v1/provisioning/mute-timings/{name} provisioning stable RouteGetMuteTiming
//
// Get a mute timing.
@ -19,6 +27,14 @@ import (
// 200: MuteTimeInterval
// 404: description: Not found.
// swagger:route GET /api/v1/provisioning/mute-timings/{name}/export provisioning stable RouteExportMuteTiming
//
// Export a mute timing in provisioning format.
//
// Responses:
// 200: AlertingFileExport
// 403: PermissionDenied
// swagger:route POST /api/v1/provisioning/mute-timings provisioning stable RoutePostMuteTiming
//
// Create a new mute timing.
@ -53,7 +69,7 @@ import (
// swagger:model
type MuteTimings []MuteTimeInterval
// swagger:parameters RouteGetTemplate RouteGetMuteTiming RoutePutMuteTiming stable RouteDeleteMuteTiming
// swagger:parameters RouteGetTemplate RouteGetMuteTiming RoutePutMuteTiming stable RouteDeleteMuteTiming RouteExportMuteTiming
type RouteGetMuteTimingParam struct {
// Mute timing name
// in:path
@ -79,3 +95,30 @@ func (mt *MuteTimeInterval) ResourceType() string {
func (mt *MuteTimeInterval) ResourceID() string {
return mt.MuteTimeInterval.Name
}
type MuteTimeIntervalExport struct {
OrgID int64 `json:"orgId" yaml:"orgId"`
config.MuteTimeInterval `json:",inline" yaml:",inline"`
}
// MuteTimeIntervalExportHcl is a representation of the MuteTimeInterval in HCL
type MuteTimeIntervalExportHcl struct {
Name string `json:"name" hcl:"name"`
TimeIntervals []TimeIntervalExportHcl `json:"time_intervals" hcl:"intervals,block"`
}
// TimeIntervalExportHcl is a representation of the timeinterval.TimeInterval in HCL
type TimeIntervalExportHcl struct {
Times []TimeRangeExportHcl `json:"times,omitempty" hcl:"times,block"`
Weekdays *[]string `json:"weekdays,omitempty" hcl:"weekdays"`
DaysOfMonth *[]string `json:"days_of_month,omitempty" hcl:"days_of_month"`
Months *[]string `json:"months,omitempty" hcl:"months"`
Years *[]string `json:"years,omitempty" hcl:"years"`
Location *string `json:"location,omitempty" hcl:"location"`
}
// TimeRangeExportHcl is a representation of the timeinterval.TimeRange in HCL
type TimeRangeExportHcl struct {
StartMinute string `json:"start_time" hcl:"start"`
EndMinute string `json:"end_time" hcl:"end"`
}

@ -298,6 +298,12 @@
},
"type": "array"
},
"muteTimes": {
"items": {
"$ref": "#/definitions/MuteTimeIntervalExport"
},
"type": "array"
},
"policies": {
"items": {
"$ref": "#/definitions/NotificationPolicyExport"
@ -1920,6 +1926,24 @@
"title": "MuteTimeInterval represents a named set of time intervals for which a route should be muted.",
"type": "object"
},
"MuteTimeIntervalExport": {
"properties": {
"OrgID": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"time_intervals": {
"items": {
"$ref": "#/definitions/TimeInterval"
},
"type": "array"
}
},
"type": "object"
},
"MuteTimings": {
"items": {
"$ref": "#/definitions/MuteTimeInterval"
@ -4205,6 +4229,7 @@
"type": "object"
},
"alertGroup": {
"description": "AlertGroup alert group",
"properties": {
"alerts": {
"description": "alerts",
@ -4228,7 +4253,6 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/definitions/alertGroup"
},
@ -4333,7 +4357,6 @@
"type": "object"
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"properties": {
"annotations": {
"$ref": "#/definitions/labelSet"
@ -4396,6 +4419,7 @@
"type": "array"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"properties": {
"comment": {
"description": "comment",
@ -4444,7 +4468,6 @@
"type": "object"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"items": {
"$ref": "#/definitions/gettableSilence"
},
@ -4595,6 +4618,7 @@
"type": "array"
},
"postableSilence": {
"description": "PostableSilence postable silence",
"properties": {
"comment": {
"description": "comment",
@ -7344,6 +7368,45 @@
]
}
},
"/api/v1/provisioning/mute-timings/export": {
"get": {
"operationId": "RouteExportMuteTimings",
"parameters": [
{
"default": false,
"description": "Whether to initiate a download of the file or not.",
"in": "query",
"name": "download",
"type": "boolean"
},
{
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"in": "query",
"name": "format",
"type": "string"
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
},
"summary": "Export all mute timings in provisioning format.",
"tags": [
"provisioning"
]
}
},
"/api/v1/provisioning/mute-timings/{name}": {
"delete": {
"operationId": "RouteDeleteMuteTiming",
@ -7434,6 +7497,52 @@
]
}
},
"/api/v1/provisioning/mute-timings/{name}/export": {
"get": {
"operationId": "RouteExportMuteTiming",
"parameters": [
{
"default": false,
"description": "Whether to initiate a download of the file or not.",
"in": "query",
"name": "download",
"type": "boolean"
},
{
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"in": "query",
"name": "format",
"type": "string"
},
{
"description": "Mute timing name",
"in": "path",
"name": "name",
"required": true,
"type": "string"
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
},
"summary": "Export a mute timing in provisioning format.",
"tags": [
"provisioning"
]
}
},
"/api/v1/provisioning/policies": {
"delete": {
"consumes": [

@ -2626,6 +2626,46 @@
}
}
},
"/api/v1/provisioning/mute-timings/export": {
"get": {
"tags": [
"provisioning",
"stable"
],
"summary": "Export all mute timings in provisioning format.",
"operationId": "RouteExportMuteTimings",
"parameters": [
{
"type": "boolean",
"default": false,
"description": "Whether to initiate a download of the file or not.",
"name": "download",
"in": "query"
},
{
"type": "string",
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"name": "format",
"in": "query"
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
}
}
},
"/api/v1/provisioning/mute-timings/{name}": {
"get": {
"tags": [
@ -2719,6 +2759,53 @@
}
}
},
"/api/v1/provisioning/mute-timings/{name}/export": {
"get": {
"tags": [
"provisioning",
"stable"
],
"summary": "Export a mute timing in provisioning format.",
"operationId": "RouteExportMuteTiming",
"parameters": [
{
"type": "boolean",
"default": false,
"description": "Whether to initiate a download of the file or not.",
"name": "download",
"in": "query"
},
{
"type": "string",
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"name": "format",
"in": "query"
},
{
"type": "string",
"description": "Mute timing name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
}
}
},
"/api/v1/provisioning/policies": {
"get": {
"tags": [
@ -3362,6 +3449,12 @@
"$ref": "#/definitions/AlertRuleGroupExport"
}
},
"muteTimes": {
"type": "array",
"items": {
"$ref": "#/definitions/MuteTimeIntervalExport"
}
},
"policies": {
"type": "array",
"items": {
@ -4986,6 +5079,24 @@
}
}
},
"MuteTimeIntervalExport": {
"type": "object",
"properties": {
"OrgID": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"time_intervals": {
"type": "array",
"items": {
"$ref": "#/definitions/TimeInterval"
}
}
}
},
"MuteTimings": {
"type": "array",
"items": {
@ -7271,6 +7382,7 @@
}
},
"alertGroup": {
"description": "AlertGroup alert group",
"type": "object",
"required": [
"alerts",
@ -7295,7 +7407,6 @@
"$ref": "#/definitions/alertGroup"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"type": "array",
"items": {
"$ref": "#/definitions/alertGroup"
@ -7401,7 +7512,6 @@
}
},
"gettableAlert": {
"description": "GettableAlert gettable alert",
"type": "object",
"required": [
"labels",
@ -7466,6 +7576,7 @@
"$ref": "#/definitions/gettableAlerts"
},
"gettableSilence": {
"description": "GettableSilence gettable silence",
"type": "object",
"required": [
"comment",
@ -7515,7 +7626,6 @@
"$ref": "#/definitions/gettableSilence"
},
"gettableSilences": {
"description": "GettableSilences gettable silences",
"type": "array",
"items": {
"$ref": "#/definitions/gettableSilence"
@ -7668,6 +7778,7 @@
}
},
"postableSilence": {
"description": "PostableSilence postable silence",
"type": "object",
"required": [
"comment",

@ -3079,6 +3079,45 @@
}
}
},
"/api/v1/provisioning/mute-timings/export": {
"get": {
"tags": [
"provisioning"
],
"summary": "Export all mute timings in provisioning format.",
"operationId": "RouteExportMuteTimings",
"parameters": [
{
"type": "boolean",
"default": false,
"description": "Whether to initiate a download of the file or not.",
"name": "download",
"in": "query"
},
{
"type": "string",
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"name": "format",
"in": "query"
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
}
}
},
"/api/v1/provisioning/mute-timings/{name}": {
"get": {
"tags": [
@ -3169,6 +3208,52 @@
}
}
},
"/api/v1/provisioning/mute-timings/{name}/export": {
"get": {
"tags": [
"provisioning"
],
"summary": "Export a mute timing in provisioning format.",
"operationId": "RouteExportMuteTiming",
"parameters": [
{
"type": "boolean",
"default": false,
"description": "Whether to initiate a download of the file or not.",
"name": "download",
"in": "query"
},
{
"type": "string",
"default": "yaml",
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"name": "format",
"in": "query"
},
{
"type": "string",
"description": "Mute timing name",
"name": "name",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "AlertingFileExport",
"schema": {
"$ref": "#/definitions/AlertingFileExport"
}
},
"403": {
"description": "PermissionDenied",
"schema": {
"$ref": "#/definitions/PermissionDenied"
}
}
}
}
},
"/api/v1/provisioning/policies": {
"get": {
"tags": [
@ -11776,6 +11861,12 @@
"$ref": "#/definitions/AlertRuleGroupExport"
}
},
"muteTimes": {
"type": "array",
"items": {
"$ref": "#/definitions/MuteTimeIntervalExport"
}
},
"policies": {
"type": "array",
"items": {
@ -15691,6 +15782,24 @@
}
}
},
"MuteTimeIntervalExport": {
"type": "object",
"properties": {
"OrgID": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"time_intervals": {
"type": "array",
"items": {
"$ref": "#/definitions/TimeInterval"
}
}
}
},
"MuteTimings": {
"type": "array",
"items": {
@ -20559,7 +20668,6 @@
}
},
"alertGroups": {
"description": "AlertGroups alert groups",
"type": "array",
"items": {
"$ref": "#/definitions/alertGroup"

@ -2792,6 +2792,12 @@
},
"type": "array"
},
"muteTimes": {
"items": {
"$ref": "#/components/schemas/MuteTimeIntervalExport"
},
"type": "array"
},
"policies": {
"items": {
"$ref": "#/components/schemas/NotificationPolicyExport"
@ -6709,6 +6715,24 @@
"title": "MuteTimeInterval represents a named set of time intervals for which a route should be muted.",
"type": "object"
},
"MuteTimeIntervalExport": {
"properties": {
"OrgID": {
"format": "int64",
"type": "integer"
},
"name": {
"type": "string"
},
"time_intervals": {
"items": {
"$ref": "#/components/schemas/TimeInterval"
},
"type": "array"
}
},
"type": "object"
},
"MuteTimings": {
"items": {
"$ref": "#/components/schemas/MuteTimeInterval"
@ -11575,7 +11599,6 @@
"type": "object"
},
"alertGroups": {
"description": "AlertGroups alert groups",
"items": {
"$ref": "#/components/schemas/alertGroup"
},
@ -15557,6 +15580,57 @@
]
}
},
"/api/v1/provisioning/mute-timings/export": {
"get": {
"operationId": "RouteExportMuteTimings",
"parameters": [
{
"description": "Whether to initiate a download of the file or not.",
"in": "query",
"name": "download",
"schema": {
"default": false,
"type": "boolean"
}
},
{
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"in": "query",
"name": "format",
"schema": {
"default": "yaml",
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlertingFileExport"
}
}
},
"description": "AlertingFileExport"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PermissionDenied"
}
}
},
"description": "PermissionDenied"
}
},
"summary": "Export all mute timings in provisioning format.",
"tags": [
"provisioning"
]
}
},
"/api/v1/provisioning/mute-timings/{name}": {
"delete": {
"operationId": "RouteDeleteMuteTiming",
@ -15665,6 +15739,66 @@
]
}
},
"/api/v1/provisioning/mute-timings/{name}/export": {
"get": {
"operationId": "RouteExportMuteTiming",
"parameters": [
{
"description": "Whether to initiate a download of the file or not.",
"in": "query",
"name": "download",
"schema": {
"default": false,
"type": "boolean"
}
},
{
"description": "Format of the downloaded file, either yaml or json. Accept header can also be used, but the query parameter will take precedence.",
"in": "query",
"name": "format",
"schema": {
"default": "yaml",
"type": "string"
}
},
{
"description": "Mute timing name",
"in": "path",
"name": "name",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AlertingFileExport"
}
}
},
"description": "AlertingFileExport"
},
"403": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PermissionDenied"
}
}
},
"description": "PermissionDenied"
}
},
"summary": "Export a mute timing in provisioning format.",
"tags": [
"provisioning"
]
}
},
"/api/v1/provisioning/policies": {
"delete": {
"operationId": "RouteResetPolicyTree",

Loading…
Cancel
Save