From 85475d4e5017afdc8da0e1b0d86ed112d64905e6 Mon Sep 17 00:00:00 2001 From: Fabian Reinartz Date: Mon, 2 Nov 2015 19:41:23 +0100 Subject: [PATCH] Add /api/status endpoint for config and version info --- api.go | 34 +++++++++++++++++++++++++++++++--- main.go | 16 ++++++++++------ ui/app/js/app.js | 17 +++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/api.go b/api.go index ff0a2313..23187ae7 100644 --- a/api.go +++ b/api.go @@ -18,6 +18,7 @@ import ( "fmt" "net/http" "strconv" + "sync" "time" "github.com/prometheus/common/log" @@ -27,32 +28,38 @@ import ( "github.com/prometheus/alertmanager/provider" "github.com/prometheus/alertmanager/types" + "github.com/prometheus/alertmanager/version" ) type API struct { alerts provider.Alerts silences provider.Silences + config string route func() *UIRoute // context is an indirection for testing. context func(r *http.Request) context.Context + mtx sync.RWMutex } -func RegisterAPI(r *route.Router, alerts provider.Alerts, silences provider.Silences, rf func() *UIRoute) *API { - api := &API{ +func NewAPI(alerts provider.Alerts, silences provider.Silences, rf func() *UIRoute) *API { + return &API{ context: route.Context, alerts: alerts, silences: silences, route: rf, } +} +func (api *API) Register(r *route.Router) { // Register legacy forwarder for alert pushing. r.Post("/alerts", api.legacyAddAlerts) // Register actual API. r = r.WithPrefix("/v1") + r.Get("/status", api.status) r.Get("/routes", api.routes) r.Get("/alerts", api.listAlerts) @@ -64,8 +71,13 @@ func RegisterAPI(r *route.Router, alerts provider.Alerts, silences provider.Sile r.Get("/silence/:sid", api.getSilence) r.Put("/silence/:sid", api.setSilence) r.Del("/silence/:sid", api.delSilence) +} - return api +func (api *API) Update(config string) { + api.mtx.Lock() + defer api.mtx.Unlock() + + api.config = config } type errorType string @@ -86,6 +98,22 @@ func (e *apiError) Error() string { return fmt.Sprintf("%s: %s", e.typ, e.err) } +func (api *API) status(w http.ResponseWriter, req *http.Request) { + api.mtx.RLock() + + var status = struct { + Config string `json:"config"` + VersionInfo map[string]string `json:"versionInfo"` + }{ + Config: api.config, + VersionInfo: version.Map, + } + + api.mtx.RUnlock() + + respond(w, status) +} + func pruneUIRoute(r *UIRoute) { for _, sr := range r.Routes { pruneUIRoute(sr) diff --git a/main.go b/main.go index 973ada26..5b97a4f2 100644 --- a/main.go +++ b/main.go @@ -66,6 +66,13 @@ func main() { ) defer disp.Stop() + api := NewAPI(alerts, silences, func() *UIRoute { + uir := disp.route.UIRoute() + disp.Populate(uir) + + return uir + }) + build := func(nconf []*config.NotificationConfig) notify.Notifier { var ( router = notify.Router{} @@ -106,6 +113,8 @@ func main() { return err } + api.Update(conf.String()) + tmpl, err = template.FromGlobs(conf.Templates...) if err != nil { return err @@ -128,12 +137,7 @@ func main() { router := route.New() RegisterWeb(router) - RegisterAPI(router.WithPrefix("/api"), alerts, silences, func() *UIRoute { - uir := disp.route.UIRoute() - disp.Populate(uir) - - return uir - }) + api.Register(router.WithPrefix("/api")) go http.ListenAndServe(*listenAddress, router) diff --git a/ui/app/js/app.js b/ui/app/js/app.js index 3902b568..27643331 100644 --- a/ui/app/js/app.js +++ b/ui/app/js/app.js @@ -295,6 +295,23 @@ angular.module('am.controllers').controller('SilenceCreateCtrl', } ); +angular.module('am.services').factory('Status', + function($resource) { + return $resource('', {}, { + 'get': { + method: 'GET', + url: '/api/v1/status' + } + }); + } +); + +angular.module('am.controllers').controller('StatusCtrl', + function($scope, Status) { + + } +); + angular.module('am', [ 'ngRoute',