diff --git a/contrib/HACK.md b/contrib/HACK.md
new file mode 100644
index 00000000..b525a29e
--- /dev/null
+++ b/contrib/HACK.md
@@ -0,0 +1,11 @@
+## Hack on the UI for the API Gateway
+
+To hack on the UI without rebuilding the gateway mount the assets in a bind-mount like this:
+
+```
+$ docker network create func_functions --driver=overlay --attachable=true
+$ docker run -v `pwd`/gateway/assets:/root/assets -v "/var/run/docker.sock:/var/run/docker.sock" \
+-p 8080:8080 --network=func_functions -ti alexellis2/faas-gateway:latest-dev
+```
+
+Then edit `docker-compose.yml` to use an external network and do a `./deploy_stack.sh`.
diff --git a/docker-compose.yml b/docker-compose.yml
index 4bce97c8..bbe6de3d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -7,13 +7,13 @@ services:
- "/var/run/docker.sock:/var/run/docker.sock"
ports:
- 8080:8080
- image: alexellis2/faas-gateway:latest
+ image: alexellis2/faas-gateway:latest-dev
networks:
- functions
deploy:
placement:
constraints: [node.role == manager]
-
+
prometheus:
image: quay.io/prometheus/prometheus:latest
volumes:
diff --git a/gateway/assets/newfunction.html b/gateway/assets/newfunction.html
index d8d30b76..d0d6e856 100644
--- a/gateway/assets/newfunction.html
+++ b/gateway/assets/newfunction.html
@@ -20,6 +20,12 @@
+
+
+
+
+
+
diff --git a/gateway/assets/script/bootstrap.js b/gateway/assets/script/bootstrap.js
index 154b336b..ef44240d 100644
--- a/gateway/assets/script/bootstrap.js
+++ b/gateway/assets/script/bootstrap.js
@@ -98,6 +98,22 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$md
};
$scope.createFunc = function() {
+ var options = {
+ url: "/system/functions",
+ data: $scope.item,
+ method: "POST",
+ headers: { "Content-Type": "application/json"},
+ responseType: "json"
+ };
+
+ $http(options)
+ .then(function(response) {
+ $scope.invocationResponse = response.data;
+ $scope.invocationStatus = response.status;
+ }).catch(function(error1) {
+ $scope.invocationResponse = error1;
+ $scope.invocationStatus = null;
+ });
console.log($scope.item);
$scope.closeDialog();
};
@@ -109,28 +125,3 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$md
fetch();
}]);
-
-
-// '' +
-// ' '+
-// ''+
-// ''+
-// ' ' +
-// ' ' +
-// ' ' +
-// ' Close Dialog' +
-// ' ' +
-// ' ' +
-// ' Create' +
-// ' ' +
-// ' ' +
-// ''
\ No newline at end of file
diff --git a/gateway/handlers/functionshandler.go b/gateway/handlers/functionshandler.go
index 675eeb76..428cf28f 100644
--- a/gateway/handlers/functionshandler.go
+++ b/gateway/handlers/functionshandler.go
@@ -6,6 +6,8 @@ import (
"fmt"
"net/http"
+ "io/ioutil"
+
"github.com/alexellis/faas/gateway/metrics"
"github.com/alexellis/faas/gateway/requests"
"github.com/docker/docker/api/types"
@@ -59,3 +61,22 @@ func MakeFunctionReader(metricsOptions metrics.MetricOptions, c *client.Client)
w.Write(functionBytes)
}
}
+
+// MakeNewFunctionHandler creates a new function (service) inside the swarm network.
+func MakeNewFunctionHandler(metricsOptions metrics.MetricOptions, c *client.Client) http.HandlerFunc {
+ return func(w http.ResponseWriter, r *http.Request) {
+
+ body, _ := ioutil.ReadAll(r.Body)
+ defer r.Body.Close()
+
+ request := requests.CreateFunctionRequest{}
+ err := json.Unmarshal(body, &request)
+ if err != nil {
+ w.WriteHeader(http.StatusBadRequest)
+ return
+ }
+
+ fmt.Println(request)
+ w.WriteHeader(http.StatusNotImplemented)
+ }
+}
diff --git a/gateway/requests/requests.go b/gateway/requests/requests.go
index d0cf4512..1b1e24c5 100644
--- a/gateway/requests/requests.go
+++ b/gateway/requests/requests.go
@@ -1,5 +1,13 @@
package requests
+// CreateFunctionRequest create a function in the swarm.
+type CreateFunctionRequest struct {
+ Service string `json:"service"`
+ FProcess string `json:"fprocess"`
+ Image string `json:"image"`
+ Network string `json:"network"`
+}
+
type AlexaSessionApplication struct {
ApplicationId string `json:"applicationId"`
}
diff --git a/gateway/server.go b/gateway/server.go
index 5dc96d7c..8f389dd0 100644
--- a/gateway/server.go
+++ b/gateway/server.go
@@ -7,7 +7,7 @@ import (
"time"
"github.com/Sirupsen/logrus"
- faashandlers "github.com/alexellis/faas/gateway/handlers"
+ faasHandlers "github.com/alexellis/faas/gateway/handlers"
"github.com/alexellis/faas/gateway/metrics"
"github.com/docker/docker/client"
"github.com/gorilla/mux"
@@ -35,14 +35,15 @@ func main() {
r := mux.NewRouter()
// r.StrictSlash(false)
- functionHandler := faashandlers.MakeProxy(metricsOptions, true, dockerClient, &logger)
+ functionHandler := faasHandlers.MakeProxy(metricsOptions, true, dockerClient, &logger)
r.HandleFunc("/function/{name:[a-zA-Z_0-9]+}", functionHandler)
r.HandleFunc("/function/{name:[a-zA-Z_0-9]+}/", functionHandler)
- r.HandleFunc("/system/alert", faashandlers.MakeAlertHandler(dockerClient))
- r.HandleFunc("/system/functions", faashandlers.MakeFunctionReader(metricsOptions, dockerClient)).Methods("GET")
+ r.HandleFunc("/system/alert", faasHandlers.MakeAlertHandler(dockerClient))
+ r.HandleFunc("/system/functions", faasHandlers.MakeFunctionReader(metricsOptions, dockerClient)).Methods("GET")
+ r.HandleFunc("/system/functions", faasHandlers.MakeNewFunctionHandler(metricsOptions, dockerClient)).Methods("POST")
- r.HandleFunc("/", faashandlers.MakeProxy(metricsOptions, false, dockerClient, &logger)).Methods("POST")
+ r.HandleFunc("/", faasHandlers.MakeProxy(metricsOptions, false, dockerClient, &logger)).Methods("POST")
metricsHandler := metrics.PrometheusHandler()
r.Handle("/metrics", metricsHandler)
diff --git a/gateway/tests/integration/createfunction_test.go b/gateway/tests/integration/createfunction_test.go
new file mode 100644
index 00000000..ff317f59
--- /dev/null
+++ b/gateway/tests/integration/createfunction_test.go
@@ -0,0 +1,34 @@
+package inttests
+
+import (
+ "net/http"
+ "testing"
+)
+
+func TestCreate_ValidJson(t *testing.T) {
+ reqBody := `{}`
+ _, code, err := fireRequest("http://localhost:8080/system/functions", http.MethodPost, reqBody)
+
+ if err != nil {
+ t.Log(err)
+ t.Fail()
+ }
+
+ if code != http.StatusOK {
+ t.Errorf("Got HTTP code: %d, want %d\n", code, http.StatusBadRequest)
+ }
+}
+
+func TestCreateBadFunctionNotJson(t *testing.T) {
+ reqBody := `not json`
+ _, code, err := fireRequest("http://localhost:8080/system/functions", http.MethodPost, reqBody)
+
+ if err != nil {
+ t.Log(err)
+ t.Fail()
+ }
+
+ if code != http.StatusBadRequest {
+ t.Errorf("Got HTTP code: %d, want %d\n", code, http.StatusBadRequest)
+ }
+}
diff --git a/gateway/tests/integration/routes_test.go b/gateway/tests/integration/routes_test.go
index 9560f6bc..8d3f9936 100644
--- a/gateway/tests/integration/routes_test.go
+++ b/gateway/tests/integration/routes_test.go
@@ -25,7 +25,7 @@ func fireRequestWithHeader(url string, method string, reqBody string, xheader st
log.Fatal(err)
}
- req.Header.Set("User-Agent", "spacecount-tutorial")
+ req.Header.Set("User-Agent", "go-integration")
if len(xheader) != 0 {
req.Header.Set("X-Function", xheader)
}