2021-04-20 13:12:32 -04:00
package definitions
2021-04-19 14:26:04 -04:00
import (
2021-10-07 16:33:50 +02:00
"context"
2021-04-19 14:26:04 -04:00
"encoding/json"
"fmt"
2021-08-17 13:49:05 +01:00
"time"
2021-04-19 14:26:04 -04:00
2021-06-15 17:14:02 +01:00
"github.com/go-openapi/strfmt"
2024-03-06 20:48:32 +00:00
"github.com/grafana/alerting/definition"
2021-05-18 13:34:47 +05:30
amv2 "github.com/prometheus/alertmanager/api/v2/models"
2021-04-19 14:26:04 -04:00
"github.com/prometheus/alertmanager/config"
2021-10-04 14:06:40 +01:00
"github.com/prometheus/common/model"
2021-04-19 14:26:04 -04:00
"gopkg.in/yaml.v3"
)
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/grafana/config/api/v1/alerts alertmanager RoutePostGrafanaAlertingConfig
2022-02-04 12:42:04 -05:00
//
// sets an Alerting config
//
// Responses:
// 201: Ack
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/{DatasourceUID}/config/api/v1/alerts alertmanager RoutePostAlertingConfig
2021-04-19 14:26:04 -04:00
//
// sets an Alerting config
//
// Responses:
// 201: Ack
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/config/api/v1/alerts alertmanager RouteGetGrafanaAlertingConfig
2022-02-04 12:42:04 -05:00
//
// gets an Alerting config
//
// Responses:
// 200: GettableUserConfig
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/{DatasourceUID}/config/api/v1/alerts alertmanager RouteGetAlertingConfig
2021-04-19 14:26:04 -04:00
//
// gets an Alerting config
//
// Responses:
// 200: GettableUserConfig
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/config/history alertmanager RouteGetGrafanaAlertingConfigHistory
2023-03-31 17:43:04 -03:00
//
// gets Alerting configurations that were successfully applied in the past
//
// Responses:
// 200: GettableHistoricUserConfigs
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/grafana/config/history/{id}/_activate alertmanager RoutePostGrafanaAlertingConfigHistoryActivate
2023-04-05 14:10:03 -04:00
//
// revert Alerting configuration to the historical configuration specified by the given id
//
// Responses:
// 202: Ack
// 400: ValidationError
// 404: NotFound
2024-01-17 11:53:16 -05:00
// swagger:route DELETE /alertmanager/grafana/config/api/v1/alerts alertmanager RouteDeleteGrafanaAlertingConfig
2022-02-04 12:42:04 -05:00
//
// deletes the Alerting config for a tenant
//
// Responses:
// 200: Ack
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route DELETE /alertmanager/{DatasourceUID}/config/api/v1/alerts alertmanager RouteDeleteAlertingConfig
2021-04-19 14:26:04 -04:00
//
// deletes the Alerting config for a tenant
//
// Responses:
// 200: Ack
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/api/v2/status alertmanager RouteGetGrafanaAMStatus
2022-02-04 12:42:04 -05:00
//
// get alertmanager status and configuration
//
// Responses:
// 200: GettableStatus
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/{DatasourceUID}/api/v2/status alertmanager RouteGetAMStatus
2021-06-15 17:14:02 +01:00
//
// get alertmanager status and configuration
//
// Responses:
// 200: GettableStatus
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-06-15 17:14:02 +01:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/api/v2/alerts alertmanager RouteGetGrafanaAMAlerts
2022-02-04 12:42:04 -05:00
//
// get alertmanager alerts
//
// Responses:
// 200: gettableAlerts
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/{DatasourceUID}/api/v2/alerts alertmanager RouteGetAMAlerts
2021-04-19 14:26:04 -04:00
//
// get alertmanager alerts
//
// Responses:
2021-08-13 16:15:53 +03:00
// 200: gettableAlerts
2021-04-19 14:26:04 -04:00
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/{DatasourceUID}/api/v2/alerts alertmanager RoutePostAMAlerts
2021-04-19 14:26:04 -04:00
//
// create alertmanager alerts
//
// Responses:
// 200: Ack
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/api/v2/alerts/groups alertmanager RouteGetGrafanaAMAlertGroups
2022-02-04 12:42:04 -05:00
//
// get alertmanager alerts
//
// Responses:
// 200: alertGroups
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/{DatasourceUID}/api/v2/alerts/groups alertmanager RouteGetAMAlertGroups
2021-04-19 14:26:04 -04:00
//
// get alertmanager alerts
//
// Responses:
2021-08-13 16:15:53 +03:00
// 200: alertGroups
2021-04-19 14:26:04 -04:00
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/config/api/v1/receivers alertmanager RouteGetGrafanaReceivers
2022-10-03 10:58:41 -03:00
//
2022-10-17 16:58:55 -03:00
// Get a list of all receivers
2022-10-03 10:58:41 -03:00
//
// Responses:
2022-10-17 16:58:55 -03:00
// 200: receiversResponse
2022-10-03 10:58:41 -03:00
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/grafana/config/api/v1/receivers/test alertmanager RoutePostTestGrafanaReceivers
2022-02-04 12:42:04 -05:00
//
// Test Grafana managed receivers without saving them.
//
// Responses:
//
// 200: Ack
// 207: MultiStatus
// 400: ValidationError
// 403: PermissionDenied
2022-08-02 09:33:59 -04:00
// 404: NotFound
2022-02-04 12:42:04 -05:00
// 408: Failure
// 409: AlertManagerNotReady
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/grafana/config/api/v1/templates/test alertmanager RoutePostTestGrafanaTemplates
2023-04-28 10:56:59 -04:00
//
// Test Grafana managed templates without saving them.
// Produces:
// - application/json
//
// Responses:
//
// 200: TestTemplatesResults
// 400: ValidationError
// 403: PermissionDenied
// 409: AlertManagerNotReady
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/api/v2/silences alertmanager RouteGetGrafanaSilences
2022-02-04 12:42:04 -05:00
//
// get silences
//
// Responses:
// 200: gettableSilences
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/{DatasourceUID}/api/v2/silences alertmanager RouteGetSilences
2021-04-19 14:26:04 -04:00
//
// get silences
//
// Responses:
2021-08-13 16:15:53 +03:00
// 200: gettableSilences
2021-04-19 14:26:04 -04:00
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/grafana/api/v2/silences alertmanager RouteCreateGrafanaSilence
2022-02-04 12:42:04 -05:00
//
// create silence
//
// Responses:
2023-05-15 11:23:30 -04:00
// 202: postSilencesOKBody
2022-02-04 12:42:04 -05:00
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route POST /alertmanager/{DatasourceUID}/api/v2/silences alertmanager RouteCreateSilence
2021-04-19 14:26:04 -04:00
//
// create silence
//
// Responses:
2022-10-17 15:43:37 -04:00
// 201: postSilencesOKBody
2021-04-19 14:26:04 -04:00
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/grafana/api/v2/silence/{SilenceId} alertmanager RouteGetGrafanaSilence
2022-02-04 12:42:04 -05:00
//
// get silence
//
// Responses:
// 200: gettableSilence
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route GET /alertmanager/{DatasourceUID}/api/v2/silence/{SilenceId} alertmanager RouteGetSilence
2021-04-19 14:26:04 -04:00
//
// get silence
//
// Responses:
2021-08-13 16:15:53 +03:00
// 200: gettableSilence
2021-04-19 14:26:04 -04:00
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-01-17 11:53:16 -05:00
// swagger:route DELETE /alertmanager/grafana/api/v2/silence/{SilenceId} alertmanager RouteDeleteGrafanaSilence
2022-02-04 12:42:04 -05:00
//
// delete silence
//
// Responses:
// 200: Ack
// 400: ValidationError
2024-01-17 11:53:16 -05:00
// swagger:route DELETE /alertmanager/{DatasourceUID}/api/v2/silence/{SilenceId} alertmanager RouteDeleteSilence
2021-04-19 14:26:04 -04:00
//
// delete silence
//
// Responses:
// 200: Ack
// 400: ValidationError
2022-08-02 09:33:59 -04:00
// 404: NotFound
2021-04-19 14:26:04 -04:00
2024-03-06 20:48:32 +00:00
// Alias all the needed Alertmanager types, functions and constants so that they can be imported directly from grafana/alerting
// without having to modify any of the usage within Grafana.
type (
Config = definition . Config
Route = definition . Route
PostableGrafanaReceiver = definition . PostableGrafanaReceiver
PostableApiAlertingConfig = definition . PostableApiAlertingConfig
RawMessage = definition . RawMessage
Provenance = definition . Provenance
ObjectMatchers = definition . ObjectMatchers
PostableApiReceiver = definition . PostableApiReceiver
PostableGrafanaReceivers = definition . PostableGrafanaReceivers
ReceiverType = definition . ReceiverType
)
const (
GrafanaReceiverType = definition . GrafanaReceiverType
AlertmanagerReceiverType = definition . AlertmanagerReceiverType
)
var (
AsGrafanaRoute = definition . AsGrafanaRoute
AllReceivers = definition . AllReceivers
)
2021-08-17 13:49:05 +01:00
// swagger:model
2021-09-10 12:46:02 +03:00
type PermissionDenied struct { }
// swagger:model
type AlertManagerNotReady struct { }
// swagger:model
type MultiStatus struct { }
2021-08-17 13:49:05 +01:00
2023-03-31 17:43:04 -03:00
// swagger:parameters RouteGetGrafanaAlertingConfigHistory
type RouteGetGrafanaAlertingConfigHistoryParams struct {
// Limit response to n historic configurations.
// in:query
Limit int ` json:"limit" `
}
2022-10-26 23:35:52 -03:00
// swagger:parameters RoutePostTestGrafanaReceivers
2021-08-17 13:49:05 +01:00
type TestReceiversConfigParams struct {
2021-10-21 13:47:06 +01:00
// in:body
2021-11-30 21:55:54 +02:00
Body TestReceiversConfigBodyParams
}
type TestReceiversConfigBodyParams struct {
Alert * TestReceiversConfigAlertParams ` yaml:"alert,omitempty" json:"alert,omitempty" `
Receivers [ ] * PostableApiReceiver ` yaml:"receivers,omitempty" json:"receivers,omitempty" `
2021-08-17 13:49:05 +01:00
}
2021-10-21 13:47:06 +01:00
type TestReceiversConfigAlertParams struct {
Annotations model . LabelSet ` yaml:"annotations,omitempty" json:"annotations,omitempty" `
Labels model . LabelSet ` yaml:"labels,omitempty" json:"labels,omitempty" `
}
2021-08-17 13:49:05 +01:00
// swagger:model
type TestReceiversResult struct {
2021-10-21 13:47:06 +01:00
Alert TestReceiversConfigAlertParams ` json:"alert" `
Receivers [ ] TestReceiverResult ` json:"receivers" `
NotifiedAt time . Time ` json:"notified_at" `
2021-08-17 13:49:05 +01:00
}
// swagger:model
type TestReceiverResult struct {
Name string ` json:"name" `
Configs [ ] TestReceiverConfigResult ` json:"grafana_managed_receiver_configs" `
}
// swagger:model
type TestReceiverConfigResult struct {
Name string ` json:"name" `
UID string ` json:"uid" `
Status string ` json:"status" `
Error string ` json:"error,omitempty" `
}
2023-04-28 10:56:59 -04:00
// swagger:parameters RoutePostTestGrafanaTemplates
type TestTemplatesConfigParams struct {
// in:body
Body TestTemplatesConfigBodyParams
}
type TestTemplatesConfigBodyParams struct {
// Alerts to use as data when testing the template.
Alerts [ ] * amv2 . PostableAlert ` json:"alerts" `
// Template string to test.
Template string ` json:"template" `
// Name of the template file.
Name string ` json:"name" `
}
// swagger:model
type TestTemplatesResults struct {
Results [ ] TestTemplatesResult ` json:"results,omitempty" `
Errors [ ] TestTemplatesErrorResult ` json:"errors,omitempty" `
}
type TestTemplatesResult struct {
// Name of the associated template definition for this result.
Name string ` json:"name" `
// Interpolated value of the template.
Text string ` json:"text" `
}
type TestTemplatesErrorResult struct {
// Name of the associated template for this error. Will be empty if the Kind is "invalid_template".
Name string ` json:"name,omitempty" `
// Kind of template error that occurred.
Kind TemplateErrorKind ` json:"kind" `
// Error message.
Message string ` json:"message" `
}
// swagger:enum TemplateErrorKind
type TemplateErrorKind string
const (
InvalidTemplate TemplateErrorKind = "invalid_template"
ExecutionError TemplateErrorKind = "execution_error"
)
2022-02-04 12:42:04 -05:00
// swagger:parameters RouteCreateSilence RouteCreateGrafanaSilence
2021-04-19 14:26:04 -04:00
type CreateSilenceParams struct {
// in:body
Silence PostableSilence
}
2022-02-04 12:42:04 -05:00
// swagger:parameters RouteGetSilence RouteDeleteSilence RouteGetGrafanaSilence RouteDeleteGrafanaSilence
2021-04-19 14:26:04 -04:00
type GetDeleteSilenceParams struct {
// in:path
SilenceId string
}
2022-02-04 12:42:04 -05:00
// swagger:parameters RouteGetSilences RouteGetGrafanaSilences
2021-04-19 14:26:04 -04:00
type GetSilencesParams struct {
// in:query
Filter [ ] string ` json:"filter" `
}
2021-06-15 17:14:02 +01:00
// swagger:model
type GettableStatus struct {
// cluster
// Required: true
Cluster * amv2 . ClusterStatus ` json:"cluster" `
// config
// Required: true
Config * PostableApiAlertingConfig ` json:"config" `
// uptime
// Required: true
// Format: date-time
Uptime * strfmt . DateTime ` json:"uptime" `
// version info
// Required: true
VersionInfo * amv2 . VersionInfo ` json:"versionInfo" `
}
func ( s * GettableStatus ) UnmarshalJSON ( b [ ] byte ) error {
amStatus := amv2 . AlertmanagerStatus { }
if err := json . Unmarshal ( b , & amStatus ) ; err != nil {
return err
}
c := config . Config { }
if err := yaml . Unmarshal ( [ ] byte ( * amStatus . Config . Original ) , & c ) ; err != nil {
return err
}
s . Cluster = amStatus . Cluster
s . Config = & PostableApiAlertingConfig { Config : Config {
Global : c . Global ,
2021-10-04 14:06:40 +01:00
Route : AsGrafanaRoute ( c . Route ) ,
2021-06-15 17:14:02 +01:00
InhibitRules : c . InhibitRules ,
Templates : c . Templates ,
} }
s . Uptime = amStatus . Uptime
s . VersionInfo = amStatus . VersionInfo
type overrides struct {
Receivers * [ ] * PostableApiReceiver ` yaml:"receivers,omitempty" json:"receivers,omitempty" `
}
if err := yaml . Unmarshal ( [ ] byte ( * amStatus . Config . Original ) , & overrides { Receivers : & s . Config . Receivers } ) ; err != nil {
return err
}
return nil
}
func NewGettableStatus ( cfg * PostableApiAlertingConfig ) * GettableStatus {
// In Grafana, the only field we support is Config.
cs := amv2 . ClusterStatusStatusDisabled
na := "N/A"
return & GettableStatus {
Cluster : & amv2 . ClusterStatus {
Status : & cs ,
Peers : [ ] * amv2 . PeerStatus { } ,
} ,
VersionInfo : & amv2 . VersionInfo {
Branch : & na ,
BuildDate : & na ,
BuildUser : & na ,
GoVersion : & na ,
Revision : & na ,
Version : & na ,
} ,
Config : cfg ,
}
}
2021-08-13 16:15:53 +03:00
// swagger:model postableSilence
2021-04-19 14:26:04 -04:00
type PostableSilence = amv2 . PostableSilence
2022-10-17 15:43:37 -04:00
// swagger:model postSilencesOKBody
type PostSilencesOKBody struct { // vendored from "github.com/prometheus/alertmanager/api/v2/restapi/operations/silence/PostSilencesOKBody" because import brings too many other things
// silence ID
SilenceID string ` json:"silenceID,omitempty" `
}
2021-08-13 16:15:53 +03:00
// swagger:model gettableSilences
2021-04-19 14:26:04 -04:00
type GettableSilences = amv2 . GettableSilences
2021-08-13 16:15:53 +03:00
// swagger:model gettableSilence
2021-04-19 14:26:04 -04:00
type GettableSilence = amv2 . GettableSilence
2021-08-13 16:15:53 +03:00
// swagger:model gettableAlerts
2021-04-19 14:26:04 -04:00
type GettableAlerts = amv2 . GettableAlerts
2021-08-13 16:15:53 +03:00
// swagger:model gettableAlert
2021-04-19 14:26:04 -04:00
type GettableAlert = amv2 . GettableAlert
2021-08-13 16:15:53 +03:00
// swagger:model alertGroups
2021-04-19 14:26:04 -04:00
type AlertGroups = amv2 . AlertGroups
2021-08-13 16:15:53 +03:00
// swagger:model alertGroup
2021-04-19 14:26:04 -04:00
type AlertGroup = amv2 . AlertGroup
2021-08-13 16:15:53 +03:00
// swagger:model receiver
2021-04-19 14:26:04 -04:00
type Receiver = amv2 . Receiver
2022-10-17 16:58:55 -03:00
// swagger:response receiversResponse
type ReceiversResponse struct {
// in:body
Body [ ] amv2 . Receiver
}
2022-10-03 10:58:41 -03:00
// swagger:model integration
type Integration = amv2 . Integration
2022-02-04 12:42:04 -05:00
// swagger:parameters RouteGetAMAlerts RouteGetAMAlertGroups RouteGetGrafanaAMAlerts RouteGetGrafanaAMAlertGroups
2021-04-19 14:26:04 -04:00
type AlertsParams struct {
// Show active alerts
// in: query
// required: false
// default: true
Active bool ` json:"active" `
// Show silenced alerts
// in: query
// required: false
// default: true
Silenced bool ` json:"silenced" `
// Show inhibited alerts
// in: query
// required: false
// default: true
Inhibited bool ` json:"inhibited" `
// A list of matchers to filter alerts by
// in: query
// required: false
Matchers [ ] string ` json:"filter" `
// A regex matching receivers to filter alerts by
// in: query
// required: false
Receivers string ` json:"receiver" `
}
2022-10-26 23:35:52 -03:00
// swagger:parameters RoutePostAMAlerts
2021-04-19 14:26:04 -04:00
type PostableAlerts struct {
// in:body
PostableAlerts [ ] amv2 . PostableAlert ` yaml:"" json:"" `
}
2022-02-04 12:42:04 -05:00
// swagger:parameters RoutePostAlertingConfig RoutePostGrafanaAlertingConfig
2021-04-19 14:26:04 -04:00
type BodyAlertingConfig struct {
// in:body
Body PostableUserConfig
}
2023-04-05 14:10:03 -04:00
// swagger:parameters RoutePostGrafanaAlertingConfigHistoryActivate
type HistoricalConfigId struct {
// Id should be the id of the GettableHistoricUserConfig
// in:path
Id int64 ` json:"id" `
}
2022-04-29 10:25:22 +03:00
// alertmanager routes
2022-10-26 23:35:52 -03:00
// swagger:parameters RoutePostAlertingConfig RouteGetAlertingConfig RouteDeleteAlertingConfig RouteGetAMStatus RouteGetAMAlerts RoutePostAMAlerts RouteGetAMAlertGroups RouteGetSilences RouteCreateSilence RouteGetSilence RouteDeleteSilence RoutePostAlertingConfig
2022-05-17 14:10:20 +03:00
// testing routes
// swagger:parameters RouteTestRuleConfig
2022-05-06 22:05:02 +03:00
// prom routes
// swagger:parameters RouteGetRuleStatuses RouteGetAlertStatuses
2022-05-05 14:58:32 +03:00
// ruler routes
// swagger:parameters RouteGetRulesConfig RoutePostNameRulesConfig RouteGetNamespaceRulesConfig RouteDeleteNamespaceRulesConfig RouteGetRulegGroupConfig RouteDeleteRuleGroupConfig
2022-04-29 10:25:22 +03:00
type DatasourceUIDReference struct {
// DatasoureUID should be the datasource UID identifier
// in:path
DatasourceUID string
}
2021-04-19 14:26:04 -04:00
// swagger:model
type PostableUserConfig struct {
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
AlertmanagerConfig PostableApiAlertingConfig ` yaml:"alertmanager_config" json:"alertmanager_config" `
2021-05-05 16:21:53 -04:00
amSimple map [ string ] interface { } ` yaml:"-" json:"-" `
2021-04-19 14:26:04 -04:00
}
func ( c * PostableUserConfig ) UnmarshalJSON ( b [ ] byte ) error {
type plain PostableUserConfig
if err := json . Unmarshal ( b , ( * plain ) ( c ) ) ; err != nil {
return err
}
2021-05-05 16:21:53 -04:00
// validate first
if err := c . validate ( ) ; err != nil {
return err
}
type intermediate struct {
AlertmanagerConfig map [ string ] interface { } ` yaml:"alertmanager_config" json:"alertmanager_config" `
}
var tmp intermediate
if err := json . Unmarshal ( b , & tmp ) ; err != nil {
return err
}
// store the map[string]interface{} variant for re-encoding later without redaction
c . amSimple = tmp . AlertmanagerConfig
return nil
2021-04-19 14:26:04 -04:00
}
func ( c * PostableUserConfig ) validate ( ) error {
// Taken from https://github.com/prometheus/alertmanager/blob/master/config/config.go#L170-L191
// Check if we have a root route. We cannot check for it in the
// UnmarshalYAML method because it won't be called if the input is empty
// (e.g. the config file is empty or only contains whitespace).
if c . AlertmanagerConfig . Route == nil {
return fmt . Errorf ( "no route provided in config" )
}
// Check if continue in root route.
if c . AlertmanagerConfig . Route . Continue {
return fmt . Errorf ( "cannot have continue in root route" )
}
return nil
2021-05-10 15:30:42 +03:00
}
2021-05-18 17:31:00 +03:00
// GetGrafanaReceiverMap returns a map that associates UUIDs to grafana receivers
func ( c * PostableUserConfig ) GetGrafanaReceiverMap ( ) map [ string ] * PostableGrafanaReceiver {
UIDs := make ( map [ string ] * PostableGrafanaReceiver )
for _ , r := range c . AlertmanagerConfig . Receivers {
switch r . Type ( ) {
case GrafanaReceiverType :
for _ , gr := range r . PostableGrafanaReceivers . GrafanaManagedReceivers {
UIDs [ gr . UID ] = gr
}
default :
}
}
return UIDs
}
2021-04-19 14:26:04 -04:00
// MarshalYAML implements yaml.Marshaller.
func ( c * PostableUserConfig ) MarshalYAML ( ) ( interface { } , error ) {
2021-05-05 16:21:53 -04:00
yml , err := yaml . Marshal ( c . amSimple )
2021-04-19 14:26:04 -04:00
if err != nil {
return nil , err
}
// cortex/loki actually pass the AM config as a string.
cortexPostableUserConfig := struct {
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
AlertmanagerConfig string ` yaml:"alertmanager_config" json:"alertmanager_config" `
} {
TemplateFiles : c . TemplateFiles ,
AlertmanagerConfig : string ( yml ) ,
}
return cortexPostableUserConfig , nil
}
func ( c * PostableUserConfig ) UnmarshalYAML ( value * yaml . Node ) error {
// cortex/loki actually pass the AM config as a string.
type cortexPostableUserConfig struct {
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
AlertmanagerConfig string ` yaml:"alertmanager_config" json:"alertmanager_config" `
}
var tmp cortexPostableUserConfig
if err := value . Decode ( & tmp ) ; err != nil {
return err
}
if err := yaml . Unmarshal ( [ ] byte ( tmp . AlertmanagerConfig ) , & c . AlertmanagerConfig ) ; err != nil {
return err
}
c . TemplateFiles = tmp . TemplateFiles
return nil
}
// swagger:model
type GettableUserConfig struct {
2023-02-27 17:57:15 -05:00
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
TemplateFileProvenances map [ string ] Provenance ` yaml:"template_file_provenances,omitempty" json:"template_file_provenances,omitempty" `
AlertmanagerConfig GettableApiAlertingConfig ` yaml:"alertmanager_config" json:"alertmanager_config" `
2021-05-05 16:21:53 -04:00
// amSimple stores a map[string]interface of the decoded alertmanager config.
// This enables circumventing the underlying alertmanager secret type
// which redacts itself during encoding.
amSimple map [ string ] interface { } ` yaml:"-" json:"-" `
2021-04-19 14:26:04 -04:00
}
func ( c * GettableUserConfig ) UnmarshalYAML ( value * yaml . Node ) error {
// cortex/loki actually pass the AM config as a string.
type cortexGettableUserConfig struct {
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
AlertmanagerConfig string ` yaml:"alertmanager_config" json:"alertmanager_config" `
}
var tmp cortexGettableUserConfig
if err := value . Decode ( & tmp ) ; err != nil {
return err
}
if err := yaml . Unmarshal ( [ ] byte ( tmp . AlertmanagerConfig ) , & c . AlertmanagerConfig ) ; err != nil {
return err
}
2021-05-05 16:21:53 -04:00
if err := yaml . Unmarshal ( [ ] byte ( tmp . AlertmanagerConfig ) , & c . amSimple ) ; err != nil {
return err
}
2021-04-19 14:26:04 -04:00
c . TemplateFiles = tmp . TemplateFiles
return nil
}
2021-05-05 16:21:53 -04:00
func ( c * GettableUserConfig ) MarshalJSON ( ) ( [ ] byte , error ) {
type plain struct {
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
AlertmanagerConfig map [ string ] interface { } ` yaml:"alertmanager_config" json:"alertmanager_config" `
}
tmp := plain {
TemplateFiles : c . TemplateFiles ,
AlertmanagerConfig : c . amSimple ,
}
return json . Marshal ( tmp )
}
2021-05-18 17:31:00 +03:00
// GetGrafanaReceiverMap returns a map that associates UUIDs to grafana receivers
func ( c * GettableUserConfig ) GetGrafanaReceiverMap ( ) map [ string ] * GettableGrafanaReceiver {
UIDs := make ( map [ string ] * GettableGrafanaReceiver )
for _ , r := range c . AlertmanagerConfig . Receivers {
switch r . Type ( ) {
case GrafanaReceiverType :
for _ , gr := range r . GettableGrafanaReceivers . GrafanaManagedReceivers {
UIDs [ gr . UID ] = gr
}
default :
}
}
return UIDs
}
2023-03-31 17:43:04 -03:00
type GettableHistoricUserConfig struct {
ID int64 ` yaml:"id" json:"id" `
TemplateFiles map [ string ] string ` yaml:"template_files" json:"template_files" `
TemplateFileProvenances map [ string ] Provenance ` yaml:"template_file_provenances,omitempty" json:"template_file_provenances,omitempty" `
AlertmanagerConfig GettableApiAlertingConfig ` yaml:"alertmanager_config" json:"alertmanager_config" `
LastApplied * strfmt . DateTime ` yaml:"last_applied,omitempty" json:"last_applied,omitempty" `
}
// swagger:response GettableHistoricUserConfigs
type GettableHistoricUserConfigs struct {
// in:body
Body [ ] GettableHistoricUserConfig
}
2021-04-19 14:26:04 -04:00
type GettableApiAlertingConfig struct {
2022-06-03 19:32:31 +02:00
Config ` yaml:",inline" `
2023-02-27 17:57:15 -05:00
MuteTimeProvenances map [ string ] Provenance ` yaml:"muteTimeProvenances,omitempty" json:"muteTimeProvenances,omitempty" `
2021-04-19 14:26:04 -04:00
// Override with our superset receiver type
Receivers [ ] * GettableApiReceiver ` yaml:"receivers,omitempty" json:"receivers,omitempty" `
}
2024-02-15 09:45:10 -05:00
func ( c * GettableApiAlertingConfig ) GetReceivers ( ) [ ] * GettableApiReceiver {
return c . Receivers
}
func ( c * GettableApiAlertingConfig ) GetMuteTimeIntervals ( ) [ ] config . MuteTimeInterval {
return c . MuteTimeIntervals
}
2024-02-22 16:57:20 +00:00
func ( c * GettableApiAlertingConfig ) GetTimeIntervals ( ) [ ] config . TimeInterval { return c . TimeIntervals }
2024-02-15 09:45:10 -05:00
func ( c * GettableApiAlertingConfig ) GetRoute ( ) * Route {
return c . Route
}
2021-04-19 14:26:04 -04:00
func ( c * GettableApiAlertingConfig ) UnmarshalJSON ( b [ ] byte ) error {
type plain GettableApiAlertingConfig
if err := json . Unmarshal ( b , ( * plain ) ( c ) ) ; err != nil {
return err
}
2021-05-19 06:22:44 -04:00
// Since Config implements json.Unmarshaler, we must handle _all_ other fields independently.
// Otherwise, the json decoder will detect this and only use the embedded type.
// Additionally, we'll use pointers to slices in order to reference the intended target.
type overrides struct {
Receivers * [ ] * GettableApiReceiver ` yaml:"receivers,omitempty" json:"receivers,omitempty" `
}
if err := json . Unmarshal ( b , & overrides { Receivers : & c . Receivers } ) ; err != nil {
return err
}
2021-04-19 14:26:04 -04:00
return c . validate ( )
}
// validate ensures that the two routing trees use the correct receiver types.
func ( c * GettableApiAlertingConfig ) validate ( ) error {
receivers := make ( map [ string ] struct { } , len ( c . Receivers ) )
var hasGrafReceivers , hasAMReceivers bool
for _ , r := range c . Receivers {
receivers [ r . Name ] = struct { } { }
switch r . Type ( ) {
case GrafanaReceiverType :
hasGrafReceivers = true
case AlertmanagerReceiverType :
hasAMReceivers = true
2021-05-12 07:58:16 -04:00
default :
continue
2021-04-19 14:26:04 -04:00
}
}
if hasGrafReceivers && hasAMReceivers {
return fmt . Errorf ( "cannot mix Alertmanager & Grafana receiver types" )
}
2021-10-04 14:06:40 +01:00
for _ , receiver := range AllReceivers ( c . Route . AsAMRoute ( ) ) {
2021-04-19 14:26:04 -04:00
_ , ok := receivers [ receiver ]
if ! ok {
return fmt . Errorf ( "unexpected receiver (%s) is undefined" , receiver )
}
}
return nil
}
2021-05-18 13:34:47 +05:30
type GettableGrafanaReceiver struct {
2023-02-27 17:57:15 -05:00
UID string ` json:"uid" `
Name string ` json:"name" `
Type string ` json:"type" `
DisableResolveMessage bool ` json:"disableResolveMessage" `
Settings RawMessage ` json:"settings,omitempty" `
SecureFields map [ string ] bool ` json:"secureFields" `
Provenance Provenance ` json:"provenance,omitempty" `
2021-05-18 13:34:47 +05:30
}
2021-04-19 14:26:04 -04:00
type GettableApiReceiver struct {
config . Receiver ` yaml:",inline" `
GettableGrafanaReceivers ` yaml:",inline" `
}
func ( r * GettableApiReceiver ) UnmarshalJSON ( b [ ] byte ) error {
type plain GettableApiReceiver
if err := json . Unmarshal ( b , ( * plain ) ( r ) ) ; err != nil {
return err
}
hasGrafanaReceivers := len ( r . GettableGrafanaReceivers . GrafanaManagedReceivers ) > 0
if hasGrafanaReceivers {
if len ( r . EmailConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager EmailConfigs & Grafana receivers together" )
}
if len ( r . PagerdutyConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager PagerdutyConfigs & Grafana receivers together" )
}
if len ( r . SlackConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager SlackConfigs & Grafana receivers together" )
}
if len ( r . WebhookConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager WebhookConfigs & Grafana receivers together" )
}
if len ( r . OpsGenieConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager OpsGenieConfigs & Grafana receivers together" )
}
if len ( r . WechatConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager WechatConfigs & Grafana receivers together" )
}
if len ( r . PushoverConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager PushoverConfigs & Grafana receivers together" )
}
if len ( r . VictorOpsConfigs ) > 0 {
return fmt . Errorf ( "cannot have both Alertmanager VictorOpsConfigs & Grafana receivers together" )
}
}
return nil
}
func ( r * GettableApiReceiver ) Type ( ) ReceiverType {
if len ( r . GettableGrafanaReceivers . GrafanaManagedReceivers ) > 0 {
return GrafanaReceiverType
}
return AlertmanagerReceiverType
}
2024-02-15 09:45:10 -05:00
func ( r * GettableApiReceiver ) GetName ( ) string {
return r . Receiver . Name
}
2021-04-19 14:26:04 -04:00
type GettableGrafanaReceivers struct {
GrafanaManagedReceivers [ ] * GettableGrafanaReceiver ` yaml:"grafana_managed_receiver_configs,omitempty" json:"grafana_managed_receiver_configs,omitempty" `
}
2023-03-27 16:35:54 -04:00
type EncryptFn func ( ctx context . Context , payload [ ] byte ) ( [ ] byte , error )