/proc/self/cwd/test/config/utility.cc
Line | Count | Source (jump to first uncovered line) |
1 | | #include "test/config/utility.h" |
2 | | |
3 | | #include "envoy/config/bootstrap/v3/bootstrap.pb.h" |
4 | | #include "envoy/config/cluster/v3/cluster.pb.h" |
5 | | #include "envoy/config/core/v3/base.pb.h" |
6 | | #include "envoy/config/endpoint/v3/endpoint.pb.h" |
7 | | #include "envoy/config/listener/v3/listener_components.pb.h" |
8 | | #include "envoy/config/route/v3/route_components.pb.h" |
9 | | #include "envoy/extensions/access_loggers/file/v3/file.pb.h" |
10 | | #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" |
11 | | #include "envoy/extensions/transport_sockets/quic/v3/quic_transport.pb.h" |
12 | | #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h" |
13 | | #include "envoy/extensions/transport_sockets/tls/v3/common.pb.h" |
14 | | #include "envoy/http/codec.h" |
15 | | #include "envoy/service/discovery/v3/discovery.pb.h" |
16 | | |
17 | | #include "source/common/common/assert.h" |
18 | | #include "source/common/http/utility.h" |
19 | | #include "source/common/protobuf/utility.h" |
20 | | |
21 | | #include "test/config/integration/certs/client2cert_hash.h" |
22 | | #include "test/config/integration/certs/client_ecdsacert_hash.h" |
23 | | #include "test/config/integration/certs/clientcert_hash.h" |
24 | | #include "test/test_common/environment.h" |
25 | | #include "test/test_common/network_utility.h" |
26 | | #include "test/test_common/resources.h" |
27 | | #include "test/test_common/utility.h" |
28 | | |
29 | | #include "absl/strings/str_replace.h" |
30 | | #include "gtest/gtest.h" |
31 | | |
32 | | namespace Envoy { |
33 | | namespace { |
34 | | envoy::config::bootstrap::v3::Bootstrap& |
35 | 0 | basicBootstrap(envoy::config::bootstrap::v3::Bootstrap& bootstrap, const std::string& config) { |
36 | 0 | #ifdef ENVOY_ENABLE_YAML |
37 | 0 | TestUtility::loadFromYaml(config, bootstrap); |
38 | | #else |
39 | | UNREFERENCED_PARAMETER(config); |
40 | | UNREFERENCED_PARAMETER(bootstrap); |
41 | | PANIC("JSON compiled out: can't load config"); |
42 | | #endif |
43 | 0 | return bootstrap; |
44 | 0 | } |
45 | | } // namespace |
46 | | |
47 | 2.63k | std::string ConfigHelper::baseConfigNoListeners() { |
48 | 2.63k | return fmt::format(R"EOF( |
49 | 2.63k | admin: |
50 | 2.63k | access_log: |
51 | 2.63k | - name: envoy.access_loggers.file |
52 | 2.63k | typed_config: |
53 | 2.63k | "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog |
54 | 2.63k | path: "{}" |
55 | 2.63k | address: |
56 | 2.63k | socket_address: |
57 | 2.63k | address: 127.0.0.1 |
58 | 2.63k | port_value: 0 |
59 | 2.63k | dynamic_resources: |
60 | 2.63k | lds_config: |
61 | 2.63k | resource_api_version: V3 |
62 | 2.63k | path_config_source: |
63 | 2.63k | path: {} |
64 | 2.63k | static_resources: |
65 | 2.63k | secrets: |
66 | 2.63k | - name: "secret_static_0" |
67 | 2.63k | tls_certificate: |
68 | 2.63k | certificate_chain: |
69 | 2.63k | inline_string: "DUMMY_INLINE_BYTES" |
70 | 2.63k | private_key: |
71 | 2.63k | inline_string: "DUMMY_INLINE_BYTES" |
72 | 2.63k | password: |
73 | 2.63k | inline_string: "DUMMY_INLINE_BYTES" |
74 | 2.63k | clusters: |
75 | 2.63k | name: cluster_0 |
76 | 2.63k | load_assignment: |
77 | 2.63k | cluster_name: cluster_0 |
78 | 2.63k | endpoints: |
79 | 2.63k | - lb_endpoints: |
80 | 2.63k | - endpoint: |
81 | 2.63k | address: |
82 | 2.63k | socket_address: |
83 | 2.63k | address: 127.0.0.1 |
84 | 2.63k | port_value: 0 |
85 | 2.63k | )EOF", |
86 | 2.63k | Platform::null_device_path, Platform::null_device_path); |
87 | 2.63k | } |
88 | | |
89 | 2.63k | std::string ConfigHelper::baseConfig(bool multiple_addresses) { |
90 | 2.63k | if (multiple_addresses) { |
91 | 0 | return absl::StrCat(baseConfigNoListeners(), R"EOF( |
92 | 0 | listeners: |
93 | 0 | - name: listener_0 |
94 | 0 | address: |
95 | 0 | socket_address: |
96 | 0 | address: 127.0.0.1 |
97 | 0 | port_value: 0 |
98 | 0 | additional_addresses: |
99 | 0 | - address: |
100 | 0 | socket_address: |
101 | 0 | address: 127.0.0.1 |
102 | 0 | port_value: 0 |
103 | 0 | )EOF"); |
104 | 0 | } |
105 | 2.63k | return absl::StrCat(baseConfigNoListeners(), R"EOF( |
106 | 2.63k | listeners: |
107 | 2.63k | - name: listener_0 |
108 | 2.63k | address: |
109 | 2.63k | socket_address: |
110 | 2.63k | address: 127.0.0.1 |
111 | 2.63k | port_value: 0 |
112 | 2.63k | )EOF"); |
113 | 2.63k | } |
114 | | |
115 | | std::string ConfigHelper::baseUdpListenerConfig(std::string listen_address, |
116 | 0 | bool multiple_addresses) { |
117 | 0 | std::string config = fmt::format(R"EOF( |
118 | 0 | admin: |
119 | 0 | access_log: |
120 | 0 | - name: envoy.access_loggers.file |
121 | 0 | typed_config: |
122 | 0 | "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog |
123 | 0 | path: "{}" |
124 | 0 | address: |
125 | 0 | socket_address: |
126 | 0 | address: 127.0.0.1 |
127 | 0 | port_value: 0 |
128 | 0 | static_resources: |
129 | 0 | clusters: |
130 | 0 | name: cluster_0 |
131 | 0 | load_assignment: |
132 | 0 | cluster_name: cluster_0 |
133 | 0 | endpoints: |
134 | 0 | - lb_endpoints: |
135 | 0 | - endpoint: |
136 | 0 | address: |
137 | 0 | socket_address: |
138 | 0 | address: 127.0.0.1 |
139 | 0 | port_value: 0 |
140 | 0 | )EOF", |
141 | 0 | Platform::null_device_path); |
142 | |
|
143 | 0 | if (multiple_addresses) { |
144 | 0 | return absl::StrCat(config, fmt::format(R"EOF( |
145 | 0 | listeners: |
146 | 0 | name: listener_0 |
147 | 0 | address: |
148 | 0 | socket_address: |
149 | 0 | address: {} |
150 | 0 | port_value: 0 |
151 | 0 | protocol: udp |
152 | 0 | additional_addresses: |
153 | 0 | - address: |
154 | 0 | socket_address: |
155 | 0 | address: {} |
156 | 0 | port_value: 0 |
157 | 0 | protocol: udp |
158 | 0 | )EOF", |
159 | 0 | listen_address, listen_address)); |
160 | 0 | } |
161 | 0 | return absl::StrCat(config, fmt::format(R"EOF( |
162 | 0 | listeners: |
163 | 0 | name: listener_0 |
164 | 0 | address: |
165 | 0 | socket_address: |
166 | 0 | address: {} |
167 | 0 | port_value: 0 |
168 | 0 | protocol: udp |
169 | 0 | )EOF", |
170 | 0 | listen_address)); |
171 | 0 | } |
172 | | |
173 | 0 | std::string ConfigHelper::tcpProxyConfig() { |
174 | 0 | return absl::StrCat(baseConfig(), R"EOF( |
175 | 0 | filter_chains: |
176 | 0 | filters: |
177 | 0 | name: tcp |
178 | 0 | typed_config: |
179 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy |
180 | 0 | stat_prefix: tcpproxy_stats |
181 | 0 | cluster: cluster_0 |
182 | 0 | )EOF"); |
183 | 0 | } |
184 | | |
185 | 0 | std::string ConfigHelper::startTlsConfig() { |
186 | 0 | return absl::StrCat( |
187 | 0 | tcpProxyConfig(), |
188 | 0 | fmt::format(R"EOF( |
189 | 0 | transport_socket: |
190 | 0 | name: "starttls" |
191 | 0 | typed_config: |
192 | 0 | "@type": type.googleapis.com/envoy.extensions.transport_sockets.starttls.v3.StartTlsConfig |
193 | 0 | cleartext_socket_config: |
194 | 0 | tls_socket_config: |
195 | 0 | common_tls_context: |
196 | 0 | tls_certificates: |
197 | 0 | certificate_chain: |
198 | 0 | filename: {} |
199 | 0 | private_key: |
200 | 0 | filename: {} |
201 | 0 | )EOF", |
202 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/servercert.pem"), |
203 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/serverkey.pem"))); |
204 | 0 | } |
205 | | |
206 | 0 | std::string ConfigHelper::testInspectorFilter() { |
207 | 0 | return R"EOF( |
208 | 0 | name: "envoy.filters.listener.test" |
209 | 0 | typed_config: |
210 | 0 | "@type": type.googleapis.com/test.integration.filters.TestInspectorFilterConfig |
211 | 0 | )EOF"; |
212 | 0 | } |
213 | | |
214 | 0 | std::string ConfigHelper::tlsInspectorFilter(bool enable_ja3_fingerprinting) { |
215 | 0 | if (!enable_ja3_fingerprinting) { |
216 | 0 | return R"EOF( |
217 | 0 | name: "envoy.filters.listener.tls_inspector" |
218 | 0 | typed_config: |
219 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector |
220 | 0 | )EOF"; |
221 | 0 | } |
222 | | |
223 | 0 | return R"EOF( |
224 | 0 | name: "envoy.filters.listener.tls_inspector" |
225 | 0 | typed_config: |
226 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector |
227 | 0 | enable_ja3_fingerprinting: true |
228 | 0 | )EOF"; |
229 | 0 | } |
230 | | |
231 | 2.63k | std::string ConfigHelper::httpProxyConfig(bool downstream_use_quic, bool multiple_addresses) { |
232 | 2.63k | if (downstream_use_quic) { |
233 | 0 | return quicHttpProxyConfig(multiple_addresses); |
234 | 0 | } |
235 | 2.63k | return absl::StrCat(baseConfig(multiple_addresses), fmt::format(R"EOF( |
236 | 2.63k | filter_chains: |
237 | 2.63k | filters: |
238 | 2.63k | name: http |
239 | 2.63k | typed_config: |
240 | 2.63k | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager |
241 | 2.63k | stat_prefix: config_test |
242 | 2.63k | delayed_close_timeout: |
243 | 2.63k | nanos: 10000000 |
244 | 2.63k | http_filters: |
245 | 2.63k | - name: envoy.filters.http.router |
246 | 2.63k | typed_config: |
247 | 2.63k | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router |
248 | 2.63k | codec_type: HTTP1 |
249 | 2.63k | access_log: |
250 | 2.63k | name: accesslog |
251 | 2.63k | filter: |
252 | 2.63k | not_health_check_filter: {{}} |
253 | 2.63k | typed_config: |
254 | 2.63k | "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog |
255 | 2.63k | path: {} |
256 | 2.63k | route_config: |
257 | 2.63k | virtual_hosts: |
258 | 2.63k | name: integration |
259 | 2.63k | routes: |
260 | 2.63k | route: |
261 | 2.63k | cluster: cluster_0 |
262 | 2.63k | match: |
263 | 2.63k | prefix: "/" |
264 | 2.63k | domains: "*" |
265 | 2.63k | name: route_config_0 |
266 | 2.63k | )EOF", |
267 | 2.63k | Platform::null_device_path)); |
268 | 2.63k | } |
269 | | |
270 | | // TODO(danzh): For better compatibility with HTTP integration test framework, |
271 | | // it's better to combine with HTTP_PROXY_CONFIG, and use config modifiers to |
272 | | // specify quic specific things. |
273 | 0 | std::string ConfigHelper::quicHttpProxyConfig(bool multiple_addresses) { |
274 | 0 | return absl::StrCat(baseUdpListenerConfig("127.0.0.1", multiple_addresses), |
275 | 0 | fmt::format(R"EOF( |
276 | 0 | filter_chains: |
277 | 0 | transport_socket: |
278 | 0 | name: envoy.transport_sockets.quic |
279 | 0 | typed_config: |
280 | 0 | "@type": type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransport |
281 | 0 | filters: |
282 | 0 | name: http |
283 | 0 | typed_config: |
284 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager |
285 | 0 | stat_prefix: config_test |
286 | 0 | http_filters: |
287 | 0 | - name: envoy.filters.http.router |
288 | 0 | typed_config: |
289 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router |
290 | 0 | codec_type: HTTP3 |
291 | 0 | access_log: |
292 | 0 | name: file_access_log |
293 | 0 | filter: |
294 | 0 | not_health_check_filter: {{}} |
295 | 0 | typed_config: |
296 | 0 | "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog |
297 | 0 | path: {} |
298 | 0 | route_config: |
299 | 0 | virtual_hosts: |
300 | 0 | name: integration |
301 | 0 | routes: |
302 | 0 | route: |
303 | 0 | cluster: cluster_0 |
304 | 0 | match: |
305 | 0 | prefix: "/" |
306 | 0 | domains: "*" |
307 | 0 | name: route_config_0 |
308 | 0 | udp_listener_config: |
309 | 0 | quic_options: {{}} |
310 | 0 | )EOF", |
311 | 0 | Platform::null_device_path)); |
312 | 0 | } |
313 | | |
314 | 0 | std::string ConfigHelper::defaultBufferFilter() { |
315 | 0 | return R"EOF( |
316 | 0 | name: buffer |
317 | 0 | typed_config: |
318 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer |
319 | 0 | max_request_bytes : 5242880 |
320 | 0 | )EOF"; |
321 | 0 | } |
322 | | |
323 | 0 | std::string ConfigHelper::smallBufferFilter() { |
324 | 0 | return R"EOF( |
325 | 0 | name: buffer |
326 | 0 | typed_config: |
327 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer |
328 | 0 | max_request_bytes : 1024 |
329 | 0 | )EOF"; |
330 | 0 | } |
331 | | |
332 | 0 | std::string ConfigHelper::defaultHealthCheckFilter() { |
333 | 0 | return R"EOF( |
334 | 0 | name: health_check |
335 | 0 | typed_config: |
336 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.http.health_check.v3.HealthCheck |
337 | 0 | pass_through_mode: false |
338 | 0 | )EOF"; |
339 | 0 | } |
340 | | |
341 | 0 | std::string ConfigHelper::defaultSquashFilter() { |
342 | 0 | return R"EOF( |
343 | 0 | name: squash |
344 | 0 | typed_config: |
345 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.http.squash.v3.Squash |
346 | 0 | cluster: squash |
347 | 0 | attachment_template: |
348 | 0 | spec: |
349 | 0 | attachment: |
350 | 0 | env: "{{ SQUASH_ENV_TEST }}" |
351 | 0 | match_request: true |
352 | 0 | attachment_timeout: |
353 | 0 | seconds: 1 |
354 | 0 | nanos: 0 |
355 | 0 | attachment_poll_period: |
356 | 0 | seconds: 2 |
357 | 0 | nanos: 0 |
358 | 0 | request_timeout: |
359 | 0 | seconds: 1 |
360 | 0 | nanos: 0 |
361 | 0 | )EOF"; |
362 | 0 | } |
363 | | |
364 | 0 | std::string ConfigHelper::clustersNoListenerBootstrap(const std::string& api_type) { |
365 | 0 | return fmt::format( |
366 | 0 | R"EOF( |
367 | 0 | admin: |
368 | 0 | access_log: |
369 | 0 | - name: envoy.access_loggers.file |
370 | 0 | typed_config: |
371 | 0 | "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog |
372 | 0 | path: "{}" |
373 | 0 | address: |
374 | 0 | socket_address: |
375 | 0 | address: 127.0.0.1 |
376 | 0 | port_value: 0 |
377 | 0 | dynamic_resources: |
378 | 0 | cds_config: |
379 | 0 | resource_api_version: V3 |
380 | 0 | api_config_source: |
381 | 0 | api_type: {} |
382 | 0 | transport_api_version: V3 |
383 | 0 | grpc_services: |
384 | 0 | envoy_grpc: |
385 | 0 | cluster_name: my_cds_cluster |
386 | 0 | set_node_on_first_message_only: true |
387 | 0 | static_resources: |
388 | 0 | clusters: |
389 | 0 | - name: my_cds_cluster |
390 | 0 | typed_extension_protocol_options: |
391 | 0 | envoy.extensions.upstreams.http.v3.HttpProtocolOptions: |
392 | 0 | "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions |
393 | 0 | explicit_http_config: |
394 | 0 | http2_protocol_options: {{}} |
395 | 0 | load_assignment: |
396 | 0 | cluster_name: my_cds_cluster |
397 | 0 | endpoints: |
398 | 0 | - lb_endpoints: |
399 | 0 | - endpoint: |
400 | 0 | address: |
401 | 0 | socket_address: |
402 | 0 | address: 127.0.0.1 |
403 | 0 | port_value: 0 |
404 | 0 | )EOF", |
405 | 0 | Platform::null_device_path, api_type); |
406 | 0 | } |
407 | | |
408 | | // TODO(#6327) cleaner approach to testing with static config. |
409 | 0 | std::string ConfigHelper::discoveredClustersBootstrap(const std::string& api_type) { |
410 | 0 | return absl::StrCat(clustersNoListenerBootstrap(api_type), |
411 | 0 | R"EOF( |
412 | 0 | listeners: |
413 | 0 | name: http |
414 | 0 | address: |
415 | 0 | socket_address: |
416 | 0 | address: 127.0.0.1 |
417 | 0 | port_value: 0 |
418 | 0 | filter_chains: |
419 | 0 | filters: |
420 | 0 | name: http |
421 | 0 | typed_config: |
422 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager |
423 | 0 | stat_prefix: config_test |
424 | 0 | http_filters: |
425 | 0 | - name: envoy.filters.http.router |
426 | 0 | typed_config: |
427 | 0 | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router |
428 | 0 | codec_type: HTTP2 |
429 | 0 | route_config: |
430 | 0 | name: route_config_0 |
431 | 0 | validate_clusters: false |
432 | 0 | virtual_hosts: |
433 | 0 | name: integration |
434 | 0 | routes: |
435 | 0 | - route: |
436 | 0 | cluster: cluster_1 |
437 | 0 | match: |
438 | 0 | prefix: "/cluster1" |
439 | 0 | - route: |
440 | 0 | cluster: cluster_2 |
441 | 0 | match: |
442 | 0 | prefix: "/cluster2" |
443 | 0 | domains: "*" |
444 | 0 | )EOF"); |
445 | 0 | } |
446 | | |
447 | | // TODO(#6327) cleaner approach to testing with static config. |
448 | 14 | std::string ConfigHelper::adsBootstrap(const std::string& api_type) { |
449 | | // We use this to allow tests to default to having a single API version but override and make |
450 | | // the transport/resource API version distinction when needed. |
451 | 14 | return fmt::format(R"EOF( |
452 | 14 | dynamic_resources: |
453 | 14 | lds_config: |
454 | 14 | resource_api_version: V3 |
455 | 14 | ads: {{}} |
456 | 14 | cds_config: |
457 | 14 | resource_api_version: V3 |
458 | 14 | ads: {{}} |
459 | 14 | ads_config: |
460 | 14 | transport_api_version: V3 |
461 | 14 | api_type: {0} |
462 | 14 | set_node_on_first_message_only: true |
463 | 14 | static_resources: |
464 | 14 | clusters: |
465 | 14 | name: dummy_cluster |
466 | 14 | connect_timeout: |
467 | 14 | seconds: 5 |
468 | 14 | type: STATIC |
469 | 14 | load_assignment: |
470 | 14 | cluster_name: dummy_cluster |
471 | 14 | endpoints: |
472 | 14 | - lb_endpoints: |
473 | 14 | - endpoint: |
474 | 14 | address: |
475 | 14 | socket_address: |
476 | 14 | address: 127.0.0.1 |
477 | 14 | port_value: 0 |
478 | 14 | lb_policy: ROUND_ROBIN |
479 | 14 | typed_extension_protocol_options: |
480 | 14 | envoy.extensions.upstreams.http.v3.HttpProtocolOptions: |
481 | 14 | "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions |
482 | 14 | explicit_http_config: |
483 | 14 | http2_protocol_options: {{}} |
484 | 14 | admin: |
485 | 14 | access_log: |
486 | 14 | - name: envoy.access_loggers.file |
487 | 14 | typed_config: |
488 | 14 | "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog |
489 | 14 | path: "{1}" |
490 | 14 | address: |
491 | 14 | socket_address: |
492 | 14 | address: 127.0.0.1 |
493 | 14 | port_value: 0 |
494 | 14 | )EOF", |
495 | 14 | api_type, Platform::null_device_path); |
496 | 14 | } |
497 | | |
498 | | // TODO(samflattery): bundle this up with buildCluster |
499 | | envoy::config::cluster::v3::Cluster |
500 | | ConfigHelper::buildStaticCluster(const std::string& name, int port, const std::string& address, |
501 | 0 | const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy) { |
502 | 0 | envoy::config::cluster::v3::Cluster cluster; |
503 | 0 | cluster.mutable_connect_timeout()->set_seconds(5); |
504 | 0 | cluster.set_type(envoy::config::cluster::v3::Cluster::STATIC); |
505 | 0 | cluster.set_name(name); |
506 | 0 | cluster.mutable_load_assignment()->set_cluster_name(name); |
507 | 0 | auto* endpoint = |
508 | 0 | cluster.mutable_load_assignment()->add_endpoints()->add_lb_endpoints()->mutable_endpoint(); |
509 | 0 | auto* addr = endpoint->mutable_address(); |
510 | 0 | addr->mutable_socket_address()->set_address(address); |
511 | 0 | addr->mutable_socket_address()->set_port_value(port); |
512 | 0 | addr = endpoint->mutable_health_check_config()->mutable_address(); |
513 | 0 | addr->mutable_socket_address()->set_address(address); |
514 | 0 | addr->mutable_socket_address()->set_port_value(port); |
515 | 0 | cluster.set_lb_policy(lb_policy); |
516 | 0 | envoy::extensions::upstreams::http::v3::HttpProtocolOptions protocol_options; |
517 | 0 | protocol_options.mutable_explicit_http_config()->mutable_http2_protocol_options(); |
518 | |
|
519 | 0 | (*cluster.mutable_typed_extension_protocol_options()) |
520 | 0 | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] |
521 | 0 | .PackFrom(protocol_options); |
522 | 0 | return cluster; |
523 | 0 | } |
524 | | |
525 | | envoy::config::cluster::v3::Cluster ConfigHelper::buildH1ClusterWithHighCircuitBreakersLimits( |
526 | | const std::string& name, int port, const std::string& address, |
527 | 0 | const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy) { |
528 | 0 | envoy::config::cluster::v3::Cluster cluster; |
529 | 0 | cluster.set_name(name); |
530 | 0 | cluster.mutable_connect_timeout()->set_seconds(50); |
531 | 0 | cluster.set_type(envoy::config::cluster::v3::Cluster::STATIC); |
532 | 0 | auto* threshold = cluster.mutable_circuit_breakers()->mutable_thresholds()->Add(); |
533 | 0 | threshold->set_priority(envoy::config::core::v3::RoutingPriority::DEFAULT); |
534 | 0 | threshold->mutable_max_connections()->set_value(10000); |
535 | 0 | threshold->mutable_max_pending_requests()->set_value(10000); |
536 | 0 | threshold->mutable_max_requests()->set_value(10000); |
537 | 0 | threshold->mutable_max_retries()->set_value(10000); |
538 | 0 | cluster.mutable_load_assignment()->set_cluster_name(name); |
539 | 0 | auto* endpoint = |
540 | 0 | cluster.mutable_load_assignment()->add_endpoints()->add_lb_endpoints()->mutable_endpoint(); |
541 | 0 | cluster.set_lb_policy(lb_policy); |
542 | 0 | auto* addr = endpoint->mutable_address(); |
543 | 0 | addr->mutable_socket_address()->set_address(address); |
544 | 0 | addr->mutable_socket_address()->set_port_value(port); |
545 | 0 | return cluster; |
546 | 0 | } |
547 | | |
548 | | envoy::config::cluster::v3::Cluster |
549 | | ConfigHelper::buildCluster(const std::string& name, |
550 | 28 | const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy) { |
551 | 28 | envoy::config::cluster::v3::Cluster cluster; |
552 | 28 | cluster.mutable_connect_timeout()->set_seconds(5); |
553 | 28 | cluster.set_type(envoy::config::cluster::v3::Cluster::EDS); |
554 | 28 | cluster.set_name(name); |
555 | 28 | cluster.set_lb_policy(lb_policy); |
556 | | |
557 | 28 | auto* eds = cluster.mutable_eds_cluster_config()->mutable_eds_config(); |
558 | 28 | eds->set_resource_api_version(envoy::config::core::v3::ApiVersion::V3); |
559 | 28 | eds->mutable_ads(); |
560 | | |
561 | 28 | envoy::extensions::upstreams::http::v3::HttpProtocolOptions protocol_options; |
562 | 28 | protocol_options.mutable_explicit_http_config()->mutable_http2_protocol_options(); |
563 | 28 | (*cluster.mutable_typed_extension_protocol_options()) |
564 | 28 | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] |
565 | 28 | .PackFrom(protocol_options); |
566 | | |
567 | 28 | return cluster; |
568 | 28 | } |
569 | | |
570 | | envoy::config::cluster::v3::Cluster |
571 | | ConfigHelper::buildTlsCluster(const std::string& name, |
572 | 0 | const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy) { |
573 | 0 | envoy::config::cluster::v3::Cluster cluster = buildCluster(name, lb_policy); |
574 | |
|
575 | 0 | auto* socket = cluster.mutable_transport_socket(); |
576 | 0 | envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_socket; |
577 | 0 | tls_socket.mutable_common_tls_context() |
578 | 0 | ->mutable_validation_context() |
579 | 0 | ->mutable_trusted_ca() |
580 | 0 | ->set_filename( |
581 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/upstreamcacert.pem")); |
582 | 0 | socket->set_name("envoy.transport_sockets.tls"); |
583 | 0 | socket->mutable_typed_config()->PackFrom(tls_socket); |
584 | 0 | return cluster; |
585 | 0 | } |
586 | | |
587 | | envoy::config::endpoint::v3::ClusterLoadAssignment |
588 | | ConfigHelper::buildClusterLoadAssignment(const std::string& name, const std::string& address_str, |
589 | 28 | uint32_t port) { |
590 | 28 | API_NO_BOOST(envoy::config::endpoint::v3::ClusterLoadAssignment) cluster_load_assignment; |
591 | 28 | cluster_load_assignment.set_cluster_name(name); |
592 | 28 | auto* address = cluster_load_assignment.add_endpoints() |
593 | 28 | ->add_lb_endpoints() |
594 | 28 | ->mutable_endpoint() |
595 | 28 | ->mutable_address() |
596 | 28 | ->mutable_socket_address(); |
597 | 28 | address->set_address(address_str); |
598 | 28 | address->set_port_value(port); |
599 | | |
600 | 28 | return cluster_load_assignment; |
601 | 28 | } |
602 | | |
603 | | envoy::config::endpoint::v3::ClusterLoadAssignment |
604 | | ConfigHelper::buildClusterLoadAssignmentWithLeds(const std::string& name, |
605 | 0 | const std::string& leds_collection_name) { |
606 | 0 | API_NO_BOOST(envoy::config::endpoint::v3::ClusterLoadAssignment) cluster_load_assignment; |
607 | |
|
608 | 0 | cluster_load_assignment.set_cluster_name(name); |
609 | 0 | auto* lclc = cluster_load_assignment.add_endpoints()->mutable_leds_cluster_locality_config(); |
610 | 0 | auto* leds = lclc->mutable_leds_config(); |
611 | 0 | leds->set_resource_api_version(envoy::config::core::v3::ApiVersion::V3); |
612 | 0 | leds->mutable_ads(); |
613 | 0 | lclc->set_leds_collection_name(leds_collection_name); |
614 | 0 | return cluster_load_assignment; |
615 | 0 | } |
616 | | |
617 | | envoy::config::endpoint::v3::LbEndpoint |
618 | 0 | ConfigHelper::buildLbEndpoint(const std::string& address_str, uint32_t port) { |
619 | 0 | API_NO_BOOST(envoy::config::endpoint::v3::LbEndpoint) lb_endpoint; |
620 | 0 | auto* address = lb_endpoint.mutable_endpoint()->mutable_address()->mutable_socket_address(); |
621 | 0 | address->set_address(address_str); |
622 | 0 | address->set_port_value(port); |
623 | 0 | return lb_endpoint; |
624 | 0 | } |
625 | | |
626 | | envoy::config::listener::v3::Listener |
627 | | ConfigHelper::buildBaseListener(const std::string& name, const std::string& address, |
628 | 90 | const std::string& filter_chains) { |
629 | 90 | API_NO_BOOST(envoy::config::listener::v3::Listener) listener; |
630 | 90 | #ifdef ENVOY_ENABLE_YAML |
631 | 90 | TestUtility::loadFromYaml(fmt::format( |
632 | 90 | R"EOF( |
633 | 90 | name: {} |
634 | 90 | address: |
635 | 90 | socket_address: |
636 | 90 | address: {} |
637 | 90 | port_value: 0 |
638 | 90 | filter_chains: |
639 | 90 | {} |
640 | 90 | )EOF", |
641 | 90 | name, address, filter_chains), |
642 | 90 | listener); |
643 | 90 | return listener; |
644 | | #else |
645 | | UNREFERENCED_PARAMETER(name); |
646 | | UNREFERENCED_PARAMETER(address); |
647 | | UNREFERENCED_PARAMETER(filter_chains); |
648 | | PANIC("YAML support compiled out"); |
649 | | #endif |
650 | 90 | } |
651 | | |
652 | | envoy::config::listener::v3::Listener ConfigHelper::buildListener(const std::string& name, |
653 | | const std::string& route_config, |
654 | | const std::string& address, |
655 | 90 | const std::string& stat_prefix) { |
656 | 90 | std::string hcm = fmt::format( |
657 | 90 | R"EOF( |
658 | 90 | filters: |
659 | 90 | - name: http |
660 | 90 | typed_config: |
661 | 90 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager |
662 | 90 | stat_prefix: {} |
663 | 90 | codec_type: HTTP2 |
664 | 90 | rds: |
665 | 90 | route_config_name: {} |
666 | 90 | config_source: |
667 | 90 | resource_api_version: V3 |
668 | 90 | ads: {{}} |
669 | 90 | http_filters: |
670 | 90 | - name: envoy.filters.http.router |
671 | 90 | typed_config: |
672 | 90 | "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router |
673 | 90 | )EOF", |
674 | 90 | stat_prefix, route_config); |
675 | 90 | return buildBaseListener(name, address, hcm); |
676 | 90 | } |
677 | | |
678 | | envoy::config::route::v3::RouteConfiguration |
679 | 46 | ConfigHelper::buildRouteConfig(const std::string& name, const std::string& cluster) { |
680 | 46 | API_NO_BOOST(envoy::config::route::v3::RouteConfiguration) route; |
681 | 46 | #ifdef ENVOY_ENABLE_YAML |
682 | 46 | TestUtility::loadFromYaml(fmt::format(R"EOF( |
683 | 46 | name: "{}" |
684 | 46 | virtual_hosts: |
685 | 46 | - name: integration |
686 | 46 | domains: ["*"] |
687 | 46 | routes: |
688 | 46 | - match: {{ prefix: "/" }} |
689 | 46 | route: {{ cluster: "{}" }} |
690 | 46 | )EOF", |
691 | 46 | name, cluster), |
692 | 46 | route); |
693 | 46 | return route; |
694 | | #else |
695 | | UNREFERENCED_PARAMETER(name); |
696 | | UNREFERENCED_PARAMETER(cluster); |
697 | | PANIC("YAML support compiled out"); |
698 | | #endif |
699 | 46 | } |
700 | | |
701 | 0 | envoy::config::endpoint::v3::Endpoint ConfigHelper::buildEndpoint(const std::string& address) { |
702 | 0 | envoy::config::endpoint::v3::Endpoint endpoint; |
703 | 0 | endpoint.mutable_address()->mutable_socket_address()->set_address(address); |
704 | 0 | return endpoint; |
705 | 0 | } |
706 | | |
707 | | ConfigHelper::ConfigHelper(const Network::Address::IpVersion version, Api::Api&, |
708 | | const std::string& config) |
709 | 0 | : ConfigHelper(version, basicBootstrap(bootstrap_, config)) {} |
710 | | |
711 | | ConfigHelper::ConfigHelper(const Network::Address::IpVersion version, |
712 | 2.64k | const envoy::config::bootstrap::v3::Bootstrap& bootstrap) { |
713 | 2.64k | RELEASE_ASSERT(!finalized_, ""); |
714 | 2.64k | bootstrap_ = bootstrap; |
715 | | |
716 | | // Fix up all the socket addresses with the correct version. |
717 | 2.64k | auto* admin = bootstrap_.mutable_admin(); |
718 | 2.64k | auto* admin_socket_addr = admin->mutable_address()->mutable_socket_address(); |
719 | 2.64k | admin_socket_addr->set_address(Network::Test::getLoopbackAddressString(version)); |
720 | | |
721 | 2.64k | auto* static_resources = bootstrap_.mutable_static_resources(); |
722 | 5.28k | for (int i = 0; i < static_resources->listeners_size(); ++i) { |
723 | 2.63k | auto* listener = static_resources->mutable_listeners(i); |
724 | 2.63k | if (listener->mutable_address()->has_envoy_internal_address()) { |
725 | 0 | ENVOY_LOG_MISC( |
726 | 0 | debug, "Listener {} has internal address {}. Will not reset to loop back socket address.", |
727 | 0 | i, listener->mutable_address()->envoy_internal_address().server_listener_name()); |
728 | 0 | continue; |
729 | 0 | } |
730 | 2.63k | if (listener->mutable_address()->has_pipe()) { |
731 | 0 | ENVOY_LOG_MISC(debug, |
732 | 0 | "Listener {} has pipe address {}. Will not reset to loop back socket address.", |
733 | 0 | i, listener->mutable_address()->pipe().path()); |
734 | 0 | continue; |
735 | 0 | } |
736 | 2.63k | auto* listener_socket_addr = listener->mutable_address()->mutable_socket_address(); |
737 | 2.63k | if (listener_socket_addr->address() == "0.0.0.0" || listener_socket_addr->address() == "::") { |
738 | 0 | listener_socket_addr->set_address(Network::Test::getAnyAddressString(version)); |
739 | 2.63k | } else { |
740 | 2.63k | listener_socket_addr->set_address(Network::Test::getLoopbackAddressString(version)); |
741 | 2.63k | } |
742 | | |
743 | 2.63k | for (int i = 0; i < listener->additional_addresses_size(); i++) { |
744 | 0 | auto* listener_socket_addr = |
745 | 0 | listener->mutable_additional_addresses(i)->mutable_address()->mutable_socket_address(); |
746 | 0 | if (listener_socket_addr->address() == "0.0.0.0" || listener_socket_addr->address() == "::") { |
747 | 0 | listener_socket_addr->set_address(Network::Test::getAnyAddressString(version)); |
748 | 0 | } else { |
749 | 0 | listener_socket_addr->set_address(Network::Test::getLoopbackAddressString(version)); |
750 | 0 | } |
751 | 0 | } |
752 | 2.63k | } |
753 | | |
754 | 5.29k | for (int i = 0; i < static_resources->clusters_size(); ++i) { |
755 | 2.64k | auto* cluster = static_resources->mutable_clusters(i); |
756 | 5.29k | for (int j = 0; j < cluster->load_assignment().endpoints_size(); ++j) { |
757 | 2.64k | auto* locality_lb = cluster->mutable_load_assignment()->mutable_endpoints(j); |
758 | 5.29k | for (int k = 0; k < locality_lb->lb_endpoints_size(); ++k) { |
759 | 2.64k | auto* lb_endpoint = locality_lb->mutable_lb_endpoints(k); |
760 | 2.64k | if (lb_endpoint->endpoint().address().has_socket_address()) { |
761 | 2.64k | lb_endpoint->mutable_endpoint()->mutable_address()->mutable_socket_address()->set_address( |
762 | 2.64k | Network::Test::getLoopbackAddressString(version)); |
763 | 2.64k | } |
764 | 2.64k | } |
765 | 2.64k | } |
766 | 2.64k | } |
767 | | |
768 | | // Ensure we have a basic admin-capable runtime layer. |
769 | 2.64k | if (bootstrap_.mutable_layered_runtime()->layers_size() == 0) { |
770 | 2.64k | auto* static_layer = bootstrap_.mutable_layered_runtime()->add_layers(); |
771 | 2.64k | static_layer->set_name("static_layer"); |
772 | 2.64k | static_layer->mutable_static_layer(); |
773 | 2.64k | auto* admin_layer = bootstrap_.mutable_layered_runtime()->add_layers(); |
774 | 2.64k | admin_layer->set_name("admin"); |
775 | 2.64k | admin_layer->mutable_admin_layer(); |
776 | 2.64k | } |
777 | 2.64k | } |
778 | | |
779 | 0 | void ConfigHelper::addListenerTypedMetadata(absl::string_view key, ProtobufWkt::Any& packed_value) { |
780 | 0 | RELEASE_ASSERT(!finalized_, ""); |
781 | 0 | auto* static_resources = bootstrap_.mutable_static_resources(); |
782 | 0 | ASSERT_TRUE(static_resources->listeners_size() > 0); |
783 | 0 | auto* listener = static_resources->mutable_listeners(0); |
784 | 0 | auto* map = listener->mutable_metadata()->mutable_typed_filter_metadata(); |
785 | 0 | (*map)[std::string(key)] = packed_value; |
786 | 0 | }; |
787 | | |
788 | | void ConfigHelper::addClusterFilterMetadata(absl::string_view metadata_yaml, |
789 | 0 | absl::string_view cluster_name) { |
790 | 0 | #ifdef ENVOY_ENABLE_YAML |
791 | 0 | RELEASE_ASSERT(!finalized_, ""); |
792 | 0 | ProtobufWkt::Struct cluster_metadata; |
793 | 0 | TestUtility::loadFromYaml(std::string(metadata_yaml), cluster_metadata); |
794 | |
|
795 | 0 | auto* static_resources = bootstrap_.mutable_static_resources(); |
796 | 0 | for (int i = 0; i < static_resources->clusters_size(); ++i) { |
797 | 0 | auto* cluster = static_resources->mutable_clusters(i); |
798 | 0 | if (cluster->name() != cluster_name) { |
799 | 0 | continue; |
800 | 0 | } |
801 | 0 | for (const auto& kvp : cluster_metadata.fields()) { |
802 | 0 | ASSERT_TRUE(kvp.second.kind_case() == ProtobufWkt::Value::KindCase::kStructValue); |
803 | 0 | cluster->mutable_metadata()->mutable_filter_metadata()->insert( |
804 | 0 | {kvp.first, kvp.second.struct_value()}); |
805 | 0 | } |
806 | 0 | break; |
807 | 0 | } |
808 | | #else |
809 | | UNREFERENCED_PARAMETER(metadata_yaml); |
810 | | UNREFERENCED_PARAMETER(cluster_name); |
811 | | PANIC("YAML support compiled out"); |
812 | | #endif |
813 | 0 | } |
814 | | |
815 | | void ConfigHelper::setConnectConfig( |
816 | | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm, |
817 | | bool terminate_connect, bool allow_post, bool http3, |
818 | 0 | absl::optional<envoy::config::core::v3::ProxyProtocolConfig::Version> proxy_protocol_version) { |
819 | 0 | auto* route_config = hcm.mutable_route_config(); |
820 | 0 | ASSERT_EQ(1, route_config->virtual_hosts_size()); |
821 | 0 | auto* route = route_config->mutable_virtual_hosts(0)->mutable_routes(0); |
822 | 0 | auto* match = route->mutable_match(); |
823 | 0 | match->Clear(); |
824 | |
|
825 | 0 | if (allow_post) { |
826 | 0 | match->set_prefix("/"); |
827 | |
|
828 | 0 | auto* header = match->add_headers(); |
829 | 0 | header->set_name(":method"); |
830 | 0 | header->mutable_string_match()->set_exact("POST"); |
831 | 0 | } else { |
832 | 0 | match->mutable_connect_matcher(); |
833 | 0 | } |
834 | |
|
835 | 0 | if (terminate_connect) { |
836 | 0 | auto* upgrade = route->mutable_route()->add_upgrade_configs(); |
837 | 0 | upgrade->set_upgrade_type("CONNECT"); |
838 | 0 | auto* config = upgrade->mutable_connect_config(); |
839 | 0 | if (allow_post) { |
840 | 0 | config->set_allow_post(true); |
841 | 0 | } |
842 | |
|
843 | 0 | if (proxy_protocol_version.has_value()) { |
844 | 0 | config->mutable_proxy_protocol_config()->set_version(proxy_protocol_version.value()); |
845 | 0 | } |
846 | 0 | } |
847 | |
|
848 | 0 | hcm.add_upgrade_configs()->set_upgrade_type("CONNECT"); |
849 | 0 | hcm.mutable_http2_protocol_options()->set_allow_connect(true); |
850 | 0 | if (http3) { |
851 | 0 | hcm.mutable_http3_protocol_options()->set_allow_extended_connect(true); |
852 | 0 | } |
853 | 0 | } |
854 | | |
855 | | void ConfigHelper::setConnectUdpConfig( |
856 | | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm, |
857 | 0 | bool terminate_connect, bool http3) { |
858 | 0 | auto* route_config = hcm.mutable_route_config(); |
859 | 0 | ASSERT_EQ(1, route_config->virtual_hosts_size()); |
860 | 0 | auto* route = route_config->mutable_virtual_hosts(0)->mutable_routes(0); |
861 | 0 | auto* match = route->mutable_match(); |
862 | 0 | match->Clear(); |
863 | 0 | match->mutable_connect_matcher(); |
864 | |
|
865 | 0 | if (terminate_connect) { |
866 | 0 | auto* upgrade = route->mutable_route()->add_upgrade_configs(); |
867 | 0 | upgrade->set_upgrade_type("connect-udp"); |
868 | 0 | } |
869 | |
|
870 | 0 | hcm.add_upgrade_configs()->set_upgrade_type("connect-udp"); |
871 | 0 | hcm.mutable_http2_protocol_options()->set_allow_connect(true); |
872 | 0 | if (http3) { |
873 | 0 | hcm.mutable_http3_protocol_options()->set_allow_extended_connect(true); |
874 | 0 | } |
875 | 0 | } |
876 | | |
877 | 2.64k | void ConfigHelper::applyConfigModifiers() { |
878 | 6.92k | for (const auto& config_modifier : config_modifiers_) { |
879 | 6.92k | config_modifier(bootstrap_); |
880 | 6.92k | } |
881 | 2.64k | config_modifiers_.clear(); |
882 | 2.64k | } |
883 | | |
884 | | void ConfigHelper::configureUpstreamTls( |
885 | | bool use_alpn, bool http3, |
886 | | absl::optional<envoy::config::core::v3::AlternateProtocolsCacheOptions> |
887 | | alternate_protocol_cache_config, |
888 | | std::function<void(envoy::extensions::transport_sockets::tls::v3::CommonTlsContext&)> |
889 | 0 | configure_tls_context) { |
890 | 0 | addConfigModifier([use_alpn, http3, alternate_protocol_cache_config, |
891 | 0 | configure_tls_context](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { |
892 | 0 | auto* cluster = bootstrap.mutable_static_resources()->mutable_clusters(0); |
893 | |
|
894 | 0 | ConfigHelper::HttpProtocolOptions protocol_options; |
895 | 0 | protocol_options.mutable_upstream_http_protocol_options()->set_auto_sni(true); |
896 | 0 | ConfigHelper::setProtocolOptions(*cluster, protocol_options); |
897 | |
|
898 | 0 | if (use_alpn) { |
899 | 0 | ConfigHelper::HttpProtocolOptions new_protocol_options; |
900 | |
|
901 | 0 | HttpProtocolOptions old_protocol_options = |
902 | 0 | MessageUtil::anyConvert<ConfigHelper::HttpProtocolOptions>( |
903 | 0 | (*cluster->mutable_typed_extension_protocol_options()) |
904 | 0 | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"]); |
905 | 0 | protocol_options.MergeFrom(old_protocol_options); |
906 | |
|
907 | 0 | new_protocol_options = old_protocol_options; |
908 | 0 | new_protocol_options.clear_explicit_http_config(); |
909 | 0 | new_protocol_options.mutable_auto_config(); |
910 | 0 | if (old_protocol_options.explicit_http_config().has_http_protocol_options()) { |
911 | 0 | new_protocol_options.mutable_auto_config()->mutable_http_protocol_options()->MergeFrom( |
912 | 0 | old_protocol_options.explicit_http_config().http_protocol_options()); |
913 | 0 | } else if (old_protocol_options.explicit_http_config().has_http2_protocol_options()) { |
914 | 0 | new_protocol_options.mutable_auto_config()->mutable_http2_protocol_options()->MergeFrom( |
915 | 0 | old_protocol_options.explicit_http_config().http2_protocol_options()); |
916 | 0 | } |
917 | 0 | if (http3 || old_protocol_options.explicit_http_config().has_http3_protocol_options()) { |
918 | 0 | new_protocol_options.mutable_auto_config()->mutable_http3_protocol_options()->MergeFrom( |
919 | 0 | old_protocol_options.explicit_http_config().http3_protocol_options()); |
920 | 0 | } |
921 | 0 | if (alternate_protocol_cache_config.has_value()) { |
922 | 0 | new_protocol_options.mutable_auto_config() |
923 | 0 | ->mutable_alternate_protocols_cache_options() |
924 | 0 | ->set_name("default_alternate_protocols_cache"); |
925 | 0 | new_protocol_options.mutable_auto_config() |
926 | 0 | ->mutable_alternate_protocols_cache_options() |
927 | 0 | ->CopyFrom(alternate_protocol_cache_config.value()); |
928 | 0 | } |
929 | 0 | (*cluster->mutable_typed_extension_protocol_options()) |
930 | 0 | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] |
931 | 0 | .PackFrom(new_protocol_options); |
932 | 0 | } |
933 | 0 | envoy::extensions::transport_sockets::tls::v3::UpstreamTlsContext tls_context; |
934 | 0 | if (configure_tls_context != nullptr) { |
935 | 0 | configure_tls_context(*tls_context.mutable_common_tls_context()); |
936 | 0 | } |
937 | 0 | auto* validation_context = |
938 | 0 | tls_context.mutable_common_tls_context()->mutable_validation_context(); |
939 | 0 | validation_context->mutable_trusted_ca()->set_filename( |
940 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/upstreamcacert.pem")); |
941 | | // The test certs are for *.lyft.com, so make sure SNI matches. |
942 | 0 | tls_context.set_sni("foo.lyft.com"); |
943 | 0 | if (http3) { |
944 | 0 | envoy::extensions::transport_sockets::quic::v3::QuicUpstreamTransport quic_context; |
945 | 0 | quic_context.mutable_upstream_tls_context()->CopyFrom(tls_context); |
946 | 0 | cluster->mutable_transport_socket()->set_name("envoy.transport_sockets.quic"); |
947 | 0 | cluster->mutable_transport_socket()->mutable_typed_config()->PackFrom(quic_context); |
948 | 0 | } else { |
949 | 0 | cluster->mutable_transport_socket()->set_name("envoy.transport_sockets.tls"); |
950 | 0 | cluster->mutable_transport_socket()->mutable_typed_config()->PackFrom(tls_context); |
951 | 0 | } |
952 | 0 | }); |
953 | 0 | } |
954 | | |
955 | 2.66k | void ConfigHelper::addRuntimeOverride(absl::string_view key, absl::string_view value) { |
956 | 2.66k | auto* static_layer = |
957 | 2.66k | bootstrap_.mutable_layered_runtime()->mutable_layers(0)->mutable_static_layer(); |
958 | | |
959 | 2.66k | if (value == "true") { |
960 | 7 | (*static_layer->mutable_fields())[std::string(key)] = ValueUtil::boolValue(true); |
961 | 2.65k | } else if (value == "false") { |
962 | 2.65k | (*static_layer->mutable_fields())[std::string(key)] = ValueUtil::boolValue(false); |
963 | 2.65k | } else { |
964 | 0 | (*static_layer->mutable_fields())[std::string(key)] = |
965 | 0 | ValueUtil::stringValue(std::string(value)); |
966 | 0 | } |
967 | 2.66k | } |
968 | | |
969 | | void ConfigHelper::setProtocolOptions(envoy::config::cluster::v3::Cluster& cluster, |
970 | 3.33k | HttpProtocolOptions& protocol_options) { |
971 | 3.33k | if (cluster.typed_extension_protocol_options().contains( |
972 | 3.33k | "envoy.extensions.upstreams.http.v3.HttpProtocolOptions")) { |
973 | 1.13k | HttpProtocolOptions old_options = MessageUtil::anyConvert<ConfigHelper::HttpProtocolOptions>( |
974 | 1.13k | (*cluster.mutable_typed_extension_protocol_options()) |
975 | 1.13k | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"]); |
976 | 1.13k | bool auto_config = old_options.has_auto_config(); |
977 | 1.13k | old_options.MergeFrom(protocol_options); |
978 | 1.13k | protocol_options.CopyFrom(old_options); |
979 | 1.13k | if (auto_config) { |
980 | 0 | protocol_options.mutable_auto_config(); |
981 | 0 | } |
982 | 1.13k | } |
983 | 3.33k | (*cluster.mutable_typed_extension_protocol_options()) |
984 | 3.33k | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] |
985 | 3.33k | .PackFrom(protocol_options); |
986 | 3.33k | } |
987 | | |
988 | 1.18k | void ConfigHelper::setHttp2(envoy::config::cluster::v3::Cluster& cluster) { |
989 | 1.18k | HttpProtocolOptions protocol_options; |
990 | 1.18k | protocol_options.mutable_explicit_http_config()->mutable_http2_protocol_options(); |
991 | 1.18k | setProtocolOptions(cluster, protocol_options); |
992 | 1.18k | } |
993 | | |
994 | 2.64k | void ConfigHelper::finalize(const std::vector<uint32_t>& ports) { |
995 | 2.64k | RELEASE_ASSERT(!finalized_, ""); |
996 | | |
997 | 2.64k | applyConfigModifiers(); |
998 | | |
999 | 2.64k | setPorts(ports); |
1000 | | |
1001 | 2.64k | if (!connect_timeout_set_) { |
1002 | | #ifdef __APPLE__ |
1003 | | // Set a high default connect timeout. Under heavy load (and in particular in CI), macOS |
1004 | | // connections can take inordinately long to complete. |
1005 | | setConnectTimeout(std::chrono::seconds(30)); |
1006 | | #else |
1007 | | // Set a default connect timeout. |
1008 | 2.64k | setConnectTimeout(std::chrono::seconds(5)); |
1009 | 2.64k | #endif |
1010 | 2.64k | } |
1011 | | |
1012 | 2.64k | finalized_ = true; |
1013 | 2.64k | } |
1014 | | |
1015 | 2.64k | void ConfigHelper::setPorts(const std::vector<uint32_t>& ports, bool override_port_zero) { |
1016 | 2.64k | uint32_t port_idx = 0; |
1017 | 2.64k | bool eds_hosts = false; |
1018 | 2.64k | bool custom_cluster = false; |
1019 | 2.64k | bool original_dst_cluster = false; |
1020 | 2.64k | auto* static_resources = bootstrap_.mutable_static_resources(); |
1021 | 5.90k | for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) { |
1022 | 3.25k | auto* cluster = static_resources->mutable_clusters(i); |
1023 | 3.25k | if (cluster->type() == envoy::config::cluster::v3::Cluster::EDS) { |
1024 | 0 | eds_hosts = true; |
1025 | 3.25k | } else if (cluster->type() == envoy::config::cluster::v3::Cluster::ORIGINAL_DST) { |
1026 | 0 | original_dst_cluster = true; |
1027 | 3.25k | } else if (cluster->has_cluster_type()) { |
1028 | 0 | custom_cluster = true; |
1029 | 3.25k | } else { |
1030 | | // Assign ports to statically defined load_assignment hosts. |
1031 | 6.50k | for (int j = 0; j < cluster->load_assignment().endpoints_size(); ++j) { |
1032 | 3.25k | auto locality_lb = cluster->mutable_load_assignment()->mutable_endpoints(j); |
1033 | 6.50k | for (int k = 0; k < locality_lb->lb_endpoints_size(); ++k) { |
1034 | 3.25k | auto lb_endpoint = locality_lb->mutable_lb_endpoints(k); |
1035 | 3.25k | if (lb_endpoint->endpoint().address().has_socket_address()) { |
1036 | 3.25k | if (lb_endpoint->endpoint().address().socket_address().port_value() == 0 || |
1037 | 3.25k | override_port_zero) { |
1038 | 2.66k | RELEASE_ASSERT(ports.size() > port_idx, ""); |
1039 | 2.66k | lb_endpoint->mutable_endpoint() |
1040 | 2.66k | ->mutable_address() |
1041 | 2.66k | ->mutable_socket_address() |
1042 | 2.66k | ->set_port_value(ports[port_idx++]); |
1043 | 2.66k | } else { |
1044 | 591 | ENVOY_LOG_MISC(debug, "Not overriding preset port", |
1045 | 591 | lb_endpoint->endpoint().address().socket_address().port_value()); |
1046 | 591 | } |
1047 | 3.25k | } |
1048 | 3.25k | } |
1049 | 3.25k | } |
1050 | 3.25k | } |
1051 | 3.25k | } |
1052 | 2.64k | ASSERT(skip_port_usage_validation_ || port_idx == ports.size() || eds_hosts || |
1053 | 2.64k | original_dst_cluster || custom_cluster || bootstrap_.dynamic_resources().has_cds_config()); |
1054 | 2.64k | } |
1055 | | |
1056 | 0 | void ConfigHelper::setSourceAddress(const std::string& address_string) { |
1057 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1058 | 0 | bootstrap_.mutable_cluster_manager() |
1059 | 0 | ->mutable_upstream_bind_config() |
1060 | 0 | ->mutable_source_address() |
1061 | 0 | ->set_address(address_string); |
1062 | | // We don't have the ability to bind to specific ports yet. |
1063 | 0 | bootstrap_.mutable_cluster_manager() |
1064 | 0 | ->mutable_upstream_bind_config() |
1065 | 0 | ->mutable_source_address() |
1066 | 0 | ->set_port_value(0); |
1067 | 0 | } |
1068 | | |
1069 | 0 | void ConfigHelper::setDefaultHostAndRoute(const std::string& domains, const std::string& prefix) { |
1070 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1071 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1072 | 0 | hcm_config; |
1073 | 0 | loadHttpConnectionManager(hcm_config); |
1074 | |
|
1075 | 0 | auto* virtual_host = hcm_config.mutable_route_config()->mutable_virtual_hosts(0); |
1076 | 0 | virtual_host->set_domains(0, domains); |
1077 | 0 | virtual_host->mutable_routes(0)->mutable_match()->set_prefix(prefix); |
1078 | |
|
1079 | 0 | storeHttpConnectionManager(hcm_config); |
1080 | 0 | } |
1081 | | |
1082 | | void ConfigHelper::setBufferLimits(uint32_t upstream_buffer_limit, |
1083 | 591 | uint32_t downstream_buffer_limit) { |
1084 | 591 | RELEASE_ASSERT(!finalized_, ""); |
1085 | 591 | auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0); |
1086 | 591 | listener->mutable_per_connection_buffer_limit_bytes()->set_value(downstream_buffer_limit); |
1087 | 591 | const uint32_t stream_buffer_size = std::max( |
1088 | 591 | downstream_buffer_limit, Http2::Utility::OptionsLimits::MIN_INITIAL_STREAM_WINDOW_SIZE); |
1089 | 591 | if (Network::Utility::protobufAddressSocketType(listener->address()) == |
1090 | 591 | Network::Socket::Type::Datagram && |
1091 | 591 | listener->udp_listener_config().has_quic_options()) { |
1092 | | // QUIC stream's flow control window is configured in listener config. |
1093 | 0 | listener->mutable_udp_listener_config() |
1094 | 0 | ->mutable_quic_options() |
1095 | 0 | ->mutable_quic_protocol_options() |
1096 | 0 | ->mutable_initial_stream_window_size() |
1097 | | // The same as kStreamReceiveWindowLimit in QUICHE which only supports stream flow control |
1098 | | // window no larger than 16MB. |
1099 | 0 | ->set_value(std::min(16u * 1024 * 1024, stream_buffer_size)); |
1100 | 0 | } |
1101 | | |
1102 | 591 | auto* static_resources = bootstrap_.mutable_static_resources(); |
1103 | 1.18k | for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) { |
1104 | 591 | auto* cluster = static_resources->mutable_clusters(i); |
1105 | 591 | cluster->mutable_per_connection_buffer_limit_bytes()->set_value(upstream_buffer_limit); |
1106 | 591 | } |
1107 | | |
1108 | 591 | auto filter = getFilterFromListener("http"); |
1109 | 591 | if (filter) { |
1110 | 591 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1111 | 591 | hcm_config; |
1112 | 591 | loadHttpConnectionManager(hcm_config); |
1113 | 591 | if (hcm_config.codec_type() == envoy::extensions::filters::network::http_connection_manager:: |
1114 | 591 | v3::HttpConnectionManager::HTTP2) { |
1115 | 591 | auto* options = hcm_config.mutable_http2_protocol_options(); |
1116 | 591 | options->mutable_initial_stream_window_size()->set_value(stream_buffer_size); |
1117 | 591 | storeHttpConnectionManager(hcm_config); |
1118 | 591 | } |
1119 | 591 | } |
1120 | 591 | } |
1121 | | |
1122 | 0 | void ConfigHelper::setListenerSendBufLimits(uint32_t limit) { |
1123 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1124 | 0 | RELEASE_ASSERT(bootstrap_.mutable_static_resources()->listeners_size() == 1, ""); |
1125 | 0 | auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0); |
1126 | 0 | auto* options = listener->add_socket_options(); |
1127 | 0 | options->set_description("SO_SNDBUF"); |
1128 | 0 | options->set_level(SOL_SOCKET); |
1129 | 0 | options->set_int_value(limit); |
1130 | 0 | options->set_name(SO_SNDBUF); |
1131 | 0 | } |
1132 | | |
1133 | 0 | void ConfigHelper::setDownstreamHttpIdleTimeout(std::chrono::milliseconds timeout) { |
1134 | 0 | addConfigModifier( |
1135 | 0 | [timeout]( |
1136 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& |
1137 | 0 | hcm) { |
1138 | 0 | hcm.mutable_common_http_protocol_options()->mutable_idle_timeout()->MergeFrom( |
1139 | 0 | ProtobufUtil::TimeUtil::MillisecondsToDuration(timeout.count())); |
1140 | 0 | }); |
1141 | 0 | } |
1142 | | |
1143 | 0 | void ConfigHelper::setDownstreamMaxConnectionDuration(std::chrono::milliseconds timeout) { |
1144 | 0 | addConfigModifier( |
1145 | 0 | [timeout]( |
1146 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& |
1147 | 0 | hcm) { |
1148 | 0 | hcm.mutable_common_http_protocol_options()->mutable_max_connection_duration()->MergeFrom( |
1149 | 0 | ProtobufUtil::TimeUtil::MillisecondsToDuration(timeout.count())); |
1150 | 0 | }); |
1151 | 0 | } |
1152 | | |
1153 | 0 | void ConfigHelper::setDownstreamMaxStreamDuration(std::chrono::milliseconds timeout) { |
1154 | 0 | addConfigModifier( |
1155 | 0 | [timeout]( |
1156 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& |
1157 | 0 | hcm) { |
1158 | 0 | hcm.mutable_common_http_protocol_options()->mutable_max_stream_duration()->MergeFrom( |
1159 | 0 | ProtobufUtil::TimeUtil::MillisecondsToDuration(timeout.count())); |
1160 | 0 | }); |
1161 | 0 | } |
1162 | | |
1163 | 2.64k | void ConfigHelper::setConnectTimeout(std::chrono::milliseconds timeout) { |
1164 | 2.64k | RELEASE_ASSERT(!finalized_, ""); |
1165 | | |
1166 | 2.64k | auto* static_resources = bootstrap_.mutable_static_resources(); |
1167 | 5.90k | for (int i = 0; i < bootstrap_.mutable_static_resources()->clusters_size(); ++i) { |
1168 | 3.25k | auto* cluster = static_resources->mutable_clusters(i); |
1169 | 3.25k | cluster->mutable_connect_timeout()->MergeFrom( |
1170 | 3.25k | ProtobufUtil::TimeUtil::MillisecondsToDuration(timeout.count())); |
1171 | 3.25k | } |
1172 | 2.64k | connect_timeout_set_ = true; |
1173 | 2.64k | } |
1174 | | |
1175 | 0 | void ConfigHelper::disableDelayClose() { |
1176 | 0 | addConfigModifier( |
1177 | 0 | [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& |
1178 | 0 | hcm) { hcm.mutable_delayed_close_timeout()->set_nanos(0); }); |
1179 | 0 | } |
1180 | | |
1181 | 0 | void ConfigHelper::setDownstreamMaxRequestsPerConnection(uint64_t max_requests_per_connection) { |
1182 | 0 | addConfigModifier( |
1183 | 0 | [max_requests_per_connection]( |
1184 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& |
1185 | 0 | hcm) { |
1186 | 0 | hcm.mutable_common_http_protocol_options() |
1187 | 0 | ->mutable_max_requests_per_connection() |
1188 | 0 | ->set_value(max_requests_per_connection); |
1189 | 0 | }); |
1190 | 0 | } |
1191 | | |
1192 | | envoy::config::route::v3::VirtualHost |
1193 | 0 | ConfigHelper::createVirtualHost(const char* domain, const char* prefix, const char* cluster) { |
1194 | 0 | envoy::config::route::v3::VirtualHost virtual_host; |
1195 | 0 | virtual_host.set_name(domain); |
1196 | 0 | virtual_host.add_domains(domain); |
1197 | 0 | virtual_host.add_routes()->mutable_match()->set_prefix(prefix); |
1198 | 0 | auto* route = virtual_host.mutable_routes(0)->mutable_route(); |
1199 | 0 | route->set_cluster(cluster); |
1200 | 0 | return virtual_host; |
1201 | 0 | } |
1202 | | |
1203 | 0 | void ConfigHelper::addVirtualHost(const envoy::config::route::v3::VirtualHost& vhost) { |
1204 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1205 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1206 | 0 | hcm_config; |
1207 | 0 | loadHttpConnectionManager(hcm_config); |
1208 | 0 | auto route_config = hcm_config.mutable_route_config(); |
1209 | 0 | auto* virtual_host = route_config->add_virtual_hosts(); |
1210 | 0 | virtual_host->CopyFrom(vhost); |
1211 | 0 | storeHttpConnectionManager(hcm_config); |
1212 | 0 | } |
1213 | | |
1214 | 0 | void ConfigHelper::addFilter(const std::string& config) { prependFilter(config); } |
1215 | | |
1216 | 591 | void ConfigHelper::prependFilter(const std::string& config, bool downstream) { |
1217 | 591 | RELEASE_ASSERT(!finalized_, ""); |
1218 | 591 | if (downstream) { |
1219 | 591 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1220 | 591 | hcm_config; |
1221 | 591 | loadHttpConnectionManager(hcm_config); |
1222 | | |
1223 | 591 | auto* filter_list_back = hcm_config.add_http_filters(); |
1224 | 591 | #ifdef ENVOY_ENABLE_YAML |
1225 | 591 | TestUtility::loadFromYaml(config, *filter_list_back); |
1226 | | #else |
1227 | | UNREFERENCED_PARAMETER(config); |
1228 | | UNREFERENCED_PARAMETER(filter_list_back); |
1229 | | PANIC("YAML support compiled out"); |
1230 | | #endif |
1231 | | |
1232 | | // Now move it to the front. |
1233 | 1.18k | for (int i = hcm_config.http_filters_size() - 1; i > 0; --i) { |
1234 | 591 | hcm_config.mutable_http_filters()->SwapElements(i, i - 1); |
1235 | 591 | } |
1236 | 591 | storeHttpConnectionManager(hcm_config); |
1237 | 591 | return; |
1238 | 591 | } |
1239 | | |
1240 | 0 | auto* static_resources = bootstrap_.mutable_static_resources(); |
1241 | 0 | for (int i = 0; i < static_resources->clusters_size(); ++i) { |
1242 | 0 | auto* cluster = static_resources->mutable_clusters(i); |
1243 | |
|
1244 | 0 | HttpProtocolOptions old_protocol_options; |
1245 | 0 | if (cluster->typed_extension_protocol_options().contains( |
1246 | 0 | "envoy.extensions.upstreams.http.v3.HttpProtocolOptions")) { |
1247 | 0 | old_protocol_options = MessageUtil::anyConvert<ConfigHelper::HttpProtocolOptions>( |
1248 | 0 | (*cluster->mutable_typed_extension_protocol_options()) |
1249 | 0 | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"]); |
1250 | 0 | } |
1251 | 0 | if (old_protocol_options.http_filters().empty()) { |
1252 | 0 | old_protocol_options.add_http_filters()->set_name("envoy.filters.http.upstream_codec"); |
1253 | 0 | } |
1254 | 0 | auto* filter_list_back = old_protocol_options.add_http_filters(); |
1255 | 0 | #ifdef ENVOY_ENABLE_YAML |
1256 | 0 | TestUtility::loadFromYaml(config, *filter_list_back); |
1257 | | #else |
1258 | | UNREFERENCED_PARAMETER(filter_list_back); |
1259 | | PANIC("YAML support compiled out"); |
1260 | | #endif |
1261 | 0 | for (int i = old_protocol_options.http_filters_size() - 1; i > 0; --i) { |
1262 | 0 | old_protocol_options.mutable_http_filters()->SwapElements(i, i - 1); |
1263 | 0 | } |
1264 | 0 | (*cluster->mutable_typed_extension_protocol_options()) |
1265 | 0 | ["envoy.extensions.upstreams.http.v3.HttpProtocolOptions"] |
1266 | 0 | .PackFrom(old_protocol_options); |
1267 | 0 | } |
1268 | 0 | } |
1269 | | |
1270 | | void ConfigHelper::setClientCodec(envoy::extensions::filters::network::http_connection_manager::v3:: |
1271 | 4.25k | HttpConnectionManager::CodecType type) { |
1272 | 4.25k | RELEASE_ASSERT(!finalized_, ""); |
1273 | 4.25k | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1274 | 4.25k | hcm_config; |
1275 | 4.25k | if (loadHttpConnectionManager(hcm_config)) { |
1276 | 4.24k | hcm_config.set_codec_type(type); |
1277 | 4.24k | storeHttpConnectionManager(hcm_config); |
1278 | 4.24k | } |
1279 | 4.25k | } |
1280 | | |
1281 | | void ConfigHelper::configDownstreamTransportSocketWithTls( |
1282 | | envoy::config::bootstrap::v3::Bootstrap& bootstrap, |
1283 | | std::function<void(envoy::extensions::transport_sockets::tls::v3::CommonTlsContext&)> |
1284 | | configure_tls_context, |
1285 | 0 | bool enable_quic_early_data) { |
1286 | 0 | for (auto& listener : *bootstrap.mutable_static_resources()->mutable_listeners()) { |
1287 | 0 | ASSERT(listener.filter_chains_size() > 0); |
1288 | 0 | auto* filter_chain = listener.mutable_filter_chains(0); |
1289 | 0 | auto* transport_socket = filter_chain->mutable_transport_socket(); |
1290 | 0 | if (listener.has_udp_listener_config() && listener.udp_listener_config().has_quic_options()) { |
1291 | 0 | transport_socket->set_name("envoy.transport_sockets.quic"); |
1292 | 0 | envoy::extensions::transport_sockets::quic::v3::QuicDownstreamTransport |
1293 | 0 | quic_transport_socket_config; |
1294 | 0 | configure_tls_context(*quic_transport_socket_config.mutable_downstream_tls_context() |
1295 | 0 | ->mutable_common_tls_context()); |
1296 | 0 | quic_transport_socket_config.mutable_enable_early_data()->set_value(enable_quic_early_data); |
1297 | 0 | transport_socket->mutable_typed_config()->PackFrom(quic_transport_socket_config); |
1298 | 0 | } else if (!listener.has_udp_listener_config()) { |
1299 | 0 | transport_socket->set_name("envoy.transport_sockets.tls"); |
1300 | 0 | envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext tls_context; |
1301 | 0 | configure_tls_context(*tls_context.mutable_common_tls_context()); |
1302 | 0 | transport_socket->mutable_typed_config()->PackFrom(tls_context); |
1303 | 0 | } |
1304 | 0 | } |
1305 | 0 | } |
1306 | | |
1307 | 0 | void ConfigHelper::addSslConfig(const ServerSslOptions& options) { |
1308 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1309 | | |
1310 | 0 | auto* filter_chain = |
1311 | 0 | bootstrap_.mutable_static_resources()->mutable_listeners(0)->mutable_filter_chains(0); |
1312 | 0 | envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext tls_context; |
1313 | 0 | initializeTls(options, *tls_context.mutable_common_tls_context()); |
1314 | 0 | if (options.ocsp_staple_required_) { |
1315 | 0 | tls_context.set_ocsp_staple_policy( |
1316 | 0 | envoy::extensions::transport_sockets::tls::v3::DownstreamTlsContext::MUST_STAPLE); |
1317 | 0 | } |
1318 | 0 | filter_chain->mutable_transport_socket()->set_name("envoy.transport_sockets.tls"); |
1319 | 0 | filter_chain->mutable_transport_socket()->mutable_typed_config()->PackFrom(tls_context); |
1320 | 0 | } |
1321 | | |
1322 | 0 | void ConfigHelper::addQuicDownstreamTransportSocketConfig(bool enable_early_data) { |
1323 | 0 | for (auto& listener : *bootstrap_.mutable_static_resources()->mutable_listeners()) { |
1324 | 0 | if (listener.udp_listener_config().has_quic_options()) { |
1325 | | // Disable SO_REUSEPORT, because it undesirably allows parallel test jobs to use the same |
1326 | | // port. |
1327 | 0 | listener.mutable_enable_reuse_port()->set_value(false); |
1328 | 0 | } |
1329 | 0 | } |
1330 | 0 | configDownstreamTransportSocketWithTls( |
1331 | 0 | bootstrap_, |
1332 | 0 | [](envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& common_tls_context) { |
1333 | 0 | initializeTls(ServerSslOptions().setRsaCert(true).setTlsV13(true), common_tls_context); |
1334 | 0 | }, |
1335 | 0 | enable_early_data); |
1336 | 0 | } |
1337 | | |
1338 | | bool ConfigHelper::setAccessLog( |
1339 | | const std::string& filename, absl::string_view format, |
1340 | 0 | std::vector<envoy::config::core::v3::TypedExtensionConfig> formatters) { |
1341 | 0 | if (getFilterFromListener("http") == nullptr) { |
1342 | 0 | return false; |
1343 | 0 | } |
1344 | | // Replace null device with a real path for the file access log. |
1345 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1346 | 0 | hcm_config; |
1347 | 0 | loadHttpConnectionManager(hcm_config); |
1348 | 0 | envoy::extensions::access_loggers::file::v3::FileAccessLog access_log_config; |
1349 | 0 | if (!format.empty()) { |
1350 | 0 | auto* log_format = access_log_config.mutable_log_format(); |
1351 | 0 | log_format->mutable_text_format_source()->set_inline_string(absl::StrCat(format, "\n")); |
1352 | 0 | if (!formatters.empty()) { |
1353 | 0 | for (const auto& formatter : formatters) { |
1354 | 0 | auto* added_formatter = log_format->add_formatters(); |
1355 | 0 | added_formatter->CopyFrom(formatter); |
1356 | 0 | } |
1357 | 0 | } |
1358 | 0 | } |
1359 | 0 | access_log_config.set_path(filename); |
1360 | 0 | hcm_config.mutable_access_log(0)->mutable_typed_config()->PackFrom(access_log_config); |
1361 | 0 | storeHttpConnectionManager(hcm_config); |
1362 | 0 | return true; |
1363 | 0 | } |
1364 | | |
1365 | 0 | bool ConfigHelper::setListenerAccessLog(const std::string& filename, absl::string_view format) { |
1366 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1367 | 0 | if (bootstrap_.mutable_static_resources()->listeners_size() == 0) { |
1368 | 0 | return false; |
1369 | 0 | } |
1370 | 0 | envoy::extensions::access_loggers::file::v3::FileAccessLog access_log_config; |
1371 | 0 | if (!format.empty()) { |
1372 | 0 | access_log_config.mutable_log_format()->mutable_text_format_source()->set_inline_string( |
1373 | 0 | std::string(format)); |
1374 | 0 | } |
1375 | 0 | access_log_config.set_path(filename); |
1376 | 0 | bootstrap_.mutable_static_resources() |
1377 | 0 | ->mutable_listeners(0) |
1378 | 0 | ->add_access_log() |
1379 | 0 | ->mutable_typed_config() |
1380 | 0 | ->PackFrom(access_log_config); |
1381 | 0 | return true; |
1382 | 0 | } |
1383 | | |
1384 | | void ConfigHelper::initializeTlsKeyLog( |
1385 | | envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& tls_context, |
1386 | 0 | const ServerSslOptions& options) { |
1387 | 0 | if (options.keylog_path_.empty()) { |
1388 | 0 | return; |
1389 | 0 | } |
1390 | 0 | auto tls_keylog_path = tls_context.mutable_key_log()->mutable_path(); |
1391 | 0 | *tls_keylog_path = options.keylog_path_; |
1392 | |
|
1393 | 0 | if (options.keylog_local_filter_) { |
1394 | 0 | auto tls_keylog_local = tls_context.mutable_key_log()->mutable_local_address_range(); |
1395 | 0 | auto new_element_local = tls_keylog_local->Add(); |
1396 | 0 | if (options.keylog_local_negative_) { |
1397 | 0 | if (options.ip_version_ == Network::Address::IpVersion::v6) { |
1398 | 0 | new_element_local->set_address_prefix("1::2"); |
1399 | 0 | new_element_local->mutable_prefix_len()->set_value(128); |
1400 | 0 | } else { |
1401 | 0 | new_element_local->set_address_prefix("127.0.0.2"); |
1402 | 0 | new_element_local->mutable_prefix_len()->set_value(32); |
1403 | 0 | } |
1404 | 0 | } else { |
1405 | 0 | new_element_local->set_address_prefix( |
1406 | 0 | Network::Test::getLoopbackAddressString(options.ip_version_)); |
1407 | 0 | if (options.keylog_multiple_ips_) { |
1408 | 0 | auto more_local = tls_keylog_local->Add(); |
1409 | 0 | if (options.ip_version_ == Network::Address::IpVersion::v6) { |
1410 | 0 | more_local->set_address_prefix("1::2"); |
1411 | 0 | more_local->mutable_prefix_len()->set_value(128); |
1412 | 0 | } else { |
1413 | 0 | more_local->set_address_prefix("127.0.0.2"); |
1414 | 0 | more_local->mutable_prefix_len()->set_value(32); |
1415 | 0 | } |
1416 | 0 | } |
1417 | 0 | } |
1418 | 0 | } |
1419 | |
|
1420 | 0 | if (options.keylog_remote_filter_) { |
1421 | 0 | auto tls_keylog_remote = tls_context.mutable_key_log()->mutable_remote_address_range(); |
1422 | 0 | auto new_element_remote = tls_keylog_remote->Add(); |
1423 | 0 | if (options.keylog_remote_negative_) { |
1424 | 0 | if (options.ip_version_ == Network::Address::IpVersion::v6) { |
1425 | 0 | new_element_remote->set_address_prefix("1::2"); |
1426 | 0 | new_element_remote->mutable_prefix_len()->set_value(128); |
1427 | 0 | } else { |
1428 | 0 | new_element_remote->set_address_prefix("127.0.0.2"); |
1429 | 0 | new_element_remote->mutable_prefix_len()->set_value(32); |
1430 | 0 | } |
1431 | 0 | } else { |
1432 | 0 | new_element_remote->set_address_prefix( |
1433 | 0 | Network::Test::getLoopbackAddressString(options.ip_version_)); |
1434 | 0 | if (options.keylog_multiple_ips_) { |
1435 | 0 | auto more_remote = tls_keylog_remote->Add(); |
1436 | 0 | if (options.ip_version_ == Network::Address::IpVersion::v6) { |
1437 | 0 | more_remote->set_address_prefix("1::2"); |
1438 | 0 | more_remote->mutable_prefix_len()->set_value(128); |
1439 | 0 | } else { |
1440 | 0 | more_remote->set_address_prefix("127.0.0.2"); |
1441 | 0 | more_remote->mutable_prefix_len()->set_value(32); |
1442 | 0 | } |
1443 | 0 | } |
1444 | 0 | } |
1445 | 0 | } |
1446 | 0 | } |
1447 | | |
1448 | | void ConfigHelper::initializeTls( |
1449 | | const ServerSslOptions& options, |
1450 | 0 | envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& common_tls_context) { |
1451 | 0 | common_tls_context.add_alpn_protocols(Http::Utility::AlpnNames::get().Http2); |
1452 | 0 | common_tls_context.add_alpn_protocols(Http::Utility::AlpnNames::get().Http11); |
1453 | |
|
1454 | 0 | auto* validation_context = common_tls_context.mutable_validation_context(); |
1455 | 0 | if (options.custom_validator_config_) { |
1456 | 0 | validation_context->set_allocated_custom_validator_config(options.custom_validator_config_); |
1457 | 0 | } else { |
1458 | 0 | if (options.client_with_intermediate_cert_) { |
1459 | 0 | validation_context->add_verify_certificate_hash(TEST_CLIENT2_CERT_HASH); |
1460 | 0 | std::string cert_yaml; |
1461 | 0 | if (options.trust_root_only_) { |
1462 | 0 | cert_yaml = R"EOF( |
1463 | 0 | trusted_ca: |
1464 | 0 | filename: "{{ test_rundir }}/test/config/integration/certs/cacert.pem" |
1465 | 0 | )EOF"; |
1466 | 0 | } else { |
1467 | 0 | cert_yaml = R"EOF( |
1468 | 0 | trusted_ca: |
1469 | 0 | filename: "{{ test_rundir }}/test/config/integration/certs/intermediate_partial_ca_cert_chain.pem" |
1470 | 0 | )EOF"; |
1471 | 0 | } |
1472 | 0 | #ifdef ENVOY_ENABLE_YAML |
1473 | 0 | TestUtility::loadFromYaml(TestEnvironment::substitute(cert_yaml), *validation_context); |
1474 | | #else |
1475 | | UNREFERENCED_PARAMETER(cert_yaml); |
1476 | | PANIC("YAML support compiled out"); |
1477 | | #endif |
1478 | 0 | if (options.max_verify_depth_.has_value()) { |
1479 | 0 | validation_context->mutable_max_verify_depth()->set_value( |
1480 | 0 | options.max_verify_depth_.value()); |
1481 | 0 | } |
1482 | 0 | } else { |
1483 | 0 | validation_context->mutable_trusted_ca()->set_filename( |
1484 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/cacert.pem")); |
1485 | 0 | validation_context->add_verify_certificate_hash( |
1486 | 0 | options.expect_client_ecdsa_cert_ ? TEST_CLIENT_ECDSA_CERT_HASH : TEST_CLIENT_CERT_HASH); |
1487 | 0 | } |
1488 | 0 | } |
1489 | 0 | validation_context->set_allow_expired_certificate(options.allow_expired_certificate_); |
1490 | | |
1491 | | // We'll negotiate up to TLSv1.3 for the tests that care, but it really |
1492 | | // depends on what the client sets. |
1493 | 0 | common_tls_context.mutable_tls_params()->set_tls_maximum_protocol_version( |
1494 | 0 | options.tlsv1_3_ ? envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_3 |
1495 | 0 | : envoy::extensions::transport_sockets::tls::v3::TlsParameters::TLSv1_2); |
1496 | 0 | for (const auto& curve : options.curves_) { |
1497 | 0 | common_tls_context.mutable_tls_params()->add_ecdh_curves(curve); |
1498 | 0 | } |
1499 | 0 | if (options.rsa_cert_) { |
1500 | 0 | auto* tls_certificate = common_tls_context.add_tls_certificates(); |
1501 | 0 | tls_certificate->mutable_certificate_chain()->set_filename( |
1502 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/servercert.pem")); |
1503 | 0 | tls_certificate->mutable_private_key()->set_filename( |
1504 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/serverkey.pem")); |
1505 | 0 | if (options.rsa_cert_ocsp_staple_) { |
1506 | 0 | tls_certificate->mutable_ocsp_staple()->set_filename( |
1507 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/server_ocsp_resp.der")); |
1508 | 0 | } |
1509 | 0 | } |
1510 | 0 | if (options.ecdsa_cert_) { |
1511 | 0 | auto* tls_certificate = common_tls_context.add_tls_certificates(); |
1512 | 0 | tls_certificate->mutable_certificate_chain()->set_filename( |
1513 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/server_ecdsacert.pem")); |
1514 | 0 | tls_certificate->mutable_private_key()->set_filename( |
1515 | 0 | TestEnvironment::runfilesPath("test/config/integration/certs/server_ecdsakey.pem")); |
1516 | 0 | if (options.ecdsa_cert_ocsp_staple_) { |
1517 | 0 | tls_certificate->mutable_ocsp_staple()->set_filename(TestEnvironment::runfilesPath( |
1518 | 0 | "test/config/integration/certs/server_ecdsa_ocsp_resp.der")); |
1519 | 0 | } |
1520 | 0 | } |
1521 | 0 | if (!options.san_matchers_.empty()) { |
1522 | 0 | *validation_context->mutable_match_typed_subject_alt_names() = {options.san_matchers_.begin(), |
1523 | 0 | options.san_matchers_.end()}; |
1524 | 0 | } |
1525 | 0 | initializeTlsKeyLog(common_tls_context, options); |
1526 | 0 | } |
1527 | | |
1528 | 2.64k | void ConfigHelper::renameListener(const std::string& name) { |
1529 | 2.64k | auto* static_resources = bootstrap_.mutable_static_resources(); |
1530 | 2.64k | if (static_resources->listeners_size() > 0) { |
1531 | 2.63k | static_resources->mutable_listeners(0)->set_name(name); |
1532 | 2.63k | } |
1533 | 2.64k | } |
1534 | | |
1535 | 14.5k | envoy::config::listener::v3::Filter* ConfigHelper::getFilterFromListener(const std::string& name) { |
1536 | 14.5k | RELEASE_ASSERT(!finalized_, ""); |
1537 | 14.5k | if (bootstrap_.mutable_static_resources()->listeners_size() == 0) { |
1538 | 14 | return nullptr; |
1539 | 14 | } |
1540 | 14.5k | auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0); |
1541 | 14.5k | if (listener->filter_chains_size() == 0) { |
1542 | 0 | return nullptr; |
1543 | 0 | } |
1544 | 14.5k | auto* filter_chain = listener->mutable_filter_chains(0); |
1545 | 14.5k | for (ssize_t i = 0; i < filter_chain->filters_size(); i++) { |
1546 | 14.5k | if (filter_chain->mutable_filters(i)->name() == name) { |
1547 | 14.5k | return filter_chain->mutable_filters(i); |
1548 | 14.5k | } |
1549 | 14.5k | } |
1550 | 0 | return nullptr; |
1551 | 14.5k | } |
1552 | | |
1553 | 0 | void ConfigHelper::addNetworkFilter(const std::string& filter_yaml) { |
1554 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1555 | 0 | auto* filter_chain = |
1556 | 0 | bootstrap_.mutable_static_resources()->mutable_listeners(0)->mutable_filter_chains(0); |
1557 | 0 | auto* filter_list_back = filter_chain->add_filters(); |
1558 | 0 | #ifdef ENVOY_ENABLE_YAML |
1559 | 0 | TestUtility::loadFromYaml(filter_yaml, *filter_list_back); |
1560 | | #else |
1561 | | UNREFERENCED_PARAMETER(filter_list_back); |
1562 | | UNREFERENCED_PARAMETER(filter_yaml); |
1563 | | PANIC("YAML support compiled out"); |
1564 | | #endif |
1565 | | |
1566 | | // Now move it to the front. |
1567 | 0 | for (int i = filter_chain->filters_size() - 1; i > 0; --i) { |
1568 | 0 | filter_chain->mutable_filters()->SwapElements(i, i - 1); |
1569 | 0 | } |
1570 | 0 | } |
1571 | | |
1572 | 0 | void ConfigHelper::addListenerFilter(const std::string& filter_yaml) { |
1573 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1574 | 0 | auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0); |
1575 | 0 | auto* filter_list_back = listener->add_listener_filters(); |
1576 | 0 | #ifdef ENVOY_ENABLE_YAML |
1577 | 0 | TestUtility::loadFromYaml(filter_yaml, *filter_list_back); |
1578 | | #else |
1579 | | UNREFERENCED_PARAMETER(filter_list_back); |
1580 | | UNREFERENCED_PARAMETER(filter_yaml); |
1581 | | PANIC("YAML support compiled out"); |
1582 | | #endif |
1583 | | |
1584 | | // Now move it to the front. |
1585 | 0 | for (int i = listener->listener_filters_size() - 1; i > 0; --i) { |
1586 | 0 | listener->mutable_listener_filters()->SwapElements(i, i - 1); |
1587 | 0 | } |
1588 | 0 | } |
1589 | | |
1590 | 0 | void ConfigHelper::addBootstrapExtension(const std::string& config) { |
1591 | 0 | RELEASE_ASSERT(!finalized_, ""); |
1592 | 0 | auto* extension = bootstrap_.add_bootstrap_extensions(); |
1593 | 0 | #ifdef ENVOY_ENABLE_YAML |
1594 | 0 | TestUtility::loadFromYaml(config, *extension); |
1595 | | #else |
1596 | | UNREFERENCED_PARAMETER(extension); |
1597 | | UNREFERENCED_PARAMETER(config); |
1598 | | PANIC("YAML support compiled out"); |
1599 | | #endif |
1600 | 0 | } |
1601 | | |
1602 | | bool ConfigHelper::loadHttpConnectionManager( |
1603 | 6.97k | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) { |
1604 | 6.97k | return loadFilter< |
1605 | 6.97k | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager>( |
1606 | 6.97k | "http", hcm); |
1607 | 6.97k | } |
1608 | | |
1609 | | void ConfigHelper::storeHttpConnectionManager( |
1610 | | const envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& |
1611 | 6.95k | hcm) { |
1612 | 6.95k | return storeFilter< |
1613 | 6.95k | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager>( |
1614 | 6.95k | "http", hcm); |
1615 | 6.95k | } |
1616 | | |
1617 | 6.92k | void ConfigHelper::addConfigModifier(ConfigModifierFunction function) { |
1618 | 6.92k | RELEASE_ASSERT(!finalized_, ""); |
1619 | 6.92k | config_modifiers_.push_back(std::move(function)); |
1620 | 6.92k | } |
1621 | | |
1622 | 1.53k | void ConfigHelper::addConfigModifier(HttpModifierFunction function) { |
1623 | 1.53k | addConfigModifier([function, this](envoy::config::bootstrap::v3::Bootstrap&) -> void { |
1624 | 1.53k | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1625 | 1.53k | hcm_config; |
1626 | 1.53k | if (!loadHttpConnectionManager(hcm_config)) { |
1627 | 0 | return; |
1628 | 0 | } |
1629 | 1.53k | function(hcm_config); |
1630 | 1.53k | storeHttpConnectionManager(hcm_config); |
1631 | 1.53k | }); |
1632 | 1.53k | } |
1633 | | |
1634 | 0 | void ConfigHelper::setLds(absl::string_view version_info) { |
1635 | 0 | applyConfigModifiers(); |
1636 | |
|
1637 | 0 | envoy::service::discovery::v3::DiscoveryResponse lds; |
1638 | 0 | lds.set_version_info(std::string(version_info)); |
1639 | 0 | for (auto& listener : bootstrap_.static_resources().listeners()) { |
1640 | 0 | ProtobufWkt::Any* resource = lds.add_resources(); |
1641 | 0 | resource->PackFrom(listener); |
1642 | 0 | } |
1643 | |
|
1644 | 0 | const std::string lds_filename = |
1645 | 0 | bootstrap().dynamic_resources().lds_config().path_config_source().path(); |
1646 | 0 | #ifdef ENVOY_ENABLE_YAML |
1647 | 0 | std::string file = TestEnvironment::writeStringToFileForTest( |
1648 | 0 | "new_lds_file", MessageUtil::getJsonStringFromMessageOrError(lds)); |
1649 | 0 | TestEnvironment::renameFile(file, lds_filename); |
1650 | | #else |
1651 | | UNREFERENCED_PARAMETER(lds_filename); |
1652 | | PANIC("YAML support compiled out"); |
1653 | | #endif |
1654 | 0 | } |
1655 | | |
1656 | | void ConfigHelper::setDownstreamOutboundFramesLimits(uint32_t max_all_frames, |
1657 | 0 | uint32_t max_control_frames) { |
1658 | 0 | auto filter = getFilterFromListener("http"); |
1659 | 0 | if (filter) { |
1660 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1661 | 0 | hcm_config; |
1662 | 0 | loadHttpConnectionManager(hcm_config); |
1663 | 0 | if (hcm_config.codec_type() == envoy::extensions::filters::network::http_connection_manager:: |
1664 | 0 | v3::HttpConnectionManager::HTTP2) { |
1665 | 0 | auto* options = hcm_config.mutable_http2_protocol_options(); |
1666 | 0 | options->mutable_max_outbound_frames()->set_value(max_all_frames); |
1667 | 0 | options->mutable_max_outbound_control_frames()->set_value(max_control_frames); |
1668 | 0 | storeHttpConnectionManager(hcm_config); |
1669 | 0 | } |
1670 | 0 | } |
1671 | 0 | } |
1672 | | |
1673 | | void ConfigHelper::setUpstreamOutboundFramesLimits(uint32_t max_all_frames, |
1674 | 0 | uint32_t max_control_frames) { |
1675 | 0 | addConfigModifier( |
1676 | 0 | [max_all_frames, max_control_frames](envoy::config::bootstrap::v3::Bootstrap& bootstrap) { |
1677 | 0 | ConfigHelper::HttpProtocolOptions protocol_options; |
1678 | 0 | auto* http_protocol_options = |
1679 | 0 | protocol_options.mutable_explicit_http_config()->mutable_http2_protocol_options(); |
1680 | 0 | http_protocol_options->mutable_max_outbound_frames()->set_value(max_all_frames); |
1681 | 0 | http_protocol_options->mutable_max_outbound_control_frames()->set_value(max_control_frames); |
1682 | 0 | ConfigHelper::setProtocolOptions(*bootstrap.mutable_static_resources()->mutable_clusters(0), |
1683 | 0 | protocol_options); |
1684 | 0 | }); |
1685 | 0 | } |
1686 | | |
1687 | | void ConfigHelper::setLocalReply( |
1688 | | const envoy::extensions::filters::network::http_connection_manager::v3::LocalReplyConfig& |
1689 | 0 | config) { |
1690 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager |
1691 | 0 | hcm_config; |
1692 | 0 | loadHttpConnectionManager(hcm_config); |
1693 | 0 | hcm_config.mutable_local_reply_config()->MergeFrom(config); |
1694 | 0 | storeHttpConnectionManager(hcm_config); |
1695 | 0 | } |
1696 | | |
1697 | | void ConfigHelper::adjustUpstreamTimeoutForTsan( |
1698 | 0 | envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm) { |
1699 | 0 | auto* route = |
1700 | 0 | hcm.mutable_route_config()->mutable_virtual_hosts(0)->mutable_routes(0)->mutable_route(); |
1701 | 0 | uint64_t timeout_ms = PROTOBUF_GET_MS_OR_DEFAULT(*route, timeout, 15000u); |
1702 | 0 | auto* timeout = route->mutable_timeout(); |
1703 | | // QUIC stream processing is slow under TSAN. Use larger timeout to prevent |
1704 | | // response_timeout. |
1705 | 0 | timeout->set_seconds(TSAN_TIMEOUT_FACTOR * timeout_ms / 1000); |
1706 | 0 | } |
1707 | | |
1708 | | envoy::config::core::v3::Http3ProtocolOptions ConfigHelper::http2ToHttp3ProtocolOptions( |
1709 | | const envoy::config::core::v3::Http2ProtocolOptions& http2_options, |
1710 | 0 | size_t http3_max_stream_receive_window) { |
1711 | 0 | envoy::config::core::v3::Http3ProtocolOptions http3_options; |
1712 | 0 | if (http2_options.has_initial_stream_window_size() && |
1713 | 0 | http2_options.initial_stream_window_size().value() < http3_max_stream_receive_window) { |
1714 | | // Set http3 stream flow control window only if the configured http2 stream flow control |
1715 | | // window is smaller than the upper limit of flow control window supported by QUICHE which is |
1716 | | // also the default for http3 streams. |
1717 | 0 | http3_options.mutable_quic_protocol_options()->mutable_initial_stream_window_size()->set_value( |
1718 | 0 | http2_options.initial_stream_window_size().value()); |
1719 | 0 | } |
1720 | 0 | if (http2_options.has_override_stream_error_on_invalid_http_message()) { |
1721 | 0 | http3_options.mutable_override_stream_error_on_invalid_http_message()->set_value( |
1722 | 0 | http2_options.override_stream_error_on_invalid_http_message().value()); |
1723 | 0 | } else if (http2_options.stream_error_on_invalid_http_messaging()) { |
1724 | 0 | http3_options.mutable_override_stream_error_on_invalid_http_message()->set_value(true); |
1725 | 0 | } |
1726 | 0 | return http3_options; |
1727 | 0 | } |
1728 | | |
1729 | 0 | CdsHelper::CdsHelper() : cds_path_(TestEnvironment::writeStringToFileForTest("cds.pb_text", "")) {} |
1730 | | |
1731 | 0 | void CdsHelper::setCds(const std::vector<envoy::config::cluster::v3::Cluster>& clusters) { |
1732 | | // Write to file the DiscoveryResponse and trigger inotify watch. |
1733 | 0 | envoy::service::discovery::v3::DiscoveryResponse cds_response; |
1734 | 0 | cds_response.set_version_info(std::to_string(cds_version_++)); |
1735 | 0 | cds_response.set_type_url(Config::TypeUrl::get().Cluster); |
1736 | 0 | for (const auto& cluster : clusters) { |
1737 | 0 | cds_response.add_resources()->PackFrom(cluster); |
1738 | 0 | } |
1739 | | // Past the initial write, need move semantics to trigger inotify move event that the |
1740 | | // FilesystemSubscriptionImpl is subscribed to. |
1741 | 0 | std::string path = |
1742 | 0 | TestEnvironment::writeStringToFileForTest("cds.update.pb_text", cds_response.DebugString()); |
1743 | 0 | TestEnvironment::renameFile(path, cds_path_); |
1744 | 0 | } |
1745 | | |
1746 | 0 | EdsHelper::EdsHelper() : eds_path_(TestEnvironment::writeStringToFileForTest("eds.pb_text", "")) { |
1747 | | // cluster.cluster_0.update_success will be incremented on the initial |
1748 | | // load when Envoy comes up. |
1749 | 0 | ++update_successes_; |
1750 | 0 | } |
1751 | | |
1752 | | void EdsHelper::setEds(const std::vector<envoy::config::endpoint::v3::ClusterLoadAssignment>& |
1753 | 0 | cluster_load_assignments) { |
1754 | | // Write to file the DiscoveryResponse and trigger inotify watch. |
1755 | 0 | envoy::service::discovery::v3::DiscoveryResponse eds_response; |
1756 | 0 | eds_response.set_version_info(std::to_string(eds_version_++)); |
1757 | 0 | eds_response.set_type_url(Config::TypeUrl::get().ClusterLoadAssignment); |
1758 | 0 | for (const auto& cluster_load_assignment : cluster_load_assignments) { |
1759 | 0 | eds_response.add_resources()->PackFrom(cluster_load_assignment); |
1760 | 0 | } |
1761 | | // Past the initial write, need move semantics to trigger inotify move event that the |
1762 | | // FilesystemSubscriptionImpl is subscribed to. |
1763 | 0 | std::string path = |
1764 | 0 | TestEnvironment::writeStringToFileForTest("eds.update.pb_text", eds_response.DebugString()); |
1765 | 0 | TestEnvironment::renameFile(path, eds_path_); |
1766 | 0 | } |
1767 | | |
1768 | | void EdsHelper::setEdsAndWait( |
1769 | | const std::vector<envoy::config::endpoint::v3::ClusterLoadAssignment>& cluster_load_assignments, |
1770 | 0 | IntegrationTestServerStats& server_stats) { |
1771 | | // Make sure the last version has been accepted before setting a new one. |
1772 | 0 | server_stats.waitForCounterGe("cluster.cluster_0.update_success", update_successes_); |
1773 | 0 | setEds(cluster_load_assignments); |
1774 | | // Make sure Envoy has consumed the update now that it is running. |
1775 | 0 | ++update_successes_; |
1776 | 0 | server_stats.waitForCounterGe("cluster.cluster_0.update_success", update_successes_); |
1777 | 0 | RELEASE_ASSERT( |
1778 | 0 | update_successes_ == server_stats.counter("cluster.cluster_0.update_success")->value(), ""); |
1779 | 0 | } |
1780 | | |
1781 | | } // namespace Envoy |