Extending Envoy Proxy with Golang WebAssembly

$ brew update
$ brew install envoy
$ brew tap tinygo-org/tools
$ brew install tinygo
package main

import (
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
)

type helloHttpContext struct {
proxywasm.DefaultHttpContext
}

func main() {

proxywasm.SetNewHttpContext(newHttpContext)
}

func newHttpContext(uint32, uint32) proxywasm.HttpContext {

return &helloHttpContext{}
}

func (ctx *helloHttpContext) OnHttpRequestHeaders(numHeaders int, _ bool) types.Action {

if numHeaders > 0 {
headers, err := proxywasm.GetHttpRequestHeaders()
if err != nil {
proxywasm.LogErrorf("failed to get request headers with '%v'", err)
return types.ActionContinue
}
proxywasm.LogInfof("request headers: '%+v'", headers)
}

return types.ActionContinue
}
$ tinygo build -o ./hello.wasm -scheduler=none -target=wasi ./main.go
static_resources:
listeners:
- name: listener_0
address:
socket_address: { address: 127.0.0.1, port_value: 8085 }
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/" }
route: { cluster: svc_hello }
http_filters:
- name: envoy.filters.http.wasm
typed_config:
"@type": type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
name: "my_plugin"
root_id: "my_root_id"
vm_config:
vm_id: "my_vm_id"
runtime: "envoy.wasm.runtime.v8"
code:
local:
filename: "hello.wasm"
allow_precompiled: true
- name: envoy.filters.http.router
typed_config: {}

clusters:
- name: svc_hello
connect_timeout: 0.25s
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: svc_hello
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 127.0.0.1
port_value: 8080

admin:
access_log_path: "/dev/null"
address:
socket_address:
address: 0.0.0.0
port_value: 8001
package main

import (
"net/http"

log "github.com/sirupsen/logrus"
)

func main() {

m := http.NewServeMux()
m.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
if _, err := w.Write([]byte("hola mundo :)")); err != nil {
log.Errorf("failed to stream response with '%v'", err)
}
})
const addr = ":8080"
server := &http.Server{
Addr: addr,
Handler: m,
}
log.Infof("listening on '%s'", addr)
log.Fatal(server.ListenAndServe())
}
$ envoy -c envoy.yaml -l debug
$ curl localhost:8085/hello
wasm log: response headers: [[:status 200] [date Sun, 24 Jan 2021 00:42:00 GMT] [content-length 13] [content-type text/plain; charset=utf-8] [x-envoy-upstream-service-time 0]]

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Tufin

Tufin

109 Followers

From the Security Policy Company. This blog is dedicated to cloud-native topics such as Kubernetes, cloud security and micro-services.