Expose version information via REST API

/v1/data/system/version will return information similar to:

Version: 0.9.3-dev
Build Commit: c5171ed5-dirty
Build Timestamp: 2018-10-07T02:12:58Z
Build Hostname: JOHNDOE-M-9130

Signed-off-by: repenno <rapenno@gmail.com>
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
This commit is contained in:
repenno
2018-10-08 08:25:17 -07:00
committed by Torin Sandall
parent 52530516e2
commit ed2c05a77e
2 changed files with 62 additions and 2 deletions
+42 -2
View File
@@ -7,6 +7,7 @@ package server
import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"fmt"
"html/template"
@@ -21,8 +22,6 @@ import (
"sync"
"time"
"crypto/tls"
"net/url"
"github.com/gorilla/mux"
@@ -132,6 +131,7 @@ func New() *Server {
router.Handle("/metrics", promhttp.HandlerFor(promRegistry, promhttp.HandlerOpts{})).Methods(http.MethodGet)
s.registerHandler(router, 0, "/data/{path:.+}", http.MethodPost, promhttp.InstrumentHandlerDuration(v0DataDur, http.HandlerFunc(s.v0DataPost)))
s.registerHandler(router, 0, "/data", http.MethodPost, promhttp.InstrumentHandlerDuration(v0DataDur, http.HandlerFunc(s.v0DataPost)))
s.registerHandler(router, 1, "/data/system/version", http.MethodGet, promhttp.InstrumentHandlerDuration(v1DataDur, http.HandlerFunc(s.v1VersionGet)))
s.registerHandler(router, 1, "/data/system/diagnostics", http.MethodGet, promhttp.InstrumentHandlerDuration(v1DataDur, http.HandlerFunc(s.v1DiagnosticsGet)))
s.registerHandler(router, 1, "/data/{path:.+}", http.MethodDelete, promhttp.InstrumentHandlerDuration(v1DataDur, http.HandlerFunc(s.v1DataDelete)))
s.registerHandler(router, 1, "/data/{path:.+}", http.MethodPut, promhttp.InstrumentHandlerDuration(v1DataDur, http.HandlerFunc(s.v1DataPut)))
@@ -605,6 +605,46 @@ func (s *Server) v1DiagnosticsGet(w http.ResponseWriter, r *http.Request) {
writer.JSON(w, 200, resp, pretty)
}
func (s *Server) v1VersionGet(w http.ResponseWriter, r *http.Request) {
code := 200
opaVersion := `
{
"result": {
"Version": "{{.Version}}",
"BuildCommit": "{{.BuildCommit}}",
"BuildTimestamp": "{{.BuildTimestamp}}",
"BuildHostname": "{{.BuildHostname}}"
}
}
`
tmpl, err := template.New("").Parse(opaVersion)
if err != nil {
panic(err)
}
var buf bytes.Buffer
err = tmpl.Execute(&buf, struct {
Version string
BuildCommit string
BuildTimestamp string
BuildHostname string
}{
Version: version.Version,
BuildCommit: version.Vcs,
BuildTimestamp: version.Timestamp,
BuildHostname: version.Hostname,
})
jsonBytes := buf.Bytes()
headers := w.Header()
headers.Add("Content-Type", "application/json")
writer.Bytes(w, code, jsonBytes)
}
func (s *Server) v1CompilePost(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
pretty := getBoolParam(r.URL, types.ParamPrettyV1, true)
+20
View File
@@ -15,6 +15,7 @@ import (
"net/http/httptest"
"net/http/httputil"
"reflect"
"regexp"
"strings"
"testing"
"time"
@@ -1207,6 +1208,25 @@ func TestIndexGetCompileError(t *testing.T) {
}
}
func TestVersionGet(t *testing.T) {
f := newFixture(t)
get := newReqV1(http.MethodGet, "/data/system/version", "")
f.server.Handler.ServeHTTP(f.recorder, get)
if f.recorder.Code != 200 {
t.Fatalf("Expected 200 OK but got %v", f.recorder)
return
}
page := f.recorder.Body.String()
var re = regexp.MustCompile(`[\s\S]*Version\b[\s\S]*BuildCommit\b[\s\S]*BuildTimestamp\b[\s\S]*BuildHostname\b`)
if !re.MatchString(page) {
t.Errorf("Expected page to contain 'version' but got: %v", page)
return
}
}
func TestPoliciesPutV1(t *testing.T) {
f := newFixture(t)
req := newReqV1(http.MethodPut, "/policies/1", testMod)