Enhance info endpoint to include gateway version

Extend the health endpoint and add gateway version information

Resolves: #733
Signed-off-by: Edward Wilde <ewilde@gmail.com>
This commit is contained in:
Edward Wilde 2018-07-02 16:42:16 +01:00 committed by Alex Ellis
parent 672a6be182
commit aca2c7fe2a
10 changed files with 209 additions and 7 deletions

View File

@ -1,4 +1,5 @@
#!/bin/bash
set -e
if [ ! -s "$TRAVIS_TAG" ] ; then
echo "This build will be published under the tag: ${TRAVIS_TAG}"

View File

@ -1,4 +1,7 @@
FROM golang:1.9.7 as build
ARG GIT_COMMIT_SHA
ARG GIT_COMMIT_MESSAGE
ARG VERSION='dev'
RUN curl -sL https://github.com/alexellis/license-check/releases/download/0.2.2/license-check \
> /usr/bin/license-check \
@ -16,13 +19,18 @@ COPY tests tests
COPY types types
COPY queue queue
COPY plugin plugin
COPY version version
COPY server.go .
# Run a gofmt and exclude all vendored code.
RUN license-check -path ./ --verbose=false "Alex Ellis" "OpenFaaS Project" "OpenFaaS Authors" \
&& test -z "$(gofmt -l $(find . -type f -name '*.go' -not -path "./vendor/*"))" \
&& go test $(go list ./... | grep -v integration | grep -v /vendor/ | grep -v /template/) -cover \
&& CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o gateway .
&& CGO_ENABLED=0 GOOS=linux go build --ldflags "-s -w \
-X github.com/openfaas/faas/gateway/version.GitCommitSHA=${GIT_COMMIT_SHA}\
-X \"github.com/openfaas/faas/gateway/version.GitCommitMessage=${GIT_COMMIT_MESSAGE}\"\
-X github.com/openfaas/faas/gateway/version.Version=${VERSION}" \
-a -installsuffix cgo -o gateway .
FROM alpine:3.7

View File

@ -1,4 +1,5 @@
#!/bin/sh
set -e
export dockerfile="Dockerfile"
export arch=$(uname -m)
@ -20,5 +21,11 @@ fi
echo Building openfaas/gateway:$eTAG
GIT_COMMIT_MESSAGE=$(git log -1 --pretty=%B 2>&1 | head -n 1)
GIT_COMMIT_SHA=$(git rev-list -1 HEAD)
VERSION=$(git describe --all --exact-match `git rev-parse HEAD` | grep tags | sed 's/tags\///' || echo dev)
docker build --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy \
--build-arg GIT_COMMIT_MESSAGE="$GIT_COMMIT_MESSAGE" --build-arg GIT_COMMIT_SHA=$GIT_COMMIT_SHA \
--build-arg VERSION=${VERSION:-dev} \
-t openfaas/gateway:$eTAG . -f $dockerfile --no-cache

View File

@ -0,0 +1,56 @@
package handlers
import (
"encoding/json"
"log"
"net/http"
"github.com/openfaas/faas/gateway/types"
"github.com/openfaas/faas/gateway/version"
)
// MakeInfoHandler is responsible for display component version information
func MakeInfoHandler(h http.Handler) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
sw := types.NewStringResponseWriter()
h.ServeHTTP(sw, r)
log.Printf("Body: %s", sw.Body())
provider := make(map[string]interface{})
providerVersion := &types.VersionInfo{}
err := json.Unmarshal(sw.Body(), &provider)
if err != nil {
log.Printf("Error unmarshalling provider json. Got %s. Error %s\n", string(sw.Body()), err.Error())
}
versionMap := provider["version"].(map[string]interface{})
providerVersion.SHA = versionMap["sha"].(string)
providerVersion.Release = versionMap["release"].(string)
gatewayInfo := &types.GatewayInfo{
Version: &types.VersionInfo{
CommitMessage: version.GitCommitMessage,
Release: version.BuildVersion(),
SHA: version.GitCommitSHA,
},
Provider: &types.ProviderInfo{
Version: providerVersion,
Name: provider["provider"].(string),
Orchestration: provider["orchestration"].(string),
},
}
jsonOut, marshalErr := json.Marshal(gatewayInfo)
if marshalErr != nil {
log.Printf("Error during unmarshal of gateway info request %s\n", marshalErr.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(jsonOut)
}
}

View File

@ -118,7 +118,8 @@ func main() {
r.HandleFunc("/function/{name:[-a-zA-Z_0-9]+}", faasHandlers.Proxy)
r.HandleFunc("/function/{name:[-a-zA-Z_0-9]+}/", faasHandlers.Proxy)
r.HandleFunc("/system/info", handlers.MakeForwardingProxyHandler(reverseProxy, forwardingNotifiers, urlResolver)).Methods(http.MethodGet)
r.HandleFunc("/system/info", handlers.MakeInfoHandler(handlers.MakeForwardingProxyHandler(
reverseProxy, forwardingNotifiers, urlResolver))).Methods(http.MethodGet)
r.HandleFunc("/system/alert", faasHandlers.Alert)

View File

@ -0,0 +1,48 @@
package inttests
import (
"encoding/json"
"net/http"
"testing"
"github.com/openfaas/faas/gateway/types"
)
func Test_InfoEndpoint_Returns_200(t *testing.T) {
_, code, err := fireRequest("http://localhost:8080/system/info", http.MethodGet, "")
if err != nil {
t.Log(err)
t.Fail()
}
wantCode := http.StatusOK
if code != wantCode {
t.Errorf("status code, want: %d, got: %d", wantCode, code)
t.Fail()
}
}
func Test_InfoEndpoint_Returns_Gateway_Version_SHA_And_Message(t *testing.T) {
body, _, err := fireRequest("http://localhost:8080/system/info", http.MethodGet, "")
if err != nil {
t.Log(err)
t.Fail()
}
gatewayInfo := &types.GatewayInfo{}
err = json.Unmarshal([]byte(body), gatewayInfo)
if err != nil {
t.Log(err)
t.Fail()
}
if len(gatewayInfo.Version.SHA) != 40 {
t.Errorf("length of SHA incorrect, want: %d, got: %d. Json body was %s", 40, len(gatewayInfo.Version.SHA), body)
}
if len(gatewayInfo.Version.CommitMessage) == 0 {
t.Errorf("length of commit message should be greater than 0. Json body was %s", body)
}
}

View File

@ -50,7 +50,7 @@ func fireRequestWithHeaders(url string, method string, reqBody string, headers m
func TestGet_Rejected(t *testing.T) {
var reqBody string
unsupportedMethod := http.MethodHead
_, code, err := fireRequest("http://localhost:8080/function/func_echoit", unsupportedMethod, reqBody)
_, code, err := fireRequest("http://localhost:8080/function/echoit", unsupportedMethod, reqBody)
want := http.StatusMethodNotAllowed
if code != want {
t.Logf("Failed got: %d, wanted: %d", code, want)
@ -68,15 +68,18 @@ func TestEchoIt_Post_Route_Handler_ForwardsClientHeaders(t *testing.T) {
headers := make(map[string]string, 0)
headers["X-Api-Key"] = "123"
body, code, err := fireRequestWithHeaders("http://localhost:8080/function/func_echoit", http.MethodPost, reqBody, headers)
body, code, err := fireRequestWithHeaders("http://localhost:8080/function/echoit", http.MethodPost, reqBody, headers)
if err != nil {
t.Log(err)
t.Fail()
}
if code != http.StatusOK {
t.Log("Failed")
t.Logf("Failed, code: %d, body:%s", code, body)
t.Fail()
}
if body != reqBody {
t.Log("Expected body returned")
t.Fail()
@ -85,7 +88,7 @@ func TestEchoIt_Post_Route_Handler_ForwardsClientHeaders(t *testing.T) {
func TestEchoIt_Post_Route_Handler(t *testing.T) {
reqBody := "test message"
body, code, err := fireRequest("http://localhost:8080/function/func_echoit", http.MethodPost, reqBody)
body, code, err := fireRequest("http://localhost:8080/function/echoit", http.MethodPost, reqBody)
if err != nil {
t.Log(err)

View File

@ -0,0 +1,58 @@
package types
import (
"bytes"
"net/http"
)
// GatewayInfo provides information about the gateway and it's connected components
type GatewayInfo struct {
Provider *ProviderInfo `json:"provider"`
Version *VersionInfo `json:"version"`
}
// ProviderInfo provides information about the configured provider
type ProviderInfo struct {
Name string `json:"provider"`
Version *VersionInfo `json:"version"`
Orchestration string `json:"orchestration"`
}
// VersionInfo provides the commit message, sha and release version number
type VersionInfo struct {
CommitMessage string `json:"commit_message,omitempty"`
SHA string `json:"sha"`
Release string `json:"release"`
}
// StringResponseWriter captures the handlers HTTP response in a buffer
type StringResponseWriter struct {
body *bytes.Buffer
headerCode int
header http.Header
}
// NewStringResponseWriter create a new StringResponseWriter
func NewStringResponseWriter() *StringResponseWriter {
return &StringResponseWriter{body: &bytes.Buffer{}, header: make(http.Header)}
}
// Header capture the Header information
func (s StringResponseWriter) Header() http.Header {
return s.header
}
// Write captures the response data
func (s StringResponseWriter) Write(data []byte) (int, error) {
return s.body.Write(data)
}
// WriteHeader captures the status code of the response
func (s StringResponseWriter) WriteHeader(statusCode int) {
s.headerCode = statusCode
}
// Body returns the response body bytes
func (s StringResponseWriter) Body() []byte {
return s.body.Bytes()
}

View File

@ -0,0 +1,20 @@
package version
var (
//Version release version of the provider
Version string
//GitCommit SHA of the last git commit
GitCommitSHA string
//GitCommit message of the last commit
GitCommitMessage string
//DevVersion string for the development version
DevVersion = "dev"
)
//BuildVersion returns current version of the provider
func BuildVersion() string {
if len(Version) == 0 {
return DevVersion
}
return Version
}

View File

@ -1,5 +1,5 @@
#!/bin/sh
set -e
export arch=$(uname -m)
if [ "$arch" = "armv7l" ] ; then