Skip to content

Commit a331da7

Browse files
authored
Support TinyGo SDK for extension toolkit (#104)
Signed-off-by: Takeshi Yoneda <[email protected]>
1 parent 5ceed06 commit a331da7

File tree

38 files changed

+594
-84
lines changed

38 files changed

+594
-84
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
ENVOY = standard:1.11.1
1616
HUB ?= docker.io/getenvoy
1717
GETENVOY_TAG ?= dev
18-
BUILDERS_LANGS := rust
18+
BUILDERS_LANGS := rust tinygo
1919
BUILDERS_TAG ?= latest
2020
EXTRA_TAG ?=
2121

@@ -139,7 +139,7 @@ builder/$(1):
139139
$(if $(USE_DOCKER_BUILDKIT_CACHE),--build-arg BUILDKIT_INLINE_CACHE=1,) \
140140
$(if $(USE_DOCKER_BUILDKIT_CACHE),--cache-from $(call EXTENSION_BUILDER_IMAGE,$(1),$(EXTENSION_BUILDER_IMAGE_LATEST_VERSION)),) \
141141
-t $(call EXTENSION_BUILDER_IMAGE,$(1),$(BUILDERS_TAG)) \
142-
images/extension-builders/$(1)
142+
-f images/extension-builders/$(1)/Dockerfile images/extension-builders
143143
endef
144144
$(foreach lang,$(BUILDERS_LANGS),$(eval $(call GEN_BUILD_EXTENSION_BUILDER_IMAGE_TARGET,$(lang))))
145145

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module {{ .Extension.Name }}
2+
3+
go 1.15
4+
5+
require (
6+
github.com/stretchr/testify v1.6.1
7+
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0
8+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
6+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
7+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
8+
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0 h1:9CUaOB8CZInfG/VRCjOEOkzS4JLkri/weqogwmrl2a0=
9+
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0/go.mod h1:y1ZQT4bQEBnR8Do4nSOzb3roczzPvcAp8UrF6NEYWNY=
10+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
11+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
12+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
13+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package main
2+
3+
import (
4+
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
5+
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
6+
)
7+
8+
func main() {
9+
proxywasm.SetNewRootContext(newAccessLogger)
10+
}
11+
12+
type accessLogger struct {
13+
// You'd better embed the default root context
14+
// so that you don't need to reimplement all the methods by yourself.
15+
proxywasm.DefaultRootContext
16+
logMessage string
17+
}
18+
19+
func newAccessLogger(contextID uint32) proxywasm.RootContext {
20+
return &accessLogger{}
21+
}
22+
23+
// Override proxywasm.DefaultRootContext
24+
func (l *accessLogger) OnPluginStart(configurationSize int) types.OnPluginStartStatus {
25+
// Read plugin configuration provided in Envoy configuration.
26+
data, err := proxywasm.GetPluginConfiguration(configurationSize)
27+
if err != nil && err != types.ErrorStatusNotFound {
28+
proxywasm.LogCriticalf("failed to load config: %v", err)
29+
return types.OnPluginStartStatusFailed
30+
}
31+
l.logMessage = string(data)
32+
return types.OnPluginStartStatusOK
33+
}
34+
35+
// Override proxywasm.DefaultRootContext
36+
func (l *accessLogger) OnLog() {
37+
hdr, err := proxywasm.GetHttpRequestHeader(":path")
38+
if err != nil {
39+
proxywasm.LogCritical(err.Error())
40+
return
41+
}
42+
43+
proxywasm.LogInfof(":path = %s", hdr)
44+
proxywasm.LogInfof("message = %s", l.logMessage)
45+
46+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/tetratelabs/proxy-wasm-go-sdk/proxytest"
9+
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
10+
)
11+
12+
func TestAccessLogger_OnLog(t *testing.T) {
13+
configuration := `this is my log message`
14+
opt := proxytest.NewEmulatorOption().
15+
WithNewRootContext(newAccessLogger).
16+
WithPluginConfiguration([]byte(configuration))
17+
18+
host := proxytest.NewHostEmulator(opt)
19+
// Release the host emulation lock so that other test cases can insert their own host emulation.
20+
defer host.Done()
21+
22+
// Call OnPluginStart -> the message field of root context is configured.
23+
status := host.StartPlugin()
24+
// Check the status returned by OnPluginStart is OK.
25+
require.Equal(t, types.OnPluginStartStatusOK, status)
26+
27+
// Call OnLog with the given headers.
28+
host.CallOnLogForAccessLogger(types.Headers{
29+
{":path", "/this/is/path"},
30+
}, nil)
31+
32+
// Check the Envoy logs.
33+
logs := host.GetLogs(types.LogLevelInfo)
34+
require.Contains(t, logs, ":path = /this/is/path")
35+
require.Contains(t, logs, "message = this is my log message")
36+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build/
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module {{ .Extension.Name }}
2+
3+
go 1.15
4+
5+
require (
6+
github.com/stretchr/testify v1.6.1
7+
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0
8+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
4+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
6+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
7+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
8+
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0 h1:9CUaOB8CZInfG/VRCjOEOkzS4JLkri/weqogwmrl2a0=
9+
github.com/tetratelabs/proxy-wasm-go-sdk v0.1.0/go.mod h1:y1ZQT4bQEBnR8Do4nSOzb3roczzPvcAp8UrF6NEYWNY=
10+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
11+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
12+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
13+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"bytes"
6+
"strings"
7+
8+
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
9+
"github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
10+
)
11+
12+
var (
13+
requestCounterName = "my_http_filter.request_counter"
14+
counter proxywasm.MetricCounter
15+
)
16+
17+
func main() {
18+
proxywasm.SetNewRootContext(newRootContext)
19+
}
20+
21+
type rootContext struct {
22+
// You'd better embed the default root context
23+
// so that you don't need to reimplement all the methods by yourself.
24+
proxywasm.DefaultRootContext
25+
contextID uint32
26+
additionalHeaders map[string]string
27+
}
28+
29+
func newRootContext(rootContextID uint32) proxywasm.RootContext {
30+
return &rootContext{contextID: rootContextID, additionalHeaders: map[string]string{"additional": "header"}}
31+
}
32+
33+
// Override proxywasm.DefaultRootContext
34+
func (ctx *rootContext) OnPluginStart(configurationSize int) types.OnPluginStartStatus {
35+
// Initialize the counter.
36+
counter = proxywasm.DefineCounterMetric(requestCounterName)
37+
38+
// Read plugin configuration provided in Envoy configuration.
39+
data, err := proxywasm.GetPluginConfiguration(configurationSize)
40+
if err != nil && err != types.ErrorStatusNotFound {
41+
proxywasm.LogCriticalf("failed to load config: %v", err)
42+
return types.OnPluginStartStatusFailed
43+
}
44+
45+
// Each line in the configuration is in the "KEY=VALUE" format.
46+
scanner := bufio.NewScanner(bytes.NewReader(data))
47+
for scanner.Scan() {
48+
tokens := strings.Split(scanner.Text(), "=")
49+
ctx.additionalHeaders[tokens[0]] = tokens[1]
50+
}
51+
return types.OnPluginStartStatusOK
52+
}
53+
54+
// Override proxywasm.DefaultRootContext
55+
func (ctx *rootContext) NewHttpContext(uint32) proxywasm.HttpContext {
56+
return &httpContext{additionalHeaders: ctx.additionalHeaders}
57+
}
58+
59+
type httpContext struct {
60+
// You'd better embed the default http context
61+
// so that you don't need to reimplement all the methods by yourself.
62+
proxywasm.DefaultHttpContext
63+
additionalHeaders map[string]string
64+
}
65+
66+
// Override proxywasm.DefaultHttpContext
67+
func (ctx *httpContext) OnHttpRequestHeaders(numHeaders int, endOfStream bool) types.Action {
68+
hs, err := proxywasm.GetHttpRequestHeaders()
69+
if err != nil {
70+
proxywasm.LogCriticalf("failed to get request headers: %v", err)
71+
return types.ActionPause
72+
}
73+
74+
proxywasm.LogInfo("observing request headers")
75+
for _, h := range hs {
76+
proxywasm.LogInfof("%s: %s", h[0], h[1])
77+
}
78+
79+
return types.ActionContinue
80+
}
81+
82+
// Override proxywasm.DefaultHttpContext
83+
func (ctx *httpContext) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action {
84+
// Set additional headers in the response.
85+
for key, value := range ctx.additionalHeaders {
86+
if err := proxywasm.SetHttpResponseHeader(key, value); err != nil {
87+
proxywasm.LogCriticalf("failed to add header: %v", err)
88+
return types.ActionPause
89+
}
90+
proxywasm.LogInfof("header set: %s=%s", key, value)
91+
}
92+
return types.ActionContinue
93+
}
94+
95+
// Override proxywasm.DefaultHttpContext
96+
func (ctx *httpContext) OnHttpStreamDone() {
97+
counter.Increment(1)
98+
}

0 commit comments

Comments
 (0)