diff --git a/include/envoy/upstream/outlier_detection.h b/include/envoy/upstream/outlier_detection.h index 1722435de4462..98c9bbb278966 100644 --- a/include/envoy/upstream/outlier_detection.h +++ b/include/envoy/upstream/outlier_detection.h @@ -29,7 +29,7 @@ enum class Result { CONNECT_FAILED, // Remote host rejected the connection. // The entries below only make sense when Envoy understands requests/responses for the - // protocol being proxied. They do not make sense for TcpProxy, for example. + // protocol being proxied. They do not make sense for TcpProxy, for example. REQUEST_FAILED, // Request was not completed successfully. SERVER_FAILURE, // The server indicated it cannot process a request. diff --git a/source/common/config/BUILD b/source/common/config/BUILD index 114c5cfcb16a7..b2587174f81d5 100644 --- a/source/common/config/BUILD +++ b/source/common/config/BUILD @@ -93,10 +93,13 @@ envoy_cc_library( "envoy_filter_http_buffer", "envoy_filter_http_fault", "envoy_filter_http_health_check", + "envoy_filter_http_rate_limit", "envoy_filter_http_router", "envoy_filter_network_mongo_proxy", "envoy_filter_network_redis_proxy", "envoy_filter_network_tcp_proxy", + "envoy_filter_network_rate_limit", + "envoy_filter_network_client_ssl_auth", ], deps = [ ":address_json_lib", diff --git a/source/common/config/filter_json.cc b/source/common/config/filter_json.cc index 3e14398a1d3e8..5e7a5582eb99e 100644 --- a/source/common/config/filter_json.cc +++ b/source/common/config/filter_json.cc @@ -17,9 +17,9 @@ namespace Config { namespace { -void translateComparisonFilter(const Json::Object& config, +void translateComparisonFilter(const Json::Object& json_config, envoy::api::v2::filter::accesslog::ComparisonFilter& filter) { - const std::string op = config.getString("op"); + const std::string op = json_config.getString("op"); if (op == ">=") { filter.set_op(envoy::api::v2::filter::accesslog::ComparisonFilter::GE); } else { @@ -28,41 +28,41 @@ void translateComparisonFilter(const Json::Object& config, } auto* runtime = filter.mutable_value(); - runtime->set_default_value(config.getInteger("value")); - runtime->set_runtime_key(config.getString("runtime_key", "")); + runtime->set_default_value(json_config.getInteger("value")); + runtime->set_runtime_key(json_config.getString("runtime_key", "")); } -void translateStatusCodeFilter(const Json::Object& config, +void translateStatusCodeFilter(const Json::Object& json_config, envoy::api::v2::filter::accesslog::StatusCodeFilter& filter) { - translateComparisonFilter(config, *filter.mutable_comparison()); + translateComparisonFilter(json_config, *filter.mutable_comparison()); } -void translateDurationFilter(const Json::Object& config, +void translateDurationFilter(const Json::Object& json_config, envoy::api::v2::filter::accesslog::DurationFilter& filter) { - translateComparisonFilter(config, *filter.mutable_comparison()); + translateComparisonFilter(json_config, *filter.mutable_comparison()); } -void translateRuntimeFilter(const Json::Object& config, +void translateRuntimeFilter(const Json::Object& json_config, envoy::api::v2::filter::accesslog::RuntimeFilter& filter) { - filter.set_runtime_key(config.getString("key")); + filter.set_runtime_key(json_config.getString("key")); } void translateRepeatedFilter( - const Json::Object& config, + const Json::Object& json_config, Protobuf::RepeatedPtrField& filters) { - for (const auto& json_filter : config.getObjectArray("filters")) { + for (const auto& json_filter : json_config.getObjectArray("filters")) { FilterJson::translateAccessLogFilter(*json_filter, *filters.Add()); } } -void translateOrFilter(const Json::Object& config, +void translateOrFilter(const Json::Object& json_config, envoy::api::v2::filter::accesslog::OrFilter& filter) { - translateRepeatedFilter(config, *filter.mutable_filters()); + translateRepeatedFilter(json_config, *filter.mutable_filters()); } -void translateAndFilter(const Json::Object& config, +void translateAndFilter(const Json::Object& json_config, envoy::api::v2::filter::accesslog::AndFilter& filter) { - translateRepeatedFilter(config, *filter.mutable_filters()); + translateRepeatedFilter(json_config, *filter.mutable_filters()); } void translateRepeatedAccessLog( @@ -77,76 +77,74 @@ void translateRepeatedAccessLog( } // namespace void FilterJson::translateAccessLogFilter( - const Json::Object& json_access_log_filter, - envoy::api::v2::filter::accesslog::AccessLogFilter& access_log_filter) { - const std::string type = json_access_log_filter.getString("type"); + const Json::Object& json_config, + envoy::api::v2::filter::accesslog::AccessLogFilter& proto_config) { + const std::string type = json_config.getString("type"); if (type == "status_code") { - translateStatusCodeFilter(json_access_log_filter, - *access_log_filter.mutable_status_code_filter()); + translateStatusCodeFilter(json_config, *proto_config.mutable_status_code_filter()); } else if (type == "duration") { - translateDurationFilter(json_access_log_filter, *access_log_filter.mutable_duration_filter()); + translateDurationFilter(json_config, *proto_config.mutable_duration_filter()); } else if (type == "runtime") { - translateRuntimeFilter(json_access_log_filter, *access_log_filter.mutable_runtime_filter()); + translateRuntimeFilter(json_config, *proto_config.mutable_runtime_filter()); } else if (type == "logical_or") { - translateOrFilter(json_access_log_filter, *access_log_filter.mutable_or_filter()); + translateOrFilter(json_config, *proto_config.mutable_or_filter()); } else if (type == "logical_and") { - translateAndFilter(json_access_log_filter, *access_log_filter.mutable_and_filter()); + translateAndFilter(json_config, *proto_config.mutable_and_filter()); } else if (type == "not_healthcheck") { - access_log_filter.mutable_not_health_check_filter(); + proto_config.mutable_not_health_check_filter(); } else { ASSERT(type == "traceable_request"); - access_log_filter.mutable_traceable_filter(); + proto_config.mutable_traceable_filter(); } } -void FilterJson::translateAccessLog(const Json::Object& json_access_log, - envoy::api::v2::filter::accesslog::AccessLog& access_log) { - json_access_log.validateSchema(Json::Schema::ACCESS_LOG_SCHEMA); +void FilterJson::translateAccessLog(const Json::Object& json_config, + envoy::api::v2::filter::accesslog::AccessLog& proto_config) { + json_config.validateSchema(Json::Schema::ACCESS_LOG_SCHEMA); envoy::api::v2::filter::accesslog::FileAccessLog file_access_log; - JSON_UTIL_SET_STRING(json_access_log, file_access_log, path); - JSON_UTIL_SET_STRING(json_access_log, file_access_log, format); + JSON_UTIL_SET_STRING(json_config, file_access_log, path); + JSON_UTIL_SET_STRING(json_config, file_access_log, format); - ProtobufWkt::Struct& custom_config = *access_log.mutable_config(); + ProtobufWkt::Struct& custom_config = *proto_config.mutable_config(); MessageUtil::jsonConvert(file_access_log, custom_config); // Statically registered access logs are a v2-only feature, so use the standard internal file // access log for json config conversion. - access_log.set_name(Config::AccessLogNames::get().FILE); + proto_config.set_name(Config::AccessLogNames::get().FILE); - if (json_access_log.hasObject("filter")) { - translateAccessLogFilter(*json_access_log.getObject("filter"), *access_log.mutable_filter()); + if (json_config.hasObject("filter")) { + translateAccessLogFilter(*json_config.getObject("filter"), *proto_config.mutable_filter()); } } void FilterJson::translateHttpConnectionManager( - const Json::Object& json_http_connection_manager, - envoy::api::v2::filter::network::HttpConnectionManager& http_connection_manager) { - json_http_connection_manager.validateSchema(Json::Schema::HTTP_CONN_NETWORK_FILTER_SCHEMA); + const Json::Object& json_config, + envoy::api::v2::filter::network::HttpConnectionManager& proto_config) { + json_config.validateSchema(Json::Schema::HTTP_CONN_NETWORK_FILTER_SCHEMA); envoy::api::v2::filter::network::HttpConnectionManager::CodecType codec_type{}; envoy::api::v2::filter::network::HttpConnectionManager::CodecType_Parse( - StringUtil::toUpper(json_http_connection_manager.getString("codec_type")), &codec_type); - http_connection_manager.set_codec_type(codec_type); + StringUtil::toUpper(json_config.getString("codec_type")), &codec_type); + proto_config.set_codec_type(codec_type); - JSON_UTIL_SET_STRING(json_http_connection_manager, http_connection_manager, stat_prefix); + JSON_UTIL_SET_STRING(json_config, proto_config, stat_prefix); - if (json_http_connection_manager.hasObject("rds")) { - Utility::translateRdsConfig(*json_http_connection_manager.getObject("rds"), - *http_connection_manager.mutable_rds()); + if (json_config.hasObject("rds")) { + Utility::translateRdsConfig(*json_config.getObject("rds"), *proto_config.mutable_rds()); } - if (json_http_connection_manager.hasObject("route_config")) { - if (json_http_connection_manager.hasObject("rds")) { + if (json_config.hasObject("route_config")) { + if (json_config.hasObject("rds")) { throw EnvoyException( "http connection manager must have either rds or route_config but not both"); } - RdsJson::translateRouteConfiguration(*json_http_connection_manager.getObject("route_config"), - *http_connection_manager.mutable_route_config()); + RdsJson::translateRouteConfiguration(*json_config.getObject("route_config"), + *proto_config.mutable_route_config()); } - for (const auto& json_filter : json_http_connection_manager.getObjectArray("filters", true)) { - auto* filter = http_connection_manager.mutable_http_filters()->Add(); + for (const auto& json_filter : json_config.getObjectArray("filters", true)) { + auto* filter = proto_config.mutable_http_filters()->Add(); JSON_UTIL_SET_STRING(*json_filter, *filter, name); // Translate v1 name to v2 name. @@ -154,20 +152,21 @@ void FilterJson::translateHttpConnectionManager( Config::HttpFilterNames::get().v1_converter_.getV2Name(json_filter->getString("name"))); JSON_UTIL_SET_STRING(*json_filter, *filter->mutable_deprecated_v1(), type); - const std::string json_config = "{\"deprecated_v1\": true, \"value\": " + - json_filter->getObject("config")->asJsonString() + "}"; + const std::string deprecated_config = "{\"deprecated_v1\": true, \"value\": " + + json_filter->getObject("config")->asJsonString() + "}"; - const auto status = Protobuf::util::JsonStringToMessage(json_config, filter->mutable_config()); + const auto status = + Protobuf::util::JsonStringToMessage(deprecated_config, filter->mutable_config()); // JSON schema has already validated that this is a valid JSON object. ASSERT(status.ok()); UNREFERENCED_PARAMETER(status); } - JSON_UTIL_SET_BOOL(json_http_connection_manager, http_connection_manager, add_user_agent); + JSON_UTIL_SET_BOOL(json_config, proto_config, add_user_agent); - if (json_http_connection_manager.hasObject("tracing")) { - const auto json_tracing = json_http_connection_manager.getObject("tracing"); - auto* tracing = http_connection_manager.mutable_tracing(); + if (json_config.hasObject("tracing")) { + const auto json_tracing = json_config.getObject("tracing"); + auto* tracing = proto_config.mutable_tracing(); envoy::api::v2::filter::network::HttpConnectionManager::Tracing::OperationName operation_name{}; envoy::api::v2::filter::network::HttpConnectionManager::Tracing::OperationName_Parse( @@ -180,72 +179,64 @@ void FilterJson::translateHttpConnectionManager( } } - if (json_http_connection_manager.hasObject("http1_settings")) { - ProtocolJson::translateHttp1ProtocolOptions( - *json_http_connection_manager.getObject("http1_settings"), - *http_connection_manager.mutable_http_protocol_options()); + if (json_config.hasObject("http1_settings")) { + ProtocolJson::translateHttp1ProtocolOptions(*json_config.getObject("http1_settings"), + *proto_config.mutable_http_protocol_options()); } - if (json_http_connection_manager.hasObject("http2_settings")) { - ProtocolJson::translateHttp2ProtocolOptions( - *json_http_connection_manager.getObject("http2_settings"), - *http_connection_manager.mutable_http2_protocol_options()); + if (json_config.hasObject("http2_settings")) { + ProtocolJson::translateHttp2ProtocolOptions(*json_config.getObject("http2_settings"), + *proto_config.mutable_http2_protocol_options()); } - JSON_UTIL_SET_STRING(json_http_connection_manager, http_connection_manager, server_name); - JSON_UTIL_SET_DURATION_SECONDS(json_http_connection_manager, http_connection_manager, - idle_timeout); - JSON_UTIL_SET_DURATION(json_http_connection_manager, http_connection_manager, drain_timeout); + JSON_UTIL_SET_STRING(json_config, proto_config, server_name); + JSON_UTIL_SET_DURATION_SECONDS(json_config, proto_config, idle_timeout); + JSON_UTIL_SET_DURATION(json_config, proto_config, drain_timeout); - translateRepeatedAccessLog(json_http_connection_manager.getObjectArray("access_log", true), - *http_connection_manager.mutable_access_log()); + translateRepeatedAccessLog(json_config.getObjectArray("access_log", true), + *proto_config.mutable_access_log()); - JSON_UTIL_SET_BOOL(json_http_connection_manager, http_connection_manager, use_remote_address); - JSON_UTIL_SET_BOOL(json_http_connection_manager, http_connection_manager, generate_request_id); + JSON_UTIL_SET_BOOL(json_config, proto_config, use_remote_address); + JSON_UTIL_SET_BOOL(json_config, proto_config, generate_request_id); envoy::api::v2::filter::network::HttpConnectionManager::ForwardClientCertDetails fcc_details{}; envoy::api::v2::filter::network::HttpConnectionManager::ForwardClientCertDetails_Parse( - StringUtil::toUpper( - json_http_connection_manager.getString("forward_client_cert", "sanitize")), - &fcc_details); - http_connection_manager.set_forward_client_cert_details(fcc_details); + StringUtil::toUpper(json_config.getString("forward_client_cert", "sanitize")), &fcc_details); + proto_config.set_forward_client_cert_details(fcc_details); for (const std::string& detail : - json_http_connection_manager.getStringArray("set_current_client_cert_details", true)) { + json_config.getStringArray("set_current_client_cert_details", true)) { if (detail == "Subject") { - http_connection_manager.mutable_set_current_client_cert_details() - ->mutable_subject() - ->set_value(true); + proto_config.mutable_set_current_client_cert_details()->mutable_subject()->set_value(true); } else { ASSERT(detail == "SAN"); - http_connection_manager.mutable_set_current_client_cert_details()->mutable_san()->set_value( - true); + proto_config.mutable_set_current_client_cert_details()->mutable_san()->set_value(true); } } } -void FilterJson::translateRedisProxy(const Json::Object& json_redis_proxy, - envoy::api::v2::filter::network::RedisProxy& redis_proxy) { - json_redis_proxy.validateSchema(Json::Schema::REDIS_PROXY_NETWORK_FILTER_SCHEMA); - JSON_UTIL_SET_STRING(json_redis_proxy, redis_proxy, stat_prefix); - redis_proxy.set_cluster(json_redis_proxy.getString("cluster_name")); +void FilterJson::translateRedisProxy(const Json::Object& json_config, + envoy::api::v2::filter::network::RedisProxy& proto_config) { + json_config.validateSchema(Json::Schema::REDIS_PROXY_NETWORK_FILTER_SCHEMA); + JSON_UTIL_SET_STRING(json_config, proto_config, stat_prefix); + proto_config.set_cluster(json_config.getString("cluster_name")); - const auto json_conn_pool = json_redis_proxy.getObject("conn_pool"); + const auto json_conn_pool = json_config.getObject("conn_pool"); json_conn_pool->validateSchema(Json::Schema::REDIS_CONN_POOL_SCHEMA); - auto* conn_pool = redis_proxy.mutable_settings(); + auto* conn_pool = proto_config.mutable_settings(); JSON_UTIL_SET_DURATION(*json_conn_pool, *conn_pool, op_timeout); } -void FilterJson::translateMongoProxy(const Json::Object& json_mongo_proxy, - envoy::api::v2::filter::network::MongoProxy& mongo_proxy) { - json_mongo_proxy.validateSchema(Json::Schema::MONGO_PROXY_NETWORK_FILTER_SCHEMA); +void FilterJson::translateMongoProxy(const Json::Object& json_config, + envoy::api::v2::filter::network::MongoProxy& proto_config) { + json_config.validateSchema(Json::Schema::MONGO_PROXY_NETWORK_FILTER_SCHEMA); - JSON_UTIL_SET_STRING(json_mongo_proxy, mongo_proxy, stat_prefix); - JSON_UTIL_SET_STRING(json_mongo_proxy, mongo_proxy, access_log); - if (json_mongo_proxy.hasObject("fault")) { - const auto json_fault = json_mongo_proxy.getObject("fault")->getObject("fixed_delay"); - auto* delay = mongo_proxy.mutable_delay(); + JSON_UTIL_SET_STRING(json_config, proto_config, stat_prefix); + JSON_UTIL_SET_STRING(json_config, proto_config, access_log); + if (json_config.hasObject("fault")) { + const auto json_fault = json_config.getObject("fault")->getObject("fixed_delay"); + auto* delay = proto_config.mutable_delay(); delay->set_type(envoy::api::v2::filter::FaultDelay::FIXED); delay->set_percent(static_cast(json_fault->getInteger("percent"))); @@ -253,79 +244,79 @@ void FilterJson::translateMongoProxy(const Json::Object& json_mongo_proxy, } } -void FilterJson::translateFaultFilter(const Json::Object& json_fault, - envoy::api::v2::filter::http::HTTPFault& fault) { - json_fault.validateSchema(Json::Schema::FAULT_HTTP_FILTER_SCHEMA); +void FilterJson::translateFaultFilter(const Json::Object& json_config, + envoy::api::v2::filter::http::HTTPFault& proto_config) { + json_config.validateSchema(Json::Schema::FAULT_HTTP_FILTER_SCHEMA); - const Json::ObjectSharedPtr config_abort = json_fault.getObject("abort", true); - const Json::ObjectSharedPtr config_delay = json_fault.getObject("delay", true); + const Json::ObjectSharedPtr json_config_abort = json_config.getObject("abort", true); + const Json::ObjectSharedPtr json_config_delay = json_config.getObject("delay", true); - if (!config_abort->empty()) { - auto* abort_fault = fault.mutable_abort(); - abort_fault->set_percent(static_cast(config_abort->getInteger("abort_percent"))); + if (!json_config_abort->empty()) { + auto* abort_fault = proto_config.mutable_abort(); + abort_fault->set_percent(static_cast(json_config_abort->getInteger("abort_percent"))); // TODO(mattklein123): Throw error if invalid return code is provided - abort_fault->set_http_status(static_cast(config_abort->getInteger("http_status"))); + abort_fault->set_http_status( + static_cast(json_config_abort->getInteger("http_status"))); } - if (!config_delay->empty()) { - auto* delay = fault.mutable_delay(); + if (!json_config_delay->empty()) { + auto* delay = proto_config.mutable_delay(); delay->set_type(envoy::api::v2::filter::FaultDelay::FIXED); - delay->set_percent(static_cast(config_delay->getInteger("fixed_delay_percent"))); - JSON_UTIL_SET_DURATION_FROM_FIELD(*config_delay, *delay, fixed_delay, fixed_duration); + delay->set_percent(static_cast(json_config_delay->getInteger("fixed_delay_percent"))); + JSON_UTIL_SET_DURATION_FROM_FIELD(*json_config_delay, *delay, fixed_delay, fixed_duration); } - for (const auto json_header_matcher : json_fault.getObjectArray("headers", true)) { - auto* header_matcher = fault.mutable_headers()->Add(); + for (const auto json_header_matcher : json_config.getObjectArray("headers", true)) { + auto* header_matcher = proto_config.mutable_headers()->Add(); RdsJson::translateHeaderMatcher(*json_header_matcher, *header_matcher); } - JSON_UTIL_SET_STRING(json_fault, fault, upstream_cluster); + JSON_UTIL_SET_STRING(json_config, proto_config, upstream_cluster); - for (auto json_downstream_node : json_fault.getStringArray("downstream_nodes", true)) { - auto* downstream_node = fault.mutable_downstream_nodes()->Add(); + for (auto json_downstream_node : json_config.getStringArray("downstream_nodes", true)) { + auto* downstream_node = proto_config.mutable_downstream_nodes()->Add(); *downstream_node = json_downstream_node; } } void FilterJson::translateHealthCheckFilter( - const Json::Object& json_health_check, - envoy::api::v2::filter::http::HealthCheck& health_check) { - json_health_check.validateSchema(Json::Schema::HEALTH_CHECK_HTTP_FILTER_SCHEMA); + const Json::Object& json_config, envoy::api::v2::filter::http::HealthCheck& proto_config) { + json_config.validateSchema(Json::Schema::HEALTH_CHECK_HTTP_FILTER_SCHEMA); - JSON_UTIL_SET_BOOL(json_health_check, health_check, pass_through_mode); - JSON_UTIL_SET_DURATION(json_health_check, health_check, cache_time); - JSON_UTIL_SET_STRING(json_health_check, health_check, endpoint); + JSON_UTIL_SET_BOOL(json_config, proto_config, pass_through_mode); + JSON_UTIL_SET_DURATION(json_config, proto_config, cache_time); + JSON_UTIL_SET_STRING(json_config, proto_config, endpoint); } -void FilterJson::translateRouter(const Json::Object& json_router, - envoy::api::v2::filter::http::Router& router) { - json_router.validateSchema(Json::Schema::ROUTER_HTTP_FILTER_SCHEMA); +void FilterJson::translateRouter(const Json::Object& json_config, + envoy::api::v2::filter::http::Router& proto_config) { + json_config.validateSchema(Json::Schema::ROUTER_HTTP_FILTER_SCHEMA); - router.mutable_dynamic_stats()->set_value(json_router.getBoolean("dynamic_stats", true)); - router.set_start_child_span(json_router.getBoolean("start_child_span", false)); + proto_config.mutable_dynamic_stats()->set_value(json_config.getBoolean("dynamic_stats", true)); + proto_config.set_start_child_span(json_config.getBoolean("start_child_span", false)); } -void FilterJson::translateBufferFilter(const Json::Object& json_buffer, - envoy::api::v2::filter::http::Buffer& buffer) { - json_buffer.validateSchema(Json::Schema::BUFFER_HTTP_FILTER_SCHEMA); +void FilterJson::translateBufferFilter(const Json::Object& json_config, + envoy::api::v2::filter::http::Buffer& proto_config) { + json_config.validateSchema(Json::Schema::BUFFER_HTTP_FILTER_SCHEMA); - JSON_UTIL_SET_INTEGER(json_buffer, buffer, max_request_bytes); - JSON_UTIL_SET_DURATION_SECONDS(json_buffer, buffer, max_request_time); + JSON_UTIL_SET_INTEGER(json_config, proto_config, max_request_bytes); + JSON_UTIL_SET_DURATION_SECONDS(json_config, proto_config, max_request_time); } -void FilterJson::translateTcpProxy(const Json::Object& json_tcp_proxy, - envoy::api::v2::filter::network::TcpProxy& tcp_proxy) { - json_tcp_proxy.validateSchema(Json::Schema::TCP_PROXY_NETWORK_FILTER_SCHEMA); +void FilterJson::translateTcpProxy(const Json::Object& json_config, + envoy::api::v2::filter::network::TcpProxy& proto_config) { + json_config.validateSchema(Json::Schema::TCP_PROXY_NETWORK_FILTER_SCHEMA); - JSON_UTIL_SET_STRING(json_tcp_proxy, tcp_proxy, stat_prefix); - translateRepeatedAccessLog(json_tcp_proxy.getObjectArray("access_log", true), - *tcp_proxy.mutable_access_log()); + JSON_UTIL_SET_STRING(json_config, proto_config, stat_prefix); + translateRepeatedAccessLog(json_config.getObjectArray("access_log", true), + *proto_config.mutable_access_log()); for (const Json::ObjectSharedPtr& route_desc : - json_tcp_proxy.getObject("route_config")->getObjectArray("routes")) { + json_config.getObject("route_config")->getObjectArray("routes")) { envoy::api::v2::filter::network::TcpProxy::DeprecatedV1::TCPRoute* route = - tcp_proxy.mutable_deprecated_v1()->mutable_routes()->Add(); + proto_config.mutable_deprecated_v1()->mutable_routes()->Add(); JSON_UTIL_SET_STRING(*route_desc, *route, cluster); JSON_UTIL_SET_STRING(*route_desc, *route, destination_ports); JSON_UTIL_SET_STRING(*route_desc, *route, source_ports); @@ -336,5 +327,47 @@ void FilterJson::translateTcpProxy(const Json::Object& json_tcp_proxy, } } +void FilterJson::translateTcpRateLimitFilter( + const Json::Object& json_config, envoy::api::v2::filter::network::RateLimit& proto_config) { + json_config.validateSchema(Json::Schema::RATELIMIT_NETWORK_FILTER_SCHEMA); + + JSON_UTIL_SET_STRING(json_config, proto_config, stat_prefix); + JSON_UTIL_SET_STRING(json_config, proto_config, domain); + JSON_UTIL_SET_DURATION(json_config, proto_config, timeout); + + auto* descriptors = proto_config.mutable_descriptors(); + for (const auto& json_descriptor : json_config.getObjectArray("descriptors", false)) { + auto* entries = descriptors->Add()->mutable_entries(); + for (const auto& json_entry : json_descriptor->asObjectArray()) { + auto* entry = entries->Add(); + JSON_UTIL_SET_STRING(*json_entry, *entry, key); + JSON_UTIL_SET_STRING(*json_entry, *entry, value); + } + } +} + +void FilterJson::translateHttpRateLimitFilter( + const Json::Object& json_config, envoy::api::v2::filter::http::RateLimit& proto_config) { + json_config.validateSchema(Json::Schema::RATE_LIMIT_HTTP_FILTER_SCHEMA); + + JSON_UTIL_SET_STRING(json_config, proto_config, domain); + proto_config.set_stage(json_config.getInteger("stage", 0)); + + JSON_UTIL_SET_STRING(json_config, proto_config, request_type); + JSON_UTIL_SET_DURATION(json_config, proto_config, timeout); +} + +void FilterJson::translateClientSslAuthFilter( + const Json::Object& json_config, envoy::api::v2::filter::network::ClientSSLAuth& proto_config) { + json_config.validateSchema(Json::Schema::CLIENT_SSL_NETWORK_FILTER_SCHEMA); + + JSON_UTIL_SET_STRING(json_config, proto_config, auth_api_cluster); + JSON_UTIL_SET_STRING(json_config, proto_config, stat_prefix); + JSON_UTIL_SET_DURATION(json_config, proto_config, refresh_delay); + + AddressJson::translateCidrRangeList(json_config.getStringArray("ip_white_list", true), + *proto_config.mutable_ip_white_list()); +} + } // namespace Config } // namespace Envoy diff --git a/source/common/config/filter_json.h b/source/common/config/filter_json.h index ef02a90fd840a..d62900f29389f 100644 --- a/source/common/config/filter_json.h +++ b/source/common/config/filter_json.h @@ -5,9 +5,12 @@ #include "api/filter/http/buffer.pb.h" #include "api/filter/http/fault.pb.h" #include "api/filter/http/health_check.pb.h" +#include "api/filter/http/rate_limit.pb.h" #include "api/filter/http/router.pb.h" +#include "api/filter/network/client_ssl_auth.pb.h" #include "api/filter/network/http_connection_manager.pb.h" #include "api/filter/network/mongo_proxy.pb.h" +#include "api/filter/network/rate_limit.pb.h" #include "api/filter/network/redis_proxy.pb.h" #include "api/filter/network/tcp_proxy.pb.h" @@ -19,92 +22,120 @@ class FilterJson { /** * Translate a v1 JSON access log filter object to v2 * envoy::api::v2::filter::accesslog::AccessLogFilter. - * @param json_access_log_filter source v1 JSON access log object. - * @param access_log_filter destination v2 envoy::api::v2::filter::accesslog::AccessLog. + * @param json_config source v1 JSON access log object. + * @param proto_config destination v2 envoy::api::v2::filter::accesslog::AccessLog. */ static void - translateAccessLogFilter(const Json::Object& json_access_log_filter, - envoy::api::v2::filter::accesslog::AccessLogFilter& access_log_filter); + translateAccessLogFilter(const Json::Object& json_config, + envoy::api::v2::filter::accesslog::AccessLogFilter& proto_config); /** * Translate a v1 JSON access log object to v2 envoy::api::v2::filter::accesslog::AccessLog. - * @param json_access_log source v1 JSON access log object. - * @param access_log destination v2 envoy::api::v2::filter::accesslog::AccessLog. + * @param json_config source v1 JSON access log object. + * @param proto_config destination v2 envoy::api::v2::filter::accesslog::AccessLog. */ - static void translateAccessLog(const Json::Object& json_access_log, - envoy::api::v2::filter::accesslog::AccessLog& access_log); + static void translateAccessLog(const Json::Object& json_config, + envoy::api::v2::filter::accesslog::AccessLog& proto_config); /** * Translate a v1 JSON HTTP connection manager object to v2 * envoy::api::v2::filter::network::HttpConnectionManager. - * @param json_http_connection_manager source v1 JSON HTTP connection manager object. - * @param http_connection_manager destination v2 + * @param json_config source v1 JSON HTTP connection manager object. + * @param proto_config destination v2 * envoy::api::v2::filter::network::HttpConnectionManager. */ static void translateHttpConnectionManager( - const Json::Object& json_http_connection_manager, - envoy::api::v2::filter::network::HttpConnectionManager& http_connection_manager); + const Json::Object& json_config, + envoy::api::v2::filter::network::HttpConnectionManager& proto_config); /** * Translate a v1 JSON Redis proxy object to v2 envoy::api::v2::filter::network::RedisProxy. - * @param json_redis_proxy source v1 JSON HTTP connection manager object. - * @param redis_proxy destination v2 + * @param json_config source v1 JSON HTTP connection manager object. + * @param proto_config destination v2 * envoy::api::v2::filter::network::RedisProxy. */ - static void translateRedisProxy(const Json::Object& json_redis_proxy, - envoy::api::v2::filter::network::RedisProxy& redis_proxy); + static void translateRedisProxy(const Json::Object& json_config, + envoy::api::v2::filter::network::RedisProxy& proto_config); /** * Translate a v1 JSON Mongo proxy object to v2 envoy::api::v2::filter::network::MongoProxy. - * @param json_mongo_proxy source v1 JSON HTTP connection manager object. - * @param mongo_proxy destination v2 + * @param json_config source v1 JSON HTTP connection manager object. + * @param proto_config destination v2 * envoy::api::v2::filter::network::MongoProxy. */ - static void translateMongoProxy(const Json::Object& json_mongo_proxy, - envoy::api::v2::filter::network::MongoProxy& mongo_proxy); + static void translateMongoProxy(const Json::Object& json_config, + envoy::api::v2::filter::network::MongoProxy& proto_config); /** * Translate a v1 JSON Fault filter object to v2 envoy::api::v2::filter::http::HTTPFault. - * @param json_fault source v1 JSON HTTP Fault Filter object. - * @param fault destination v2 + * @param json_config source v1 JSON HTTP Fault Filter object. + * @param proto_config destination v2 * envoy::api::v2::filter::http::HTTPFault. */ - static void translateFaultFilter(const Json::Object& json_fault, - envoy::api::v2::filter::http::HTTPFault& fault); + static void translateFaultFilter(const Json::Object& json_config, + envoy::api::v2::filter::http::HTTPFault& proto_config); /** * Translate a v1 JSON Health Check filter object to v2 envoy::api::v2::filter::http::HealthCheck. - * @param config source v1 JSON Health Check Filter object. - * @param health_check destination v2 + * @param json_config source v1 JSON Health Check Filter object. + * @param proto_config destination v2 * envoy::api::v2::filter::http::HealthCheck. */ - static void translateHealthCheckFilter(const Json::Object& config, - envoy::api::v2::filter::http::HealthCheck& health_check); + static void translateHealthCheckFilter(const Json::Object& json_config, + envoy::api::v2::filter::http::HealthCheck& proto_config); - /* + /** * Translate a v1 JSON Router object to v2 envoy::api::v2::filter::http::Router. - * @param json_router source v1 JSON HTTP router object. - * @param router destination v2 envoy::api::v2::filter::http::Router. + * @param json_config source v1 JSON HTTP router object. + * @param proto_config destination v2 envoy::api::v2::filter::http::Router. */ - static void translateRouter(const Json::Object& json_router, - envoy::api::v2::filter::http::Router& router); + static void translateRouter(const Json::Object& json_config, + envoy::api::v2::filter::http::Router& proto_config); /** * Translate a v1 JSON Buffer filter object to v2 envoy::api::v2::filter::http::Buffer. - * @param json_buffer source v1 JSON HTTP Buffer Filter object. - * @param buffer destination v2 + * @param json_config source v1 JSON HTTP Buffer Filter object. + * @param proto_config destination v2 * envoy::api::v2::filter::http::Buffer. */ - static void translateBufferFilter(const Json::Object& json_buffer, - envoy::api::v2::filter::http::Buffer& buffer); + static void translateBufferFilter(const Json::Object& json_config, + envoy::api::v2::filter::http::Buffer& proto_config); /** * Translate a v1 JSON TCP proxy filter object to a v2 envoy::api::v2::filter::network::TcpProxy. - * @param json_tcp_proxy source v1 JSON TCP proxy object. - * @param tcp_proxy destination v2 envoy::api::v2::filter::network::TcpProxy. + * @param json_config source v1 JSON TCP proxy object. + * @param proto_config destination v2 envoy::api::v2::filter::network::TcpProxy. + */ + static void translateTcpProxy(const Json::Object& json_config, + envoy::api::v2::filter::network::TcpProxy& proto_config); + + /** + * Translate a v1 JSON TCP Rate Limit filter object to v2 + * envoy::api::v2::filter::network::RateLimit. + * @param json_config source v1 JSON Tcp Rate Limit Filter object. + * @param proto_config destination v2 envoy::api::v2::filter::network::RateLimit. */ - static void translateTcpProxy(const Json::Object& json_tcp_proxy, - envoy::api::v2::filter::network::TcpProxy& tcp_proxy); + static void translateTcpRateLimitFilter(const Json::Object& json_config, + envoy::api::v2::filter::network::RateLimit& proto_config); + + /** + * Translate a v1 JSON HTTP Rate Limit filter object to v2 + * envoy::api::v2::filter::http::RateLimit. + * @param json_config source v1 JSON Http Rate Limit Filter object. + * @param proto_config destination v2 envoy::api::v2::filter::http::RateLimit. + */ + static void translateHttpRateLimitFilter(const Json::Object& json_config, + envoy::api::v2::filter::http::RateLimit& proto_config); + + /** + * Translate a v1 JSON Client SSL Auth filter object to v2 + * envoy::api::v2::filter::network::ClientSSLAuth. + * @param json_config source v1 JSON Client SSL Auth Filter object. + * @param proto_config destination v2 envoy::api::v2::filter::network::ClientSSLAuth. + */ + static void + translateClientSslAuthFilter(const Json::Object& json_config, + envoy::api::v2::filter::network::ClientSSLAuth& proto_config); }; } // namespace Config diff --git a/source/common/filter/BUILD b/source/common/filter/BUILD index 2373a04dfb689..86aa9848e25b2 100644 --- a/source/common/filter/BUILD +++ b/source/common/filter/BUILD @@ -25,14 +25,13 @@ envoy_cc_library( name = "ratelimit_lib", srcs = ["ratelimit.cc"], hdrs = ["ratelimit.h"], + external_deps = ["envoy_filter_network_rate_limit"], deps = [ "//include/envoy/network:connection_interface", "//include/envoy/network:filter_interface", "//include/envoy/ratelimit:ratelimit_interface", "//include/envoy/runtime:runtime_interface", "//include/envoy/stats:stats_macros", - "//source/common/json:config_schemas_lib", - "//source/common/json:json_loader_lib", "//source/common/tracing:http_tracer_lib", ], ) diff --git a/source/common/filter/auth/BUILD b/source/common/filter/auth/BUILD index 4484063b145e6..efc1aa64c0736 100644 --- a/source/common/filter/auth/BUILD +++ b/source/common/filter/auth/BUILD @@ -12,6 +12,7 @@ envoy_cc_library( name = "client_ssl_lib", srcs = ["client_ssl.cc"], hdrs = ["client_ssl.h"], + external_deps = ["envoy_filter_network_client_ssl_auth"], deps = [ "//include/envoy/network:connection_interface", "//include/envoy/network:filter_interface", diff --git a/source/common/filter/auth/client_ssl.cc b/source/common/filter/auth/client_ssl.cc index d6378136f5549..7d5f67f527960 100644 --- a/source/common/filter/auth/client_ssl.cc +++ b/source/common/filter/auth/client_ssl.cc @@ -11,7 +11,6 @@ #include "common/http/headers.h" #include "common/http/message_impl.h" #include "common/http/utility.h" -#include "common/json/config_schemas.h" #include "common/network/utility.h" #include "fmt/format.h" @@ -21,15 +20,14 @@ namespace Filter { namespace Auth { namespace ClientSsl { -Config::Config(const Json::Object& config, ThreadLocal::SlotAllocator& tls, - Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher, Stats::Scope& scope, - Runtime::RandomGenerator& random) - : RestApiFetcher(cm, config.getString("auth_api_cluster"), dispatcher, random, - std::chrono::milliseconds(config.getInteger("refresh_delay_ms", 60000))), - tls_(tls.allocateSlot()), ip_white_list_(config, "ip_white_list"), - stats_(generateStats(scope, config.getString("stat_prefix"))) { - - config.validateSchema(Json::Schema::CLIENT_SSL_NETWORK_FILTER_SCHEMA); +Config::Config(const envoy::api::v2::filter::network::ClientSSLAuth& config, + ThreadLocal::SlotAllocator& tls, Upstream::ClusterManager& cm, + Event::Dispatcher& dispatcher, Stats::Scope& scope, Runtime::RandomGenerator& random) + : RestApiFetcher( + cm, config.auth_api_cluster(), dispatcher, random, + std::chrono::milliseconds(PROTOBUF_GET_MS_OR_DEFAULT(config, refresh_delay, 60000))), + tls_(tls.allocateSlot()), ip_white_list_(config.ip_white_list()), + stats_(generateStats(scope, config.stat_prefix())) { if (!cm.get(remote_cluster_name_)) { throw EnvoyException( @@ -41,9 +39,10 @@ Config::Config(const Json::Object& config, ThreadLocal::SlotAllocator& tls, [empty](Event::Dispatcher&) -> ThreadLocal::ThreadLocalObjectSharedPtr { return empty; }); } -ConfigSharedPtr Config::create(const Json::Object& config, ThreadLocal::SlotAllocator& tls, - Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher, - Stats::Scope& scope, Runtime::RandomGenerator& random) { +ConfigSharedPtr Config::create(const envoy::api::v2::filter::network::ClientSSLAuth& config, + ThreadLocal::SlotAllocator& tls, Upstream::ClusterManager& cm, + Event::Dispatcher& dispatcher, Stats::Scope& scope, + Runtime::RandomGenerator& random) { ConfigSharedPtr new_config(new Config(config, tls, cm, dispatcher, scope, random)); new_config->initialize(); return new_config; diff --git a/source/common/filter/auth/client_ssl.h b/source/common/filter/auth/client_ssl.h index 68cdb2b94167a..4fe5ec5d5c8c7 100644 --- a/source/common/filter/auth/client_ssl.h +++ b/source/common/filter/auth/client_ssl.h @@ -12,9 +12,11 @@ #include "envoy/upstream/cluster_manager.h" #include "common/http/rest_api_fetcher.h" -#include "common/json/json_loader.h" #include "common/network/cidr_range.h" #include "common/network/utility.h" +#include "common/protobuf/utility.h" + +#include "api/filter/network/client_ssl_auth.pb.h" namespace Envoy { namespace Filter { @@ -73,16 +75,18 @@ typedef std::shared_ptr ConfigSharedPtr; */ class Config : public Http::RestApiFetcher { public: - static ConfigSharedPtr create(const Json::Object& config, ThreadLocal::SlotAllocator& tls, - Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher, - Stats::Scope& scope, Runtime::RandomGenerator& random); + static ConfigSharedPtr create(const envoy::api::v2::filter::network::ClientSSLAuth& config, + ThreadLocal::SlotAllocator& tls, Upstream::ClusterManager& cm, + Event::Dispatcher& dispatcher, Stats::Scope& scope, + Runtime::RandomGenerator& random); const AllowedPrincipals& allowedPrincipals(); const Network::Address::IpList& ipWhiteList() { return ip_white_list_; } GlobalStats& stats() { return stats_; } private: - Config(const Json::Object& config, ThreadLocal::SlotAllocator& tls, Upstream::ClusterManager& cm, + Config(const envoy::api::v2::filter::network::ClientSSLAuth& config, + ThreadLocal::SlotAllocator& tls, Upstream::ClusterManager& cm, Event::Dispatcher& dispatcher, Stats::Scope& scope, Runtime::RandomGenerator& random); static GlobalStats generateStats(Stats::Scope& scope, const std::string& prefix); diff --git a/source/common/filter/ratelimit.cc b/source/common/filter/ratelimit.cc index 5af1c4aff6734..350e25deeebfe 100644 --- a/source/common/filter/ratelimit.cc +++ b/source/common/filter/ratelimit.cc @@ -3,7 +3,6 @@ #include #include -#include "common/json/config_schemas.h" #include "common/tracing/http_tracer_impl.h" #include "fmt/format.h" @@ -12,16 +11,15 @@ namespace Envoy { namespace RateLimit { namespace TcpFilter { -Config::Config(const Json::Object& config, Stats::Scope& scope, Runtime::Loader& runtime) - : domain_(config.getString("domain")), - stats_(generateStats(config.getString("stat_prefix"), scope)), runtime_(runtime) { +Config::Config(const envoy::api::v2::filter::network::RateLimit& config, Stats::Scope& scope, + Runtime::Loader& runtime) + : domain_(config.domain()), stats_(generateStats(config.stat_prefix(), scope)), + runtime_(runtime) { - config.validateSchema(Json::Schema::RATELIMIT_NETWORK_FILTER_SCHEMA); - - for (const Json::ObjectSharedPtr& descriptor : config.getObjectArray("descriptors")) { + for (const auto& descriptor : config.descriptors()) { Descriptor new_descriptor; - for (const Json::ObjectSharedPtr& entry : descriptor->asObjectArray()) { - new_descriptor.entries_.push_back({entry->getString("key"), entry->getString("value")}); + for (const auto& entry : descriptor.entries()) { + new_descriptor.entries_.push_back({entry.key(), entry.value()}); } descriptors_.push_back(new_descriptor); } diff --git a/source/common/filter/ratelimit.h b/source/common/filter/ratelimit.h index af973b7c1d20c..b94c0774ed284 100644 --- a/source/common/filter/ratelimit.h +++ b/source/common/filter/ratelimit.h @@ -11,7 +11,7 @@ #include "envoy/runtime/runtime.h" #include "envoy/stats/stats_macros.h" -#include "common/json/json_loader.h" +#include "api/filter/network/rate_limit.pb.h" namespace Envoy { namespace RateLimit { @@ -42,7 +42,8 @@ struct InstanceStats { */ class Config { public: - Config(const Json::Object& config, Stats::Scope& scope, Runtime::Loader& runtime); + Config(const envoy::api::v2::filter::network::RateLimit& config, Stats::Scope& scope, + Runtime::Loader& runtime); const std::string& domain() { return domain_; } const std::vector& descriptors() { return descriptors_; } Runtime::Loader& runtime() { return runtime_; } diff --git a/source/common/http/filter/BUILD b/source/common/http/filter/BUILD index e2388b4d199ee..5b381e8c4442e 100644 --- a/source/common/http/filter/BUILD +++ b/source/common/http/filter/BUILD @@ -97,6 +97,7 @@ envoy_cc_library( envoy_cc_library( name = "ratelimit_includes", hdrs = ["ratelimit.h"], + external_deps = ["envoy_filter_http_rate_limit"], deps = [ "//include/envoy/http:filter_interface", "//include/envoy/local_info:local_info_interface", diff --git a/source/common/http/filter/ratelimit.h b/source/common/http/filter/ratelimit.h index cf472cca194e4..870209e007996 100644 --- a/source/common/http/filter/ratelimit.h +++ b/source/common/http/filter/ratelimit.h @@ -13,9 +13,8 @@ #include "common/common/assert.h" #include "common/http/header_map_impl.h" -#include "common/json/config_schemas.h" -#include "common/json/json_loader.h" -#include "common/json/json_validator.h" + +#include "api/filter/http/rate_limit.pb.h" namespace Envoy { namespace Http { @@ -29,14 +28,14 @@ enum class FilterRequestType { Internal, External, Both }; /** * Global configuration for the HTTP rate limit filter. */ -class FilterConfig : Json::Validator { +class FilterConfig { public: - FilterConfig(const Json::Object& config, const LocalInfo::LocalInfo& local_info, - Stats::Scope& scope, Runtime::Loader& runtime, Upstream::ClusterManager& cm) - : Json::Validator(config, Json::Schema::RATE_LIMIT_HTTP_FILTER_SCHEMA), - domain_(config.getString("domain")), - stage_(static_cast(config.getInteger("stage", 0))), - request_type_(stringToType(config.getString("request_type", "both"))), + FilterConfig(const envoy::api::v2::filter::http::RateLimit& config, + const LocalInfo::LocalInfo& local_info, Stats::Scope& scope, + Runtime::Loader& runtime, Upstream::ClusterManager& cm) + : domain_(config.domain()), stage_(static_cast(config.stage())), + request_type_(config.request_type().empty() ? stringToType("both") + : stringToType(config.request_type())), local_info_(local_info), scope_(scope), runtime_(runtime), cm_(cm) {} const std::string& domain() const { return domain_; } diff --git a/source/server/config/http/BUILD b/source/server/config/http/BUILD index 15adff3294718..d0f49704f5cbc 100644 --- a/source/server/config/http/BUILD +++ b/source/server/config/http/BUILD @@ -157,9 +157,11 @@ envoy_cc_library( deps = [ "//include/envoy/registry", "//include/envoy/server:filter_config_interface", + "//source/common/config:filter_json_lib", "//source/common/config:well_known_names", "//source/common/http/filter:ratelimit_includes", "//source/common/http/filter:ratelimit_lib", + "//source/common/protobuf:utility_lib", ], ) diff --git a/source/server/config/http/ratelimit.cc b/source/server/config/http/ratelimit.cc index 7a723e118e2d2..41d6e22dfd8ed 100644 --- a/source/server/config/http/ratelimit.cc +++ b/source/server/config/http/ratelimit.cc @@ -5,18 +5,20 @@ #include "envoy/registry/registry.h" +#include "common/config/filter_json.h" #include "common/http/filter/ratelimit.h" +#include "common/protobuf/utility.h" namespace Envoy { namespace Server { namespace Configuration { -HttpFilterFactoryCb RateLimitFilterConfig::createFilterFactory(const Json::Object& config, - const std::string&, - FactoryContext& context) { +HttpFilterFactoryCb +RateLimitFilterConfig::createFilter(const envoy::api::v2::filter::http::RateLimit& config, + const std::string&, FactoryContext& context) { Http::RateLimit::FilterConfigSharedPtr filter_config(new Http::RateLimit::FilterConfig( config, context.localInfo(), context.scope(), context.runtime(), context.clusterManager())); - const uint32_t timeout_ms = config.getInteger("timeout_ms", 20); + const uint32_t timeout_ms = PROTOBUF_GET_MS_OR_DEFAULT(config, timeout, 20); return [filter_config, timeout_ms, &context](Http::FilterChainFactoryCallbacks& callbacks) -> void { callbacks.addStreamDecoderFilter(Http::StreamDecoderFilterSharedPtr{new Http::RateLimit::Filter( @@ -24,6 +26,20 @@ HttpFilterFactoryCb RateLimitFilterConfig::createFilterFactory(const Json::Objec }; } +HttpFilterFactoryCb RateLimitFilterConfig::createFilterFactory(const Json::Object& json_config, + const std::string& stats_prefix, + FactoryContext& context) { + envoy::api::v2::filter::http::RateLimit config; + Config::FilterJson::translateHttpRateLimitFilter(json_config, config); + return createFilter(config, stats_prefix, context); +} + +HttpFilterFactoryCb RateLimitFilterConfig::createFilterFactoryFromProto( + const Protobuf::Message& config, const std::string& stats_prefix, FactoryContext& context) { + return createFilter(dynamic_cast(config), + stats_prefix, context); +} + /** * Static registration for the rate limit filter. @see RegisterFactory. */ diff --git a/source/server/config/http/ratelimit.h b/source/server/config/http/ratelimit.h index 0628601a63352..5c451bfaab633 100644 --- a/source/server/config/http/ratelimit.h +++ b/source/server/config/http/ratelimit.h @@ -6,6 +6,8 @@ #include "common/config/well_known_names.h" +#include "api/filter/http/rate_limit.pb.h" + namespace Envoy { namespace Server { namespace Configuration { @@ -17,7 +19,19 @@ class RateLimitFilterConfig : public NamedHttpFilterConfigFactory { public: HttpFilterFactoryCb createFilterFactory(const Json::Object& config, const std::string&, FactoryContext& context) override; + HttpFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message& config, + const std::string& stats_prefix, + FactoryContext& context) override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new envoy::api::v2::filter::http::RateLimit()}; + } + std::string name() override { return Config::HttpFilterNames::get().RATE_LIMIT; } + +private: + HttpFilterFactoryCb createFilter(const envoy::api::v2::filter::http::RateLimit& config, + const std::string& stats_prefix, FactoryContext& context); }; } // namespace Configuration diff --git a/source/server/config/network/BUILD b/source/server/config/network/BUILD index 8f789fa2a5ff0..e764f7f8e043e 100644 --- a/source/server/config/network/BUILD +++ b/source/server/config/network/BUILD @@ -15,6 +15,7 @@ envoy_cc_library( deps = [ "//include/envoy/registry", "//include/envoy/server:filter_config_interface", + "//source/common/config:filter_json_lib", "//source/common/config:well_known_names", "//source/common/filter/auth:client_ssl_lib", ], @@ -94,8 +95,10 @@ envoy_cc_library( deps = [ "//include/envoy/registry", "//include/envoy/server:filter_config_interface", + "//source/common/config:filter_json_lib", "//source/common/config:well_known_names", "//source/common/filter:ratelimit_lib", + "//source/common/protobuf:utility_lib", ], ) diff --git a/source/server/config/network/client_ssl_auth.cc b/source/server/config/network/client_ssl_auth.cc index 87cd67475c49a..ce7d5f08f3f07 100644 --- a/source/server/config/network/client_ssl_auth.cc +++ b/source/server/config/network/client_ssl_auth.cc @@ -5,24 +5,42 @@ #include "envoy/network/connection.h" #include "envoy/registry/registry.h" +#include "common/config/filter_json.h" #include "common/filter/auth/client_ssl.h" namespace Envoy { namespace Server { namespace Configuration { -NetworkFilterFactoryCb -ClientSslAuthConfigFactory::createFilterFactory(const Json::Object& json_config, - FactoryContext& context) { - Filter::Auth::ClientSsl::ConfigSharedPtr config(Filter::Auth::ClientSsl::Config::create( - json_config, context.threadLocal(), context.clusterManager(), context.dispatcher(), +NetworkFilterFactoryCb ClientSslAuthConfigFactory::createFilter( + const envoy::api::v2::filter::network::ClientSSLAuth& config, FactoryContext& context) { + ASSERT(!config.auth_api_cluster().empty()); + ASSERT(!config.stat_prefix().empty()); + + Filter::Auth::ClientSsl::ConfigSharedPtr filter_config(Filter::Auth::ClientSsl::Config::create( + config, context.threadLocal(), context.clusterManager(), context.dispatcher(), context.scope(), context.random())); - return [config](Network::FilterManager& filter_manager) -> void { + return [filter_config](Network::FilterManager& filter_manager) -> void { filter_manager.addReadFilter( - Network::ReadFilterSharedPtr{new Filter::Auth::ClientSsl::Instance(config)}); + Network::ReadFilterSharedPtr{new Filter::Auth::ClientSsl::Instance(filter_config)}); }; } +NetworkFilterFactoryCb +ClientSslAuthConfigFactory::createFilterFactory(const Json::Object& json_config, + FactoryContext& context) { + envoy::api::v2::filter::network::ClientSSLAuth config; + Config::FilterJson::translateClientSslAuthFilter(json_config, config); + return createFilter(config, context); +} + +NetworkFilterFactoryCb +ClientSslAuthConfigFactory::createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) { + return createFilter(dynamic_cast(config), + context); +} + /** * Static registration for the client SSL auth filter. @see RegisterFactory. */ diff --git a/source/server/config/network/client_ssl_auth.h b/source/server/config/network/client_ssl_auth.h index b738633937f11..7b6ccddaf7a60 100644 --- a/source/server/config/network/client_ssl_auth.h +++ b/source/server/config/network/client_ssl_auth.h @@ -6,6 +6,8 @@ #include "common/config/well_known_names.h" +#include "api/filter/network/client_ssl_auth.pb.h" + namespace Envoy { namespace Server { namespace Configuration { @@ -16,9 +18,20 @@ namespace Configuration { class ClientSslAuthConfigFactory : public NamedNetworkFilterConfigFactory { public: // NamedNetworkFilterConfigFactory - NetworkFilterFactoryCb createFilterFactory(const Json::Object& json_config, + NetworkFilterFactoryCb createFilterFactory(const Json::Object& config, FactoryContext& context) override; + NetworkFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new envoy::api::v2::filter::network::ClientSSLAuth()}; + } + std::string name() override { return Config::NetworkFilterNames::get().CLIENT_SSL_AUTH; } + +private: + NetworkFilterFactoryCb createFilter(const envoy::api::v2::filter::network::ClientSSLAuth& config, + FactoryContext& context); }; } // namespace Configuration diff --git a/source/server/config/network/echo.cc b/source/server/config/network/echo.cc index aa1501b051789..dbe65519d2660 100644 --- a/source/server/config/network/echo.cc +++ b/source/server/config/network/echo.cc @@ -22,6 +22,17 @@ class EchoConfigFactory : public NamedNetworkFilterConfigFactory { }; } + NetworkFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message&, + FactoryContext&) override { + return [](Network::FilterManager& filter_manager) -> void { + filter_manager.addReadFilter(Network::ReadFilterSharedPtr{new Filter::Echo()}); + }; + } + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new Envoy::ProtobufWkt::Empty()}; + } + std::string name() override { return Config::NetworkFilterNames::get().ECHO; } }; diff --git a/source/server/config/network/ratelimit.cc b/source/server/config/network/ratelimit.cc index d08a08e033d87..7eb596061d024 100644 --- a/source/server/config/network/ratelimit.cc +++ b/source/server/config/network/ratelimit.cc @@ -6,23 +6,46 @@ #include "envoy/network/connection.h" #include "envoy/registry/registry.h" +#include "common/config/filter_json.h" #include "common/filter/ratelimit.h" +#include "common/protobuf/utility.h" namespace Envoy { namespace Server { namespace Configuration { -NetworkFilterFactoryCb RateLimitConfigFactory::createFilterFactory(const Json::Object& json_config, - FactoryContext& context) { - RateLimit::TcpFilter::ConfigSharedPtr config( - new RateLimit::TcpFilter::Config(json_config, context.scope(), context.runtime())); - const uint32_t timeout_ms = json_config.getInteger("timeout_ms", 20); - return [config, timeout_ms, &context](Network::FilterManager& filter_manager) -> void { +NetworkFilterFactoryCb +RateLimitConfigFactory::createFilter(const envoy::api::v2::filter::network::RateLimit& config, + FactoryContext& context) { + + ASSERT(!config.stat_prefix().empty()); + ASSERT(!config.domain().empty()); + ASSERT(config.descriptors_size() > 0); + + RateLimit::TcpFilter::ConfigSharedPtr filter_config( + new RateLimit::TcpFilter::Config(config, context.scope(), context.runtime())); + const uint32_t timeout_ms = PROTOBUF_GET_MS_OR_DEFAULT(config, timeout, 20); + + return [filter_config, timeout_ms, &context](Network::FilterManager& filter_manager) -> void { filter_manager.addReadFilter(Network::ReadFilterSharedPtr{new RateLimit::TcpFilter::Instance( - config, context.rateLimitClient(std::chrono::milliseconds(timeout_ms)))}); + filter_config, context.rateLimitClient(std::chrono::milliseconds(timeout_ms)))}); }; } +NetworkFilterFactoryCb RateLimitConfigFactory::createFilterFactory(const Json::Object& json_config, + FactoryContext& context) { + envoy::api::v2::filter::network::RateLimit config; + Config::FilterJson::translateTcpRateLimitFilter(json_config, config); + return createFilter(config, context); +} + +NetworkFilterFactoryCb +RateLimitConfigFactory::createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) { + return createFilter(dynamic_cast(config), + context); +} + /** * Static registration for the rate limit filter. @see RegisterFactory. */ diff --git a/source/server/config/network/ratelimit.h b/source/server/config/network/ratelimit.h index c0d03f9d95b6b..d98f3faaf355d 100644 --- a/source/server/config/network/ratelimit.h +++ b/source/server/config/network/ratelimit.h @@ -6,6 +6,8 @@ #include "common/config/well_known_names.h" +#include "api/filter/network/rate_limit.pb.h" + namespace Envoy { namespace Server { namespace Configuration { @@ -18,7 +20,19 @@ class RateLimitConfigFactory : public NamedNetworkFilterConfigFactory { // NamedNetworkFilterConfigFactory NetworkFilterFactoryCb createFilterFactory(const Json::Object& json_config, FactoryContext& context) override; + + NetworkFilterFactoryCb createFilterFactoryFromProto(const Protobuf::Message& config, + FactoryContext& context) override; + + ProtobufTypes::MessagePtr createEmptyConfigProto() override { + return ProtobufTypes::MessagePtr{new envoy::api::v2::filter::network::RateLimit()}; + } + std::string name() override { return Config::NetworkFilterNames::get().RATE_LIMIT; } + +private: + NetworkFilterFactoryCb createFilter(const envoy::api::v2::filter::network::RateLimit& config, + FactoryContext& context); }; } // namespace Configuration diff --git a/test/common/filter/BUILD b/test/common/filter/BUILD index 4bb1ad8e5f19f..c7143cf90149b 100644 --- a/test/common/filter/BUILD +++ b/test/common/filter/BUILD @@ -13,6 +13,7 @@ envoy_cc_test( srcs = ["ratelimit_test.cc"], deps = [ "//source/common/buffer:buffer_lib", + "//source/common/config:filter_json_lib", "//source/common/event:dispatcher_lib", "//source/common/filter:ratelimit_lib", "//source/common/stats:stats_lib", diff --git a/test/common/filter/auth/BUILD b/test/common/filter/auth/BUILD index 690b9059fd78d..9f0be4ac51a92 100644 --- a/test/common/filter/auth/BUILD +++ b/test/common/filter/auth/BUILD @@ -13,6 +13,7 @@ envoy_cc_test( srcs = ["client_ssl_test.cc"], data = glob(["test_data/**"]), deps = [ + "//source/common/config:filter_json_lib", "//source/common/event:dispatcher_lib", "//source/common/filesystem:filesystem_lib", "//source/common/filter/auth:client_ssl_lib", diff --git a/test/common/filter/auth/client_ssl_test.cc b/test/common/filter/auth/client_ssl_test.cc index 72728add83e7b..27cfb71062e5d 100644 --- a/test/common/filter/auth/client_ssl_test.cc +++ b/test/common/filter/auth/client_ssl_test.cc @@ -2,6 +2,7 @@ #include #include +#include "common/config/filter_json.h" #include "common/filesystem/filesystem_impl.h" #include "common/filter/auth/client_ssl.h" #include "common/http/message_impl.h" @@ -38,6 +39,22 @@ TEST(ClientSslAuthAllowedPrincipalsTest, EmptyString) { EXPECT_EQ(0UL, principals.size()); } +TEST(ClientSslAuthConfigTest, BadClientSslAuthConfig) { + std::string json = R"EOF( + { + "stat_prefix": "my_stat_prefix", + "auth_api_cluster" : "fake_cluster", + "ip_white_list": ["192.168.3.0/24"], + "test" : "a" + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json); + envoy::api::v2::filter::network::ClientSSLAuth proto_config{}; + EXPECT_THROW(Envoy::Config::FilterJson::translateClientSslAuthFilter(*json_config, proto_config), + Json::Exception); +} + class ClientSslAuthFilterTest : public testing::Test { public: ClientSslAuthFilterTest() @@ -56,10 +73,12 @@ class ClientSslAuthFilterTest : public testing::Test { } )EOF"; - Json::ObjectSharedPtr loader = Json::Factory::loadFromString(json); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json); + envoy::api::v2::filter::network::ClientSSLAuth proto_config{}; + Envoy::Config::FilterJson::translateClientSslAuthFilter(*json_config, proto_config); EXPECT_CALL(cm_, get("vpn")); setupRequest(); - config_ = Config::create(*loader, tls_, cm_, dispatcher_, stats_store_, random_); + config_ = Config::create(proto_config, tls_, cm_, dispatcher_, stats_store_, random_); createAuthFilter(); } @@ -103,27 +122,14 @@ TEST_F(ClientSslAuthFilterTest, NoCluster) { } )EOF"; - Json::ObjectSharedPtr loader = Json::Factory::loadFromString(json); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json); + envoy::api::v2::filter::network::ClientSSLAuth proto_config{}; + Envoy::Config::FilterJson::translateClientSslAuthFilter(*json_config, proto_config); EXPECT_CALL(cm_, get("bad_cluster")).WillOnce(Return(nullptr)); - EXPECT_THROW(Config::create(*loader, tls_, cm_, dispatcher_, stats_store_, random_), + EXPECT_THROW(Config::create(proto_config, tls_, cm_, dispatcher_, stats_store_, random_), EnvoyException); } -TEST_F(ClientSslAuthFilterTest, BadClientSslAuthConfig) { - std::string json_string = R"EOF( - { - "stat_prefix": "my_stat_prefix", - "auth_api_cluster" : "fake_cluster", - "ip_white_list": ["192.168.3.0/24"], - "test" : "a" - } - )EOF"; - - Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); - EXPECT_THROW(Config::create(*json_config, tls_, cm_, dispatcher_, stats_store_, random_), - Json::Exception); -} - TEST_F(ClientSslAuthFilterTest, NoSsl) { setup(); Buffer::OwnedImpl dummy("hello"); diff --git a/test/common/filter/ratelimit_test.cc b/test/common/filter/ratelimit_test.cc index b192c7f2c0ced..aca4d6ca8a831 100644 --- a/test/common/filter/ratelimit_test.cc +++ b/test/common/filter/ratelimit_test.cc @@ -3,7 +3,9 @@ #include #include "common/buffer/buffer_impl.h" +#include "common/config/filter_json.h" #include "common/filter/ratelimit.h" +#include "common/json/json_loader.h" #include "common/stats/stats_impl.h" #include "test/mocks/network/mocks.h" @@ -45,8 +47,10 @@ class RateLimitFilterTest : public testing::Test { ON_CALL(runtime_.snapshot_, featureEnabled("ratelimit.tcp_filter_enforcing", 100)) .WillByDefault(Return(true)); - Json::ObjectSharedPtr config = Json::Factory::loadFromString(json); - config_.reset(new Config(*config, stats_store_, runtime_)); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json); + envoy::api::v2::filter::network::RateLimit proto_config{}; + Envoy::Config::FilterJson::translateTcpRateLimitFilter(*json_config, proto_config); + config_.reset(new Config(proto_config, stats_store_, runtime_)); client_ = new MockClient(); filter_.reset(new Instance(config_, ClientPtr{client_})); filter_->initializeReadFilterCallbacks(filter_callbacks_); @@ -82,7 +86,10 @@ TEST_F(RateLimitFilterTest, BadRatelimitConfig) { )EOF"; Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); - EXPECT_THROW(Config(*json_config, stats_store_, runtime_), Json::Exception); + envoy::api::v2::filter::network::RateLimit proto_config{}; + + EXPECT_THROW(Envoy::Config::FilterJson::translateTcpRateLimitFilter(*json_config, proto_config), + Json::Exception); } TEST_F(RateLimitFilterTest, OK) { diff --git a/test/common/http/filter/BUILD b/test/common/http/filter/BUILD index 23e6be51a63c0..2d5dcaa896965 100644 --- a/test/common/http/filter/BUILD +++ b/test/common/http/filter/BUILD @@ -75,6 +75,7 @@ envoy_cc_test( deps = [ "//source/common/buffer:buffer_lib", "//source/common/common:empty_string", + "//source/common/config:filter_json_lib", "//source/common/http:headers_lib", "//source/common/http/filter:ratelimit_includes", "//source/common/http/filter:ratelimit_lib", diff --git a/test/common/http/filter/ratelimit_test.cc b/test/common/http/filter/ratelimit_test.cc index c6ba58ff4fd5e..50829de720428 100644 --- a/test/common/http/filter/ratelimit_test.cc +++ b/test/common/http/filter/ratelimit_test.cc @@ -4,6 +4,7 @@ #include "common/buffer/buffer_impl.h" #include "common/common/empty_string.h" +#include "common/config/filter_json.h" #include "common/http/filter/ratelimit.h" #include "common/http/headers.h" @@ -44,8 +45,10 @@ class HttpRateLimitFilterTest : public testing::Test { } void SetUpTest(const std::string json) { - Json::ObjectSharedPtr config = Json::Factory::loadFromString(json); - config_.reset(new FilterConfig(*config, local_info_, stats_store_, runtime_, cm_)); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json); + envoy::api::v2::filter::http::RateLimit proto_config{}; + Config::FilterJson::translateHttpRateLimitFilter(*json_config, proto_config); + config_.reset(new FilterConfig(proto_config, local_info_, stats_store_, runtime_, cm_)); client_ = new Envoy::RateLimit::MockClient(); filter_.reset(new Filter(config_, Envoy::RateLimit::ClientPtr{client_})); @@ -89,8 +92,10 @@ TEST_F(HttpRateLimitFilterTest, BadConfig) { } )EOF"; - Json::ObjectSharedPtr config = Json::Factory::loadFromString(filter_config); - EXPECT_THROW(FilterConfig(*config, local_info_, stats_store_, runtime_, cm_), Json::Exception); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(filter_config); + envoy::api::v2::filter::http::RateLimit proto_config{}; + EXPECT_THROW(Config::FilterJson::translateHttpRateLimitFilter(*json_config, proto_config), + Json::Exception); } TEST_F(HttpRateLimitFilterTest, NoRoute) { diff --git a/test/common/network/BUILD b/test/common/network/BUILD index b94d59af311d0..0c3f270809ee4 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -75,6 +75,7 @@ envoy_cc_test( srcs = ["filter_manager_impl_test.cc"], deps = [ "//source/common/buffer:buffer_lib", + "//source/common/config:filter_json_lib", "//source/common/event:dispatcher_lib", "//source/common/filter:ratelimit_lib", "//source/common/filter:tcp_proxy_lib", diff --git a/test/common/network/filter_manager_impl_test.cc b/test/common/network/filter_manager_impl_test.cc index 36cd6454a063a..78e502c0b6e67 100644 --- a/test/common/network/filter_manager_impl_test.cc +++ b/test/common/network/filter_manager_impl_test.cc @@ -2,6 +2,7 @@ #include #include "common/buffer/buffer_impl.h" +#include "common/config/filter_json.h" #include "common/filter/ratelimit.h" #include "common/filter/tcp_proxy.h" #include "common/network/filter_manager_impl.h" @@ -119,10 +120,12 @@ TEST_F(NetworkFilterManagerTest, RateLimitAndTcpProxy) { featureEnabled("ratelimit.tcp_filter_enforcing", 100)) .WillByDefault(Return(true)); - Json::ObjectSharedPtr rl_config_loader = Json::Factory::loadFromString(rl_json); + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(rl_json); + envoy::api::v2::filter::network::RateLimit proto_config{}; + Config::FilterJson::translateTcpRateLimitFilter(*json_config, proto_config); RateLimit::TcpFilter::ConfigSharedPtr rl_config(new RateLimit::TcpFilter::Config( - *rl_config_loader, factory_context.scope_, factory_context.runtime_loader_)); + proto_config, factory_context.scope_, factory_context.runtime_loader_)); RateLimit::MockClient* rl_client = new RateLimit::MockClient(); manager.addReadFilter(ReadFilterSharedPtr{ new RateLimit::TcpFilter::Instance(rl_config, RateLimit::ClientPtr{rl_client})}); diff --git a/test/config/utility.cc b/test/config/utility.cc index 5b7297042cb2b..2ef948b535980 100644 --- a/test/config/utility.cc +++ b/test/config/utility.cc @@ -55,18 +55,14 @@ const std::string ConfigHelper::DEFAULT_BUFFER_FILTER = R"EOF( name: envoy.buffer config: - deprecated_v1: true - value: max_request_bytes : 5242880 - max_request_time_s : 120 + max_request_time : 120s )EOF"; const std::string ConfigHelper::DEFAULT_HEALTH_CHECK_FILTER = R"EOF( name: envoy.health_check config: - deprecated_v1: true - value: pass_through_mode: false endpoint: /healthcheck )EOF"; diff --git a/test/integration/ratelimit_integration_test.cc b/test/integration/ratelimit_integration_test.cc index 8e497497cfe08..563a640317f22 100644 --- a/test/integration/ratelimit_integration_test.cc +++ b/test/integration/ratelimit_integration_test.cc @@ -29,8 +29,7 @@ class RatelimitIntegrationTest : public HttpIntegrationTest, void initialize() override { config_helper_.addFilter( - "{ name: envoy.rate_limit, config: { deprecated_v1: true, value: { domain: " - "some_domain, timeout_ms: 500 } } }"); + "{ name: envoy.rate_limit, config: { domain: some_domain, timeout: 0.5s } }"); config_helper_.addConfigModifier([](envoy::api::v2::Bootstrap& bootstrap) { bootstrap.mutable_rate_limit_service()->set_cluster_name("ratelimit"); auto* ratelimit_cluster = bootstrap.mutable_static_resources()->add_clusters(); diff --git a/test/server/config/http/config_test.cc b/test/server/config/http/config_test.cc index 673fc4c1b2d5e..cdf3b73cb8358 100644 --- a/test/server/config/http/config_test.cc +++ b/test/server/config/http/config_test.cc @@ -4,6 +4,7 @@ #include "common/config/filter_json.h" #include "common/config/well_known_names.h" +#include "common/json/json_loader.h" #include "common/protobuf/protobuf.h" #include "common/protobuf/utility.h" #include "common/router/router.h" @@ -96,7 +97,7 @@ TEST(HttpFilterConfigTest, BufferFilterWithEmptyProto) { cb(filter_callback); } -TEST(HttpFilterConfigTest, RateLimitFilter) { +TEST(HttpFilterConfigTest, RateLimitFilterCorrectJson) { std::string json_string = R"EOF( { "domain" : "test", @@ -113,6 +114,49 @@ TEST(HttpFilterConfigTest, RateLimitFilter) { cb(filter_callback); } +TEST(HttpFilterConfigTest, RateLimitFilterCorrectProto) { + std::string json_string = R"EOF( + { + "domain" : "test", + "timeout_ms" : 1337 + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + envoy::api::v2::filter::http::RateLimit proto_config{}; + Envoy::Config::FilterJson::translateHttpRateLimitFilter(*json_config, proto_config); + + NiceMock context; + RateLimitFilterConfig factory; + HttpFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, "stats", context); + Http::MockFilterChainFactoryCallbacks filter_callback; + EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); + cb(filter_callback); +} + +TEST(HttpFilterConfigTest, RateLimitFilterEmptyProto) { + std::string json_string = R"EOF( + { + "domain" : "test", + "timeout_ms" : 1337 + } + )EOF"; + + NiceMock context; + RateLimitFilterConfig factory; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + envoy::api::v2::filter::http::RateLimit proto_config = + *dynamic_cast( + factory.createEmptyConfigProto().get()); + Envoy::Config::FilterJson::translateHttpRateLimitFilter(*json_config, proto_config); + + HttpFilterFactoryCb cb = factory.createFilterFactory(*json_config, "stats", context); + Http::MockFilterChainFactoryCallbacks filter_callback; + EXPECT_CALL(filter_callback, addStreamDecoderFilter(_)); + cb(filter_callback); +} + TEST(HttpFilterConfigTest, BadRateLimitFilterConfig) { std::string json_string = R"EOF( { @@ -142,7 +186,7 @@ TEST(HttpFilterConfigTest, DynamoFilter) { cb(filter_callback); } -TEST(HttpFilterConfigTest, CorrectFaultFilterInJson) { +TEST(HttpFilterConfigTest, FaultFilterCorrectJson) { std::string json_string = R"EOF( { "delay" : { @@ -162,7 +206,7 @@ TEST(HttpFilterConfigTest, CorrectFaultFilterInJson) { cb(filter_callback); } -TEST(HttpFilterConfigTest, CorrectFaultFilterInProto) { +TEST(HttpFilterConfigTest, FaultFilterCorrectProto) { envoy::api::v2::filter::http::HTTPFault config{}; config.mutable_delay()->set_percent(100); config.mutable_delay()->mutable_fixed_delay()->set_seconds(5); @@ -182,7 +226,7 @@ TEST(HttpFilterConfigTest, InvalidFaultFilterInProto) { EXPECT_THROW(factory.createFilterFactoryFromProto(config, "stats", context), EnvoyException); } -TEST(HttpFilterConfigTest, FaultFilterWithEmptyProto) { +TEST(HttpFilterConfigTest, FaultFilterEmptyProto) { NiceMock context; FaultFilterConfig factory; EXPECT_THROW( diff --git a/test/server/config/network/config_test.cc b/test/server/config/network/config_test.cc index 247f7bb356fb0..742b3dea5900d 100644 --- a/test/server/config/network/config_test.cc +++ b/test/server/config/network/config_test.cc @@ -3,6 +3,7 @@ #include "envoy/registry/registry.h" #include "common/access_log/access_log_impl.h" +#include "common/config/filter_json.h" #include "common/config/well_known_names.h" #include "common/dynamo/dynamo_filter.h" @@ -57,30 +58,38 @@ TEST(NetworkFilterConfigTest, RedisProxyCorrectProto) { } )EOF"; - envoy::api::v2::filter::network::RedisProxy config{}; - config.set_cluster("fake_cluster"); - config.set_stat_prefix("foo"); - config.mutable_settings()->mutable_op_timeout()->set_seconds(1); - + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + envoy::api::v2::filter::network::RedisProxy proto_config{}; + Config::FilterJson::translateRedisProxy(*json_config, proto_config); NiceMock context; RedisProxyFilterConfigFactory factory; - NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(config, context); + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); Network::MockConnection connection; EXPECT_CALL(connection, addReadFilter(_)); cb(connection); } TEST(NetworkFilterConfigTest, RedisProxyEmptyProto) { + std::string json_string = R"EOF( + { + "cluster_name": "fake_cluster", + "stat_prefix": "foo", + "conn_pool": { + "op_timeout_ms": 20 + } + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); NiceMock context; RedisProxyFilterConfigFactory factory; - envoy::api::v2::filter::network::RedisProxy config = + envoy::api::v2::filter::network::RedisProxy proto_config = *dynamic_cast( factory.createEmptyConfigProto().get()); - config.set_cluster("fake_cluster"); - config.set_stat_prefix("foo"); - config.mutable_settings()->mutable_op_timeout()->set_seconds(1); - NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(config, context); + Config::FilterJson::translateRedisProxy(*json_config, proto_config); + + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); Network::MockConnection connection; EXPECT_CALL(connection, addReadFilter(_)); cb(connection); @@ -144,7 +153,7 @@ INSTANTIATE_TEST_CASE_P(IpList, IpWhiteListConfigTest, ::testing::Values(R"EOF(["192.168.3.0/24"])EOF", R"EOF(["2001:abcd::/64"])EOF")); -TEST_P(IpWhiteListConfigTest, ClientSslAuth) { +TEST_P(IpWhiteListConfigTest, ClientSslAuthCorrectJson) { std::string json_string = R"EOF( { "stat_prefix": "my_stat_prefix", @@ -163,7 +172,52 @@ TEST_P(IpWhiteListConfigTest, ClientSslAuth) { cb(connection); } -TEST(NetworkFilterConfigTest, Ratelimit) { +TEST_P(IpWhiteListConfigTest, ClientSslAuthCorrectProto) { + std::string json_string = R"EOF( + { + "stat_prefix": "my_stat_prefix", + "auth_api_cluster" : "fake_cluster", + "ip_white_list":)EOF" + GetParam() + + R"EOF( + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + envoy::api::v2::filter::network::ClientSSLAuth proto_config{}; + Envoy::Config::FilterJson::translateClientSslAuthFilter(*json_config, proto_config); + NiceMock context; + ClientSslAuthConfigFactory factory; + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); + Network::MockConnection connection; + EXPECT_CALL(connection, addReadFilter(_)); + cb(connection); +} + +TEST_P(IpWhiteListConfigTest, ClientSslAuthEmptyProto) { + std::string json_string = R"EOF( + { + "stat_prefix": "my_stat_prefix", + "auth_api_cluster" : "fake_cluster", + "ip_white_list":)EOF" + GetParam() + + R"EOF( + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + NiceMock context; + ClientSslAuthConfigFactory factory; + envoy::api::v2::filter::network::ClientSSLAuth proto_config = + *dynamic_cast( + factory.createEmptyConfigProto().get()); + + Envoy::Config::FilterJson::translateClientSslAuthFilter(*json_config, proto_config); + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); + Network::MockConnection connection; + EXPECT_CALL(connection, addReadFilter(_)); + cb(connection); +} + +TEST(NetworkFilterConfigTest, RatelimitCorrectJson) { std::string json_string = R"EOF( { "stat_prefix": "my_stat_prefix", @@ -182,6 +236,53 @@ TEST(NetworkFilterConfigTest, Ratelimit) { cb(connection); } +TEST(NetworkFilterConfigTest, RatelimitCorrectProto) { + std::string json_string = R"EOF( + { + "stat_prefix": "my_stat_prefix", + "domain" : "fake_domain", + "descriptors": [[{ "key" : "my_key", "value" : "my_value" }]], + "timeout_ms": 1337 + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + envoy::api::v2::filter::network::RateLimit proto_config{}; + Config::FilterJson::translateTcpRateLimitFilter(*json_config, proto_config); + + NiceMock context; + RateLimitConfigFactory factory; + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); + Network::MockConnection connection; + EXPECT_CALL(connection, addReadFilter(_)); + cb(connection); +} + +TEST(NetworkFilterConfigTest, RatelimitEmptyProto) { + std::string json_string = R"EOF( + { + "stat_prefix": "my_stat_prefix", + "domain" : "fake_domain", + "descriptors": [[{ "key" : "my_key", "value" : "my_value" }]], + "timeout_ms": 1337 + } + )EOF"; + + Json::ObjectSharedPtr json_config = Json::Factory::loadFromString(json_string); + + NiceMock context; + RateLimitConfigFactory factory; + envoy::api::v2::filter::network::RateLimit proto_config = + *dynamic_cast( + factory.createEmptyConfigProto().get()); + Config::FilterJson::translateTcpRateLimitFilter(*json_config, proto_config); + + NetworkFilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, context); + Network::MockConnection connection; + EXPECT_CALL(connection, addReadFilter(_)); + cb(connection); +} + TEST(NetworkFilterConfigTest, BadHttpConnectionMangerConfig) { std::string json_string = R"EOF( {