diff --git a/README.md b/README.md index 7dc167ba..cf16dc50 100644 --- a/README.md +++ b/README.md @@ -52,9 +52,19 @@ $ curl -H "Content-type: application/json" -X POST \ ## Configuration -The configuration file is essentially a list of receivers matching 1-to-1 all Alertmanager receivers using JIRAlert; plus defaults (in the form of a partially defined receiver); and a pointer to the template file. +The configuration file is essentially a list of JiraAlert receivers plus defaults (in the form of a partially defined receiver); and a pointer to the template file. -Each receiver must have a unique name (matching the Alertmanager receiver name), JIRA API access fields (URL, username and password), a handful of required issue fields (such as the JIRA project and issue summary), some optional issue fields (e.g. priority) and a `fields` map for other (standard or custom) JIRA fields. Most of these may use [Go templating](https://golang.org/pkg/text/template/) to generate the actual field values based on the contents of the Alertmanager notification. The exact same data structures and functions as those defined in the [Alertmanager template reference](https://prometheus.io/docs/alerting/notifications/) are available in JIRAlert. +You can find more docs in [the configuration itself](/pkg/config/config.go) + +Each receiver must have: +* a unique name (matching the Alertmanager receiver name) +* JIRA API access fields (URL, username and password), +* handful of required issue fields (such as the JIRA project and issue summary), +* some optional issue fields (e.g. priority) and a `fields` map for other (standard or custom) JIRA fields. + +Most of these may use [Go templating](https://golang.org/pkg/text/template/) to generate the actual field values based on the contents of the Alertmanager notification. + +The exact same data structures and functions as those defined in the [Alertmanager template reference](https://prometheus.io/docs/alerting/notifications/) are available in JIRAlert. ## Alertmanager configuration diff --git a/cmd/jiralert/content.go b/cmd/jiralert/content.go index eead48ce..49051d74 100644 --- a/cmd/jiralert/content.go +++ b/cmd/jiralert/content.go @@ -53,11 +53,6 @@ const (
{{ .Config }}
{{- end }}
-
- {{ define "content.error" -}}
- {{ .Err }}
- {{- end }}
`
)
@@ -66,16 +61,12 @@ type tdata struct {
// `/config` only
Config string
-
- // `/error` only
- Err error
}
var (
allTemplates = template.Must(template.New("").Parse(templates))
homeTemplate = pageTemplate("home")
configTemplate = pageTemplate("config")
- // errorTemplate = pageTemplate("error")
)
func pageTemplate(name string) *template.Template {
@@ -86,7 +77,7 @@ func pageTemplate(name string) *template.Template {
// HomeHandlerFunc is the HTTP handler for the home page (`/`).
func HomeHandlerFunc() func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
- homeTemplate.Execute(w, &tdata{
+ _ = homeTemplate.Execute(w, &tdata{
DocsUrl: docsUrl,
})
}
@@ -95,19 +86,9 @@ func HomeHandlerFunc() func(http.ResponseWriter, *http.Request) {
// ConfigHandlerFunc is the HTTP handler for the `/config` page. It outputs the configuration marshaled in YAML format.
func ConfigHandlerFunc(config *config.Config) func(http.ResponseWriter, *http.Request) {
return func(w http.ResponseWriter, r *http.Request) {
- configTemplate.Execute(w, &tdata{
+ _ = configTemplate.Execute(w, &tdata{
DocsUrl: docsUrl,
Config: config.String(),
})
}
}
-
-// HandleError is an error handler that other handlers defer to in case of error. It is important to not have written
-// anything to w before calling HandleError(), or the 500 status code won't be set (and the content might be mixed up).
-//func HandleError(err error, metricsPath string, w http.ResponseWriter, r *http.Request) {
-// w.WriteHeader(http.StatusInternalServerError)
-// errorTemplate.Execute(w, &tdata{
-// DocsUrl: docsUrl,
-// Err: err,
-// })
-//}
diff --git a/cmd/jiralert/main.go b/cmd/jiralert/main.go
index b6881a1a..a52ef995 100644
--- a/cmd/jiralert/main.go
+++ b/cmd/jiralert/main.go
@@ -48,21 +48,21 @@ func main() {
var logger = setupLogger(*logLevel, *logFormat)
level.Info(logger).Log("msg", "starting JIRAlert", "version", Version)
- config, _, err := config.LoadFile(*configFile, logger)
+ cfg, _, err := config.LoadFile(*configFile, logger)
if err != nil {
level.Error(logger).Log("msg", "error loading configuration", "path", *configFile, "err", err)
os.Exit(1)
}
- tmpl, err := template.LoadTemplate(config.Template, logger)
+ tmpl, err := template.LoadTemplate(cfg.Template, logger)
if err != nil {
- level.Error(logger).Log("msg", "error loading templates", "path", config.Template, "err", err)
+ level.Error(logger).Log("msg", "error loading templates", "path", cfg.Template, "err", err)
os.Exit(1)
}
http.HandleFunc("/alert", func(w http.ResponseWriter, req *http.Request) {
level.Debug(logger).Log("msg", "handling /alert webhook request")
- defer req.Body.Close()
+ defer func() { _ = req.Body.Close() }()
// https://godoc.org/github.com/prometheus/alertmanager/template#Data
data := alertmanager.Data{}
@@ -71,7 +71,7 @@ func main() {
return
}
- conf := config.ReceiverByName(data.Receiver)
+ conf := cfg.ReceiverByName(data.Receiver)
if conf == nil {
errorHandler(w, http.StatusNotFound, fmt.Errorf("receiver missing: %s", data.Receiver), unknownReceiver, &data, logger)
return
@@ -107,7 +107,7 @@ func main() {
})
http.HandleFunc("/", HomeHandlerFunc())
- http.HandleFunc("/config", ConfigHandlerFunc(config))
+ http.HandleFunc("/cfg", ConfigHandlerFunc(cfg))
http.HandleFunc("/healthz", func(w http.ResponseWriter, r *http.Request) { http.Error(w, "OK", http.StatusOK) })
http.Handle("/metrics", promhttp.Handler())
diff --git a/examples/jiralert.tmpl b/examples/jiralert.tmpl
deleted file mode 100644
index a5690573..00000000
--- a/examples/jiralert.tmpl
+++ /dev/null
@@ -1,10 +0,0 @@
-{{ define "jira.summary" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
-
-{{ define "jira.description" }}{{ range .Alerts.Firing }}Labels:
-{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
-{{ end }}
-Annotations:
-{{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }}
-{{ end }}
-Source: {{ .GeneratorURL }}
-{{ end }}{{ end }}
diff --git a/examples/jiralert.yml b/examples/jiralert.yml
deleted file mode 100644
index ef634189..00000000
--- a/examples/jiralert.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-# Global defaults, applied to all receivers where not explicitly overridden. Optional.
-defaults:
- # API access fields.
- api_url: https://jiralert.atlassian.net
- user: jiralert
- password: 'JIRAlert'
-
- # The type of JIRA issue to create. Required.
- issue_type: Bug
- # Issue priority. Optional.
- priority: Critical
- # Go template invocation for generating the summary. Required.
- summary: '{{ template "jira.summary" . }}'
- # Go template invocation for generating the description. Optional.
- description: '{{ template "jira.description" . }}'
- # State to transition into when reopening a closed issue. Required.
- reopen_state: "To Do"
- # Do not reopen issues with this resolution. Optional.
- wont_fix_resolution: "Won't Fix"
- # Amount of time after being closed that an issue should be reopened, after which, a new issue is created.
- # Optional (default: always reopen)
- reopen_duration: 0h
-
-# Receiver definitions. At least one must be defined.
-receivers:
- # Must match the Alertmanager receiver name. Required.
- - name: 'jira-ab'
- # JIRA project to create the issue in. Required.
- project: AB
- # Copy all Prometheus labels into separate JIRA labels. Optional (default: false).
- add_group_labels: false
-
- - name: 'jira-xy'
- project: XY
- # Overrides default.
- issue_type: Task
- # JIRA components. Optional.
- components: [ 'Operations' ]
- # Standard or custom field values to set on created issue. Optional.
- #
- # See https://developer.atlassian.com/server/jira/platform/jira-rest-api-examples/#setting-custom-field-data-for-other-field-types for further examples.
- fields:
- # TextField
- customfield_10001: "Random text"
- # SelectList
- customfield_10002: { "value": "red" }
- # MultiSelect
- customfield_10003: [{"value": "red" }, {"value": "blue" }, {"value": "green" }]
-
-# File containing template definitions. Required.
-template: jiralert.tmpl
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 8498864f..02dde652 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -74,31 +74,52 @@ func resolveFilepaths(baseDir string, cfg *Config, logger log.Logger) {
cfg.Template = join(cfg.Template)
}
-// ReceiverConfig is the configuration for one receiver. It has a unique name and includes API access fields (URL, user
-// and password) and issue fields (required -- e.g. project, issue type -- and optional -- e.g. priority).
+// ReceiverConfig is the configuration for one receiver.
type ReceiverConfig struct {
+ // Name represents unique name for a receiver.
+ // If Iiralert is used with Alertmanager, name it as Alertmanager receiver that sends alert via webhook to Jiralert for
+ // desired propagation.
Name string `yaml:"name" json:"name"`
- // API access fields
+ // APIURL specifies API URL for JIRA e.g https://