mirror of
https://github.com/openfaas/faas.git
synced 2025-06-09 00:36:46 +00:00
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:
parent
672a6be182
commit
aca2c7fe2a
1
build.sh
1
build.sh
@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
if [ ! -s "$TRAVIS_TAG" ] ; then
|
||||
echo "This build will be published under the tag: ${TRAVIS_TAG}"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
56
gateway/handlers/infohandler.go
Normal file
56
gateway/handlers/infohandler.go
Normal 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)
|
||||
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
||||
|
48
gateway/tests/integration/infohandler_test.go
Normal file
48
gateway/tests/integration/infohandler_test.go
Normal 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)
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
58
gateway/types/inforequest.go
Normal file
58
gateway/types/inforequest.go
Normal 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()
|
||||
}
|
20
gateway/version/version.go
Normal file
20
gateway/version/version.go
Normal 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
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
export arch=$(uname -m)
|
||||
|
||||
if [ "$arch" = "armv7l" ] ; then
|
||||
|
Loading…
x
Reference in New Issue
Block a user