mirror of https://github.com/istio/proxy.git
Use FilterState instead of DynamicMetadata in Metadata Exchange Filter (#2452)
* Use FilterState instead of DynamicMetadata in Metadata Exchange Plugin Also made the plugin in sync with existing HTTP Metadata Exchange Wasm Plugin, so that stats(prometheus) plugin can use this easily. Fixed based on feedback * Fix build errors
This commit is contained in:
parent
08600d765c
commit
fe67c04209
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "extensions/common/context.h"
|
#include "extensions/common/context.h"
|
||||||
|
|
||||||
|
#include "absl/strings/str_cat.h"
|
||||||
|
#include "absl/strings/str_split.h"
|
||||||
#include "google/protobuf/util/json_util.h"
|
#include "google/protobuf/util/json_util.h"
|
||||||
|
|
||||||
// WASM_PROLOG
|
// WASM_PROLOG
|
||||||
|
|
@ -160,5 +162,41 @@ void populateHTTPRequestInfo(bool outbound, RequestInfo* request_info) {
|
||||||
request_info->destination_port = destination_port;
|
request_info->destination_port = destination_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
google::protobuf::util::Status extractNodeMetadataValue(
|
||||||
|
const google::protobuf::Struct& node_metadata,
|
||||||
|
google::protobuf::Struct* metadata) {
|
||||||
|
if (metadata == nullptr) {
|
||||||
|
return google::protobuf::util::Status(
|
||||||
|
google::protobuf::util::error::INVALID_ARGUMENT,
|
||||||
|
"metadata provided is null");
|
||||||
|
}
|
||||||
|
const auto key_it = node_metadata.fields().find("EXCHANGE_KEYS");
|
||||||
|
if (key_it == node_metadata.fields().end()) {
|
||||||
|
return google::protobuf::util::Status(
|
||||||
|
google::protobuf::util::error::INVALID_ARGUMENT,
|
||||||
|
"metadata exchange key is missing");
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& keys_value = key_it->second;
|
||||||
|
if (keys_value.kind_case() != google::protobuf::Value::kStringValue) {
|
||||||
|
return google::protobuf::util::Status(
|
||||||
|
google::protobuf::util::error::INVALID_ARGUMENT,
|
||||||
|
"metadata exchange key is not a string");
|
||||||
|
}
|
||||||
|
|
||||||
|
// select keys from the metadata using the keys
|
||||||
|
const std::set<std::string> keys =
|
||||||
|
absl::StrSplit(keys_value.string_value(), ',', absl::SkipWhitespace());
|
||||||
|
for (auto key : keys) {
|
||||||
|
const auto entry_it = node_metadata.fields().find(key);
|
||||||
|
if (entry_it == node_metadata.fields().end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
(*metadata->mutable_fields())[key] = entry_it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return google::protobuf::util::Status(google::protobuf::util::error::OK, "");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
} // namespace Wasm
|
} // namespace Wasm
|
||||||
|
|
|
||||||
|
|
@ -131,5 +131,12 @@ google::protobuf::util::Status extractLocalNodeMetadata(
|
||||||
// the request context.
|
// the request context.
|
||||||
void populateHTTPRequestInfo(bool outbound, RequestInfo* request_info);
|
void populateHTTPRequestInfo(bool outbound, RequestInfo* request_info);
|
||||||
|
|
||||||
|
// Extracts node metadata value. It looks for values of all the keys
|
||||||
|
// corresponding to EXCHANGE_KEYS in node_metadata and populates it in
|
||||||
|
// google::protobuf::Value pointer that is passed in.
|
||||||
|
google::protobuf::util::Status extractNodeMetadataValue(
|
||||||
|
const google::protobuf::Struct& node_metadata,
|
||||||
|
google::protobuf::Struct* metadata);
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
} // namespace Wasm
|
} // namespace Wasm
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,24 @@ TEST(ContextTest, extractNodeMetadataUnknownField) {
|
||||||
EXPECT_EQ(status, Status::OK);
|
EXPECT_EQ(status, Status::OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test extractNodeMetadataValue.
|
||||||
|
TEST(ContextTest, extractNodeMetadataValue) {
|
||||||
|
google::protobuf::Struct metadata_struct;
|
||||||
|
auto node_metadata_map = metadata_struct.mutable_fields();
|
||||||
|
(*node_metadata_map)["EXCHANGE_KEYS"].set_string_value("namespace,labels");
|
||||||
|
(*node_metadata_map)["namespace"].set_string_value("default");
|
||||||
|
(*node_metadata_map)["labels"].set_string_value("{app, details}");
|
||||||
|
google::protobuf::Struct value_struct;
|
||||||
|
const auto status = extractNodeMetadataValue(metadata_struct, &value_struct);
|
||||||
|
EXPECT_EQ(status, Status::OK);
|
||||||
|
auto namespace_iter = value_struct.fields().find("namespace");
|
||||||
|
EXPECT_TRUE(namespace_iter != value_struct.fields().end());
|
||||||
|
EXPECT_EQ(namespace_iter->second.string_value(), "default");
|
||||||
|
auto label_iter = value_struct.fields().find("labels");
|
||||||
|
EXPECT_TRUE(label_iter != value_struct.fields().end());
|
||||||
|
EXPECT_EQ(label_iter->second.string_value(), "{app, details}");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
||||||
// WASM_EPILOG
|
// WASM_EPILOG
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ envoy_cc_library(
|
||||||
repository = "@envoy",
|
repository = "@envoy",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//extensions/common:context",
|
||||||
"@envoy//source/common/common:base64_lib",
|
"@envoy//source/common/common:base64_lib",
|
||||||
"@envoy//source/extensions/common/wasm/null:null_plugin_lib",
|
"@envoy//source/extensions/common/wasm/null:null_plugin_lib",
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include "common/common/base64.h"
|
#include "common/common/base64.h"
|
||||||
|
#include "extensions/common/context.h"
|
||||||
#include "extensions/metadata_exchange/plugin.h"
|
#include "extensions/metadata_exchange/plugin.h"
|
||||||
|
|
||||||
namespace Envoy {
|
namespace Envoy {
|
||||||
|
|
@ -67,31 +68,12 @@ void PluginRootContext::updateMetadataValue() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto key_it = node_metadata.fields().find("EXCHANGE_KEYS");
|
|
||||||
if (key_it == node_metadata.fields().end()) {
|
|
||||||
logWarn("metadata exchange key is missing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& keys_value = key_it->second;
|
|
||||||
if (keys_value.kind_case() != google::protobuf::Value::kStringValue) {
|
|
||||||
logWarn("metadata exchange key is not a string");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
google::protobuf::Value metadata;
|
google::protobuf::Value metadata;
|
||||||
|
const auto status = ::Wasm::Common::extractNodeMetadataValue(
|
||||||
// select keys from the metadata using the keys
|
node_metadata, metadata.mutable_struct_value());
|
||||||
const std::set<std::string> keys =
|
if (!status.ok()) {
|
||||||
absl::StrSplit(keys_value.string_value(), ',', absl::SkipWhitespace());
|
logWarn(status.message().ToString());
|
||||||
for (auto key : keys) {
|
return;
|
||||||
const auto entry_it = node_metadata.fields().find(key);
|
|
||||||
if (entry_it == node_metadata.fields().end()) {
|
|
||||||
logDebug(absl::StrCat("missing metadata exchange key: ", key));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
(*metadata.mutable_struct_value()->mutable_fields())[key] =
|
|
||||||
entry_it->second;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// store serialized form
|
// store serialized form
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ envoy_cc_library(
|
||||||
],
|
],
|
||||||
repository = "@envoy",
|
repository = "@envoy",
|
||||||
deps = [
|
deps = [
|
||||||
|
"//extensions/common:context",
|
||||||
"//src/envoy/tcp/metadata_exchange/config:metadata_exchange_cc_proto",
|
"//src/envoy/tcp/metadata_exchange/config:metadata_exchange_cc_proto",
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/base:endian",
|
"@com_google_absl//absl/base:endian",
|
||||||
|
|
@ -47,10 +48,12 @@ envoy_cc_library(
|
||||||
"@envoy//include/envoy/network:filter_interface",
|
"@envoy//include/envoy/network:filter_interface",
|
||||||
"@envoy//include/envoy/runtime:runtime_interface",
|
"@envoy//include/envoy/runtime:runtime_interface",
|
||||||
"@envoy//include/envoy/stats:stats_macros",
|
"@envoy//include/envoy/stats:stats_macros",
|
||||||
|
"@envoy//include/envoy/stream_info:filter_state_interface",
|
||||||
"@envoy//source/common/http:utility_lib",
|
"@envoy//source/common/http:utility_lib",
|
||||||
"@envoy//source/common/network:utility_lib",
|
"@envoy//source/common/network:utility_lib",
|
||||||
"@envoy//source/common/protobuf",
|
"@envoy//source/common/protobuf",
|
||||||
"@envoy//source/common/protobuf:utility_lib",
|
"@envoy//source/common/protobuf:utility_lib",
|
||||||
|
"@envoy//source/extensions/common/wasm:wasm_interoperation_lib",
|
||||||
"@envoy//source/extensions/filters/network:well_known_names",
|
"@envoy//source/extensions/filters/network:well_known_names",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ Network::FilterFactoryCb createFilterFactoryHelper(
|
||||||
|
|
||||||
MetadataExchangeConfigSharedPtr filter_config(
|
MetadataExchangeConfigSharedPtr filter_config(
|
||||||
std::make_shared<MetadataExchangeConfig>(
|
std::make_shared<MetadataExchangeConfig>(
|
||||||
StatPrefix, proto_config.protocol(), proto_config.node_metadata_id(),
|
StatPrefix, proto_config.protocol(), filter_direction,
|
||||||
filter_direction, context.scope()));
|
context.scope()));
|
||||||
return [filter_config,
|
return [filter_config,
|
||||||
&context](Network::FilterManager& filter_manager) -> void {
|
&context](Network::FilterManager& filter_manager) -> void {
|
||||||
filter_manager.addFilter(std::make_shared<MetadataExchangeFilter>(
|
filter_manager.addFilter(std::make_shared<MetadataExchangeFilter>(
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,4 @@ message MetadataExchange {
|
||||||
// Protocol that Alpn should support on the server.
|
// Protocol that Alpn should support on the server.
|
||||||
// [#comment:TODO(GargNupur): Make it a list.]
|
// [#comment:TODO(GargNupur): Make it a list.]
|
||||||
string protocol = 1;
|
string protocol = 1;
|
||||||
|
|
||||||
// The node metadata id whose data will be written to connection data.
|
|
||||||
// [#comment: TODO(GargNupur): Remove this and use bootstrap node.id]
|
|
||||||
string node_metadata_id = 2;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,14 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "absl/base/internal/endian.h"
|
#include "absl/base/internal/endian.h"
|
||||||
|
#include "absl/strings/str_split.h"
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "common/buffer/buffer_impl.h"
|
#include "common/buffer/buffer_impl.h"
|
||||||
#include "common/protobuf/utility.h"
|
#include "common/protobuf/utility.h"
|
||||||
#include "envoy/network/connection.h"
|
#include "envoy/network/connection.h"
|
||||||
#include "envoy/stats/scope.h"
|
#include "envoy/stats/scope.h"
|
||||||
|
#include "extensions/common/context.h"
|
||||||
|
#include "extensions/common/wasm/wasm_state.h"
|
||||||
#include "src/envoy/tcp/metadata_exchange/metadata_exchange.h"
|
#include "src/envoy/tcp/metadata_exchange/metadata_exchange.h"
|
||||||
#include "src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h"
|
#include "src/envoy/tcp/metadata_exchange/metadata_exchange_initial_header.h"
|
||||||
|
|
||||||
|
|
@ -49,16 +52,26 @@ std::unique_ptr<::Envoy::Buffer::OwnedImpl> constructProxyHeaderData(
|
||||||
return proxy_data_buffer;
|
return proxy_data_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool serializeToStringDeterministic(const google::protobuf::Struct& metadata,
|
||||||
|
std::string* metadata_bytes) {
|
||||||
|
google::protobuf::io::StringOutputStream md(metadata_bytes);
|
||||||
|
google::protobuf::io::CodedOutputStream mcs(&md);
|
||||||
|
|
||||||
|
mcs.SetSerializationDeterministic(true);
|
||||||
|
if (!metadata.SerializeToCodedStream(&mcs)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
MetadataExchangeConfig::MetadataExchangeConfig(
|
MetadataExchangeConfig::MetadataExchangeConfig(
|
||||||
const std::string& stat_prefix, const std::string& protocol,
|
const std::string& stat_prefix, const std::string& protocol,
|
||||||
const std::string& node_metadata_id, const FilterDirection filter_direction,
|
const FilterDirection filter_direction, Stats::Scope& scope)
|
||||||
Stats::Scope& scope)
|
|
||||||
: scope_(scope),
|
: scope_(scope),
|
||||||
stat_prefix_(stat_prefix),
|
stat_prefix_(stat_prefix),
|
||||||
protocol_(protocol),
|
protocol_(protocol),
|
||||||
node_metadata_id_(node_metadata_id),
|
|
||||||
filter_direction_(filter_direction),
|
filter_direction_(filter_direction),
|
||||||
stats_(generateStats(stat_prefix, scope)) {}
|
stats_(generateStats(stat_prefix, scope)) {}
|
||||||
|
|
||||||
|
|
@ -156,21 +169,24 @@ void MetadataExchangeFilter::writeNodeMetadata() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<const google::protobuf::Struct> metadata =
|
Envoy::ProtobufWkt::Struct data;
|
||||||
getMetadata(config_->node_metadata_id_);
|
Envoy::ProtobufWkt::Struct* metadata =
|
||||||
if (metadata != nullptr) {
|
(*data.mutable_fields())[ExchangeMetadataHeader].mutable_struct_value();
|
||||||
|
getMetadata(metadata);
|
||||||
|
std::string metadata_id = getMetadataId();
|
||||||
|
if (!metadata_id.empty()) {
|
||||||
|
(*data.mutable_fields())[ExchangeMetadataHeaderId].set_string_value(
|
||||||
|
metadata_id);
|
||||||
|
}
|
||||||
|
if (data.fields_size() > 0) {
|
||||||
Envoy::ProtobufWkt::Any metadata_any_value;
|
Envoy::ProtobufWkt::Any metadata_any_value;
|
||||||
*metadata_any_value.mutable_type_url() = StructTypeUrl;
|
*metadata_any_value.mutable_type_url() = StructTypeUrl;
|
||||||
*metadata_any_value.mutable_value() = metadata->SerializeAsString();
|
std::string serialized_data;
|
||||||
|
serializeToStringDeterministic(data, &serialized_data);
|
||||||
|
*metadata_any_value.mutable_value() = serialized_data;
|
||||||
std::unique_ptr<::Envoy::Buffer::OwnedImpl> buf =
|
std::unique_ptr<::Envoy::Buffer::OwnedImpl> buf =
|
||||||
constructProxyHeaderData(metadata_any_value);
|
constructProxyHeaderData(metadata_any_value);
|
||||||
write_callbacks_->injectWriteDataToFilterChain(*buf, false);
|
write_callbacks_->injectWriteDataToFilterChain(*buf, false);
|
||||||
|
|
||||||
if (config_->filter_direction_ == FilterDirection::Downstream) {
|
|
||||||
setMetadata(DownstreamDynamicDataKey, *metadata);
|
|
||||||
} else {
|
|
||||||
setMetadata(UpstreamDynamicDataKey, *metadata);
|
|
||||||
}
|
|
||||||
config_->stats().metadata_added_.inc();
|
config_->stats().metadata_added_.inc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,31 +240,58 @@ void MetadataExchangeFilter::tryReadProxyData(Buffer::Instance& data) {
|
||||||
}
|
}
|
||||||
data.drain(proxy_data_length_);
|
data.drain(proxy_data_length_);
|
||||||
|
|
||||||
Envoy::ProtobufWkt::Struct struct_metadata =
|
// Set Metadata
|
||||||
|
Envoy::ProtobufWkt::Struct value_struct =
|
||||||
Envoy::MessageUtil::anyConvert<Envoy::ProtobufWkt::Struct>(proxy_data);
|
Envoy::MessageUtil::anyConvert<Envoy::ProtobufWkt::Struct>(proxy_data);
|
||||||
if (config_->filter_direction_ == FilterDirection::Downstream) {
|
auto key_metadata_it = value_struct.fields().find(ExchangeMetadataHeader);
|
||||||
setMetadata(UpstreamDynamicDataKey, struct_metadata);
|
if (key_metadata_it != value_struct.fields().end()) {
|
||||||
} else {
|
Envoy::ProtobufWkt::Value val = key_metadata_it->second;
|
||||||
setMetadata(DownstreamDynamicDataKey, struct_metadata);
|
setMetadata(config_->filter_direction_ == FilterDirection::Downstream
|
||||||
|
? UpstreamMetadataKey
|
||||||
|
: DownstreamMetadataKey,
|
||||||
|
val);
|
||||||
|
}
|
||||||
|
const auto key_metadata_id_it =
|
||||||
|
value_struct.fields().find(ExchangeMetadataHeaderId);
|
||||||
|
if (key_metadata_id_it != value_struct.fields().end()) {
|
||||||
|
Envoy::ProtobufWkt::Value val = key_metadata_it->second;
|
||||||
|
setMetadata(config_->filter_direction_ == FilterDirection::Downstream
|
||||||
|
? UpstreamMetadataIdKey
|
||||||
|
: DownstreamMetadataIdKey,
|
||||||
|
val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MetadataExchangeFilter::setMetadata(const std::string key,
|
void MetadataExchangeFilter::setMetadata(const std::string& key,
|
||||||
const ProtobufWkt::Struct& value) {
|
Envoy::ProtobufWkt::Value& value) {
|
||||||
read_callbacks_->connection().streamInfo().setDynamicMetadata(key, value);
|
read_callbacks_->connection().streamInfo().filterState().setData(
|
||||||
|
key,
|
||||||
|
std::make_unique<::Envoy::Extensions::Common::Wasm::WasmState>(value),
|
||||||
|
StreamInfo::FilterState::StateType::Mutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<const google::protobuf::Struct>
|
void MetadataExchangeFilter::setMetadataStringValue(
|
||||||
MetadataExchangeFilter::getMetadata(const std::string& key) {
|
const std::string& key, const std::string& str_value) {
|
||||||
|
Envoy::ProtobufWkt::Value value;
|
||||||
|
value.set_string_value(str_value);
|
||||||
|
setMetadata(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MetadataExchangeFilter::getMetadata(google::protobuf::Struct* metadata) {
|
||||||
if (local_info_.node().has_metadata()) {
|
if (local_info_.node().has_metadata()) {
|
||||||
auto metadata_fields = local_info_.node().metadata().fields();
|
google::protobuf::Struct node_metadata = local_info_.node().metadata();
|
||||||
auto node_metadata = metadata_fields.find(key);
|
google::protobuf::Value value_struct;
|
||||||
if (node_metadata != metadata_fields.end()) {
|
|
||||||
return std::make_unique<const google::protobuf::Struct>(
|
const auto status =
|
||||||
node_metadata->second.struct_value());
|
Wasm::Common::extractNodeMetadataValue(node_metadata, metadata);
|
||||||
|
if (!status.ok()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
}
|
||||||
|
|
||||||
|
std::string MetadataExchangeFilter::getMetadataId() {
|
||||||
|
return local_info_.node().id();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace MetadataExchange
|
} // namespace MetadataExchange
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include "envoy/runtime/runtime.h"
|
#include "envoy/runtime/runtime.h"
|
||||||
#include "envoy/stats/scope.h"
|
#include "envoy/stats/scope.h"
|
||||||
#include "envoy/stats/stats_macros.h"
|
#include "envoy/stats/stats_macros.h"
|
||||||
|
#include "envoy/stream_info/filter_state.h"
|
||||||
#include "src/envoy/tcp/metadata_exchange/config/metadata_exchange.pb.h"
|
#include "src/envoy/tcp/metadata_exchange/config/metadata_exchange.pb.h"
|
||||||
|
|
||||||
namespace Envoy {
|
namespace Envoy {
|
||||||
|
|
@ -59,7 +60,6 @@ class MetadataExchangeConfig {
|
||||||
public:
|
public:
|
||||||
MetadataExchangeConfig(const std::string& stat_prefix,
|
MetadataExchangeConfig(const std::string& stat_prefix,
|
||||||
const std::string& protocol,
|
const std::string& protocol,
|
||||||
const std::string& node_metadata_id,
|
|
||||||
const FilterDirection filter_direction,
|
const FilterDirection filter_direction,
|
||||||
Stats::Scope& scope);
|
Stats::Scope& scope);
|
||||||
|
|
||||||
|
|
@ -71,8 +71,6 @@ class MetadataExchangeConfig {
|
||||||
const std::string stat_prefix_;
|
const std::string stat_prefix_;
|
||||||
// Expected Alpn Protocol.
|
// Expected Alpn Protocol.
|
||||||
const std::string protocol_;
|
const std::string protocol_;
|
||||||
// Node metadata id to read.
|
|
||||||
const std::string node_metadata_id_;
|
|
||||||
// Direction of filter.
|
// Direction of filter.
|
||||||
const FilterDirection filter_direction_;
|
const FilterDirection filter_direction_;
|
||||||
// Stats for MetadataExchange Filter.
|
// Stats for MetadataExchange Filter.
|
||||||
|
|
@ -129,11 +127,20 @@ class MetadataExchangeFilter : public Network::Filter {
|
||||||
void tryReadProxyData(Buffer::Instance& data);
|
void tryReadProxyData(Buffer::Instance& data);
|
||||||
|
|
||||||
// Helper function to set Dynamic metadata.
|
// Helper function to set Dynamic metadata.
|
||||||
void setMetadata(const std::string key, const ProtobufWkt::Struct& value);
|
void setMetadata(const std::string& key, ProtobufWkt::Value& value);
|
||||||
|
|
||||||
|
// Helper function to set Dynamic metadata string value.
|
||||||
|
void setMetadataStringValue(const std::string& key, const std::string& value);
|
||||||
|
|
||||||
|
// Helper function to set Dynamic metadata string value.
|
||||||
|
void setMetadataStructValue(const std::string& key,
|
||||||
|
const ProtobufWkt::Value& value);
|
||||||
|
|
||||||
// Helper function to get Dynamic metadata.
|
// Helper function to get Dynamic metadata.
|
||||||
std::unique_ptr<const google::protobuf::Struct> getMetadata(
|
void getMetadata(google::protobuf::Struct* metadata);
|
||||||
const std::string& key);
|
|
||||||
|
// Helper function to get metadata id.
|
||||||
|
std::string getMetadataId();
|
||||||
|
|
||||||
// Config for MetadataExchange filter.
|
// Config for MetadataExchange filter.
|
||||||
MetadataExchangeConfigSharedPtr config_;
|
MetadataExchangeConfigSharedPtr config_;
|
||||||
|
|
@ -147,11 +154,20 @@ class MetadataExchangeFilter : public Network::Filter {
|
||||||
uint64_t proxy_data_length_{0};
|
uint64_t proxy_data_length_{0};
|
||||||
|
|
||||||
// Key Identifier for dynamic metadata in upstream filter.
|
// Key Identifier for dynamic metadata in upstream filter.
|
||||||
const std::string UpstreamDynamicDataKey =
|
const std::string UpstreamMetadataKey =
|
||||||
"filters.network.metadata_exchange.upstream";
|
"envoy.wasm.metadata_exchange.upstream";
|
||||||
|
const std::string UpstreamMetadataIdKey =
|
||||||
|
"envoy.wasm.metadata_exchange.upstream_id";
|
||||||
|
|
||||||
// Key Identifier for dynamic metadata in downstream filter.
|
// Key Identifier for dynamic metadata in downstream filter.
|
||||||
const std::string DownstreamDynamicDataKey =
|
const std::string DownstreamMetadataKey =
|
||||||
"filters.network.metadata_exchange.downstream";
|
"envoy.wasm.metadata_exchange.downstream";
|
||||||
|
const std::string DownstreamMetadataIdKey =
|
||||||
|
"envoy.wasm.metadata_exchange.downstream_id";
|
||||||
|
|
||||||
|
const std::string ExchangeMetadataHeader = "x-envoy-peer-metadata";
|
||||||
|
const std::string ExchangeMetadataHeaderId = "x-envoy-peer-metadata-id";
|
||||||
|
|
||||||
// Type url of google::protobug::struct.
|
// Type url of google::protobug::struct.
|
||||||
const std::string StructTypeUrl =
|
const std::string StructTypeUrl =
|
||||||
"type.googleapis.com/google.protobuf.Struct";
|
"type.googleapis.com/google.protobuf.Struct";
|
||||||
|
|
|
||||||
|
|
@ -58,12 +58,16 @@ class MetadataExchangeFilterTest : public testing::Test {
|
||||||
|
|
||||||
void initialize() {
|
void initialize() {
|
||||||
config_ = std::make_shared<MetadataExchangeConfig>(
|
config_ = std::make_shared<MetadataExchangeConfig>(
|
||||||
stat_prefix_, "istio2", "istio/metadata", FilterDirection::Downstream,
|
stat_prefix_, "istio2", FilterDirection::Downstream, scope_);
|
||||||
scope_);
|
|
||||||
filter_ = std::make_unique<MetadataExchangeFilter>(config_, local_info_);
|
filter_ = std::make_unique<MetadataExchangeFilter>(config_, local_info_);
|
||||||
filter_->initializeReadFilterCallbacks(read_filter_callbacks_);
|
filter_->initializeReadFilterCallbacks(read_filter_callbacks_);
|
||||||
filter_->initializeWriteFilterCallbacks(write_filter_callbacks_);
|
filter_->initializeWriteFilterCallbacks(write_filter_callbacks_);
|
||||||
metadata_node_.set_id("test");
|
metadata_node_.set_id("test");
|
||||||
|
auto node_metadata_map =
|
||||||
|
metadata_node_.mutable_metadata()->mutable_fields();
|
||||||
|
(*node_metadata_map)["EXCHANGE_KEYS"].set_string_value("namespace, labels");
|
||||||
|
(*node_metadata_map)["namespace"].set_string_value("default");
|
||||||
|
(*node_metadata_map)["labels"].set_string_value("{app, details}");
|
||||||
EXPECT_CALL(read_filter_callbacks_.connection_, streamInfo())
|
EXPECT_CALL(read_filter_callbacks_.connection_, streamInfo())
|
||||||
.WillRepeatedly(ReturnRef(stream_info_));
|
.WillRepeatedly(ReturnRef(stream_info_));
|
||||||
EXPECT_CALL(local_info_, node()).WillRepeatedly(ReturnRef(metadata_node_));
|
EXPECT_CALL(local_info_, node()).WillRepeatedly(ReturnRef(metadata_node_));
|
||||||
|
|
@ -98,18 +102,8 @@ TEST_F(MetadataExchangeFilterTest, MetadataExchangeFound) {
|
||||||
initialize();
|
initialize();
|
||||||
initializeStructValues();
|
initializeStructValues();
|
||||||
|
|
||||||
auto node_metadata_map = metadata_node_.mutable_metadata()->mutable_fields();
|
|
||||||
google::protobuf::Value& value = (*node_metadata_map)["istio/metadata"];
|
|
||||||
(*value.mutable_struct_value()).CopyFrom(details_value_);
|
|
||||||
|
|
||||||
EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol())
|
EXPECT_CALL(read_filter_callbacks_.connection_, nextProtocol())
|
||||||
.WillRepeatedly(Return("istio2"));
|
.WillRepeatedly(Return("istio2"));
|
||||||
EXPECT_CALL(stream_info_,
|
|
||||||
setDynamicMetadata("filters.network.metadata_exchange.downstream",
|
|
||||||
MapEq(details_value_)));
|
|
||||||
EXPECT_CALL(stream_info_,
|
|
||||||
setDynamicMetadata("filters.network.metadata_exchange.upstream",
|
|
||||||
MapEq(productpage_value_)));
|
|
||||||
|
|
||||||
::Envoy::Buffer::OwnedImpl data;
|
::Envoy::Buffer::OwnedImpl data;
|
||||||
MetadataExchangeInitialHeader initial_header;
|
MetadataExchangeInitialHeader initial_header;
|
||||||
|
|
|
||||||
|
|
@ -100,9 +100,12 @@ type TestSetup struct {
|
||||||
// Whether Tls is Enabled or not.
|
// Whether Tls is Enabled or not.
|
||||||
EnableTls bool
|
EnableTls bool
|
||||||
|
|
||||||
// Format for accesslog
|
// Format for client accesslog
|
||||||
AccesslogFormat string
|
AccesslogFormat string
|
||||||
|
|
||||||
|
// Format for server accesslog
|
||||||
|
ServerAccesslogFormat string
|
||||||
|
|
||||||
// TlsContext to be used.
|
// TlsContext to be used.
|
||||||
TlsContext string
|
TlsContext string
|
||||||
|
|
||||||
|
|
@ -212,6 +215,11 @@ func (s *TestSetup) SetAccessLogFormat(accesslogformat string) {
|
||||||
s.AccesslogFormat = accesslogformat
|
s.AccesslogFormat = accesslogformat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetServerAccessLogFormat sets the serverAccesslogformat.
|
||||||
|
func (s *TestSetup) SetServerAccessLogFormat(serverAccesslogformat string) {
|
||||||
|
s.ServerAccesslogFormat = serverAccesslogformat
|
||||||
|
}
|
||||||
|
|
||||||
// SetUpstreamFiltersInClient sets upstream filters chain in client envoy..
|
// SetUpstreamFiltersInClient sets upstream filters chain in client envoy..
|
||||||
func (s *TestSetup) SetUpstreamFiltersInClient(upstreamFiltersInClient string) {
|
func (s *TestSetup) SetUpstreamFiltersInClient(upstreamFiltersInClient string) {
|
||||||
s.UpstreamFiltersInClient = upstreamFiltersInClient
|
s.UpstreamFiltersInClient = upstreamFiltersInClient
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ static_resources:
|
||||||
- name: envoy.file_access_log
|
- name: envoy.file_access_log
|
||||||
config:
|
config:
|
||||||
path: {{.ClientAccessLogPath}}
|
path: {{.ClientAccessLogPath}}
|
||||||
{{.AccesslogFormat | indent 14 }}
|
format: {{.AccesslogFormat}}
|
||||||
{{.TlsContext | indent 6 }}
|
{{.TlsContext | indent 6 }}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -117,6 +117,7 @@ static_resources:
|
||||||
- name: envoy.file_access_log
|
- name: envoy.file_access_log
|
||||||
config:
|
config:
|
||||||
path: {{.ServerAccessLogPath}}
|
path: {{.ServerAccessLogPath}}
|
||||||
|
format: {{.ServerAccesslogFormat}}
|
||||||
{{.TlsContext | indent 6 }}
|
{{.TlsContext | indent 6 }}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ const metadataExchangeIstioConfigFilter = `
|
||||||
- name: envoy.filters.network.metadata_exchange
|
- name: envoy.filters.network.metadata_exchange
|
||||||
config:
|
config:
|
||||||
protocol: istio2
|
protocol: istio2
|
||||||
node_metadata_id: istio.io/metadata
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const metadataExchangeIstioUpstreamConfigFilterChain = `
|
const metadataExchangeIstioUpstreamConfigFilterChain = `
|
||||||
|
|
@ -40,7 +39,6 @@ filters:
|
||||||
typed_config:
|
typed_config:
|
||||||
"@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange
|
"@type": type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange
|
||||||
protocol: istio2
|
protocol: istio2
|
||||||
node_metadata_id: istio.io/metadata
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const tlsContext = `
|
const tlsContext = `
|
||||||
|
|
@ -74,19 +72,63 @@ tls_context:
|
||||||
inline_string: "-----BEGIN CERTIFICATE-----\nMIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL\nBQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy\nMjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE\nAwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH\n/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA\nBGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW\nAYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX\ntQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7\nCXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves\nG4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S\nEw1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM\nfLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP\ny5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz\nAobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8\nRm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ\nh3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y\n2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3\nLuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT\nIzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL\nZ8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww\noImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8\ndvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G\nk5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh\nsaFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V\n6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM\nSHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy\nUff0OxD2hzk=\n-----END CERTIFICATE-----\n"
|
inline_string: "-----BEGIN CERTIFICATE-----\nMIIFFDCCAvygAwIBAgIUZqU0Sviq/wULK6UV7PoAZ7B+nqAwDQYJKoZIhvcNAQEL\nBQAwIjEOMAwGA1UECgwFSXN0aW8xEDAOBgNVBAMMB1Jvb3QgQ0EwHhcNMTkwNzIy\nMjEzMDA0WhcNMjkwNzE5MjEzMDA0WjAiMQ4wDAYDVQQKDAVJc3RpbzEQMA4GA1UE\nAwwHUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANNl5/pH\n/ktdqEsb83cqHrYJCyzbvWce6k/iud4Czu6FClFX8b+n/Rv9GrZFxJwKAFlUx3iA\nBGlSn/1XYpnhudQhgVGvyuWNO5kX4BfrAJwfWt+7Mn6NcWvunDqwqUPxI07sgCJW\nAYBAwkZH/Nhn6tj571XWNPziUtCwlPNkFMiRu/2nI/tq12IgwimFjVgiCuprNfyX\ntQz/DMVTWpCRQLK5ptlYMfk0P25UKyJdKHnr1MPQBJmPXMfSSqpGjksikV4QnYc7\nCXB3ucq7ty0IWA8QXH+86WqMTh22mosWVXHe0OGbzYtuyVnXc1G7YRv4D87G3Ves\nG4n/8e+RaDTacvwOsYEkuQGk+s8pggPkIqydGy02JNZ4cSRpXJRTzME2BgBZxT8S\nEw1Omr5+iuLNRAKEYRM/eWI7qrs5fxpD6K9JELHS41hWHGdW94PP0wKz70trx5pM\nfLpcVm7BQ5ppgf+t4vgKnrNiACQpfyZbInCBU0doaZaqVMnKH0vgyM7xrC43fsOP\ny5URy3tEH8Uk7Dbvsmj7AXR7IPKlYtgcqcJXmeWa+kLOpx3G55hgJL1ySrxXg/qz\nAobgmV0IycH2ntn5lXvjbwe0cfXAnZgGoALZjJVuEazyBmmVzjBjG2Qcq35nHfp8\nRm6WnCZIaGsZqgoDuSJD280ZLWW7R0PMcnypAgMBAAGjQjBAMB0GA1UdDgQWBBQZ\nh3/ckcK23ZYKO+JsZowd3dIobDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE\nAwIC5DANBgkqhkiG9w0BAQsFAAOCAgEAjh4CdrwnLsqwVxyVSgxd7TfSHtKE/J2Y\n2IZ4fJYXGkq3McPk2e9u0zjCH0buvfDwyAItLIacD+YwIP+OC2WxLe+YMZ5KkXl3\nLuhQ2TOoRlrbp5tYLQITZIIl9+vNkgnn1DkdxkLm9cDDag19LSxa9Rjrnb3wwFAT\nIzEhy+d18FpQtdMMhmonU/L8Oy5LqjT5BR3T8VrXYUsaAkcUs/yHNTFAY3iJFBWL\nZ8dFa5v0A1Ryi8quSNo7lK/hSEZvvV9k4XfFAolXSUqe8BCuXe0rbAq3Jq9HgDww\noImGM0uz4Zf89uhTk1O7UOUfQoSTmA0yZICtQkCiOC0J4AlAOTmiEXUC9gicV3R8\ndvVOqNBOcBELglZ+NIMm6FQQqPh1nZ6A3Bh+JRTPerAF12725RZZE6XMxq2MSr3G\nk5yH10QPMH7/DJRQUhRHAhbge+jk2csa7EGSxABcbsPLSV+cEzXRO4cJeItoZQLh\nsaFhIn9lGukXG6lgiperOqZl6DFVcUG6/nogK7KOTAnV9zjR/7vNwvYzPI9iOR3V\n6dbG38KnipcfL885VLJVTnfhvYHlxFklCKTEnOHnmKsM0qjQuky3DBzmDA6iqeOM\nSHRje5LKxi7mllJfu/X0MxYJWiu6i4gMCWZsC3UtAJQ09x7iwcNr/1bl9ApGszOy\nUff0OxD2hzk=\n-----END CERTIFICATE-----\n"
|
||||||
`
|
`
|
||||||
|
|
||||||
const clientNodeMetadata = `
|
const clientNodeMetadata = `"NAMESPACE": "default",
|
||||||
"istio.io/metadata": {
|
"INCLUDE_INBOUND_PORTS": "9080",
|
||||||
namespace: default,
|
"app": "productpage",
|
||||||
labels: { app: productpage },
|
"EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,CANONICAL_TELEMETRY_SERVICE,MESH_ID,SERVICE_ACCOUNT",
|
||||||
}
|
"INSTANCE_IPS": "10.52.0.34,fe80::a075:11ff:fe5e:f1cd",
|
||||||
`
|
"pod-template-hash": "84975bc778",
|
||||||
|
"INTERCEPTION_MODE": "REDIRECT",
|
||||||
|
"SERVICE_ACCOUNT": "bookinfo-productpage",
|
||||||
|
"CONFIG_NAMESPACE": "default",
|
||||||
|
"version": "v1",
|
||||||
|
"OWNER": "kubernetes://api/apps/v1/namespaces/default/deployment/productpage-v1",
|
||||||
|
"WORKLOAD_NAME": "productpage-v1",
|
||||||
|
"ISTIO_VERSION": "1.3-dev",
|
||||||
|
"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container productpage",
|
||||||
|
"POD_NAME": "productpage-v1-84975bc778-pxz2w",
|
||||||
|
"istio": "sidecar",
|
||||||
|
"PLATFORM_METADATA": {
|
||||||
|
"gcp_cluster_name": "test-cluster",
|
||||||
|
"gcp_project": "test-project",
|
||||||
|
"gcp_cluster_location": "us-east4-b"
|
||||||
|
},
|
||||||
|
"LABELS": {
|
||||||
|
"app": "productpage",
|
||||||
|
"version": "v1",
|
||||||
|
"pod-template-hash": "84975bc778"
|
||||||
|
},
|
||||||
|
"ISTIO_PROXY_SHA": "istio-proxy:47e4559b8e4f0d516c0d17b233d127a3deb3d7ce",
|
||||||
|
"NAME": "productpage-v1-84975bc778-pxz2w",`
|
||||||
|
|
||||||
const serverNodeMetadata = `
|
const serverNodeMetadata = `"NAMESPACE": "default",
|
||||||
"istio.io/metadata": {
|
"INCLUDE_INBOUND_PORTS": "9080",
|
||||||
namespace: default,
|
"app": "ratings",
|
||||||
labels: { app: details },
|
"EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,CANONICAL_TELEMETRY_SERVICE,MESH_ID,SERVICE_ACCOUNT",
|
||||||
}
|
"INSTANCE_IPS": "10.52.0.34,fe80::a075:11ff:fe5e:f1cd",
|
||||||
`
|
"pod-template-hash": "84975bc778",
|
||||||
|
"INTERCEPTION_MODE": "REDIRECT",
|
||||||
|
"SERVICE_ACCOUNT": "bookinfo-ratings",
|
||||||
|
"CONFIG_NAMESPACE": "default",
|
||||||
|
"version": "v1",
|
||||||
|
"OWNER": "kubernetes://api/apps/v1/namespaces/default/deployment/ratings-v1",
|
||||||
|
"WORKLOAD_NAME": "ratings-v1",
|
||||||
|
"ISTIO_VERSION": "1.3-dev",
|
||||||
|
"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container ratings",
|
||||||
|
"POD_NAME": "ratings-v1-84975bc778-pxz2w",
|
||||||
|
"istio": "sidecar",
|
||||||
|
"PLATFORM_METADATA": {
|
||||||
|
"gcp_cluster_name": "test-cluster",
|
||||||
|
"gcp_project": "test-project",
|
||||||
|
"gcp_cluster_location": "us-east4-b"
|
||||||
|
},
|
||||||
|
"LABELS": {
|
||||||
|
"app": "ratings",
|
||||||
|
"version": "v1",
|
||||||
|
"pod-template-hash": "84975bc778"
|
||||||
|
},
|
||||||
|
"ISTIO_PROXY_SHA": "istio-proxy:47e4559b8e4f0d516c0d17b233d127a3deb3d7ce",
|
||||||
|
"NAME": "ratings-v1-84975bc778-pxz2w",`
|
||||||
|
|
||||||
// Stats in Client Envoy proxy.
|
// Stats in Client Envoy proxy.
|
||||||
var expectedClientStats = map[string]int{
|
var expectedClientStats = map[string]int{
|
||||||
|
|
@ -140,7 +182,7 @@ func TestTcpMetadataExchange(t *testing.T) {
|
||||||
}
|
}
|
||||||
config := &tls.Config{Certificates: []tls.Certificate{certificate}, ServerName: "localhost", NextProtos: []string{"istio2"}, RootCAs: certPool}
|
config := &tls.Config{Certificates: []tls.Certificate{certificate}, ServerName: "localhost", NextProtos: []string{"istio2"}, RootCAs: certPool}
|
||||||
|
|
||||||
conn, err := tls.Dial("tcp", fmt.Sprintf("localhost:%d", s.Ports().AppToClientProxyPort /*s.Ports().ProxyToServerProxyPort*/), config)
|
conn, err := tls.Dial("tcp", fmt.Sprintf("localhost:%d", s.Ports().AppToClientProxyPort), config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue