Skip to content

Commit

Permalink
📦 release 🚀 v0.1.5 🦐
Browse files Browse the repository at this point in the history
  • Loading branch information
k33g committed Aug 15, 2022
1 parent 6b0da1b commit 791526f
Show file tree
Hide file tree
Showing 85 changed files with 346 additions and 667 deletions.
3 changes: 3 additions & 0 deletions .idea/webResources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 6 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -394,48 +394,16 @@ http://localhost:8888/functions/hola/orange
> - *The `default` revision is the `default` version of the function (http://localhost:8888/functions/hola)*
To run the **Capsule Reverse Proxy**, run the below command:
```bash
./capsule-reverse-proxy \
-config=./config.yaml \
-httpPort=8888
```
> *You have to define a configuration yaml file.*

### Define the routes in a yaml file (static mode)

*config.yaml*
```yaml
hello:
default:
- http://localhost:9091
- http://localhost:7071

hey:
default:
- http://localhost:9092

hola:
default:
- http://localhost:9093
orange:
- http://localhost:6061
yellow:
- http://localhost:6062
```
> *A revision can be a set of URLs. In this case, the Capsule reverse-proxy will use randomly one of the URLs.*
### Use the "in memory" dynamic mode of the reverse-proxy
With the Capsule Reverse Proxy, you gain an **API** that allows to define routes dynamically (in memory). You can keep the yaml config file (it is loaded in memory at startup).
To run **Capsule** as a reverse proxy, with the "in memory" dynamic mode, add this flag: `-backend="memory"`:
```bash
./capsule \
./capsule-reverse-proxy \
-config=./config.yaml \
-backend="memory" \
-httpPort=8888
```

With the Capsule Reverse Proxy, you gain an **API** that allows to define routes dynamically (in memory).

#### Registration API

##### Register a function (add a new route to a function)
Expand Down Expand Up @@ -551,6 +519,9 @@ The routes list will look like that:
}
```

> *A revision can be a set of URLs. In this case, the Capsule reverse-proxy will use randomly one of the URLs.*

##### Remove a URL from the function revision

```bash
Expand Down
2 changes: 1 addition & 1 deletion capsule-reverse-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func main() {
//flags
httpPortPtr := flag.String("httpPort", "8080", "http port")

configPtr := flag.String("config", "", "config file (reverse proxy)")
configPtr := flag.String("config", "", "config file (🚧 not implemented)")
backendPtr := flag.String("backend", "memory", "backend for reverse proxy, registration, discovery")

crtPtr := flag.String("crt", "", "certificate")
Expand Down
241 changes: 98 additions & 143 deletions capsule-reverse-proxy/reverse-proxy/reverse-proxy.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
package reverse_proxy

import (
"fmt"
"github.com/bots-garden/capsule/capsule-reverse-proxy/reverse-proxy/routes"
"github.com/bots-garden/capsule/commons"
"github.com/gin-gonic/gin"
"gopkg.in/yaml.v3"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"fmt"
"github.com/bots-garden/capsule/capsule-reverse-proxy/reverse-proxy/routes"
"github.com/bots-garden/capsule/commons"
"github.com/gin-gonic/gin"
"net/http"
"net/http/httputil"
"net/url"
)

/*
Expand All @@ -25,165 +22,123 @@ func getEnv(key, fallback string) string {
var lastUrlIndex = 0

func redirect(functionUrls []string, c *gin.Context) {
//fmt.Println("🟢🖐", functionUrls)
var functionUrl = ""
var functionUrl = ""

if len(functionUrls) == 1 {
functionUrl = functionUrls[0]
} else {
//TODO better repartition (load balancing) handling
lastUrlIndex += 1
if lastUrlIndex == len(functionUrls) {
lastUrlIndex = 0
}
if len(functionUrls) == 1 {
functionUrl = functionUrls[0]
} else {
//TODO better repartition (load balancing) handling
lastUrlIndex += 1
if lastUrlIndex == len(functionUrls) {
lastUrlIndex = 0
}

functionUrl = functionUrls[lastUrlIndex]
functionUrl = functionUrls[lastUrlIndex]

//fmt.Println("🛑 kind of load balancing", lastUrlIndex)
//fmt.Println("🌍", functionUrl)
}
}

remote, err := url.Parse(functionUrl)
remote, err := url.Parse(functionUrl)

if err != nil {
panic(err)
}
if err != nil {
panic(err)
}

proxy := httputil.NewSingleHostReverseProxy(remote)
proxy := httputil.NewSingleHostReverseProxy(remote)

proxy.Director = func(req *http.Request) {
req.Header = c.Request.Header
req.Host = remote.Host
req.URL.Scheme = remote.Scheme
req.URL.Host = remote.Host
req.URL.Path = c.Param("proxyPath")
proxy.Director = func(req *http.Request) {
req.Header = c.Request.Header
req.Host = remote.Host
req.URL.Scheme = remote.Scheme
req.URL.Host = remote.Host
req.URL.Path = c.Param("proxyPath")

//fmt.Println("🔴", c.Request.Header)
}
}

proxy.ServeHTTP(c.Writer, c.Request)
proxy.ServeHTTP(c.Writer, c.Request)
}

// 👀 See https://github.com/bots-garden/procyon/blob/main/procyon-reverse-proxy/main.go
func proxy(c *gin.Context) {

functionName := c.Param("function_name")
functionUrls := functions[functionName]["default"]

//fmt.Println("👋functionName", functionName)
//fmt.Println("👋functionUrls", functionUrls)
functionName := c.Param("function_name")
functionUrls := functions[functionName]["default"]

if functionUrls != nil {
/*
2022/08/09 14:11:44 http: panic serving 127.0.0.1:65399:
interface conversion: interface {} is []string, not []interface {}
if functionUrls != nil {
//redirect(functionUrls.([]interface{}), c)
redirect(functionUrls.([]string), c)

*/

//redirect(functionUrls.([]interface{}), c)
redirect(functionUrls.([]string), c)

} else {
c.JSON(http.StatusInternalServerError, gin.H{"code": "ERROR", "message": "😢 Houston? We have a problem 🥵"})
}
} else {
c.JSON(http.StatusInternalServerError, gin.H{"code": "ERROR", "message": "😢 Houston? We have a problem 🥵"})
}

}

func proxyRevision(c *gin.Context) {

functionName := c.Param("function_name")
functionRevision := c.Param("function_revision")
functionUrls := functions[functionName][functionRevision]
functionName := c.Param("function_name")
functionRevision := c.Param("function_revision")
functionUrls := functions[functionName][functionRevision]

if functionUrls != nil {
redirect(functionUrls.([]string), c)
} else {
c.JSON(http.StatusInternalServerError, gin.H{"code": "ERROR", "message": "😢 Houston? We have a problem 🥵"})
}
if functionUrls != nil {
redirect(functionUrls.([]string), c)
} else {
c.JSON(http.StatusInternalServerError, gin.H{"code": "ERROR", "message": "😢 Houston? We have a problem 🥵"})
}
}

var yamlConfig = make(map[interface{}]map[interface{}]map[interface{}]interface{})
//var yamlConfig = make(map[interface{}]map[interface{}]map[interface{}]interface{})
var functions = make(map[interface{}]map[interface{}]interface{})
var filters = make(map[interface{}]map[interface{}]interface{})

//var filters = make(map[interface{}]map[interface{}]interface{})

func Serve(httpPort, config, backend, crt, key string) {

if config != "" {
fmt.Println("📝 config file:", config)
yamlFile, errFile := ioutil.ReadFile(config)
if errFile != nil {
log.Fatal(errFile)
}

errYaml := yaml.Unmarshal(yamlFile, &yamlConfig)

if errYaml != nil {
log.Fatal(errYaml)
}

functions = yamlConfig["functions"]
filters = yamlConfig["filters"]

// The code below is for testing
/*
functions["sandbox"] = map[interface{}]interface{}{"default": []string{"http://localhost:5050"}, "blue": []string{"http://localhost:5051"}}
functions["sandbox"]["green"] = []string{"http://localhost:5052"}
urlsList := functions["sandbox"]["green"].([]string)
urlsList = append(urlsList, "http://localhost:5053")
functions["sandbox"]["green"] = urlsList
*/
}

switch backend {
case "yaml":
fmt.Println("👋 routes are defined in", config)
case "memory":
// it's possible to mix memory and yaml for the functions
fmt.Println("👋 routes are defined in memory")
case "redis":
default:
fmt.Println("👋 routes are defined in a Redis backend")
//TODO check the environment variables
fmt.Println("👋 use environment variable for the Redis configuration ")
}

if commons.GetEnv("DEBUG", "false") == "false" {
gin.SetMode(gin.ReleaseMode)
} else {
gin.SetMode(gin.DebugMode)
}
//router := gin.Default()
router := gin.New()

router.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{"code": "PAGE_NOT_FOUND", "message": "😢 Page not found 🥵"})
})

/*
You need to use a header with this key: CAPSULE_REVERSE_PROXY_ADMIN_TOKEN
*/
reverseProxyAdminToken := commons.GetEnv("CAPSULE_REVERSE_PROXY_ADMIN_TOKEN", "")

reverse_proxy_memory_routes.DefineFunctionsRoutes(router, functions, reverseProxyAdminToken)
reverse_proxy_memory_routes.DefineRevisionsRoutes(router, functions, reverseProxyAdminToken)
reverse_proxy_memory_routes.DefineUrlsRoutes(router, functions, reverseProxyAdminToken)

// Call the functions
router.Any("/functions/:function_name", proxy)
router.Any("/functions/:function_name/:function_revision", proxyRevision)

if crt != "" {
// certs/procyon-registry.local.crt
// certs/procyon-registry.local.key
fmt.Println("💊 Capsule (", commons.CapsuleVersion(), ") Reverse-Proxy is listening on:", httpPort, "🔐🌍")

router.RunTLS(":"+httpPort, crt, key)
} else {
fmt.Println("💊 Capsule (", commons.CapsuleVersion(), ") Reverse-Proxy is listening on:", httpPort, "🌍")
router.Run(":" + httpPort)
}
switch backend {
case "memory":
// it's possible to mix memory and yaml for the functions
fmt.Println("👋 routes are defined in memory")
case "redis":
fmt.Println("👋 Redis backend (🚧 not implemented)")
fmt.Println("👋 routes are defined in a Redis backend")
fmt.Println("👋 use environment variable for the Redis configuration ")
default:
fmt.Println("👋 routes are defined in a Redis backend")
fmt.Println("👋 use environment variable for the Redis configuration ")
}

if commons.GetEnv("DEBUG", "false") == "false" {
gin.SetMode(gin.ReleaseMode)
} else {
gin.SetMode(gin.DebugMode)
}
//router := gin.Default()
router := gin.New()

router.NoRoute(func(c *gin.Context) {
c.JSON(404, gin.H{"code": "PAGE_NOT_FOUND", "message": "😢 Page not found 🥵"})
})

/*
You need to use a header with this key: CAPSULE_REVERSE_PROXY_ADMIN_TOKEN
*/
reverseProxyAdminToken := commons.GetEnv("CAPSULE_REVERSE_PROXY_ADMIN_TOKEN", "")

reverse_proxy_memory_routes.DefineFunctionsRoutes(router, functions, reverseProxyAdminToken)
reverse_proxy_memory_routes.DefineRevisionsRoutes(router, functions, reverseProxyAdminToken)
reverse_proxy_memory_routes.DefineUrlsRoutes(router, functions, reverseProxyAdminToken)

// Call the functions
router.Any("/functions/:function_name", proxy)
router.Any("/functions/:function_name/:function_revision", proxyRevision)

if crt != "" {
// certs/procyon-registry.local.crt
// certs/procyon-registry.local.key
fmt.Println("💊 Capsule (", commons.CapsuleVersion(), ") Reverse-Proxy is listening on:", httpPort, "🔐🌍")

router.RunTLS(":"+httpPort, crt, key)
} else {
fmt.Println("💊 Capsule (", commons.CapsuleVersion(), ") Reverse-Proxy is listening on:", httpPort, "🌍")
router.Run(":" + httpPort)
}

}
1 change: 1 addition & 0 deletions wasm_modules/capsule-files/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
capsule

4 changes: 2 additions & 2 deletions wasm_modules/capsule-files/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ This wasm module is used by the `cli` mode

```bash
#!/bin/bash
MESSAGE="🎉 Hello World" go run main.go \
-wasm=../wasm_modules/capsule-function-template/hello.wasm \
MESSAGE="🎉 Hello World" ./capsule \
-wasm=./hello.wasm \
-mode=cli \
"👋 hello world 🌍🎃" 1234 "Bob Morane"

Expand Down
2 changes: 1 addition & 1 deletion wasm_modules/capsule-files/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ module github.com/bots-garden/capsule/wasm_modules/capsule-files

go 1.18

require github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815080256-b30492298265
require github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815100856-6b0da1ba4aad

require github.com/bots-garden/capsule v0.0.0-20220815052111-84fb610d29f3 // indirect
4 changes: 2 additions & 2 deletions wasm_modules/capsule-files/go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
github.com/bots-garden/capsule v0.0.0-20220815052111-84fb610d29f3 h1:jd6GhVtU6hJh2YhTOal46CxbSfGALQOw+QdwC4N/7eg=
github.com/bots-garden/capsule v0.0.0-20220815052111-84fb610d29f3/go.mod h1:PBhXY24j6vjuYghjEt+9mXzDb2ZwD9m9PAh9e6FTXck=
github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815080256-b30492298265 h1:dwYIdkYYkkxDubatShvKT+nGNKHEtIzTx2dhuuGY8jQ=
github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815080256-b30492298265/go.mod h1:tu9DYBPXGSfiDaCN1opAFZZ3FFt3TVFH5jkYnPypY64=
github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815100856-6b0da1ba4aad h1:DYsWXiMW++fY7MqJeUM2dGJRgyBTQSgWsRo2hy/1nMQ=
github.com/bots-garden/capsule/capsulemodule v0.0.0-20220815100856-6b0da1ba4aad/go.mod h1:tu9DYBPXGSfiDaCN1opAFZZ3FFt3TVFH5jkYnPypY64=
Loading

0 comments on commit 791526f

Please sign in to comment.