/
envoy.go
150 lines (133 loc) · 3.71 KB
/
envoy.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
package impltests
import (
"encoding/pem"
"fmt"
test_executor "github.com/Netflix/bettertls/test-suites/test-executor"
"net"
"net/http"
"os/exec"
"strings"
"syscall"
"time"
)
type EnvoyRunner struct {
version string
}
func (r *EnvoyRunner) Name() string {
return "envoy"
}
func (r *EnvoyRunner) Initialize() error {
version, err := execAndCapture("envoy", "--version")
if err != nil {
return err
}
version = strings.TrimSpace(version)
r.version = version
return nil
}
func (r *EnvoyRunner) Close() error {
return nil
}
func (r *EnvoyRunner) GetVersion() string {
return r.version
}
func (r *EnvoyRunner) RunTests(ctx *test_executor.ExecutionContext) (map[string]*test_executor.SuiteTestResults, error) {
suites, err := test_executor.BuildTestSuites()
if err != nil {
return nil, err
}
rootCertPem := pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: suites.GetRootCert().Raw,
})
pemString := strings.ReplaceAll(string(rootCertPem), "\n", "\\n")
return test_executor.ExecuteAllTestsRemote(ctx, suites, func(hostname string, port uint) (bool, error) {
sanType := "DNS"
if net.ParseIP(hostname) != nil {
sanType = "IP_ADDRESS"
}
var configYaml = fmt.Sprintf(`
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 127.0.0.1
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
access_log:
- name: envoy.access_loggers.stdout
typed_config:
"@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match:
prefix: "/"
route:
cluster: service_envoyproxy_io
clusters:
- name: service_envoyproxy_io
type: LOGICAL_DNS
# Comment out the following line to test on v6 networks
dns_lookup_family: V4_ONLY
load_assignment:
cluster_name: service_envoyproxy_io
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: "%s"
port_value: %d
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
common_tls_context:
validation_context:
match_typed_subject_alt_names:
- san_type: %s
matcher:
exact: "%s"
trusted_ca:
inline_string: "%s"
`, hostname, port, sanType, hostname, pemString)
cmd := exec.Command("envoy", "--config-yaml", configYaml)
err = cmd.Start()
if err != nil {
return false, err
}
for {
// Trial-and-error, 50ms is about enough to consistently have envoy startup
time.Sleep(50 * time.Millisecond)
c, err := net.Dial("tcp", "127.0.0.1:10000")
if err == nil {
c.Close()
break
}
}
resp, err := http.Get("http://127.0.0.1:10000/ok")
if resp != nil && resp.Body != nil {
_ = resp.Body.Close()
}
_ = cmd.Process.Signal(syscall.SIGTERM)
_ = cmd.Wait()
if err != nil || resp.StatusCode != http.StatusOK {
return false, nil
}
return true, nil
})
}