Skip to content

Commit

Permalink
Header to metadata filter (envoyproxy#2436)
Browse files Browse the repository at this point in the history
Add support for extracting dynamic metadata from requests. This can then
be used as static metadata would be used (e.g.: for subset load balancer
metadata matches, logging, etc).

Risk Level: Low

Testing: unit-test

Docs Changes:
Basic docs, more later.

Release Notes:
N/A

Signed-off-by: Raul Gutierrez Segales <[email protected]>
  • Loading branch information
Raul Gutierrez Segales committed Jun 14, 2018
1 parent 7ca1882 commit 9a4c44c
Show file tree
Hide file tree
Showing 19 changed files with 805 additions and 1 deletion.
1 change: 1 addition & 0 deletions api/docs/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ proto_library(
"//envoy/config/filter/http/fault/v2:fault",
"//envoy/config/filter/http/gzip/v2:gzip",
"//envoy/config/filter/http/health_check/v2:health_check",
"//envoy/config/filter/http/header_to_metadata/v2:header_to_metadata",
"//envoy/config/filter/http/ip_tagging/v2:ip_tagging",
"//envoy/config/filter/http/lua/v2:lua",
"//envoy/config/filter/http/rate_limit/v2:rate_limit",
Expand Down
9 changes: 9 additions & 0 deletions api/envoy/config/filter/http/header_to_metadata/v2/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
load("//bazel:api_build_system.bzl", "api_proto_library")

licenses(["notice"]) # Apache 2

api_proto_library(
name = "header_to_metadata",
srcs = ["header_to_metadata.proto"],
deps = [],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
syntax = "proto3";

package envoy.config.filter.http.header_to_metadata.v2;

enum ValueType {
STRING = 0;
NUMBER = 1;
}

message KeyValuePair {
// The namespace. If this is empty, the filter's namespace will be used.
string metadata_namespace = 1;

// The key — must be present.
string key = 2;

// The value — may be absent.
string value = 3;

// The type.
ValueType type = 4;
}

message Rule {
// The header from which to extract a value.
string header = 1;

// The metadata key with which the extracted value will be paired.
KeyValuePair on_header_present = 2;

// If the header is not present — and this is set — insert this key/value pair instead.
KeyValuePair on_header_missing = 3;

// Whether or not to remove the header after it's been copied to metadata. By allowing the
// configuration to express header removal, we easily prevent internal metadata from leaking.
bool remove = 4;
}

message Config {
repeated Rule request_rules = 1;
repeated Rule response_rules = 2;
}
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ message HttpFilter {
// * :ref:`envoy.grpc_json_transcoder <config_http_filters_grpc_json_transcoder>`
// * :ref:`envoy.grpc_web <config_http_filters_grpc_web>`
// * :ref:`envoy.health_check <config_http_filters_health_check>`
// * :ref:`envoy.header_to_metadata <config_http_filters_header_to_metadata>`
// * :ref:`envoy.ip_tagging <config_http_filters_ip_tagging>`
// * :ref:`envoy.lua <config_http_filters_lua>`
// * :ref:`envoy.rate_limit <config_http_filters_rate_limit>`
Expand Down
1 change: 1 addition & 0 deletions api/test/validate/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ api_cc_test(
"//envoy/config/filter/http/fault/v2:fault",
"//envoy/config/filter/http/gzip/v2:gzip",
"//envoy/config/filter/http/health_check/v2:health_check",
"//envoy/config/filter/http/header_to_metadata/v2:header_to_metadata",
"//envoy/config/filter/http/ip_tagging/v2:ip_tagging",
"//envoy/config/filter/http/lua/v2:lua",
"//envoy/config/filter/http/router/v2:router",
Expand Down
1 change: 1 addition & 0 deletions api/test/validate/pgv_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "envoy/config/filter/http/fault/v2/fault.pb.validate.h"
#include "envoy/config/filter/http/gzip/v2/gzip.pb.validate.h"
#include "envoy/config/filter/http/health_check/v2/health_check.pb.validate.h"
#include "envoy/config/filter/http/ip_tagging/v2/header_to_metadata.pb.validate.h"
#include "envoy/config/filter/http/ip_tagging/v2/ip_tagging.pb.validate.h"
#include "envoy/config/filter/http/lua/v2/lua.pb.validate.h"
#include "envoy/config/filter/http/router/v2/router.pb.validate.h"
Expand Down
1 change: 1 addition & 0 deletions docs/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ PROTO_RST="
/envoy/config/filter/http/fault/v2/fault/envoy/config/filter/http/fault/v2/fault.proto.rst
/envoy/config/filter/http/gzip/v2/gzip/envoy/config/filter/http/gzip/v2/gzip.proto.rst
/envoy/config/filter/http/health_check/v2/health_check/envoy/config/filter/http/health_check/v2/health_check.proto.rst
/envoy/config/filter/http/header_to_metadata/v2/header_to_metadata/envoy/config/filter/http/header_to_metadata/v2/header_to_metadata.proto.rst
/envoy/config/filter/http/ip_tagging/v2/ip_tagging/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto.rst
/envoy/config/filter/http/lua/v2/lua/envoy/config/filter/http/lua/v2/lua.proto.rst
/envoy/config/filter/http/rate_limit/v2/rate_limit/envoy/config/filter/http/rate_limit/v2/rate_limit.proto.rst
Expand Down
14 changes: 14 additions & 0 deletions docs/root/configuration/http_filters/header_to_metadata_filter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.. _config_http_filters_header_to_metadata:

Envoy Header-To-Metadata Filter
================================

This filter enables matching against present or missing headers and transforming
those matches into dynamic metadata that can then be used for load balancing
decisions or consumed from logs.

Configuration
-------------
* :ref:`v2 API reference <envoy_api_msg_config.filter.http.header_to_metadata.v2.HeaderToMetadata>`

TODO(rgs)
1 change: 1 addition & 0 deletions docs/root/configuration/http_filters/http_filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ HTTP filters
grpc_web_filter
gzip_filter
health_check_filter
header_to_metadata
ip_tagging_filter
lua_filter
rate_limit_filter
Expand Down
1 change: 1 addition & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ Version history
* websocket: support configuring
:ref:`idle_timeout and max_connect_attempts <envoy_api_field_route.RouteAction.websocket_config>`.
* upstream: added support for host override for a request in :ref:`Original destination host request header <arch_overview_load_balancing_types_original_destination_request_header>`.
* header to metadata: added :ref:`HTTP Header to Metadata filter<config_http_filters_header_to_metadata>`.

1.6.0 (March 20, 2018)
======================
Expand Down
1 change: 1 addition & 0 deletions source/extensions/extensions_build_config.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ EXTENSIONS = {
"envoy.filters.http.grpc_web": "//source/extensions/filters/http/grpc_web:config",
"envoy.filters.http.gzip": "//source/extensions/filters/http/gzip:config",
"envoy.filters.http.health_check": "//source/extensions/filters/http/health_check:config",
"envoy.filters.http.header_to_metadata": "//source/extensions/filters/http/header_to_metadata:config",
"envoy.filters.http.ip_tagging": "//source/extensions/filters/http/ip_tagging:config",
"envoy.filters.http.jwt_authn": "//source/extensions/filters/http/jwt_authn:config",
"envoy.filters.http.lua": "//source/extensions/filters/http/lua:config",
Expand Down
34 changes: 34 additions & 0 deletions source/extensions/filters/http/header_to_metadata/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
licenses(["notice"]) # Apache 2
# HTTP L7 filter that transforms request data into dynamic metadata
# Public docs: docs/root/configuration/http_filters/header_to_metadata_filter.rst

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

envoy_package()

envoy_cc_library(
name = "header_to_metadata_filter_lib",
srcs = ["header_to_metadata_filter.cc"],
hdrs = ["header_to_metadata_filter.h"],
deps = [
"//include/envoy/server:filter_config_interface",
"//source/extensions/filters/http:well_known_names",
"@envoy_api//envoy/config/filter/http/header_to_metadata/v2:header_to_metadata_cc",
],
)

envoy_cc_library(
name = "config",
srcs = ["config.cc"],
hdrs = ["config.h"],
deps = [
"//include/envoy/registry",
"//source/common/protobuf:utility_lib",
"//source/extensions/filters/http:well_known_names",
"//source/extensions/filters/http/header_to_metadata:header_to_metadata_filter_lib",
],
)
57 changes: 57 additions & 0 deletions source/extensions/filters/http/header_to_metadata/config.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include "config.h"

#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "envoy/config/filter/http/header_to_metadata/v2/header_to_metadata.pb.h"
#include "envoy/json/json_object.h"
#include "envoy/registry/registry.h"

#include "common/protobuf/utility.h"

#include "filter.h"

namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace HeaderToMetadataFilter {

Http::FilterFactoryCb
HeaderToMetadataConfig::createFilterFactory(const Json::Object&, const std::string&,
Server::Configuration::FactoryContext&) {
throw new EnvoyException("No support for the v1 API");
}

Http::FilterFactoryCb
HeaderToMetadataConfig::createFilterFactoryFromProto(const Protobuf::Message& proto_config,
const std::string&,
Server::Configuration::FactoryContext&) {
const auto& typed_config = dynamic_cast<
const envoy::config::filter::http::header_to_metadata::v2::HeaderToMetadataConfig&>(
proto_config);
ConfigSharedPtr filter_config(std::make_shared<Config>(typed_config));

return [filter_config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
callbacks.addStreamFilter(
Http::StreamFilterSharedPtr{new HeaderToMetadataFilter(filter_config)});
};
}

ProtobufTypes::MessagePtr HeaderToMetadataConfig::createEmptyConfigProto() {
return ProtobufTypes::MessagePtr{
new envoy::config::filter::http::header_to_metadata::v2::HeaderToMetadataConfig()};
}

/**
* Static registration for the header-to-metadata filter. @see RegisterFactory.
*/
static Registry::RegisterFactory<HeaderToMetadataConfig,
Server::Configuration::NamedHttpFilterConfigFactory>
register_;

} // namespace HeaderToMetadataFilter
} // namespace HttpFilters
} // namespace Extensions
} // namespace Envoy
32 changes: 32 additions & 0 deletions source/extensions/filters/http/header_to_metadata/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "envoy/server/filter_config.h"

#include "extensions/filters/http/well_known_names.h"

namespace Envoy {
namespace Extensions {
namespace HttpFilters {
namespace HeaderToMetadataFilter {

/**
* Config registration for the header-to-metadata filter. @see NamedHttpFilterConfigFactory.
*/
class HeaderToMetadataConfig : public Server::Configuration::NamedHttpFilterConfigFactory {
public:
Http::FilterFactoryCb createFilterFactory(const Json::Object&, const std::string&,
Server::Configuration::FactoryContext&) override;

Http::FilterFactoryCb
createFilterFactoryFromProto(const Protobuf::Message&, const std::string&,
Server::Configuration::FactoryContext&) override;

ProtobufTypes::MessagePtr createEmptyConfigProto() override;

std::string name() override { return HttpFilterNames::get().HEADER_TO_METADATA; }
};

} // namespace HeaderToMetadataFilter
} // namespace HttpFilters
} // namespace Extensions
} // namespace Envoy
Loading

0 comments on commit 9a4c44c

Please sign in to comment.