-
-
Notifications
You must be signed in to change notification settings - Fork 442
/
opensearch.go
136 lines (117 loc) · 3.58 KB
/
opensearch.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
package opensearch
import (
"context"
"encoding/json"
"fmt"
"io"
"time"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-units"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
const (
defaultPassword = "admin"
defaultUsername = "admin"
defaultHTTPPort = "9200/tcp"
)
// OpenSearchContainer represents the OpenSearch container type used in the module
type OpenSearchContainer struct {
testcontainers.Container
User string
Password string
}
// RunContainer creates an instance of the OpenSearch container type
func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*OpenSearchContainer, error) {
req := testcontainers.ContainerRequest{
Image: "opensearchproject/opensearch:2.11.1",
ExposedPorts: []string{defaultHTTPPort, "9600/tcp"},
Env: map[string]string{
"discovery.type": "single-node",
"DISABLE_INSTALL_DEMO_CONFIG": "true",
"DISABLE_SECURITY_PLUGIN": "true",
"OPENSEARCH_USERNAME": defaultUsername,
"OPENSEARCH_PASSWORD": defaultPassword,
},
HostConfigModifier: func(hc *container.HostConfig) {
hc.Ulimits = []*units.Ulimit{
{
Name: "memlock",
Soft: -1, // Set memlock to unlimited (no soft or hard limit)
Hard: -1,
},
{
Name: "nofile",
Soft: 65536, // Maximum number of open files for the opensearch user - set to at least 65536
Hard: 65536,
},
}
},
}
genericContainerReq := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
}
// Gather all config options (defaults and then apply provided options)
settings := defaultOptions()
for _, opt := range opts {
if apply, ok := opt.(Option); ok {
apply(settings)
}
if err := opt.Customize(&genericContainerReq); err != nil {
return nil, err
}
}
// set credentials if they are provided, otherwise use the defaults
if settings.Username != "" {
genericContainerReq.Env["OPENSEARCH_USERNAME"] = settings.Username
}
if settings.Password != "" {
genericContainerReq.Env["OPENSEARCH_PASSWORD"] = settings.Password
}
username := genericContainerReq.Env["OPENSEARCH_USERNAME"]
password := genericContainerReq.Env["OPENSEARCH_PASSWORD"]
// the wat strategy does not support TLS at the moment,
// so we need to disable it in the strategy for now.
genericContainerReq.WaitingFor = wait.ForHTTP("/").
WithPort("9200").
WithTLS(false).
WithStartupTimeout(120*time.Second).
WithStatusCodeMatcher(func(status int) bool {
return status == 200
}).
WithBasicAuth(username, password).
WithResponseMatcher(func(body io.Reader) bool {
bs, err := io.ReadAll(body)
if err != nil {
return false
}
type response struct {
Tagline string `json:"tagline"`
}
var r response
err = json.Unmarshal(bs, &r)
if err != nil {
return false
}
return r.Tagline == "The OpenSearch Project: https://opensearch.org/"
})
container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
if err != nil {
return nil, err
}
return &OpenSearchContainer{Container: container, User: username, Password: password}, nil
}
// Address retrieves the address of the OpenSearch container.
// It will use http as protocol, as TLS is not supported at the moment.
func (c *OpenSearchContainer) Address(ctx context.Context) (string, error) {
containerPort, err := c.MappedPort(ctx, defaultHTTPPort)
if err != nil {
return "", err
}
host, err := c.Host(ctx)
if err != nil {
return "", err
}
return fmt.Sprintf("http://%s:%s", host, containerPort.Port()), nil
}