Migrate away from requests package for Function structs

The function deployment and status structs have been moved away
into the faas-provider package.

Tested with a build, running tests, and CI.

Signed-off-by: Alex Ellis (OpenFaaS Ltd) <alexellis2@gmail.com>
This commit is contained in:
Alex Ellis (OpenFaaS Ltd) 2019-08-05 12:37:53 +01:00 committed by Alex Ellis
parent 8767514527
commit df97efafae
13 changed files with 125 additions and 105 deletions

6
gateway/Gopkg.lock generated
View File

@ -93,12 +93,12 @@
version = "v1.0.0"
[[projects]]
digest = "1:d30085f782a2785c72cd5d4dda822aa615070ba745ea25e5a8a3661faa0ad980"
digest = "1:be6ac85ebf7294885126fdf1de053a333fbb8803af6b666f4cccf818d41a3776"
name = "github.com/openfaas/faas-provider"
packages = ["auth"]
pruneopts = ""
revision = "0ca8ae603fee9736e011b81fbf02777d89a4ea85"
version = "0.9.2"
revision = "45a3391b385208bd34690f84abcc1dfab6c1730b"
version = "0.9.4"
[[projects]]
digest = "1:c91d031a0f53699e18f204e8a8d360d400a34686a3bb34d82c63a53ff1d73cea"

View File

@ -26,7 +26,7 @@ ignored = ["github.com/openfaas/faas/gateway/queue"]
[[constraint]]
name = "github.com/openfaas/faas-provider"
version = "0.9.1"
version = "0.9.4"
[[constraint]]
name = "go.uber.org/goleak"

View File

@ -10,7 +10,7 @@ import (
"net/url"
"strconv"
"github.com/openfaas/faas/gateway/requests"
types "github.com/openfaas/faas-provider/types"
)
// AddMetricsHandler wraps a http.HandlerFunc with Prometheus metrics
@ -37,7 +37,7 @@ func AddMetricsHandler(handler http.HandlerFunc, prometheusQuery PrometheusQuery
}
upstreamBody, _ := ioutil.ReadAll(upstreamCall.Body)
var functions []requests.Function
var functions []types.FunctionStatus
err := json.Unmarshal(upstreamBody, &functions)
@ -75,7 +75,7 @@ func AddMetricsHandler(handler http.HandlerFunc, prometheusQuery PrometheusQuery
}
}
func mixIn(functions *[]requests.Function, metrics *VectorQueryResponse) {
func mixIn(functions *[]types.FunctionStatus, metrics *VectorQueryResponse) {
if functions == nil {
return
}

View File

@ -7,7 +7,7 @@ import (
"net/http/httptest"
"testing"
"github.com/openfaas/faas/gateway/requests"
types "github.com/openfaas/faas-provider/types"
)
type FakePrometheusQueryFetcher struct {
@ -45,7 +45,7 @@ func Test_PrometheusMetrics_MixedInto_Services(t *testing.T) {
if len(body) == 0 {
t.Errorf("Want content-length > 0, got: %d", len(rr.Body.String()))
}
results := []requests.Function{}
results := []types.FunctionStatus{}
json.Unmarshal([]byte(rr.Body.String()), &results)
if len(results) == 0 {
t.Errorf("Want %d function, got: %d", 1, len(results))
@ -82,8 +82,8 @@ func Test_FunctionsHandler_ReturnsJSONAndOneFunction(t *testing.T) {
func makeFunctionsHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
functions := []requests.Function{
requests.Function{
functions := []types.FunctionStatus{
types.FunctionStatus{
Name: "func_echoit",
Replicas: 0,
},

View File

@ -15,14 +15,14 @@ import (
"log"
"github.com/openfaas/faas-provider/auth"
"github.com/openfaas/faas/gateway/requests"
types "github.com/openfaas/faas-provider/types"
"github.com/prometheus/client_golang/prometheus"
)
// Exporter is a prometheus exporter
type Exporter struct {
metricOptions MetricOptions
services []requests.Function
services []types.FunctionStatus
credentials *auth.BasicAuthCredentials
}
@ -30,7 +30,7 @@ type Exporter struct {
func NewExporter(options MetricOptions, credentials *auth.BasicAuthCredentials) *Exporter {
return &Exporter{
metricOptions: options,
services: []requests.Function{},
services: []types.FunctionStatus{},
credentials: credentials,
}
}
@ -95,7 +95,7 @@ func (e *Exporter) StartServiceWatcher(endpointURL url.URL, metricsOptions Metri
get.SetBasicAuth(e.credentials.User, e.credentials.Password)
}
services := []requests.Function{}
services := []types.FunctionStatus{}
res, err := proxyClient.Do(get)
if err != nil {
log.Println(err)

View File

@ -3,7 +3,7 @@ package metrics
import (
"testing"
"github.com/openfaas/faas/gateway/requests"
types "github.com/openfaas/faas-provider/types"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
)
@ -67,12 +67,12 @@ func Test_Collect_CollectsTheNumberOfReplicasOfAService(t *testing.T) {
metricsOptions := BuildMetricsOptions()
exporter := NewExporter(metricsOptions, nil)
expectedService := requests.Function{
expectedService := types.FunctionStatus{
Name: "function_with_two_replica",
Replicas: 2,
}
exporter.services = []requests.Function{expectedService}
exporter.services = []types.FunctionStatus{expectedService}
ch := make(chan prometheus.Metric)
defer close(ch)

View File

@ -15,8 +15,8 @@ import (
"strconv"
"time"
types "github.com/openfaas/faas-provider/types"
"github.com/openfaas/faas/gateway/handlers"
"github.com/openfaas/faas/gateway/requests"
"github.com/openfaas/faas/gateway/scaling"
)
@ -65,7 +65,7 @@ func (s ExternalServiceQuery) GetReplicas(serviceName string) (scaling.ServiceQu
var err error
var emptyServiceQueryResponse scaling.ServiceQueryResponse
function := requests.Function{}
function := types.FunctionStatus{}
urlPath := fmt.Sprintf("%ssystem/function/%s", s.URL.String(), serviceName)

View File

@ -5,80 +5,6 @@
// the OpenFaaS gateway REST API
package requests
// CreateFunctionRequest create a function in the swarm.
type CreateFunctionRequest struct {
// Service corresponds to a Docker Service
Service string `json:"service"`
// Image corresponds to a Docker image
Image string `json:"image"`
// Network is specific to Docker Swarm - default overlay network is: func_functions
Network string `json:"network"`
// EnvProcess corresponds to the fprocess variable for your container watchdog.
EnvProcess string `json:"envProcess"`
// EnvVars provides overrides for functions.
EnvVars map[string]string `json:"envVars"`
// RegistryAuth is the registry authentication (optional)
// in the same encoded format as Docker native credentials
// (see ~/.docker/config.json)
RegistryAuth string `json:"registryAuth,omitempty"`
// Constraints are specific to back-end orchestration platform
Constraints []string `json:"constraints"`
// Secrets list of secrets to be made available to function
Secrets []string `json:"secrets"`
// Labels are metadata for functions which may be used by the
// back-end for making scheduling or routing decisions
Labels *map[string]string `json:"labels"`
// Annotations are metadata for functions which may be used by the
// back-end for management, orchestration, events and build tasks
Annotations *map[string]string `json:"annotations"`
// Limits for function
Limits *FunctionResources `json:"limits"`
// Requests of resources requested by function
Requests *FunctionResources `json:"requests"`
// ReadOnlyRootFilesystem removes write-access from the root filesystem
// mount-point.
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem"`
}
// FunctionResources Memory and CPU
type FunctionResources struct {
Memory string `json:"memory"`
CPU string `json:"cpu"`
}
// Function exported for system/functions endpoint
type Function struct {
Name string `json:"name"`
Image string `json:"image"`
InvocationCount float64 `json:"invocationCount"` // TODO: shouldn't this be int64?
Replicas uint64 `json:"replicas"`
EnvProcess string `json:"envProcess"`
// AvailableReplicas is the count of replicas ready to receive invocations as reported by the back-end
AvailableReplicas uint64 `json:"availableReplicas"`
// Labels are metadata for functions which may be used by the
// back-end for making scheduling or routing decisions
Labels *map[string]string `json:"labels"`
// Annotations are metadata for functions which may be used by the
// back-end for management, orchestration, events and build tasks
Annotations *map[string]string `json:"annotations"`
}
// AsyncReport is the report from a function executed on a queue worker.
type AsyncReport struct {
FunctionName string `json:"name"`

View File

@ -9,21 +9,22 @@ import (
"strings"
"testing"
"github.com/openfaas/faas/gateway/requests"
types "github.com/openfaas/faas-provider/types"
requests "github.com/openfaas/faas/gateway/requests"
)
func createFunction(request requests.CreateFunctionRequest) (string, int, error) {
func createFunction(request types.FunctionDeployment) (string, int, error) {
marshalled, _ := json.Marshal(request)
return fireRequest("http://localhost:8080/system/functions", http.MethodPost, string(marshalled))
}
func deleteFunction(name string) (string, int, error) {
marshalled, _ := json.Marshal(requests.DeleteFunctionRequest{name})
marshalled, _ := json.Marshal(requests.DeleteFunctionRequest{FunctionName: name})
return fireRequest("http://localhost:8080/system/functions", http.MethodDelete, string(marshalled))
}
func TestCreate_ValidRequest(t *testing.T) {
request := requests.CreateFunctionRequest{
request := types.FunctionDeployment{
Service: "test_resizer",
Image: "functions/resizer",
Network: "func_functions",
@ -47,7 +48,7 @@ func TestCreate_ValidRequest(t *testing.T) {
}
func TestCreate_InvalidImage(t *testing.T) {
request := requests.CreateFunctionRequest{
request := types.FunctionDeployment{
Service: "test_resizer",
Image: "a b c",
Network: "func_functions",
@ -75,7 +76,7 @@ func TestCreate_InvalidImage(t *testing.T) {
}
func TestCreate_InvalidNetwork(t *testing.T) {
request := requests.CreateFunctionRequest{
request := types.FunctionDeployment{
Service: "test_resizer",
Image: "functions/resizer",
Network: "non_existent_network",

View File

@ -0,0 +1,4 @@
language: go
go_import_path: github.com/openfaas/faas-provider
script:
- make test

View File

@ -1,2 +1,6 @@
build:
docker build -t faas-provider .
test :
go test -cover ./...

View File

@ -29,7 +29,7 @@ import (
"time"
"github.com/gorilla/mux"
"github.com/openfaas/faas-provider/httputils"
"github.com/openfaas/faas-provider/httputil"
)
const (
@ -112,7 +112,7 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
pathVars := mux.Vars(originalReq)
functionName := pathVars["name"]
if functionName == "" {
httputils.Errorf(w, http.StatusBadRequest, errMissingFunctionName)
httputil.Errorf(w, http.StatusBadRequest, errMissingFunctionName)
return
}
@ -120,13 +120,13 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
if resolveErr != nil {
// TODO: Should record the 404/not found error in Prometheus.
log.Printf("resolver error: cannot find %s: %s\n", functionName, resolveErr.Error())
httputils.Errorf(w, http.StatusNotFound, "Cannot find service: %s.", functionName)
httputil.Errorf(w, http.StatusNotFound, "Cannot find service: %s.", functionName)
return
}
proxyReq, err := buildProxyRequest(originalReq, functionAddr, pathVars["params"])
if err != nil {
httputils.Errorf(w, http.StatusInternalServerError, "Failed to resolve service: %s.", functionName)
httputil.Errorf(w, http.StatusInternalServerError, "Failed to resolve service: %s.", functionName)
return
}
if proxyReq.Body != nil {
@ -140,7 +140,7 @@ func proxyRequest(w http.ResponseWriter, originalReq *http.Request, proxyClient
if err != nil {
log.Printf("error with proxy request to: %s, %s\n", proxyReq.URL.String(), err.Error())
httputils.Errorf(w, http.StatusInternalServerError, "Can't reach service for: %s.", functionName)
httputil.Errorf(w, http.StatusInternalServerError, "Can't reach service for: %s.", functionName)
return
}

View File

@ -0,0 +1,85 @@
package types
// FunctionDeployment represents a request to create or update a Function.
type FunctionDeployment struct {
// Service corresponds to a Service
Service string `json:"service"`
// Image corresponds to a Docker image
Image string `json:"image"`
// Network is specific to Docker Swarm - default overlay network is: func_functions
Network string `json:"network"`
// EnvProcess corresponds to the fprocess variable for your container watchdog.
EnvProcess string `json:"envProcess"`
// EnvVars provides overrides for functions.
EnvVars map[string]string `json:"envVars"`
// RegistryAuth is the registry authentication (optional)
// in the same encoded format as Docker native credentials
// (see ~/.docker/config.json)
RegistryAuth string `json:"registryAuth,omitempty"`
// Constraints are specific to back-end orchestration platform
Constraints []string `json:"constraints"`
// Secrets list of secrets to be made available to function
Secrets []string `json:"secrets"`
// Labels are metadata for functions which may be used by the
// back-end for making scheduling or routing decisions
Labels *map[string]string `json:"labels"`
// Annotations are metadata for functions which may be used by the
// back-end for management, orchestration, events and build tasks
Annotations *map[string]string `json:"annotations"`
// Limits for function
Limits *FunctionResources `json:"limits"`
// Requests of resources requested by function
Requests *FunctionResources `json:"requests"`
// ReadOnlyRootFilesystem removes write-access from the root filesystem
// mount-point.
ReadOnlyRootFilesystem bool `json:"readOnlyRootFilesystem"`
}
// FunctionResources Memory and CPU
type FunctionResources struct {
Memory string `json:"memory"`
CPU string `json:"cpu"`
}
// FunctionStatus exported for system/functions endpoint
type FunctionStatus struct {
// Name corresponds to a Service
Name string `json:"name"`
// Image corresponds to a Docker image
Image string `json:"image"`
// InvocationCount count of invocations
InvocationCount float64 `json:"invocationCount"`
// Replicas desired within the cluster
Replicas uint64 `json:"replicas"`
// EnvProcess is the process to pass to the watchdog, if in use
EnvProcess string `json:"envProcess"`
// AvailableReplicas is the count of replicas ready to receive invocations as reported by the backend
AvailableReplicas uint64 `json:"availableReplicas"`
// Labels are metadata for functions which may be used by the
// backend for making scheduling or routing decisions
Labels *map[string]string `json:"labels"`
// Annotations are metadata for functions which may be used by the
// backend for management, orchestration, events and build tasks
Annotations *map[string]string `json:"annotations"`
}