-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
INCOMPLETE: upstream: add filter chains to upstream connections (#173) #3571
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
#include "envoy/event/timer.h" | ||
#include "envoy/network/dns.h" | ||
#include "envoy/server/transport_socket_config.h" | ||
#include "envoy/server/filter_config.h" | ||
#include "envoy/ssl/context_manager.h" | ||
#include "envoy/upstream/health_checker.h" | ||
|
||
|
@@ -33,6 +34,7 @@ | |
#include "common/upstream/original_dst_cluster.h" | ||
|
||
#include "extensions/transport_sockets/well_known_names.h" | ||
#include "server/configuration_impl.h" // TODO(alanconway): bad dependency | ||
|
||
namespace Envoy { | ||
namespace Upstream { | ||
|
@@ -135,6 +137,7 @@ HostImpl::createConnection(Event::Dispatcher& dispatcher, const ClusterInfo& clu | |
address, cluster.sourceAddress(), cluster.transportSocketFactory().createTransportSocket(), | ||
connection_options); | ||
connection->setBufferLimits(cluster.perConnectionBufferLimitBytes()); | ||
cluster.createNetworkFilters(*connection); | ||
return connection; | ||
} | ||
|
||
|
@@ -253,6 +256,30 @@ ClusterLoadReportStats ClusterInfoImpl::generateLoadReportStats(Stats::Scope& sc | |
return {ALL_CLUSTER_LOAD_REPORT_STATS(POOL_COUNTER(scope))}; | ||
} | ||
|
||
// TODO(alanconway): dummy factory context, how do we implement this? Some of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the only fields that are listener-specific are listenerScope(), listenerMetadata(), and possibly drainDecision(). listenerScope() is only used in a few places in the code-base. We may be able to leave it NOT_IMPLEMENTED here, or maybe rename it to ownerScope() or something more generic, and pass it the cluster's scope. listenerMetadata() isn't called anywhere except one test. Can it be deleted? Or am I missing something? |
||
// the methods are listener specific, should they throw, return null values, return | ||
// values derived from the Cluster or be moved/removed? | ||
class ClusterInfoImpl::FactoryContextImpl : public Server::Configuration::FactoryContext { | ||
public: | ||
AccessLog::AccessLogManager& accessLogManager() override { NOT_IMPLEMENTED; } | ||
Upstream::ClusterManager& clusterManager() override { NOT_IMPLEMENTED; } | ||
Event::Dispatcher& dispatcher() override { NOT_IMPLEMENTED; } | ||
bool healthCheckFailed() override { NOT_IMPLEMENTED; } | ||
Tracing::HttpTracer& httpTracer() override { NOT_IMPLEMENTED; } | ||
const LocalInfo::LocalInfo& localInfo() const override { NOT_IMPLEMENTED; } | ||
Envoy::Runtime::RandomGenerator& random() override { NOT_IMPLEMENTED; } | ||
RateLimit::ClientPtr rateLimitClient(const absl::optional<std::chrono::milliseconds>&) override { NOT_IMPLEMENTED; } | ||
Envoy::Runtime::Loader& runtime() override { NOT_IMPLEMENTED; } | ||
Singleton::Manager& singletonManager() override { NOT_IMPLEMENTED; } | ||
ThreadLocal::Instance& threadLocal() override { NOT_IMPLEMENTED; } | ||
Server::Admin& admin() override { NOT_IMPLEMENTED; } | ||
Init::Manager& initManager() override { NOT_IMPLEMENTED; } | ||
Stats::Scope& listenerScope() override { NOT_IMPLEMENTED; } | ||
Stats::Scope& scope() override { NOT_IMPLEMENTED; } | ||
const envoy::api::v2::core::Metadata& listenerMetadata() const override { NOT_IMPLEMENTED; } | ||
Network::DrainDecision& drainDecision() override { NOT_IMPLEMENTED; } | ||
}; | ||
|
||
ClusterInfoImpl::ClusterInfoImpl(const envoy::api::v2::Cluster& config, | ||
const envoy::api::v2::core::BindConfig& bind_config, | ||
Runtime::Loader& runtime, Stats::Store& stats, | ||
|
@@ -340,6 +367,30 @@ ClusterInfoImpl::ClusterInfoImpl(const envoy::api::v2::Cluster& config, | |
idle_timeout_ = std::chrono::milliseconds( | ||
DurationUtil::durationToMilliseconds(config.common_http_protocol_options().idle_timeout())); | ||
} | ||
|
||
auto filters = config.filters(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks very similar to the code in listemer_manager_impl. Dedupe? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep, cut-and-paste. It should be pulled up to a common place. Thought I had a TODO on that one, well spotted. |
||
for (ssize_t i = 0; i < filters.size(); i++) { | ||
const auto& proto_config = filters[i]; | ||
const ProtobufTypes::String name = proto_config.name(); | ||
const Json::ObjectSharedPtr filter_config = | ||
MessageUtil::getJsonObjectFromMessage(proto_config.config()); | ||
ENVOY_LOG(debug, "filter #{} name: {} config: {}", i, name, filter_config->asJsonString()); | ||
// Now see if there is a factory that will accept the config. | ||
auto& factory = | ||
Config::Utility::getAndCheckFactory<Server::Configuration::NamedNetworkFilterConfigFactory>(name); | ||
Network::FilterFactoryCb callback; | ||
if (filter_config->getBoolean("deprecated_v1", false)) { | ||
callback = factory.createFilterFactory(*filter_config->getObject("value", true), *factory_context_); | ||
} else { | ||
auto message = Config::Utility::translateToFactoryConfig(proto_config, factory); | ||
callback = factory.createFilterFactoryFromProto(*message, *factory_context_); | ||
} | ||
filter_factories_.push_back(callback); | ||
} | ||
} | ||
|
||
void ClusterInfoImpl::createNetworkFilters(Network::Connection& connection) const { | ||
Server::Configuration::FilterChainUtility::buildFilterChain(connection, filter_factories_); | ||
} | ||
|
||
ClusterSharedPtr ClusterImplBase::create(const envoy::api::v2::Cluster& cluster, ClusterManager& cm, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that that type should probably be moved to core. I don't know if such a change breaks protobuf compatibility or not; we'll need to sort that out before making a change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started to do it and then backed off till I got feedback. I'll resurrect it for review. On the -dev list @mattklein123 seemed to feel it wouldn't be a breaking change but best put it in code first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type of change will cause a compile time breakage, but should not cause a wire breakage. I think it's worth it in this case. @alanconway can you make this change and then I can take a look?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please also test that the canonical-json-protobuf is compatible after the change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ggreenway can you point to any existing tests for that kind of compatibility? I have yet to dive into the envoy test suite, I've been testing it from the outside so far.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know of any, but all I was thinking was to write a config that current-envoy will load that includes these bits, and add a test this config loads (and that the relevant bits seem to take effect).