Line data Source code
1 : #include "source/extensions/transport_sockets/internal_upstream/config.h" 2 : 3 : #include "envoy/common/hashable.h" 4 : #include "envoy/common/optref.h" 5 : #include "envoy/extensions/transport_sockets/internal_upstream/v3/internal_upstream.pb.validate.h" 6 : #include "envoy/registry/registry.h" 7 : 8 : #include "source/common/common/scalar_to_byte_vector.h" 9 : #include "source/common/config/utility.h" 10 : #include "source/extensions/transport_sockets/internal_upstream/internal_upstream.h" 11 : 12 : namespace Envoy { 13 : namespace Extensions { 14 : namespace TransportSockets { 15 : namespace InternalUpstream { 16 : 17 : namespace { 18 : 19 : class InternalUpstreamConfigFactory 20 : : public Server::Configuration::UpstreamTransportSocketConfigFactory { 21 : public: 22 38 : std::string name() const override { return "envoy.transport_sockets.internal_upstream"; } 23 1 : ProtobufTypes::MessagePtr createEmptyConfigProto() override { 24 1 : return std::make_unique< 25 1 : envoy::extensions::transport_sockets::internal_upstream::v3::InternalUpstreamTransport>(); 26 1 : } 27 : Network::UpstreamTransportSocketFactoryPtr createTransportSocketFactory( 28 : const Protobuf::Message& config, 29 0 : Server::Configuration::TransportSocketFactoryContext& context) override { 30 0 : const auto& outer_config = 31 0 : MessageUtil::downcastAndValidate<const envoy::extensions::transport_sockets:: 32 0 : internal_upstream::v3::InternalUpstreamTransport&>( 33 0 : config, context.messageValidationVisitor()); 34 0 : auto& inner_config_factory = Envoy::Config::Utility::getAndCheckFactory< 35 0 : Server::Configuration::UpstreamTransportSocketConfigFactory>( 36 0 : outer_config.transport_socket()); 37 0 : ProtobufTypes::MessagePtr inner_factory_config = 38 0 : Envoy::Config::Utility::translateToFactoryConfig(outer_config.transport_socket(), 39 0 : context.messageValidationVisitor(), 40 0 : inner_config_factory); 41 0 : auto inner_transport_factory = 42 0 : inner_config_factory.createTransportSocketFactory(*inner_factory_config, context); 43 0 : return std::make_unique<InternalSocketFactory>(context, outer_config, 44 0 : std::move(inner_transport_factory)); 45 0 : } 46 : }; 47 : 48 : } // namespace 49 : 50 : Config::Config( 51 : const envoy::extensions::transport_sockets::internal_upstream::v3::InternalUpstreamTransport& 52 : config_proto, 53 : Stats::Scope& scope) 54 0 : : stats_{ALL_INTERNAL_UPSTREAM_STATS(POOL_COUNTER_PREFIX(scope, "internal_upstream."))} { 55 0 : for (const auto& metadata : config_proto.passthrough_metadata()) { 56 0 : MetadataKind kind; 57 0 : switch (metadata.kind().kind_case()) { 58 0 : case envoy::type::metadata::v3::MetadataKind::KindCase::kHost: 59 0 : kind = MetadataKind::Host; 60 0 : break; 61 0 : case envoy::type::metadata::v3::MetadataKind::KindCase::kCluster: 62 0 : kind = MetadataKind::Cluster; 63 0 : break; 64 0 : default: 65 0 : throw EnvoyException( 66 0 : absl::StrCat("metadata type is not supported: ", metadata.kind().DebugString())); 67 0 : } 68 0 : metadata_sources_.push_back(MetadataSource(kind, metadata.name())); 69 0 : } 70 0 : } 71 : 72 : std::unique_ptr<envoy::config::core::v3::Metadata> 73 0 : Config::extractMetadata(const Upstream::HostDescriptionConstSharedPtr& host) const { 74 0 : if (metadata_sources_.empty()) { 75 0 : return nullptr; 76 0 : } 77 0 : auto metadata = std::make_unique<envoy::config::core::v3::Metadata>(); 78 0 : for (const auto& source : metadata_sources_) { 79 0 : OptRef<const envoy::config::core::v3::Metadata> source_metadata; 80 0 : switch (source.kind_) { 81 0 : case MetadataKind::Host: { 82 0 : if (host->metadata()) { 83 0 : source_metadata = makeOptRef(*host->metadata()); 84 0 : } 85 0 : break; 86 0 : } 87 0 : case MetadataKind::Cluster: 88 0 : source_metadata = makeOptRef(host->cluster().metadata()); 89 0 : break; 90 0 : } 91 0 : if (source_metadata && source_metadata->filter_metadata().contains(source.name_)) { 92 0 : (*metadata->mutable_filter_metadata())[source.name_] = 93 0 : source_metadata->filter_metadata().at(source.name_); 94 0 : } else { 95 0 : ENVOY_LOG(trace, "Internal upstream missing metadata: {}", source.name_); 96 0 : stats_.no_metadata_.inc(); 97 0 : } 98 0 : } 99 0 : return metadata; 100 0 : } 101 : 102 : InternalSocketFactory::InternalSocketFactory( 103 : Server::Configuration::TransportSocketFactoryContext& context, 104 : const envoy::extensions::transport_sockets::internal_upstream::v3::InternalUpstreamTransport& 105 : config_proto, 106 : Network::UpstreamTransportSocketFactoryPtr&& inner_factory) 107 0 : : PassthroughFactory(std::move(inner_factory)), config_(config_proto, context.statsScope()) {} 108 : 109 : Network::TransportSocketPtr 110 : InternalSocketFactory::createTransportSocket(Network::TransportSocketOptionsConstSharedPtr options, 111 0 : Upstream::HostDescriptionConstSharedPtr host) const { 112 0 : auto inner_socket = transport_socket_factory_->createTransportSocket(options, host); 113 0 : if (inner_socket == nullptr) { 114 0 : return nullptr; 115 0 : } 116 0 : std::unique_ptr<envoy::config::core::v3::Metadata> extracted_metadata; 117 0 : if (host) { 118 0 : extracted_metadata = config_.extractMetadata(host); 119 0 : } 120 0 : return std::make_unique<InternalSocket>(std::move(inner_socket), std::move(extracted_metadata), 121 0 : options ? options->downstreamSharedFilterStateObjects() 122 0 : : StreamInfo::FilterState::Objects()); 123 0 : } 124 : 125 : REGISTER_FACTORY(InternalUpstreamConfigFactory, 126 : Server::Configuration::UpstreamTransportSocketConfigFactory); 127 : 128 : } // namespace InternalUpstream 129 : } // namespace TransportSockets 130 : } // namespace Extensions 131 : } // namespace Envoy