Skip to content

Commit

Permalink
Metadata Exchange Filter (#2325)
Browse files Browse the repository at this point in the history
* WIP:Alpn Proxy Filter

Work left: test is not passing completely yet.. make it pass
Add an integration/e2e test

Move writing of metadata to the callback when TLS handshake is complete.
onNewConnection gets called when connection is established but before handshake is complete. Thus couldnt do metadata write here.

Updating based on feedback

Fix formatting and use MessageDifferencer

Updating based on feedback

Fix lint error

Updating based on feedback

Updating based on feedback

Added upstream filter

Add e2e test for tcp metadata exchange

Added TODO's

Remove tmp file added by mistake

Using client and server metadata variables

Fix asan and build errors

Fix lint errors

Fix construction of initial header

Updated based on feedback

Updated based on feedback

Updated based on feedback

Updated code with comments

Fix after refactor

Fix build errors

* Fix build errors

* Fix build errors

* Fix build errors

* Fixed based on feedback

* Renamed AlpnProxy to MetadataExchange

* Fix linting errors

* Update magic number

* Add tls and http inspectors in tcp envoy config

This validates that having these inspectors doesnt affect Metadata Exchange filter

* Fixed  based  on  feedback

* Fixed  based  on  feedback

* Fixed  based  on  feedback
  • Loading branch information
gargnupur authored and istio-testing committed Oct 8, 2019
1 parent d52da5a commit d9e6de4
Show file tree
Hide file tree
Showing 22 changed files with 1,472 additions and 77 deletions.
1 change: 1 addition & 0 deletions src/envoy/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ envoy_cc_binary(
"//src/envoy/http/jwt_auth:http_filter_factory",
"//src/envoy/http/mixer:filter_lib",
"//src/envoy/tcp/forward_downstream_sni:config_lib",
"//src/envoy/tcp/metadata_exchange:config_lib",
"//src/envoy/tcp/mixer:filter_lib",
"//src/envoy/tcp/sni_verifier:config_lib",
"//src/envoy/tcp/tcp_cluster_rewrite:config_lib",
Expand Down
87 changes: 87 additions & 0 deletions src/envoy/tcp/metadata_exchange/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#

# Metadata Exchange filter

load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_cc_test",
"envoy_package",
)

envoy_package()

envoy_cc_library(
name = "metadata_exchange",
srcs = [
"metadata_exchange.cc",
"metadata_exchange_initial_header.cc",
],
hdrs = [
"metadata_exchange.h",
"metadata_exchange_initial_header.h",
],
repository = "@envoy",
deps = [
"//src/envoy/tcp/metadata_exchange/config:metadata_exchange_cc_proto",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/base:endian",
"@com_google_absl//absl/strings",
"@envoy//include/envoy/local_info:local_info_interface",
"@envoy//include/envoy/network:connection_interface",
"@envoy//include/envoy/network:filter_interface",
"@envoy//include/envoy/runtime:runtime_interface",
"@envoy//include/envoy/stats:stats_macros",
"@envoy//source/common/http:utility_lib",
"@envoy//source/common/network:utility_lib",
"@envoy//source/common/protobuf",
"@envoy//source/common/protobuf:utility_lib",
"@envoy//source/extensions/filters/network:well_known_names",
],
)

envoy_cc_library(
name = "config_lib",
srcs = ["config.cc"],
hdrs = ["config.h"],
repository = "@envoy",
visibility = ["//visibility:public"],
deps = [
":metadata_exchange",
"//src/envoy/tcp/metadata_exchange/config:metadata_exchange_cc_proto",
"//src/envoy/utils:utils_lib",
"@envoy//include/envoy/registry",
"@envoy//source/extensions/filters/network/common:factory_base_lib",
],
)

envoy_cc_test(
name = "metadataexchange_test",
srcs = [
"metadata_exchange_test.cc",
],
repository = "@envoy",
deps = [
":config_lib",
":metadata_exchange",
"@envoy//source/common/protobuf",
"@envoy//test/mocks/local_info:local_info_mocks",
"@envoy//test/mocks/network:network_mocks",
"@envoy//test/mocks/protobuf:protobuf_mocks",
],
)
116 changes: 116 additions & 0 deletions src/envoy/tcp/metadata_exchange/config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "src/envoy/tcp/metadata_exchange/config.h"
#include "envoy/network/connection.h"
#include "envoy/registry/registry.h"
#include "src/envoy/tcp/metadata_exchange/metadata_exchange.h"
#include "src/envoy/utils/config.h"

namespace Envoy {
namespace Tcp {
namespace MetadataExchange {
namespace {

static constexpr char StatPrefix[] = "metadata_exchange.";

Network::FilterFactoryCb createFilterFactoryHelper(
const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config,
Server::Configuration::CommonFactoryContext& context,
FilterDirection filter_direction) {
ASSERT(!proto_config.protocol().empty());

MetadataExchangeConfigSharedPtr filter_config(
std::make_shared<MetadataExchangeConfig>(
StatPrefix, proto_config.protocol(), proto_config.node_metadata_id(),
filter_direction, context.scope()));
return [filter_config,
&context](Network::FilterManager& filter_manager) -> void {
filter_manager.addFilter(std::make_shared<MetadataExchangeFilter>(
filter_config, context.localInfo()));
};
}
} // namespace

Network::FilterFactoryCb
MetadataExchangeConfigFactory::createFilterFactoryFromProto(
const Protobuf::Message& config,
Server::Configuration::FactoryContext& context) {
return createFilterFactory(
dynamic_cast<
const envoy::tcp::metadataexchange::config::MetadataExchange&>(
config),
context);
}

ProtobufTypes::MessagePtr
MetadataExchangeConfigFactory::createEmptyConfigProto() {
return std::make_unique<
envoy::tcp::metadataexchange::config::MetadataExchange>();
}

Network::FilterFactoryCb MetadataExchangeConfigFactory::createFilterFactory(
const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config,
Server::Configuration::FactoryContext& context) {
return createFilterFactoryHelper(proto_config, context,
FilterDirection::Downstream);
}

Network::FilterFactoryCb
MetadataExchangeUpstreamConfigFactory::createFilterFactoryFromProto(
const Protobuf::Message& config,
Server::Configuration::CommonFactoryContext& context) {
return createFilterFactory(
dynamic_cast<
const envoy::tcp::metadataexchange::config::MetadataExchange&>(
config),
context);
}

ProtobufTypes::MessagePtr
MetadataExchangeUpstreamConfigFactory::createEmptyConfigProto() {
return std::make_unique<
envoy::tcp::metadataexchange::config::MetadataExchange>();
}

Network::FilterFactoryCb
MetadataExchangeUpstreamConfigFactory::createFilterFactory(
const envoy::tcp::metadataexchange::config::MetadataExchange& proto_config,
Server::Configuration::CommonFactoryContext& context) {
return createFilterFactoryHelper(proto_config, context,
FilterDirection::Upstream);
}

/**
* Static registration for the MetadataExchange Downstream filter. @see
* RegisterFactory.
*/
static Registry::RegisterFactory<
MetadataExchangeConfigFactory,
Server::Configuration::NamedNetworkFilterConfigFactory>
registered_;

/**
* Static registration for the MetadataExchange Upstream filter. @see
* RegisterFactory.
*/
static Registry::RegisterFactory<
MetadataExchangeUpstreamConfigFactory,
Server::Configuration::NamedUpstreamNetworkFilterConfigFactory>
registered_upstream_;

} // namespace MetadataExchange
} // namespace Tcp
} // namespace Envoy
80 changes: 80 additions & 0 deletions src/envoy/tcp/metadata_exchange/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "extensions/filters/network/common/factory_base.h"
#include "src/envoy/tcp/metadata_exchange/config/metadata_exchange.pb.h"

namespace Envoy {
namespace Tcp {
namespace MetadataExchange {

/**
* Config registration for the MetadataExchange filter. @see
* NamedNetworkFilterConfigFactory.
*/
class MetadataExchangeConfigFactory
: public Server::Configuration::NamedNetworkFilterConfigFactory {
public:
Network::FilterFactoryCb createFilterFactory(
const Json::Object&, Server::Configuration::FactoryContext&) override {
NOT_IMPLEMENTED_GCOVR_EXCL_LINE;
}

Network::FilterFactoryCb createFilterFactoryFromProto(
const Protobuf::Message&,
Server::Configuration::FactoryContext&) override;

ProtobufTypes::MessagePtr createEmptyConfigProto() override;

std::string name() override {
return "envoy.filters.network.metadata_exchange";
}

private:
Network::FilterFactoryCb createFilterFactory(
const envoy::tcp::metadataexchange::config::MetadataExchange&
proto_config,
Server::Configuration::FactoryContext& context);
};

/**
* Config registration for the MetadataExchange Upstream filter. @see
* NamedUpstreamNetworkFilterConfigFactory.
*/
class MetadataExchangeUpstreamConfigFactory
: public Server::Configuration::NamedUpstreamNetworkFilterConfigFactory {
public:
Network::FilterFactoryCb createFilterFactoryFromProto(
const Protobuf::Message&,
Server::Configuration::CommonFactoryContext&) override;

ProtobufTypes::MessagePtr createEmptyConfigProto() override;

std::string name() override {
return "envoy.filters.network.upstream.metadata_exchange";
}

private:
Network::FilterFactoryCb createFilterFactory(
const envoy::tcp::metadataexchange::config::MetadataExchange&
proto_config,
Server::Configuration::CommonFactoryContext& context);
};

} // namespace MetadataExchange
} // namespace Tcp
} // namespace Envoy
27 changes: 27 additions & 0 deletions src/envoy/tcp/metadata_exchange/config/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2019 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#

proto_library(
name = "metadata_exchange_proto",
srcs = ["metadata_exchange.proto"],
)

cc_proto_library(
name = "metadata_exchange_cc_proto",
visibility = ["//visibility:public"],
deps = ["metadata_exchange_proto"],
)
35 changes: 35 additions & 0 deletions src/envoy/tcp/metadata_exchange/config/metadata_exchange.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* Copyright 2019 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

syntax = "proto3";

package envoy.tcp.metadataexchange.config;

option java_outer_classname = "MetadataExchangeProto";
option java_multiple_files = true;
option java_package = "io.envoyproxy.envoy.tcp.metadataexchange.config";
option go_package = "MetadataExchange";

// [#protodoc-title: MetadataExchange protocol match and data transfer]
// MetadataExchange protocol match and data transfer
message MetadataExchange {
// Protocol that Alpn should support on the server.
// [#comment:TODO(GargNupur): Make it a list.]
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;
}
Loading

0 comments on commit d9e6de4

Please sign in to comment.