Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/test/config/utility.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <chrono>
4
#include <functional>
5
#include <string>
6
#include <vector>
7
8
#include "envoy/api/api.h"
9
#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
10
#include "envoy/config/cluster/v3/cluster.pb.h"
11
#include "envoy/config/core/v3/base.pb.h"
12
#include "envoy/config/core/v3/proxy_protocol.pb.h"
13
#include "envoy/config/endpoint/v3/endpoint.pb.h"
14
#include "envoy/config/listener/v3/listener_components.pb.h"
15
#include "envoy/config/route/v3/route_components.pb.h"
16
#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h"
17
#include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h"
18
#include "envoy/extensions/transport_sockets/tls/v3/common.pb.h"
19
#include "envoy/extensions/upstreams/http/v3/http_protocol_options.pb.h"
20
#include "envoy/http/codes.h"
21
22
#include "source/common/config/api_version.h"
23
#include "source/common/network/address_impl.h"
24
#include "source/common/protobuf/protobuf.h"
25
#include "source/common/protobuf/utility.h"
26
27
#include "test/integration/server_stats.h"
28
29
#include "absl/types/optional.h"
30
31
namespace Envoy {
32
33
class ConfigHelper {
34
public:
35
  using HttpConnectionManager =
36
      envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager;
37
  struct ServerSslOptions {
38
0
    ServerSslOptions& setAllowExpiredCertificate(bool allow) {
39
0
      allow_expired_certificate_ = allow;
40
0
      return *this;
41
0
    }
42
43
0
    ServerSslOptions& setRsaCert(bool rsa_cert) {
44
0
      rsa_cert_ = rsa_cert;
45
0
      return *this;
46
0
    }
47
48
0
    ServerSslOptions& setRsaCertOcspStaple(bool rsa_cert_ocsp_staple) {
49
0
      rsa_cert_ocsp_staple_ = rsa_cert_ocsp_staple;
50
0
      return *this;
51
0
    }
52
53
0
    ServerSslOptions& setEcdsaCert(bool ecdsa_cert) {
54
0
      ecdsa_cert_ = ecdsa_cert;
55
0
      return *this;
56
0
    }
57
58
0
    ServerSslOptions& setEcdsaCertOcspStaple(bool ecdsa_cert_ocsp_staple) {
59
0
      ecdsa_cert_ocsp_staple_ = ecdsa_cert_ocsp_staple;
60
0
      return *this;
61
0
    }
62
63
0
    ServerSslOptions& setOcspStapleRequired(bool ocsp_staple_required) {
64
0
      ocsp_staple_required_ = ocsp_staple_required;
65
0
      return *this;
66
0
    }
67
68
0
    ServerSslOptions& setTlsV13(bool tlsv1_3) {
69
0
      tlsv1_3_ = tlsv1_3;
70
0
      return *this;
71
0
    }
72
73
0
    ServerSslOptions& setCurves(const std::vector<std::string>& curves) {
74
0
      curves_ = curves;
75
0
      return *this;
76
0
    }
77
78
0
    ServerSslOptions& setExpectClientEcdsaCert(bool expect_client_ecdsa_cert) {
79
0
      expect_client_ecdsa_cert_ = expect_client_ecdsa_cert;
80
0
      return *this;
81
0
    }
82
83
    ServerSslOptions& setCustomValidatorConfig(
84
0
        envoy::config::core::v3::TypedExtensionConfig* custom_validator_config) {
85
0
      custom_validator_config_ = custom_validator_config;
86
0
      return *this;
87
0
    }
88
89
    ServerSslOptions&
90
    setSanMatchers(std::vector<envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher>
91
0
                       san_matchers) {
92
0
      san_matchers_ = san_matchers;
93
0
      return *this;
94
0
    }
95
96
0
    ServerSslOptions& setClientWithIntermediateCert(bool client_intermediate_cert) {
97
0
      client_with_intermediate_cert_ = client_intermediate_cert;
98
0
      return *this;
99
0
    }
100
101
0
    ServerSslOptions& setVerifyDepth(absl::optional<uint32_t> depth) {
102
0
      max_verify_depth_ = depth;
103
0
      return *this;
104
0
    }
105
106
    ServerSslOptions& setTlsKeyLogFilter(bool local, bool remote, bool local_negative,
107
                                         bool remote_negative, std::string log_path,
108
0
                                         bool multiple_ips, Network::Address::IpVersion version) {
109
0
      keylog_local_filter_ = local;
110
0
      keylog_remote_filter_ = remote;
111
0
      keylog_local_negative_ = local_negative;
112
0
      keylog_remote_negative_ = remote_negative;
113
0
      keylog_path_ = log_path;
114
0
      keylog_multiple_ips_ = multiple_ips;
115
0
      ip_version_ = version;
116
0
      return *this;
117
0
    }
118
119
0
    ServerSslOptions& setTrustRootOnly(bool trust_root_only) {
120
0
      trust_root_only_ = trust_root_only;
121
0
      return *this;
122
0
    }
123
124
    bool allow_expired_certificate_{};
125
    envoy::config::core::v3::TypedExtensionConfig* custom_validator_config_;
126
    bool rsa_cert_{true};
127
    bool rsa_cert_ocsp_staple_{true};
128
    bool ecdsa_cert_{false};
129
    bool ecdsa_cert_ocsp_staple_{false};
130
    bool ocsp_staple_required_{false};
131
    bool tlsv1_3_{false};
132
    std::vector<std::string> curves_;
133
    bool expect_client_ecdsa_cert_{false};
134
    bool keylog_local_filter_{false};
135
    bool keylog_remote_filter_{false};
136
    bool keylog_local_negative_{false};
137
    bool keylog_remote_negative_{false};
138
    bool keylog_multiple_ips_{false};
139
    std::string keylog_path_;
140
    Network::Address::IpVersion ip_version_{Network::Address::IpVersion::v4};
141
    std::vector<envoy::extensions::transport_sockets::tls::v3::SubjectAltNameMatcher>
142
        san_matchers_{};
143
    bool client_with_intermediate_cert_{false};
144
    bool trust_root_only_{false};
145
    absl::optional<uint32_t> max_verify_depth_{absl::nullopt};
146
  };
147
148
  // Sets up config with the provided bootstrap.
149
  ConfigHelper(const Network::Address::IpVersion version,
150
               const envoy::config::bootstrap::v3::Bootstrap& bootstrap);
151
152
  // Set up basic config, using the specified IpVersion for all connections: listeners, upstream,
153
  // and admin connections.
154
  //
155
  // By default, this runs with an L7 proxy config, but config can be set to TCP_PROXY_CONFIG
156
  // to test L4 proxying.
157
  ConfigHelper(const Network::Address::IpVersion version, Api::Api&,
158
               const std::string& config = httpProxyConfig(false, false));
159
160
  static void
161
  initializeTls(const ServerSslOptions& options,
162
                envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& common_context);
163
164
  static void initializeTlsKeyLog(
165
      envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& common_tls_context,
166
      const ServerSslOptions& options);
167
  using ConfigModifierFunction = std::function<void(envoy::config::bootstrap::v3::Bootstrap&)>;
168
  using HttpModifierFunction = std::function<void(HttpConnectionManager&)>;
169
170
  // A basic configuration (admin port, cluster_0, no listeners) with no network filters.
171
  static std::string baseConfigNoListeners();
172
173
  // A basic configuration (admin port, cluster_0, one listener) with no network filters.
174
  static std::string baseConfig(bool multiple_addresses = false);
175
176
  // A basic configuration (admin port, cluster_0, one udp listener) with no network filters.
177
  static std::string baseUdpListenerConfig(std::string listen_address = "0.0.0.0",
178
                                           bool multiple_addresses = false);
179
180
  // A string for a tls inspector listener filter which can be used with addListenerFilter()
181
  static std::string tlsInspectorFilter(bool enable_ja3_fingerprinting = false);
182
183
  // A string for the test inspector filter.
184
  static std::string testInspectorFilter();
185
186
  // A basic configuration for L4 proxying.
187
  static std::string tcpProxyConfig();
188
  // A basic configuration for L7 proxying.
189
  static std::string httpProxyConfig(bool downstream_use_quic = false,
190
                                     bool multiple_addresses = false);
191
  // A basic configuration for L7 proxying with QUIC transport.
192
  static std::string quicHttpProxyConfig(bool multiple_addresses = false);
193
  // A string for a basic buffer filter, which can be used with prependFilter()
194
  static std::string defaultBufferFilter();
195
  // A string for a small buffer filter, which can be used with prependFilter()
196
  static std::string smallBufferFilter();
197
  // A string for a health check filter which can be used with prependFilter()
198
  static std::string defaultHealthCheckFilter();
199
  // A string for a squash filter which can be used with prependFilter()
200
  static std::string defaultSquashFilter();
201
  // A string for startTls transport socket config.
202
  static std::string startTlsConfig();
203
  // A cluster that uses the startTls transport socket.
204
  static envoy::config::cluster::v3::Cluster buildStartTlsCluster(const std::string& address,
205
                                                                  int port);
206
207
  // Configuration for L7 proxying, with clusters cluster_1 and cluster_2 meant to be added via CDS.
208
  // api_type should be REST, GRPC, or DELTA_GRPC.
209
  static std::string discoveredClustersBootstrap(const std::string& api_type);
210
  // Configuration for L7 proxying, with clusters cluster_1 and cluster_2 meant to be added via CDS.
211
  // but there are no listeners.
212
  static std::string clustersNoListenerBootstrap(const std::string& api_type);
213
  static std::string adsBootstrap(const std::string& api_type);
214
  // Builds a standard Cluster config fragment, with a single endpoint (at address:port).
215
  static envoy::config::cluster::v3::Cluster
216
  buildStaticCluster(const std::string& name, int port, const std::string& address,
217
                     const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy =
218
                         envoy::config::cluster::v3::Cluster::ROUND_ROBIN);
219
220
  static envoy::config::cluster::v3::Cluster buildH1ClusterWithHighCircuitBreakersLimits(
221
      const std::string& name, int port, const std::string& address,
222
      const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy);
223
224
  // ADS configurations
225
  static envoy::config::cluster::v3::Cluster
226
  buildCluster(const std::string& name,
227
               const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy =
228
                   envoy::config::cluster::v3::Cluster::ROUND_ROBIN);
229
230
  static envoy::config::cluster::v3::Cluster
231
  buildTlsCluster(const std::string& name,
232
                  const envoy::config::cluster::v3::Cluster::LbPolicy lb_policy =
233
                      envoy::config::cluster::v3::Cluster::ROUND_ROBIN);
234
235
  static envoy::config::endpoint::v3::ClusterLoadAssignment
236
  buildClusterLoadAssignment(const std::string& name, const std::string& ip_version, uint32_t port);
237
238
  static envoy::config::endpoint::v3::ClusterLoadAssignment
239
  buildClusterLoadAssignmentWithLeds(const std::string& name,
240
                                     const std::string& leds_collection_name);
241
242
  static envoy::config::endpoint::v3::LbEndpoint buildLbEndpoint(const std::string& address,
243
                                                                 uint32_t port);
244
245
  static envoy::config::listener::v3::Listener
246
  buildBaseListener(const std::string& name, const std::string& address,
247
                    const std::string& filter_chains = "");
248
249
  static envoy::config::listener::v3::Listener buildListener(const std::string& name,
250
                                                             const std::string& route_config,
251
                                                             const std::string& address,
252
                                                             const std::string& stat_prefix);
253
254
  static envoy::config::route::v3::RouteConfiguration buildRouteConfig(const std::string& name,
255
                                                                       const std::string& cluster);
256
257
  // Builds a standard Endpoint suitable for population by finalize().
258
  static envoy::config::endpoint::v3::Endpoint buildEndpoint(const std::string& address);
259
260
  // Run the final config modifiers, and then set the upstream ports based on upstream connections.
261
  // This is the last operation run on |bootstrap_| before it is handed to Envoy.
262
  // Ports are assigned by looping through clusters, hosts, and addresses in the
263
  // order they are stored in |bootstrap_|
264
  void finalize(const std::vector<uint32_t>& ports);
265
266
  // Called by finalize to set up the ports.
267
  void setPorts(const std::vector<uint32_t>& ports, bool override_port_zero = false);
268
269
  // Set source_address in the bootstrap bind config.
270
  void setSourceAddress(const std::string& address_string);
271
272
  // Overwrite the first host and route for the primary listener.
273
  void setDefaultHostAndRoute(const std::string& host, const std::string& route);
274
275
  // Sets byte limits on upstream and downstream connections.
276
  void setBufferLimits(uint32_t upstream_buffer_limit, uint32_t downstream_buffer_limit);
277
278
  // Sets a small kernel buffer for the listener send buffer
279
  void setListenerSendBufLimits(uint32_t limit);
280
281
  // Set the idle timeout on downstream connections through the HttpConnectionManager.
282
  void setDownstreamHttpIdleTimeout(std::chrono::milliseconds idle_timeout);
283
284
  // Set the max connection duration for downstream connections through the HttpConnectionManager.
285
  void setDownstreamMaxConnectionDuration(std::chrono::milliseconds max_connection_duration);
286
287
  // Set the max stream duration for downstream connections through the HttpConnectionManager.
288
  void setDownstreamMaxStreamDuration(std::chrono::milliseconds max_stream_duration);
289
290
  // Set the connect timeout on upstream connections.
291
  void setConnectTimeout(std::chrono::milliseconds timeout);
292
293
  // Disable delay close. This is especially useful for tests doing raw TCP for
294
  // HTTP/1.1 which functionally frame by connection close.
295
  void disableDelayClose();
296
297
  // Set the max_requests_per_connection for downstream through the HttpConnectionManager.
298
  void setDownstreamMaxRequestsPerConnection(uint64_t max_requests_per_connection);
299
300
  envoy::config::route::v3::VirtualHost createVirtualHost(const char* host, const char* route = "/",
301
                                                          const char* cluster = "cluster_0");
302
303
  void addVirtualHost(const envoy::config::route::v3::VirtualHost& vhost);
304
305
  // Add an HTTP filter prior to existing filters.
306
  // By default, this prepends a downstream HTTP filter, but if downstream is set to
307
  // false it will prepend an upstream HTTP filter.
308
  void prependFilter(const std::string& filter_yaml, bool downstream = true);
309
310
  // Add an HTTP filter prior to existing filters.
311
  // TODO(rgs1): remove once envoy-filter-example has been updated.
312
  void addFilter(const std::string& filter_yaml);
313
314
  // Add a network filter prior to existing filters.
315
  void addNetworkFilter(const std::string& filter_yaml);
316
317
  // Add a listener filter prior to existing filters.
318
  void addListenerFilter(const std::string& filter_yaml);
319
320
  // Add a new bootstrap extension.
321
  void addBootstrapExtension(const std::string& config);
322
323
  // Sets the client codec to the specified type.
324
  void setClientCodec(envoy::extensions::filters::network::http_connection_manager::v3::
325
                          HttpConnectionManager::CodecType type);
326
327
  // Add TLS configuration for either SSL or QUIC transport socket according to listener config.
328
  void configDownstreamTransportSocketWithTls(
329
      envoy::config::bootstrap::v3::Bootstrap& bootstrap,
330
      std::function<void(envoy::extensions::transport_sockets::tls::v3::CommonTlsContext&)>
331
          configure_tls_context,
332
      bool enable_quic_early_data = true);
333
334
  // Add the default SSL configuration.
335
  void addSslConfig(const ServerSslOptions& options);
336
0
  void addSslConfig() { addSslConfig({}); }
337
338
  // Add the default SSL configuration for QUIC downstream.
339
  void addQuicDownstreamTransportSocketConfig(bool enable_early_data);
340
341
  // Set the HTTP access log for the first HCM (if present) to a given file. The default is
342
  // the platform's null device.
343
  bool setAccessLog(const std::string& filename, absl::string_view format = "",
344
                    std::vector<envoy::config::core::v3::TypedExtensionConfig> formatters = {});
345
346
  // Set the listener access log for the first listener to a given file.
347
  bool setListenerAccessLog(const std::string& filename, absl::string_view format = "");
348
349
  // Renames the first listener to the name specified.
350
  void renameListener(const std::string& name);
351
352
  // Allows callers to do their own modification to |bootstrap_| which will be
353
  // applied just before ports are modified in finalize().
354
  void addConfigModifier(ConfigModifierFunction function);
355
356
  // Allows callers to easily modify the HttpConnectionManager configuration.
357
  // Modifiers will be applied just before ports are modified in finalize
358
  void addConfigModifier(HttpModifierFunction function);
359
360
  // Allows callers to easily modify the filter named 'name' from the first filter chain from the
361
  // first listener. Modifiers will be applied just before ports are modified in finalize
362
  template <class FilterType>
363
  void addFilterConfigModifier(const std::string& name,
364
                               std::function<void(Protobuf::Message& filter)> function) {
365
    addConfigModifier([name, function, this](envoy::config::bootstrap::v3::Bootstrap&) -> void {
366
      FilterType filter_config;
367
      loadFilter<FilterType>(name, filter_config);
368
      function(filter_config);
369
      storeFilter<FilterType>(name, filter_config);
370
    });
371
  }
372
373
  // Apply any outstanding config modifiers, stick all the listeners in a discovery response message
374
  // and write it to the lds file.
375
  void setLds(absl::string_view version_info);
376
377
  // Set limits on pending downstream outbound frames.
378
  void setDownstreamOutboundFramesLimits(uint32_t max_all_frames, uint32_t max_control_frames);
379
380
  // Set limits on pending upstream outbound frames.
381
  void setUpstreamOutboundFramesLimits(uint32_t max_all_frames, uint32_t max_control_frames);
382
383
  // Return the bootstrap configuration for hand-off to Envoy.
384
21.5k
  const envoy::config::bootstrap::v3::Bootstrap& bootstrap() { return bootstrap_; }
385
386
  // Allow a finalized configuration to be edited for generating xDS responses
387
  void applyConfigModifiers();
388
389
  // Configure Envoy to do TLS to upstream.
390
  void configureUpstreamTls(
391
      bool use_alpn = false, bool http3 = false,
392
      absl::optional<envoy::config::core::v3::AlternateProtocolsCacheOptions>
393
          alternate_protocol_cache_config = {},
394
      std::function<void(envoy::extensions::transport_sockets::tls::v3::CommonTlsContext&)>
395
          configure_tls_context = nullptr);
396
397
  // Skip validation that ensures that all upstream ports are referenced by the
398
  // configuration generated in ConfigHelper::finalize.
399
0
  void skipPortUsageValidation() { skip_port_usage_validation_ = true; }
400
401
  // Add this key value pair to the static runtime.
402
  void addRuntimeOverride(absl::string_view key, absl::string_view value);
403
404
  // Add typed_filter_metadata to the first listener.
405
  void addListenerTypedMetadata(absl::string_view key, ProtobufWkt::Any& packed_value);
406
407
  // Add filter_metadata to a cluster with the given name
408
  void addClusterFilterMetadata(absl::string_view metadata_yaml,
409
                                absl::string_view cluster_name = "cluster_0");
410
411
  // Given an HCM with the default config, set the matcher to be a connect matcher and enable
412
  // CONNECT requests.
413
  static void setConnectConfig(HttpConnectionManager& hcm, bool terminate_connect, bool allow_post,
414
                               bool http3 = false,
415
                               absl::optional<envoy::config::core::v3::ProxyProtocolConfig::Version>
416
                                   proxy_protocol_version = absl::nullopt);
417
  // Given an HCM with the default config, set the matcher to be a connect matcher and enable
418
  // CONNECT-UDP requests.
419
  static void setConnectUdpConfig(HttpConnectionManager& hcm, bool terminate_connect,
420
                                  bool http3 = false);
421
422
  void setLocalReply(
423
      const envoy::extensions::filters::network::http_connection_manager::v3::LocalReplyConfig&
424
          config);
425
426
  // Adjust the upstream route with larger timeout if running tsan. This is the duration between
427
  // whole request being processed and whole response received.
428
  static void adjustUpstreamTimeoutForTsan(
429
      envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager& hcm);
430
431
  using HttpProtocolOptions = envoy::extensions::upstreams::http::v3::HttpProtocolOptions;
432
  static void setProtocolOptions(envoy::config::cluster::v3::Cluster& cluster,
433
                                 HttpProtocolOptions& protocol_options);
434
  static void setHttp2(envoy::config::cluster::v3::Cluster& cluster);
435
436
  // Populate and return a Http3ProtocolOptions instance based on http2_options.
437
  static envoy::config::core::v3::Http3ProtocolOptions
438
  http2ToHttp3ProtocolOptions(const envoy::config::core::v3::Http2ProtocolOptions& http2_options,
439
                              size_t http3_max_stream_receive_window);
440
  // Load the first HCM struct from the first listener into a parsed proto.
441
  bool loadHttpConnectionManager(HttpConnectionManager& hcm);
442
  // Take the contents of the provided HCM proto and stuff them into the first HCM
443
  // struct of the first listener.
444
  void storeHttpConnectionManager(const HttpConnectionManager& hcm);
445
446
private:
447
  // Load the first FilterType struct from the first listener into a parsed proto.
448
6.97k
  template <class FilterType> bool loadFilter(const std::string& name, FilterType& filter) {
449
6.97k
    RELEASE_ASSERT(!finalized_, "");
450
6.97k
    auto* filter_config = getFilterFromListener(name);
451
6.97k
    if (filter_config) {
452
6.95k
      auto* config = filter_config->mutable_typed_config();
453
6.95k
      filter = MessageUtil::anyConvert<FilterType>(*config);
454
6.95k
      return true;
455
6.95k
    }
456
14
    return false;
457
6.97k
  }
458
  // Take the contents of the provided FilterType proto and stuff them into the first FilterType
459
  // struct of the first listener.
460
6.95k
  template <class FilterType> void storeFilter(const std::string& name, const FilterType& filter) {
461
6.95k
    RELEASE_ASSERT(!finalized_, "");
462
6.95k
    auto* filter_config_any = getFilterFromListener(name)->mutable_typed_config();
463
464
6.95k
    filter_config_any->PackFrom(filter);
465
6.95k
  }
466
467
  // Finds the filter named 'name' from the first filter chain from the first listener.
468
  envoy::config::listener::v3::Filter* getFilterFromListener(const std::string& name);
469
470
  // The bootstrap proto Envoy will start up with.
471
  envoy::config::bootstrap::v3::Bootstrap bootstrap_;
472
473
  // The config modifiers added via addConfigModifier() which will be applied in finalize()
474
  std::vector<ConfigModifierFunction> config_modifiers_;
475
476
  // Track if the connect timeout has been set (to avoid clobbering a custom setting with the
477
  // default).
478
  bool connect_timeout_set_{false};
479
480
  // Option to disable port usage validation for cases where the number of
481
  // upstream ports created is expected to be larger than the number of
482
  // upstreams in the config.
483
  bool skip_port_usage_validation_{false};
484
485
  // A sanity check guard to make sure config is not modified after handing it to Envoy.
486
  bool finalized_{false};
487
};
488
489
class CdsHelper {
490
public:
491
  CdsHelper();
492
493
  // Set CDS contents on filesystem.
494
  void setCds(const std::vector<envoy::config::cluster::v3::Cluster>& cluster);
495
0
  const std::string& cdsPath() const { return cds_path_; }
496
497
private:
498
  const std::string cds_path_;
499
  uint32_t cds_version_{};
500
};
501
502
// Common code for tests that deliver EDS update via the filesystem.
503
class EdsHelper {
504
public:
505
  EdsHelper();
506
507
  // Set EDS contents on filesystem and wait for Envoy to pick this up.
508
  void setEds(const std::vector<envoy::config::endpoint::v3::ClusterLoadAssignment>&
509
                  cluster_load_assignments);
510
  void setEdsAndWait(const std::vector<envoy::config::endpoint::v3::ClusterLoadAssignment>&
511
                         cluster_load_assignments,
512
                     IntegrationTestServerStats& server_stats);
513
0
  const std::string& edsPath() const { return eds_path_; }
514
515
private:
516
  const std::string eds_path_;
517
  uint32_t eds_version_{};
518
  uint32_t update_successes_{};
519
};
520
521
} // namespace Envoy