Skip to content

Commit 2ce7ff7

Browse files
committed
add support for wasm transforms
1 parent 8d33968 commit 2ce7ff7

File tree

8 files changed

+153
-2
lines changed

8 files changed

+153
-2
lines changed

modules/k3s/go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
module github.com/testcontainers/testcontainers-go/modules/k3s
22

3-
go 1.20
3+
go 1.21
4+
5+
toolchain go1.21.5
46

57
require (
68
github.com/docker/docker v25.0.1+incompatible

modules/redpanda/examples_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ func ExampleRunContainer() {
1414
redpandaContainer, err := redpanda.RunContainer(ctx,
1515
redpanda.WithEnableSASL(),
1616
redpanda.WithEnableKafkaAuthorization(),
17+
redpanda.WithEnableWasmTransform(),
1718
redpanda.WithNewServiceAccount("superuser-1", "test"),
1819
redpanda.WithNewServiceAccount("superuser-2", "test"),
1920
redpanda.WithNewServiceAccount("no-superuser", "test"),

modules/redpanda/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/testcontainers/testcontainers-go/modules/redpanda
33
go 1.20
44

55
require (
6+
github.com/Masterminds/semver/v3 v3.2.1
67
github.com/docker/go-connections v0.5.0
78
github.com/stretchr/testify v1.8.4
89
github.com/testcontainers/testcontainers-go v0.27.0

modules/redpanda/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
33
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
44
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
55
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
6+
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
7+
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
68
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
79
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
810
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=

modules/redpanda/mounts/bootstrap.yaml.tpl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ superusers:
1515
kafka_enable_authorization: true
1616
{{- end }}
1717

18+
{{- if .EnableWasmTransform }}
19+
data_transforms_enabled: true
20+
{{- end }}
21+
1822
{{- if .AutoCreateTopics }}
1923
auto_create_topics_enabled: true
2024
{{- end }}

modules/redpanda/options.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ type options struct {
2222
// or "http_basic" for HTTP basic authentication.
2323
SchemaRegistryAuthenticationMethod string
2424

25+
// EnableWasmTransform is a flag to enable wasm transform.
26+
EnableWasmTransform bool
27+
2528
// ServiceAccounts is a map of username (key) to password (value) of users
2629
// that shall be created, so that you can use these to authenticate against
2730
// Redpanda (either for the Kafka API or Schema Registry HTTP access).
@@ -97,6 +100,14 @@ func WithEnableKafkaAuthorization() Option {
97100
}
98101
}
99102

103+
// WithEnableWasmTransform enables wasm transform.
104+
// Should not be used with RP versions before 23.3
105+
func WithEnableWasmTransform() Option {
106+
return func(o *options) {
107+
o.EnableWasmTransform = true
108+
}
109+
}
110+
100111
// WithEnableSchemaRegistryHTTPBasicAuth enables HTTP basic authentication for
101112
// Schema Registry.
102113
func WithEnableSchemaRegistryHTTPBasicAuth() Option {

modules/redpanda/redpanda.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import (
55
"context"
66
_ "embed"
77
"fmt"
8+
semver "github.com/Masterminds/semver/v3"
89
"math"
910
"os"
1011
"path/filepath"
12+
"strings"
1113
"text/template"
1214
"time"
1315

@@ -59,7 +61,7 @@ func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomize
5961
// Some (e.g. Image) may be overridden by providing an option argument to this function.
6062
req := testcontainers.GenericContainerRequest{
6163
ContainerRequest: testcontainers.ContainerRequest{
62-
Image: "docker.redpanda.com/redpandadata/redpanda:v23.1.7",
64+
Image: "docker.redpanda.com/redpandadata/redpanda:v23.3.3",
6365
User: "root:root",
6466
// Files: Will be added later after we've rendered our YAML templates.
6567
ExposedPorts: []string{
@@ -89,6 +91,19 @@ func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomize
8991
opt.Customize(&req)
9092
}
9193

94+
ver, err := semver.NewVersion(strings.Split(req.ContainerRequest.Image, ":")[1])
95+
if err != nil {
96+
return nil, err
97+
}
98+
99+
minVerForTransform, err := semver.NewVersion("v23.3")
100+
if err != nil {
101+
return nil, err
102+
}
103+
if ver.LessThan(minVerForTransform) {
104+
settings.EnableWasmTransform = false
105+
}
106+
92107
// 3. Create temporary entrypoint file. We need a custom entrypoint that waits
93108
// until the actual Redpanda node config is mounted. Once the redpanda config is
94109
// mounted we will call the original entrypoint with the same parameters.
@@ -245,6 +260,7 @@ func renderBootstrapConfig(settings options) ([]byte, error) {
245260
Superusers: settings.Superusers,
246261
KafkaAPIEnableAuthorization: settings.KafkaEnableAuthorization,
247262
AutoCreateTopics: settings.AutoCreateTopics,
263+
EnableWasmTransform: settings.EnableWasmTransform,
248264
}
249265

250266
tpl, err := template.New("bootstrap.yaml").Parse(bootstrapConfigTpl)
@@ -318,6 +334,7 @@ type redpandaBootstrapConfigTplParams struct {
318334
Superusers []string
319335
KafkaAPIEnableAuthorization bool
320336
AutoCreateTopics bool
337+
EnableWasmTransform bool
321338
}
322339

323340
type redpandaConfigTplParams struct {

modules/redpanda/redpanda_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,119 @@ func TestRedpandaWithAuthentication(t *testing.T) {
8484
container, err := RunContainer(ctx,
8585
WithEnableSASL(),
8686
WithEnableKafkaAuthorization(),
87+
WithEnableWasmTransform(),
88+
WithNewServiceAccount("superuser-1", "test"),
89+
WithNewServiceAccount("superuser-2", "test"),
90+
WithNewServiceAccount("no-superuser", "test"),
91+
WithSuperusers("superuser-1", "superuser-2"),
92+
WithEnableSchemaRegistryHTTPBasicAuth(),
93+
)
94+
require.NoError(t, err)
95+
// }
96+
97+
// Clean up the container after the test is complete
98+
t.Cleanup(func() {
99+
if err := container.Terminate(ctx); err != nil {
100+
t.Fatalf("failed to terminate container: %s", err)
101+
}
102+
})
103+
104+
// kafkaSeedBroker {
105+
seedBroker, err := container.KafkaSeedBroker(ctx)
106+
// }
107+
require.NoError(t, err)
108+
109+
// Test successful authentication & authorization with all created superusers
110+
serviceAccounts := map[string]string{
111+
"superuser-1": "test",
112+
"superuser-2": "test",
113+
}
114+
115+
for user, password := range serviceAccounts {
116+
kafkaCl, err := kgo.NewClient(
117+
kgo.SeedBrokers(seedBroker),
118+
kgo.SASL(scram.Auth{
119+
User: user,
120+
Pass: password,
121+
}.AsSha256Mechanism()),
122+
)
123+
require.NoError(t, err)
124+
125+
kafkaAdmCl := kadm.NewClient(kafkaCl)
126+
_, err = kafkaAdmCl.CreateTopic(ctx, 1, 1, nil, fmt.Sprintf("test-%v", user))
127+
require.NoError(t, err)
128+
kafkaCl.Close()
129+
}
130+
131+
// Test successful authentication, but failed authorization with a non-superuser account
132+
{
133+
kafkaCl, err := kgo.NewClient(
134+
kgo.SeedBrokers(seedBroker),
135+
kgo.SASL(scram.Auth{
136+
User: "no-superuser",
137+
Pass: "test",
138+
}.AsSha256Mechanism()),
139+
)
140+
require.NoError(t, err)
141+
142+
kafkaAdmCl := kadm.NewClient(kafkaCl)
143+
_, err = kafkaAdmCl.CreateTopic(ctx, 1, 1, nil, "test-2")
144+
require.Error(t, err)
145+
require.ErrorContains(t, err, "TOPIC_AUTHORIZATION_FAILED")
146+
kafkaCl.Close()
147+
}
148+
149+
// Test failed authentication
150+
{
151+
kafkaCl, err := kgo.NewClient(
152+
kgo.SeedBrokers(seedBroker),
153+
kgo.SASL(scram.Auth{
154+
User: "wrong",
155+
Pass: "wrong",
156+
}.AsSha256Mechanism()),
157+
)
158+
require.NoError(t, err)
159+
160+
kafkaAdmCl := kadm.NewClient(kafkaCl)
161+
_, err = kafkaAdmCl.Metadata(ctx)
162+
require.Error(t, err)
163+
require.ErrorContains(t, err, "SASL_AUTHENTICATION_FAILED")
164+
}
165+
166+
// Test Schema Registry API
167+
httpCl := &http.Client{Timeout: 5 * time.Second}
168+
// schemaRegistryAddress {
169+
schemaRegistryURL, err := container.SchemaRegistryAddress(ctx)
170+
// }
171+
require.NoError(t, err)
172+
173+
// Failed authentication
174+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("%s/subjects", schemaRegistryURL), nil)
175+
require.NoError(t, err)
176+
resp, err := httpCl.Do(req)
177+
require.NoError(t, err)
178+
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
179+
resp.Body.Close()
180+
181+
// Successful authentication
182+
for user, password := range serviceAccounts {
183+
req.SetBasicAuth(user, password)
184+
resp, err = httpCl.Do(req)
185+
require.NoError(t, err)
186+
assert.Equal(t, http.StatusOK, resp.StatusCode)
187+
resp.Body.Close()
188+
}
189+
}
190+
191+
func TestRedpandaWithOldVersionAndWasm(t *testing.T) {
192+
ctx := context.Background()
193+
// redpandaCreateContainer {
194+
// this would fail to start if we weren't ignoring wasm transforms for older versions
195+
container, err := RunContainer(ctx,
196+
testcontainers.WithImage("redpandadata/redpanda:v23.2.18"),
197+
WithEnableSASL(),
198+
WithEnableKafkaAuthorization(),
199+
WithEnableWasmTransform(),
87200
WithNewServiceAccount("superuser-1", "test"),
88201
WithNewServiceAccount("superuser-2", "test"),
89202
WithNewServiceAccount("no-superuser", "test"),

0 commit comments

Comments
 (0)