diff --git a/source/extensions/common/wasm/context.cc b/source/extensions/common/wasm/context.cc index 2b13ca94937d..131ee2fe6dab 100644 --- a/source/extensions/common/wasm/context.cc +++ b/source/extensions/common/wasm/context.cc @@ -807,7 +807,7 @@ WasmResult Context::setHeaderMapPairs(WasmHeaderMapType type, const Pairs& pairs const Http::LowerCaseString lower_key{std::string(p.first)}; map->addCopy(lower_key, std::string(p.second)); } - if (type == WasmHeaderMapType::RequestHeaders && decoder_callbacks_) { + if (type == WasmHeaderMapType::RequestHeaders && decoder_callbacks_ && decoder_callbacks_->downstreamCallbacks()) { decoder_callbacks_->downstreamCallbacks()->clearRouteCache(); } return WasmResult::Ok; diff --git a/source/extensions/filters/http/wasm/config.cc b/source/extensions/filters/http/wasm/config.cc index b949606f30bc..45f9b16522df 100644 --- a/source/extensions/filters/http/wasm/config.cc +++ b/source/extensions/filters/http/wasm/config.cc @@ -13,10 +13,12 @@ namespace Extensions { namespace HttpFilters { namespace Wasm { -Http::FilterFactoryCb WasmFilterConfig::createFilterFactoryFromProtoTyped( - const envoy::extensions::filters::http::wasm::v3::Wasm& proto_config, const std::string&, - Server::Configuration::FactoryContext& context) { - context.serverFactoryContext().api().customStatNamespaces().registerStatNamespace( +absl::StatusOr WasmFilterConfig::createFilterFactoryFromProtoTyped( + const envoy::extensions::filters::http::wasm::v3::Wasm& proto_config, + const std::string&, DualInfo, + Server::Configuration::ServerFactoryContext& context) { + + context.api().customStatNamespaces().registerStatNamespace( Extensions::Common::Wasm::CustomStatNamespace); auto filter_config = std::make_shared(proto_config, context); return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void { @@ -33,6 +35,8 @@ Http::FilterFactoryCb WasmFilterConfig::createFilterFactoryFromProtoTyped( * Static registration for the Wasm filter. @see RegisterFactory. */ REGISTER_FACTORY(WasmFilterConfig, Server::Configuration::NamedHttpFilterConfigFactory); +REGISTER_FACTORY(UpstreamWasmFilterConfig, + Server::Configuration::UpstreamHttpFilterConfigFactory); } // namespace Wasm } // namespace HttpFilters diff --git a/source/extensions/filters/http/wasm/config.h b/source/extensions/filters/http/wasm/config.h index 0085fec7f4a0..9322f8ba2dd2 100644 --- a/source/extensions/filters/http/wasm/config.h +++ b/source/extensions/filters/http/wasm/config.h @@ -14,16 +14,19 @@ namespace Wasm { * Config registration for the Wasm filter. @see NamedHttpFilterConfigFactory. */ class WasmFilterConfig - : public Common::FactoryBase { + : public Common::DualFactoryBase { public: - WasmFilterConfig() : FactoryBase("envoy.filters.http.wasm") {} + WasmFilterConfig() : DualFactoryBase("envoy.filters.http.wasm") {} private: - Http::FilterFactoryCb createFilterFactoryFromProtoTyped( - const envoy::extensions::filters::http::wasm::v3::Wasm& proto_config, const std::string&, - Server::Configuration::FactoryContext& context) override; + absl::StatusOr createFilterFactoryFromProtoTyped( + const envoy::extensions::filters::http::wasm::v3::Wasm& proto_config, + const std::string& stats_prefix, DualInfo dual_info, + Server::Configuration::ServerFactoryContext& context) override; }; +using UpstreamWasmFilterConfig = WasmFilterConfig; + } // namespace Wasm } // namespace HttpFilters } // namespace Extensions diff --git a/source/extensions/filters/http/wasm/wasm_filter.cc b/source/extensions/filters/http/wasm/wasm_filter.cc index c9f106ccaa57..24a3422b506f 100644 --- a/source/extensions/filters/http/wasm/wasm_filter.cc +++ b/source/extensions/filters/http/wasm/wasm_filter.cc @@ -5,15 +5,141 @@ namespace Extensions { namespace HttpFilters { namespace Wasm { +struct MyAsyncClientManager: public Grpc::AsyncClientManager{ + absl::StatusOr + getOrCreateRawAsyncClient(const envoy::config::core::v3::GrpcService& , + Stats::Scope& , bool ) override {return absl::StatusOr();}; + + absl::StatusOr + getOrCreateRawAsyncClientWithHashKey(const Grpc::GrpcServiceConfigWithHashKey& , + Stats::Scope& , bool ) override {return absl::StatusOr();} + + absl::StatusOr + factoryForGrpcService(const envoy::config::core::v3::GrpcService& , + Stats::Scope& , bool ) override {return absl::StatusOr();} + +}; + +class MyClusterManagerFactory: public Upstream::ClusterManagerFactory { +public: + + Upstream::ClusterManagerPtr + clusterManagerFromProto(const envoy::config::bootstrap::v3::Bootstrap& ) override {return nullptr;} + + virtual Http::ConnectionPool::InstancePtr + allocateConnPool(Event::Dispatcher& , Upstream::HostConstSharedPtr , + Upstream::ResourcePriority , std::vector& , + const absl::optional& + , + const Network::ConnectionSocket::OptionsSharedPtr& , + const Network::TransportSocketOptionsConstSharedPtr& , + TimeSource& , Upstream::ClusterConnectivityState& , + Http::PersistentQuicInfoPtr& ) override {return nullptr;} + + virtual Tcp::ConnectionPool::InstancePtr + allocateTcpConnPool(Event::Dispatcher& , Upstream::HostConstSharedPtr , + Upstream::ResourcePriority , + const Network::ConnectionSocket::OptionsSharedPtr& , + Network::TransportSocketOptionsConstSharedPtr , + Upstream::ClusterConnectivityState& , + absl::optional ) override {return nullptr;} + + virtual absl::StatusOr> + clusterFromProto(const envoy::config::cluster::v3::Cluster& , Upstream::ClusterManager& , + Upstream::Outlier::EventLoggerSharedPtr , bool ) override {return absl::StatusOr>();}; + + virtual Upstream::CdsApiPtr createCds(const envoy::config::core::v3::ConfigSource& , + const xds::core::v3::ResourceLocator* , + Upstream::ClusterManager& ) override {return nullptr;} + + virtual Secret::SecretManager& secretManager() override { throw 1; } + + virtual Singleton::Manager& singletonManager() override { throw 1; } +}; + +struct MyClusterManager : public Upstream::ClusterManager { + bool addOrUpdateCluster(const envoy::config::cluster::v3::Cluster& ,const std::string& ) override {return true;} + + + const Upstream::ClusterLbStatNames& clusterLbStatNames() const override { throw 1; } + const Upstream::ClusterEndpointStatNames& clusterEndpointStatNames() const override { + throw 1; + } + const Upstream::ClusterLoadReportStatNames& clusterLoadReportStatNames() const override { + throw 1; + } + const Upstream::ClusterCircuitBreakersStatNames& clusterCircuitBreakersStatNames() const override { + throw 1; + } + const Upstream::ClusterRequestResponseSizeStatNames& clusterRequestResponseSizeStatNames() const override { + throw 1; + } + const Upstream::ClusterTimeoutBudgetStatNames& clusterTimeoutBudgetStatNames() const override { + throw 1; + } + void drainConnections(const std::string& , + DrainConnectionsHostPredicate ) override{}; + void drainConnections(DrainConnectionsHostPredicate ) override{}; + absl::Status checkActiveStaticCluster(const std::string& ) override{ return absl::OkStatus(); }; + //void notifyMissingCluster(absl::string_view) override{}; + + std::shared_ptr getCommonLbConfigPtr( + const envoy::config::cluster::v3::Cluster::CommonLbConfig& ) override { + return nullptr; + } + Config::EdsResourcesCacheOptRef edsResourcesCache() override { return Config::EdsResourcesCacheOptRef();} + void setPrimaryClustersInitializedCb(PrimaryClustersReadyCallback ) override {} + void setInitializedCb(InitializationCompleteCallback ) override {} + bool removeCluster(const std::string& ) override {return true;} + void shutdown() override {} + bool isShutdown() override {return true;} + const absl::optional& localClusterName() const override {return any;} + + ClusterInfoMaps clusters() const override {return clusters_;} + const absl::optional& bindConfig() const override {return config_;} + Upstream::ThreadLocalCluster* getThreadLocalCluster(absl::string_view ) override {return nullptr;} + Grpc::AsyncClientManager& grpcAsyncClientManager() override {return async_manager;} + Config::GrpcMuxSharedPtr adsMux() override {return nullptr;} + Upstream::OdCdsApiHandlePtr + allocateOdCdsApi(const envoy::config::core::v3::ConfigSource& , + OptRef , + ProtobufMessage::ValidationVisitor& ) override {return nullptr;} + absl::Status + initializeSecondaryClusters(const envoy::config::bootstrap::v3::Bootstrap& ) override {return absl::Status();} + const Upstream::ClusterConfigUpdateStatNames& clusterConfigUpdateStatNames() const override {throw 1;} + Upstream::ClusterUpdateCallbacksHandlePtr + addThreadLocalClusterUpdateCallbacks(Upstream::ClusterUpdateCallbacks& ) override {return nullptr;} + const Upstream::ClusterTrafficStatNames& clusterStatNames() const override {throw 1;} + const ClusterSet& primaryClusters() override {return clusterset_;} + Upstream::ClusterManagerFactory& clusterManagerFactory() override { return c_manager_; } + Config::SubscriptionFactory& subscriptionFactory() override { throw 1;} + + //Upstream::ClusterConfigUpdateStatNames cluster_config_update_stat_names_; + //Upstream::ClusterLbStatNames cluster_lb_stat_names_; + //Upstream::ClusterEndpointStatNames cluster_endpoint_stat_names_; + //Upstream::ClusterLoadReportStatNames cluster_load_report_stat_names_; + //Upstream::ClusterCircuitBreakersStatNames cluster_circuit_breakers_stat_names_; + //Upstream::ClusterRequestResponseSizeStatNames cluster_request_response_size_stat_names_; + //Upstream::ClusterTimeoutBudgetStatNames cluster_timeout_budget_stat_names_; + //Upstream::ClusterTrafficStatNames cluster_traffic_stat_name_; + absl::optional any{""}; + + ClusterInfoMaps clusters_; + ClusterSet clusterset_; + absl::optional config_; + MyAsyncClientManager async_manager; + MyClusterManagerFactory c_manager_; +} mycluster; + FilterConfig::FilterConfig(const envoy::extensions::filters::http::wasm::v3::Wasm& config, - Server::Configuration::FactoryContext& context) { - auto& server = context.serverFactoryContext(); + Server::Configuration::ServerFactoryContext& context) { + auto& server = context; tls_slot_ = ThreadLocal::TypedSlot::makeUnique( server.threadLocal()); const auto plugin = std::make_shared( - config.config(), context.listenerInfo().direction(), server.localInfo(), - &context.listenerInfo().metadata()); + config.config(), envoy::config::core::v3::TrafficDirection::INBOUND, server.localInfo(), + nullptr); auto callback = [plugin, this](const Common::Wasm::WasmHandleSharedPtr& base_wasm) { // NB: the Slot set() call doesn't complete inline, so all arguments must outlive this call. @@ -23,7 +149,7 @@ FilterConfig::FilterConfig(const envoy::extensions::filters::http::wasm::v3::Was }); }; - if (!Common::Wasm::createWasm(plugin, context.scope().createScope(""), server.clusterManager(), + if (!Common::Wasm::createWasm(plugin, context.scope().createScope(""), mycluster /*server.clusterManager()*/, context.initManager(), server.mainThreadDispatcher(), server.api(), server.lifecycleNotifier(), remote_data_provider_, std::move(callback))) { diff --git a/source/extensions/filters/http/wasm/wasm_filter.h b/source/extensions/filters/http/wasm/wasm_filter.h index 7221ec94fcb4..f914b19bb494 100644 --- a/source/extensions/filters/http/wasm/wasm_filter.h +++ b/source/extensions/filters/http/wasm/wasm_filter.h @@ -25,7 +25,7 @@ using Envoy::Extensions::Common::Wasm::Wasm; class FilterConfig : Logger::Loggable { public: FilterConfig(const envoy::extensions::filters::http::wasm::v3::Wasm& config, - Server::Configuration::FactoryContext& context); + Server::Configuration::ServerFactoryContext& context); std::shared_ptr createFilter() { Wasm* wasm = nullptr; diff --git a/test/extensions/common/aws/credentials_provider_impl_test.cc b/test/extensions/common/aws/credentials_provider_impl_test.cc index a646453621c2..3e1c4f246318 100644 --- a/test/extensions/common/aws/credentials_provider_impl_test.cc +++ b/test/extensions/common/aws/credentials_provider_impl_test.cc @@ -139,7 +139,7 @@ TEST_F(EvironmentCredentialsProviderTest, NoSessionToken) { class CredentialsFileCredentialsProviderTest : public testing::Test { public: CredentialsFileCredentialsProviderTest() - : api_(Api::createApiForTest(time_system_)), provider_(*api_) {} + : api_(Api::createApiForTest(time_system_)), provider_(*api_, "") {} ~CredentialsFileCredentialsProviderTest() override { TestEnvironment::unsetEnvVar("AWS_SHARED_CREDENTIALS_FILE"); @@ -183,6 +183,30 @@ TEST_F(CredentialsFileCredentialsProviderTest, DefaultCredentialsFile) { EXPECT_EQ("profile1_token", credentials.sessionToken().value()); } +TEST_F(CredentialsFileCredentialsProviderTest, CustomProfileFromConfigShouldBeHonored) { + auto file_path = + TestEnvironment::writeStringToFileForTest(CREDENTIALS_FILE, CREDENTIALS_FILE_CONTENTS); + TestEnvironment::setEnvVar("AWS_SHARED_CREDENTIALS_FILE", file_path, 1); + + auto provider = CredentialsFileCredentialsProvider(*api_, "profile4"); + const auto credentials = provider.getCredentials(); + EXPECT_EQ("profile4_access_key", credentials.accessKeyId().value()); + EXPECT_EQ("profile4_secret", credentials.secretAccessKey().value()); + EXPECT_EQ("profile4_token", credentials.sessionToken().value()); +} + +TEST_F(CredentialsFileCredentialsProviderTest, UnexistingCustomProfileFomConfig) { + auto file_path = + TestEnvironment::writeStringToFileForTest(CREDENTIALS_FILE, CREDENTIALS_FILE_CONTENTS); + TestEnvironment::setEnvVar("AWS_SHARED_CREDENTIALS_FILE", file_path, 1); + + auto provider = CredentialsFileCredentialsProvider(*api_, "unexistening_profile"); + const auto credentials = provider.getCredentials(); + EXPECT_FALSE(credentials.accessKeyId().has_value()); + EXPECT_FALSE(credentials.secretAccessKey().has_value()); + EXPECT_FALSE(credentials.sessionToken().has_value()); +} + TEST_F(CredentialsFileCredentialsProviderTest, ProfileDoesNotExist) { setUpTest(CREDENTIALS_FILE_CONTENTS, "invalid_profile");