diff --git a/gateway/Gopkg.lock b/gateway/Gopkg.lock index f278e69b..3f82f5c7 100644 --- a/gateway/Gopkg.lock +++ b/gateway/Gopkg.lock @@ -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" diff --git a/gateway/Gopkg.toml b/gateway/Gopkg.toml index 7bb3888c..be0b8240 100644 --- a/gateway/Gopkg.toml +++ b/gateway/Gopkg.toml @@ -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" diff --git a/gateway/metrics/add_metrics.go b/gateway/metrics/add_metrics.go index f143a66c..4490cd2a 100644 --- a/gateway/metrics/add_metrics.go +++ b/gateway/metrics/add_metrics.go @@ -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 } diff --git a/gateway/metrics/add_metrics_test.go b/gateway/metrics/add_metrics_test.go index 1454e3b7..3389565f 100644 --- a/gateway/metrics/add_metrics_test.go +++ b/gateway/metrics/add_metrics_test.go @@ -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, }, diff --git a/gateway/metrics/exporter.go b/gateway/metrics/exporter.go index 1585b5bc..365cca88 100644 --- a/gateway/metrics/exporter.go +++ b/gateway/metrics/exporter.go @@ -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) diff --git a/gateway/metrics/exporter_test.go b/gateway/metrics/exporter_test.go index 8a345212..4d18a920 100644 --- a/gateway/metrics/exporter_test.go +++ b/gateway/metrics/exporter_test.go @@ -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) diff --git a/gateway/plugin/external.go b/gateway/plugin/external.go index b3e14df8..bbfd6ac6 100644 --- a/gateway/plugin/external.go +++ b/gateway/plugin/external.go @@ -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) diff --git a/gateway/requests/requests.go b/gateway/requests/requests.go index 5c8f1746..93439906 100644 --- a/gateway/requests/requests.go +++ b/gateway/requests/requests.go @@ -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"` diff --git a/gateway/tests/integration/createfunction_test.go b/gateway/tests/integration/createfunction_test.go index dcb023eb..7b37a637 100644 --- a/gateway/tests/integration/createfunction_test.go +++ b/gateway/tests/integration/createfunction_test.go @@ -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", diff --git a/gateway/vendor/github.com/openfaas/faas-provider/.travis.yml b/gateway/vendor/github.com/openfaas/faas-provider/.travis.yml new file mode 100644 index 00000000..d063d863 --- /dev/null +++ b/gateway/vendor/github.com/openfaas/faas-provider/.travis.yml @@ -0,0 +1,4 @@ +language: go +go_import_path: github.com/openfaas/faas-provider +script: + - make test diff --git a/gateway/vendor/github.com/openfaas/faas-provider/Makefile b/gateway/vendor/github.com/openfaas/faas-provider/Makefile index d5488ed3..1a8709c2 100644 --- a/gateway/vendor/github.com/openfaas/faas-provider/Makefile +++ b/gateway/vendor/github.com/openfaas/faas-provider/Makefile @@ -1,2 +1,6 @@ build: docker build -t faas-provider . + + +test : + go test -cover ./... diff --git a/gateway/vendor/github.com/openfaas/faas-provider/proxy/proxy.go b/gateway/vendor/github.com/openfaas/faas-provider/proxy/proxy.go index 67b1afc6..78bde88d 100644 --- a/gateway/vendor/github.com/openfaas/faas-provider/proxy/proxy.go +++ b/gateway/vendor/github.com/openfaas/faas-provider/proxy/proxy.go @@ -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 } diff --git a/gateway/vendor/github.com/openfaas/faas-provider/types/model.go b/gateway/vendor/github.com/openfaas/faas-provider/types/model.go new file mode 100644 index 00000000..736d167e --- /dev/null +++ b/gateway/vendor/github.com/openfaas/faas-provider/types/model.go @@ -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"` +}