Skip to content

Commit

Permalink
Support TinyGo SDK for extension toolkit (#104)
Browse files Browse the repository at this point in the history
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>
  • Loading branch information
mathetake authored Mar 15, 2021
1 parent 5ceed06 commit a331da7
Show file tree
Hide file tree
Showing 38 changed files with 594 additions and 84 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
ENVOY = standard:1.11.1
HUB ?= docker.io/getenvoy
GETENVOY_TAG ?= dev
BUILDERS_LANGS := rust
BUILDERS_LANGS := rust tinygo
BUILDERS_TAG ?= latest
EXTRA_TAG ?=

Expand Down Expand Up @@ -139,7 +139,7 @@ builder/$(1):
$(if $(USE_DOCKER_BUILDKIT_CACHE),--build-arg BUILDKIT_INLINE_CACHE=1,) \
$(if $(USE_DOCKER_BUILDKIT_CACHE),--cache-from $(call EXTENSION_BUILDER_IMAGE,$(1),$(EXTENSION_BUILDER_IMAGE_LATEST_VERSION)),) \
-t $(call EXTENSION_BUILDER_IMAGE,$(1),$(BUILDERS_TAG)) \
images/extension-builders/$(1)
-f images/extension-builders/$(1)/Dockerfile images/extension-builders
endef
$(foreach lang,$(BUILDERS_LANGS),$(eval $(call GEN_BUILD_EXTENSION_BUILDER_IMAGE_TARGET,$(lang))))

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module {{ .Extension.Name }}

go 1.15

require (
github.com/stretchr/testify v1.6.1
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0 h1:9CUaOB8CZInfG/VRCjOEOkzS4JLkri/weqogwmrl2a0=
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0/go.mod h1:y1ZQT4bQEBnR8Do4nSOzb3roczzPvcAp8UrF6NEYWNY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package main

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

func main() {
proxywasm.SetNewRootContext(newAccessLogger)
}

type accessLogger struct {
// You'd better embed the default root context
// so that you don't need to reimplement all the methods by yourself.
proxywasm.DefaultRootContext
logMessage string
}

func newAccessLogger(contextID uint32) proxywasm.RootContext {
return &accessLogger{}
}

// Override proxywasm.DefaultRootContext
func (l *accessLogger) OnPluginStart(configurationSize int) types.OnPluginStartStatus {
// Read plugin configuration provided in Envoy configuration.
data, err := proxywasm.GetPluginConfiguration(configurationSize)
if err != nil && err != types.ErrorStatusNotFound {
proxywasm.LogCriticalf("failed to load config: %v", err)
return types.OnPluginStartStatusFailed
}
l.logMessage = string(data)
return types.OnPluginStartStatusOK
}

// Override proxywasm.DefaultRootContext
func (l *accessLogger) OnLog() {
hdr, err := proxywasm.GetHttpRequestHeader(":path")
if err != nil {
proxywasm.LogCritical(err.Error())
return
}

proxywasm.LogInfof(":path = %s", hdr)
proxywasm.LogInfof("message = %s", l.logMessage)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package main

import (
"testing"

"github.com/stretchr/testify/require"

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

func TestAccessLogger_OnLog(t *testing.T) {
configuration := `this is my log message`
opt := proxytest.NewEmulatorOption().
WithNewRootContext(newAccessLogger).
WithPluginConfiguration([]byte(configuration))

host := proxytest.NewHostEmulator(opt)
// Release the host emulation lock so that other test cases can insert their own host emulation.
defer host.Done()

// Call OnPluginStart -> the message field of root context is configured.
status := host.StartPlugin()
// Check the status returned by OnPluginStart is OK.
require.Equal(t, types.OnPluginStartStatusOK, status)

// Call OnLog with the given headers.
host.CallOnLogForAccessLogger(types.Headers{
{":path", "/this/is/path"},
}, nil)

// Check the Envoy logs.
logs := host.GetLogs(types.LogLevelInfo)
require.Contains(t, logs, ":path = /this/is/path")
require.Contains(t, logs, "message = this is my log message")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module {{ .Extension.Name }}

go 1.15

require (
github.com/stretchr/testify v1.6.1
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0 h1:9CUaOB8CZInfG/VRCjOEOkzS4JLkri/weqogwmrl2a0=
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0/go.mod h1:y1ZQT4bQEBnR8Do4nSOzb3roczzPvcAp8UrF6NEYWNY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package main

import (
"bufio"
"bytes"
"strings"

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

var (
requestCounterName = "my_http_filter.request_counter"
counter proxywasm.MetricCounter
)

func main() {
proxywasm.SetNewRootContext(newRootContext)
}

type rootContext struct {
// You'd better embed the default root context
// so that you don't need to reimplement all the methods by yourself.
proxywasm.DefaultRootContext
contextID uint32
additionalHeaders map[string]string
}

func newRootContext(rootContextID uint32) proxywasm.RootContext {
return &rootContext{contextID: rootContextID, additionalHeaders: map[string]string{"additional": "header"}}
}

// Override proxywasm.DefaultRootContext
func (ctx *rootContext) OnPluginStart(configurationSize int) types.OnPluginStartStatus {
// Initialize the counter.
counter = proxywasm.DefineCounterMetric(requestCounterName)

// Read plugin configuration provided in Envoy configuration.
data, err := proxywasm.GetPluginConfiguration(configurationSize)
if err != nil && err != types.ErrorStatusNotFound {
proxywasm.LogCriticalf("failed to load config: %v", err)
return types.OnPluginStartStatusFailed
}

// Each line in the configuration is in the "KEY=VALUE" format.
scanner := bufio.NewScanner(bytes.NewReader(data))
for scanner.Scan() {
tokens := strings.Split(scanner.Text(), "=")
ctx.additionalHeaders[tokens[0]] = tokens[1]
}
return types.OnPluginStartStatusOK
}

// Override proxywasm.DefaultRootContext
func (ctx *rootContext) NewHttpContext(uint32) proxywasm.HttpContext {
return &httpContext{additionalHeaders: ctx.additionalHeaders}
}

type httpContext struct {
// You'd better embed the default http context
// so that you don't need to reimplement all the methods by yourself.
proxywasm.DefaultHttpContext
additionalHeaders map[string]string
}

// Override proxywasm.DefaultHttpContext
func (ctx *httpContext) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action {
hs, err := proxywasm.GetHttpRequestHeaders()
if err != nil {
proxywasm.LogCriticalf("failed to get request headers: %v", err)
return types.ActionPause
}

proxywasm.LogInfo("observing request headers")
for _, h := range hs {
proxywasm.LogInfof("%s: %s", h[0], h[1])
}

return types.ActionContinue
}

// Override proxywasm.DefaultHttpContext
func (ctx *httpContext) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action {
// Set additional headers in the response.
for key, value := range ctx.additionalHeaders {
if err := proxywasm.SetHttpResponseHeader(key, value); err != nil {
proxywasm.LogCriticalf("failed to add header: %v", err)
return types.ActionPause
}
proxywasm.LogInfof("header set: %s=%s", key, value)
}
return types.ActionContinue
}

// Override proxywasm.DefaultHttpContext
func (ctx *httpContext) OnHttpStreamDone() {
counter.Increment(1)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package main

import (
"testing"

"github.com/stretchr/testify/require"

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

func TestHttpFilter_OnHttpRequestHeaders(t *testing.T) {
configuration := `HELLO=WORLD
ENVOY=ISTIO`
opt := proxytest.NewEmulatorOption().
WithNewRootContext(newRootContext).
WithPluginConfiguration([]byte(configuration))

host := proxytest.NewHostEmulator(opt)
// Release the host emulation lock so that other test cases can insert their own host emulation.
defer host.Done()

// Call OnPluginStart -> the metric is initialized.
status := host.StartPlugin()
// Check the status returned by OnPluginStart is OK.
require.Equal(t, types.OnPluginStartStatusOK, status)

// Create http context.
contextID := host.InitializeHttpContext()

// Call OnHttpRequestHeaders with the given headers.
hs := types.Headers{
{"key1", "value1"},
{"key2", "value2"},
}
action := host.CallOnRequestHeaders(contextID, hs, false)
// Check the action returned by OnRequestHeaders is Continue.
require.Equal(t, types.ActionContinue, action)

// Call OnHttpResponseHeaders.
action = host.CallOnResponseHeaders(contextID, nil, false)
// Check the action returned by OnResponseHeaders is Continue.
require.Equal(t, types.ActionContinue, action)

// Check Envoy logs.
logs := host.GetLogs(types.LogLevelInfo)
require.Contains(t, logs, "header set: ENVOY=ISTIO")
require.Contains(t, logs, "header set: HELLO=WORLD")
require.Contains(t, logs, "header set: additional=header")
require.Contains(t, logs, "key2: value2")
require.Contains(t, logs, "key1: value1")
require.Contains(t, logs, "observing request headers")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build/
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module {{ .Extension.Name }}

go 1.15

require (
github.com/stretchr/testify v1.6.1
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0 h1:9CUaOB8CZInfG/VRCjOEOkzS4JLkri/weqogwmrl2a0=
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0/go.mod h1:y1ZQT4bQEBnR8Do4nSOzb3roczzPvcAp8UrF6NEYWNY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package main

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

var (
connectionCounterName = "my_network_filter.connection_counter"
counter proxywasm.MetricCounter
)

func main() {
proxywasm.SetNewRootContext(newRootContext)
}

type rootContext struct {
// You'd better embed the default root context
// so that you don't need to reimplement all the methods by yourself.
proxywasm.DefaultRootContext
config string
}

func newRootContext(rootContextID uint32) proxywasm.RootContext {
return &rootContext{}
}

// Override proxywasm.DefaultRootContext
func (ctx *rootContext) OnPluginStart(configurationSize int) types.OnPluginStartStatus {
counter = proxywasm.DefineCounterMetric(connectionCounterName)

data, err := proxywasm.GetPluginConfiguration(configurationSize)
if err != nil && err != types.ErrorStatusNotFound {
proxywasm.LogCriticalf("failed to load config: %v", err)
return types.OnPluginStartStatusFailed
}
ctx.config = string(data)
return types.OnPluginStartStatusOK
}

// Override proxywasm.DefaultRootContext
func (ctx *rootContext) NewStreamContext(contextID uint32) proxywasm.StreamContext {
return &streamContext{newConnectionMessage: ctx.config}
}

type streamContext struct {
// You'd better embed the default stream context
// so that you don't need to reimplement all the methods by yourself.
proxywasm.DefaultStreamContext
newConnectionMessage string
}

// Override proxywasm.DefaultStreamContext
func (ctx *streamContext) OnNewConnection() types.Action {
proxywasm.LogInfo(ctx.newConnectionMessage)
return types.ActionContinue
}

// Override proxywasm.DefaultStreamContext
func (ctx *streamContext) OnStreamDone() {
counter.Increment(1)
proxywasm.LogInfof("connection complete!")
}
Loading

0 comments on commit a331da7

Please sign in to comment.