mirror of
https://github.com/openfaas/faas.git
synced 2025-06-09 16:56:47 +00:00
Initial pop-up for new function.
This commit is contained in:
parent
edc2c4b29e
commit
98c9ef67f4
11
contrib/HACK.md
Normal file
11
contrib/HACK.md
Normal file
@ -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`.
|
@ -7,7 +7,7 @@ services:
|
|||||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||||
ports:
|
ports:
|
||||||
- 8080:8080
|
- 8080:8080
|
||||||
image: alexellis2/faas-gateway:latest
|
image: alexellis2/faas-gateway:latest-dev
|
||||||
networks:
|
networks:
|
||||||
- functions
|
- functions
|
||||||
deploy:
|
deploy:
|
||||||
|
@ -20,6 +20,12 @@
|
|||||||
<input name="fprocess" ng-model="item.fprocess" required md-maxlength="200" minlength="4">
|
<input name="fprocess" ng-model="item.fprocess" required md-maxlength="200" minlength="4">
|
||||||
</md-input-container>
|
</md-input-container>
|
||||||
</div>
|
</div>
|
||||||
|
<div layout-gt-xs="row">
|
||||||
|
<md-input-container class="md-block" flex-gt-sm>
|
||||||
|
<label>Network:</label>
|
||||||
|
<input name="network" ng-model="item.network" required md-maxlength="200" minlength="4">
|
||||||
|
</md-input-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</md-dialog-content>
|
</md-dialog-content>
|
||||||
|
41
gateway/assets/script/bootstrap.js
vendored
41
gateway/assets/script/bootstrap.js
vendored
@ -98,6 +98,22 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$md
|
|||||||
};
|
};
|
||||||
|
|
||||||
$scope.createFunc = function() {
|
$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);
|
console.log($scope.item);
|
||||||
$scope.closeDialog();
|
$scope.closeDialog();
|
||||||
};
|
};
|
||||||
@ -109,28 +125,3 @@ app.controller("home", ['$scope', '$log', '$http', '$location', '$timeout', '$md
|
|||||||
|
|
||||||
fetch();
|
fetch();
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
|
||||||
// '<md-dialog aria-label="List dialog">' +
|
|
||||||
// ' <md-dialog-content class="md-padding">'+
|
|
||||||
// '<label>Define a function</label>'+
|
|
||||||
// '<form name="userForm">'+
|
|
||||||
// '<md-input-container>'+
|
|
||||||
// '<label>Image:</label>'+
|
|
||||||
// '<input name="dockerImage" ng-model="item.image" required md-maxlength="200" minlength="4">'+
|
|
||||||
// '</md-input-container>'+
|
|
||||||
// '<md-input-container>'+
|
|
||||||
// '<label>Name:</label>'+
|
|
||||||
// '<input name="serviceName" ng-model="item.name" required md-maxlength="200" minlength="4">'+
|
|
||||||
// '</md-input-container>'+
|
|
||||||
// '</form>'+
|
|
||||||
// ' </md-dialog-content>' +
|
|
||||||
// ' <md-dialog-actions>' +
|
|
||||||
// ' <md-button ng-click="closeDialog()" class="md-secondary">' +
|
|
||||||
// ' Close Dialog' +
|
|
||||||
// ' </md-button>' +
|
|
||||||
// ' <md-button ng-click="createFunc()" class="md-primary">' +
|
|
||||||
// ' Create' +
|
|
||||||
// ' </md-button>' +
|
|
||||||
// ' </md-dialog-actions>' +
|
|
||||||
// '</md-dialog>'
|
|
@ -6,6 +6,8 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/alexellis/faas/gateway/metrics"
|
"github.com/alexellis/faas/gateway/metrics"
|
||||||
"github.com/alexellis/faas/gateway/requests"
|
"github.com/alexellis/faas/gateway/requests"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
@ -59,3 +61,22 @@ func MakeFunctionReader(metricsOptions metrics.MetricOptions, c *client.Client)
|
|||||||
w.Write(functionBytes)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,13 @@
|
|||||||
package requests
|
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 {
|
type AlexaSessionApplication struct {
|
||||||
ApplicationId string `json:"applicationId"`
|
ApplicationId string `json:"applicationId"`
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Sirupsen/logrus"
|
"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/alexellis/faas/gateway/metrics"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@ -35,14 +35,15 @@ func main() {
|
|||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
// r.StrictSlash(false)
|
// 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("/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/alert", faasHandlers.MakeAlertHandler(dockerClient))
|
||||||
r.HandleFunc("/system/functions", faashandlers.MakeFunctionReader(metricsOptions, dockerClient)).Methods("GET")
|
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()
|
metricsHandler := metrics.PrometheusHandler()
|
||||||
r.Handle("/metrics", metricsHandler)
|
r.Handle("/metrics", metricsHandler)
|
||||||
|
34
gateway/tests/integration/createfunction_test.go
Normal file
34
gateway/tests/integration/createfunction_test.go
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@ func fireRequestWithHeader(url string, method string, reqBody string, xheader st
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req.Header.Set("User-Agent", "spacecount-tutorial")
|
req.Header.Set("User-Agent", "go-integration")
|
||||||
if len(xheader) != 0 {
|
if len(xheader) != 0 {
|
||||||
req.Header.Set("X-Function", xheader)
|
req.Header.Set("X-Function", xheader)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user