From 6dcd221dbe65cfb6edd5c5568ff1bbf69368cc62 Mon Sep 17 00:00:00 2001 From: ohadvano <49730675+ohadvano@users.noreply.github.com> Date: Tue, 20 Aug 2024 23:42:55 +0300 Subject: [PATCH] test_utils: add config modifier for UDP proxy (#35725) Additional Description: Adding ``addConfigModifier`` testing utility for UdpProxy configurations. This will be used in a separate PR, but wanted to separate this to another so it's easier to review Risk Level: low Testing: none Docs Changes: none Release Notes: none Platform Specific Features: none Signed-off-by: ohadvano <49730675+ohadvano@users.noreply.github.com> --- test/config/BUILD | 1 + test/config/utility.cc | 34 ++++++++++++++++++++++++++++++++++ test/config/utility.h | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/test/config/BUILD b/test/config/BUILD index e45e7a26cd56..c338643e0709 100644 --- a/test/config/BUILD +++ b/test/config/BUILD @@ -37,6 +37,7 @@ envoy_cc_test_library( "@envoy_api//envoy/extensions/access_loggers/file/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/http/upstream_codec/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg_cc_proto", + "@envoy_api//envoy/extensions/filters/udp/udp_proxy/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/quic/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/transport_sockets/tls/v3:pkg_cc_proto", "@envoy_api//envoy/extensions/upstreams/http/v3:pkg_cc_proto", diff --git a/test/config/utility.cc b/test/config/utility.cc index 69891e86f60b..668d4f290882 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -1575,6 +1575,21 @@ envoy::config::listener::v3::Filter* ConfigHelper::getFilterFromListener(const s return nullptr; } +envoy::config::listener::v3::ListenerFilter* +ConfigHelper::getListenerFilterFromListener(const std::string& name) { + RELEASE_ASSERT(!finalized_, ""); + if (bootstrap_.mutable_static_resources()->listeners_size() == 0) { + return nullptr; + } + auto* listener = bootstrap_.mutable_static_resources()->mutable_listeners(0); + for (ssize_t i = 0; i < listener->listener_filters_size(); i++) { + if (listener->mutable_listener_filters(i)->name() == name) { + return listener->mutable_listener_filters(i); + } + } + return nullptr; +} + void ConfigHelper::addNetworkFilter(const std::string& filter_yaml) { RELEASE_ASSERT(!finalized_, ""); auto* filter_chain = @@ -1639,6 +1654,14 @@ void ConfigHelper::storeHttpConnectionManager( "http", hcm); } +bool ConfigHelper::loadUdpProxyFilter(UdpProxyConfig& udp_proxy) { + return loadListenerFilter("udp_proxy", udp_proxy); +} + +void ConfigHelper::storeUdpProxyFilter(const UdpProxyConfig& udp_proxy) { + return storeListenerFilter("udp_proxy", udp_proxy); +} + void ConfigHelper::addConfigModifier(ConfigModifierFunction function) { RELEASE_ASSERT(!finalized_, ""); config_modifiers_.push_back(std::move(function)); @@ -1656,6 +1679,17 @@ void ConfigHelper::addConfigModifier(HttpModifierFunction function) { }); } +void ConfigHelper::addConfigModifier(UdpProxyModifierFunction function) { + addConfigModifier([function, this](envoy::config::bootstrap::v3::Bootstrap&) -> void { + UdpProxyConfig udp_proxy_config; + if (!loadUdpProxyFilter(udp_proxy_config)) { + return; + } + function(udp_proxy_config); + storeUdpProxyFilter(udp_proxy_config); + }); +} + void ConfigHelper::setLds(absl::string_view version_info) { applyConfigModifiers(); diff --git a/test/config/utility.h b/test/config/utility.h index eb34d534bbec..9410d2e84ec7 100644 --- a/test/config/utility.h +++ b/test/config/utility.h @@ -14,6 +14,7 @@ #include "envoy/config/listener/v3/listener_components.pb.h" #include "envoy/config/route/v3/route_components.pb.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h" +#include "envoy/extensions/filters/udp/udp_proxy/v3/udp_proxy.pb.h" #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h" #include "envoy/extensions/transport_sockets/tls/v3/common.pb.h" #include "envoy/extensions/upstreams/http/v3/http_protocol_options.pb.h" @@ -34,6 +35,8 @@ class ConfigHelper { public: using HttpConnectionManager = envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager; + using UdpProxyConfig = envoy::extensions::filters::udp::udp_proxy::v3::UdpProxyConfig; + struct ServerSslOptions { ServerSslOptions& setAllowExpiredCertificate(bool allow) { allow_expired_certificate_ = allow; @@ -185,6 +188,7 @@ class ConfigHelper { const ServerSslOptions& options); using ConfigModifierFunction = std::function; using HttpModifierFunction = std::function; + using UdpProxyModifierFunction = std::function; // A basic configuration (admin port, cluster_0, no listeners) with no network filters. static std::string baseConfigNoListeners(); @@ -377,6 +381,10 @@ class ConfigHelper { // Modifiers will be applied just before ports are modified in finalize void addConfigModifier(HttpModifierFunction function); + // Allows callers to easily modify the UDP Proxy configuration. + // Modifiers will be applied just before ports are modified in finalize + void addConfigModifier(UdpProxyModifierFunction function); + // Allows callers to easily modify the filter named 'name' from the first filter chain from the // first listener. Modifiers will be applied just before ports are modified in finalize template @@ -462,6 +470,11 @@ class ConfigHelper { // Take the contents of the provided HCM proto and stuff them into the first HCM // struct of the first listener. void storeHttpConnectionManager(const HttpConnectionManager& hcm); + // Load the first UDP Proxy from the first listener into a parsed proto. + bool loadUdpProxyFilter(UdpProxyConfig& udp_proxy); + // Take the contents of the provided UDP Proxy and stuff them into the first HCM + // struct of the first listener. + void storeUdpProxyFilter(const UdpProxyConfig& udp_proxy); private: // Load the first FilterType struct from the first listener into a parsed proto. @@ -484,9 +497,35 @@ class ConfigHelper { filter_config_any->PackFrom(filter); } + // Load the first FilterType struct from the first listener filters into a parsed proto. + template bool loadListenerFilter(const std::string& name, FilterType& filter) { + RELEASE_ASSERT(!finalized_, ""); + auto* filter_config = getListenerFilterFromListener(name); + if (filter_config) { + auto* config = filter_config->mutable_typed_config(); + filter = MessageUtil::anyConvert(*config); + return true; + } + return false; + } + + // Take the contents of the provided FilterType proto and stuff them into the first FilterType + // struct of the first listener. + template + void storeListenerFilter(const std::string& name, const FilterType& filter) { + RELEASE_ASSERT(!finalized_, ""); + auto* filter_config_any = getListenerFilterFromListener(name)->mutable_typed_config(); + + filter_config_any->PackFrom(filter); + } + // Finds the filter named 'name' from the first filter chain from the first listener. envoy::config::listener::v3::Filter* getFilterFromListener(const std::string& name); + // Finds the filter named 'name' from the first listener filter from the first listener. + envoy::config::listener::v3::ListenerFilter* + getListenerFilterFromListener(const std::string& name); + // The bootstrap proto Envoy will start up with. envoy::config::bootstrap::v3::Bootstrap bootstrap_;