-
Notifications
You must be signed in to change notification settings - Fork 1
/
kong.go
187 lines (160 loc) · 5.79 KB
/
kong.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package kong
import (
"context"
"fmt"
"path/filepath"
"strings"
"github.com/docker/go-connections/nat"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
type kongContainer struct {
testcontainers.Container
Host string
AdminURL string
ProxyURL string
ManagerURL string
}
// TODO: mention all ports
var (
defaultProxyPort = "8000/tcp"
defaultAdminAPIPort = "8001/tcp"
defaultKongManagerPort = "8002/tcp"
)
// RunContainer is the entrypoint to the module
func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*kongContainer, error) {
req := testcontainers.ContainerRequest{
Image: "kong/kong:3.4.0",
ExposedPorts: []string{
defaultProxyPort,
defaultAdminAPIPort,
defaultKongManagerPort,
},
WaitingFor: wait.ForListeningPort(nat.Port(defaultAdminAPIPort)),
Cmd: []string{"kong", "start"},
Env: map[string]string{
// default env variables, can be overwritten in test method
"KONG_DATABASE": "off",
"KONG_LOG_LEVEL": "debug",
"KONG_PROXY_ACCESS_LOG": "/dev/stdout",
"KONG_ADMIN_ACCESS_LOG": "/dev/stdout",
"KONG_PROXY_ERROR_LOG": "/dev/stderr",
"KONG_ADMIN_ERROR_LOG": "/dev/stderr",
"KONG_ADMIN_LISTEN": "0.0.0.0:8001",
"KONG_DECLARATIVE_CONFIG": "/usr/local/kong/kong.yaml",
},
Files: []testcontainers.ContainerFile{
{
HostFilePath: filepath.Join(".", "testdata", "kong-config-default.yaml"),
ContainerFilePath: "/usr/local/kong/kong.yaml",
FileMode: 0644, // see
},
},
}
genericContainerRequest := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
}
for _, opt := range opts {
opt.Customize(&genericContainerRequest)
}
container, err := testcontainers.GenericContainer(ctx, genericContainerRequest)
if err != nil {
return nil, err
}
ip, err := container.Host(ctx)
if err != nil {
return nil, err
}
adminMappedPort, err := container.MappedPort(ctx, nat.Port(defaultAdminAPIPort))
if err != nil {
return nil, err
}
proxyMappedPort, err := container.MappedPort(ctx, nat.Port(defaultProxyPort))
if err != nil {
return nil, err
}
managerMappedPort, err := container.MappedPort(ctx, nat.Port(defaultKongManagerPort))
if err != nil {
return nil, err
}
return &kongContainer{
Container: container,
Host: ip,
AdminURL: fmt.Sprintf("http://%s:%s", ip, adminMappedPort.Port()),
ProxyURL: fmt.Sprintf("http://%s:%s", ip, proxyMappedPort.Port()),
ManagerURL: fmt.Sprintf("http://%s:%s", ip, managerMappedPort.Port()),
}, nil
}
// WithConfig adds the kong config file to the container, in the
// "/usr/local/kong/kong.yaml" directory of the container, and
// setting the KONG_DECLARATIVE_CONFIG environment variable to that path.
func WithConfig(cfg string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
req.Files = append(req.Files, testcontainers.ContainerFile{
HostFilePath: cfg,
ContainerFilePath: "/usr/local/kong/kong.yaml",
FileMode: 0644, // see https://github.com/supabase/cli/pull/132/files
})
// is this variable needed by the default kong image?
WithKongEnv(map[string]string{"KONG_DECLARATIVE_CONFIG": "/usr/local/kong/kong.yaml"})(req)
}
}
// WithKongEnv sets environment variables for kong container, possibly overwriting defaults
func WithKongEnv(env map[string]string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
for k, v := range env {
req.Env[k] = v
}
}
}
// WithLogLevel sets log level for kong container, using the KONG_LOG_LEVEL environment variable.
func WithLogLevel(level string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
WithKongEnv(map[string]string{"KONG_LOG_LEVEL": level})(req)
}
}
// WithGoPlugin adds a Go plugin to the container, in the "/usr/local/bin" directory of the container
// appending the plugin name to the KONG_PLUGINS and KONG_PLUGINSERVER_NAMES environment variables,
// and setting the KONG_PLUGINSERVER_GOPLUG_START_CMD and KONG_PLUGINSERVER_GOPLUG_QUERY_CMD to the
// executable path of the plugin.
func WithGoPlugin(goPlugPath string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
pluginName := filepath.Base(goPlugPath) // should be goplug
req.Files = append(req.Files, testcontainers.ContainerFile{
HostFilePath: goPlugPath,
ContainerFilePath: "/usr/local/bin/" + pluginName,
FileMode: 0755,
})
pluginNameUpper := strings.ToUpper(pluginName)
env := map[string]string{
"KONG_PLUGINS": appendToCommaSeparatedList(req.Env["KONG_PLUGINS"], pluginName),
"KONG_PLUGINSERVER_NAMES": appendToCommaSeparatedList(req.Env["KONG_PLUGINSERVER_NAMES"], pluginName),
"KONG_PLUGINSERVER_" + pluginNameUpper + "_START_CMD": "/usr/local/bin/" + pluginName,
"KONG_PLUGINSERVER_" + pluginNameUpper + "_QUERY_CMD": "/usr/local/bin/" + pluginName + " -dump",
}
WithKongEnv(env)(req)
}
}
func WithWasmFilter(wasmFiltersPath string) testcontainers.CustomizeRequestOption {
return func(req *testcontainers.GenericContainerRequest) {
filter := filepath.Base(wasmFiltersPath) // should be hello-world.wasm
req.Files = append(req.Files, testcontainers.ContainerFile{
HostFilePath: wasmFiltersPath,
ContainerFilePath: "/usr/local/bin/" + filter,
FileMode: 0755,
})
env := map[string]string{
"KONG_WASM": "on",
"KONG_WASM_FILTERS_PATH": "/usr/local/bin",
"KONG_NGINX_WASM_SHM_KONG_WASM_RATE_LIMITING_COUNTERS": "12m",
}
WithKongEnv(env)(req)
}
}
func appendToCommaSeparatedList(list, item string) string {
if len(list) > 0 {
return list + "," + item
}
return item
}