From 6c057e039c5ecb30bfd443de98a0ff26f9febb57 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Tue, 21 Feb 2017 19:39:04 -0800 Subject: [PATCH 1/4] Add send_attribute filter. --- src/envoy/mixer/BUILD | 13 +++ src/envoy/mixer/README.md | 48 +++++++++ src/envoy/mixer/envoy.conf.template | 68 ++++++++++++- src/envoy/mixer/http_control.cc | 18 +++- src/envoy/mixer/http_control.h | 2 +- src/envoy/mixer/http_filter.cc | 20 ++-- src/envoy/mixer/send_attribute_filter.cc | 118 +++++++++++++++++++++++ src/envoy/mixer/string_map.proto | 22 +++++ src/envoy/mixer/utils.cc | 49 ++++++++++ src/envoy/mixer/utils.h | 39 ++++++++ 10 files changed, 384 insertions(+), 13 deletions(-) create mode 100644 src/envoy/mixer/send_attribute_filter.cc create mode 100644 src/envoy/mixer/string_map.proto create mode 100644 src/envoy/mixer/utils.cc create mode 100644 src/envoy/mixer/utils.h diff --git a/src/envoy/mixer/BUILD b/src/envoy/mixer/BUILD index 917e627e073..7a64ad7bc36 100644 --- a/src/envoy/mixer/BUILD +++ b/src/envoy/mixer/BUILD @@ -17,6 +17,15 @@ load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") load("@bazel_tools//tools/build_defs/docker:docker.bzl", "docker_build") +load("@protobuf_git//:protobuf.bzl", "cc_proto_library") + +cc_proto_library( + name = "string_map_proto", + srcs = ["string_map.proto"], + default_runtime = "//external:protobuf", + protoc = "//external:protoc", + visibility = ["//visibility:public"], +) cc_library( name = "filter_lib", @@ -24,8 +33,12 @@ cc_library( "http_control.cc", "http_control.h", "http_filter.cc", + "send_attribute_filter.cc", + "utils.cc", + "utils.h", ], deps = [ + ":string_map_proto", "//external:mixer_client_lib", "@envoy_git//:envoy-common", ], diff --git a/src/envoy/mixer/README.md b/src/envoy/mixer/README.md index 5bf2198b30d..1d5a4c6b67c 100644 --- a/src/envoy/mixer/README.md +++ b/src/envoy/mixer/README.md @@ -49,3 +49,51 @@ This Proxy will use Envoy and talk to Mixer server. curl http://localhost:9090/echo -d "hello world" ``` +## How to configurate HTTP filters + +This module has two HTTP filters: +1. mixer filter: intercept all HTTP requests, call the mixer. +2. send_attribute filter: Send some attributes to next hop istio/proxy with mixer filter. + +### *mixer* filter: + +This filter will intercept all HTTP requests and call Mixer. Here is its config: + +``` + "filters": [ + "type": "both", + "name": "mixer", + "config": { + "mixer_server": "${MIXER_SERVER}", + "attributes" : { + "attribute_name1": "attribute_value1", + "attribute_name2": "attribute_value2" + } + } +``` + +Notes: +* mixer_server is required +* attributes: these attributes will be send to mixer + +### *send_attribute* HTTP filter: + +This filer will send attributes to the next hop istio/proxy with mixer_filter. + +``` + "filters": [ + "type": "decoder", + "name": "send_attribute", + "config": { + "attributes": { + "attribute_name1": "attribute_value1", + "attribute_name2": "attribute_value2" + } + } +``` + +Notes: +* attributes: these attributes will be send to the next hop istio/proxy with mixer filter. + + + diff --git a/src/envoy/mixer/envoy.conf.template b/src/envoy/mixer/envoy.conf.template index f1a00d1fb3e..b375fe2d53b 100644 --- a/src/envoy/mixer/envoy.conf.template +++ b/src/envoy/mixer/envoy.conf.template @@ -35,7 +35,62 @@ "type": "both", "name": "mixer", "config": { - "mixer_server": "${MIXER_SERVER}" + "mixer_server": "${MIXER_SERVER}", + "attributes": { + "target.uid": "POD222", + "target.namespace": "XYZ222" + } + } + }, + { + "type": "decoder", + "name": "router", + "config": {} + } + ] + } + } + ] + }, + { + "port": 7070, + "bind_to_port": true, + "filters": [ + { + "type": "read", + "name": "http_connection_manager", + "config": { + "codec_type": "auto", + "stat_prefix": "ingress_http", + "route_config": { + "virtual_hosts": [ + { + "name": "backend", + "domains": ["*"], + "routes": [ + { + "timeout_ms": 0, + "prefix": "/", + "cluster": "service2" + } + ] + } + ] + }, + "access_log": [ + { + "path": "/dev/stdout" + } + ], + "filters": [ + { + "type": "decoder", + "name": "send_attribute", + "config": { + "attributes": { + "source.uid": "POD11", + "source.namespace": "XYZ11" + } } }, { @@ -65,6 +120,17 @@ "url": "tcp://${BACKEND}" } ] + }, + { + "name": "service2", + "connect_timeout_ms": 5000, + "type": "strict_dns", + "lb_type": "round_robin", + "hosts": [ + { + "url": "tcp://localhost:9090" + } + ] } ] } diff --git a/src/envoy/mixer/http_control.cc b/src/envoy/mixer/http_control.cc index bbff6b94992..96ce2c0f878 100644 --- a/src/envoy/mixer/http_control.cc +++ b/src/envoy/mixer/http_control.cc @@ -13,8 +13,12 @@ */ #include "src/envoy/mixer/http_control.h" + +#include "common/common/base64.h" #include "common/common/utility.h" #include "common/http/utility.h" +#include "src/envoy/mixer/string_map.pb.h" +#include "src/envoy/mixer/utils.h" using ::google::protobuf::util::Status; using ::istio::mixer_client::Attributes; @@ -144,8 +148,20 @@ HttpControl::HttpControl(const std::string& mixer_server, mixer_client_ = ::istio::mixer_client::CreateMixerClient(options); } -void HttpControl::FillCheckAttributes(const HeaderMap& header_map, +void HttpControl::FillCheckAttributes(HeaderMap& header_map, Attributes* attr) { + // Extract attributes from x-istio-attributes header + const HeaderEntry* entry = header_map.get(Utils::kHeaderNameIstioAttributes); + if (entry) { + ::istio::proxy::mixer::StringMap pb; + std::string str(entry->value().c_str(), entry->value().size()); + pb.ParseFromString(Base64::decode(str)); + for (const auto& it : pb.map()) { + SetStringAttribute(it.first, it.second, attr); + } + header_map.remove(Utils::kHeaderNameIstioAttributes); + } + FillRequestHeaderAttributes(header_map, attr); for (const auto& attribute : config_attributes_) { diff --git a/src/envoy/mixer/http_control.h b/src/envoy/mixer/http_control.h index 65863d950fa..32db29a673b 100644 --- a/src/envoy/mixer/http_control.h +++ b/src/envoy/mixer/http_control.h @@ -51,7 +51,7 @@ class HttpControl final : public Logger::Loggable { ::istio::mixer_client::DoneFunc on_done); private: - void FillCheckAttributes(const HeaderMap& header_map, + void FillCheckAttributes(HeaderMap& header_map, ::istio::mixer_client::Attributes* attr); // The mixer client diff --git a/src/envoy/mixer/http_filter.cc b/src/envoy/mixer/http_filter.cc index d0796b506dd..57554726674 100644 --- a/src/envoy/mixer/http_filter.cc +++ b/src/envoy/mixer/http_filter.cc @@ -21,6 +21,7 @@ #include "envoy/server/instance.h" #include "server/config/network/http_connection_manager.h" #include "src/envoy/mixer/http_control.h" +#include "src/envoy/mixer/utils.h" using ::google::protobuf::util::Status; using StatusCode = ::google::protobuf::util::error::Code; @@ -30,8 +31,11 @@ namespace Http { namespace Mixer { namespace { -// Define lower case string for X-Forwarded-Host. -const LowerCaseString kHeaderNameXFH("x-forwarded-host", false); +// The Json object name for mixer-server. +const std::string kJsonNameMixerServer("mixer_server"); + +// The Json object name for static attributes. +const std::string kJsonNameMixerAttributes("attributes"); // Convert Status::code to HTTP code int HttpCode(int code) { @@ -88,20 +92,16 @@ class Config : public Logger::Loggable { Config(const Json::Object& config, Server::Instance& server) : cm_(server.clusterManager()) { std::string mixer_server; - if (config.hasObject("mixer_server")) { - mixer_server = config.getString("mixer_server"); + if (config.hasObject(kJsonNameMixerServer)) { + mixer_server = config.getString(kJsonNameMixerServer); } else { log().error( "mixer_server is required but not specified in the config: {}", __func__); } - std::map attributes; - if (config.hasObject("attributes")) { - for (const std::string& attr : config.getStringArray("attributes")) { - attributes[attr] = config.getString(attr); - } - } + std::map attributes = + Utils::ExtractStringMap(config, kJsonNameMixerAttributes); http_control_ = std::make_shared(mixer_server, std::move(attributes)); diff --git a/src/envoy/mixer/send_attribute_filter.cc b/src/envoy/mixer/send_attribute_filter.cc new file mode 100644 index 00000000000..896f0a22268 --- /dev/null +++ b/src/envoy/mixer/send_attribute_filter.cc @@ -0,0 +1,118 @@ +/* Copyright 2016 Google Inc. 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 "precompiled/precompiled.h" + +#include "common/common/base64.h" +#include "common/common/logger.h" +#include "common/http/headers.h" +#include "common/http/utility.h" +#include "envoy/server/instance.h" +#include "server/config/network/http_connection_manager.h" +#include "src/envoy/mixer/utils.h" + +namespace Http { +namespace AddHeader { +namespace { + +// The Json object name to specify attributes to pass to +// next hop istio proxy. +const std::string kJsonNameAttributes("attributes"); + +} // namespace + +class Config : public Logger::Loggable { + private: + Upstream::ClusterManager& cm_; + std::string serialized_attributes_; + + public: + Config(const Json::Object& config, Server::Instance& server) + : cm_(server.clusterManager()) { + const auto& attributes = + Utils::ExtractStringMap(config, kJsonNameAttributes); + if (!attributes.empty()) { + std::string serialized_str = Utils::SerializeStringMap(attributes); + serialized_attributes_ = + Base64::encode(serialized_str.c_str(), serialized_str.size()); + } + } + + const std::string& serialized_attributes() const { + return serialized_attributes_; + } +}; + +typedef std::shared_ptr ConfigPtr; + +class Instance : public Http::StreamDecoderFilter { + private: + ConfigPtr config_; + + public: + Instance(ConfigPtr config) : config_(config) {} + + FilterHeadersStatus decodeHeaders(HeaderMap& headers, + bool end_stream) override { + if (!config_->serialized_attributes().empty()) { + headers.addStatic(Utils::kHeaderNameIstioAttributes, + config_->serialized_attributes()); + } + return FilterHeadersStatus::Continue; + } + + FilterDataStatus decodeData(Buffer::Instance& data, + bool end_stream) override { + return FilterDataStatus::Continue; + } + + FilterTrailersStatus decodeTrailers(HeaderMap& trailers) override { + return FilterTrailersStatus::Continue; + } + + void setDecoderFilterCallbacks( + StreamDecoderFilterCallbacks& callbacks) override {} +}; + +} // namespace AddHeader +} // namespace Http + +namespace Server { +namespace Configuration { + +class AddHeaderConfig : public HttpFilterConfigFactory { + public: + HttpFilterFactoryCb tryCreateFilterFactory( + HttpFilterType type, const std::string& name, const Json::Object& config, + const std::string&, Server::Instance& server) override { + if (type != HttpFilterType::Decoder || name != "send_attribute") { + return nullptr; + } + + Http::AddHeader::ConfigPtr add_header_config( + new Http::AddHeader::Config(config, server)); + return [add_header_config]( + Http::FilterChainFactoryCallbacks& callbacks) -> void { + std::shared_ptr instance( + new Http::AddHeader::Instance(add_header_config)); + callbacks.addStreamDecoderFilter(Http::StreamDecoderFilterPtr(instance)); + }; + } +}; + +static RegisterHttpFilterConfigFactory register_; + +} // namespace Configuration +} // namespace server diff --git a/src/envoy/mixer/string_map.proto b/src/envoy/mixer/string_map.proto new file mode 100644 index 00000000000..b8d5b991e15 --- /dev/null +++ b/src/envoy/mixer/string_map.proto @@ -0,0 +1,22 @@ +// Copyright 2016 Google Inc. +// +// 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 istio.proxy.mixer; + +// A map of string to string. +message StringMap { + map map = 1; +} \ No newline at end of file diff --git a/src/envoy/mixer/utils.cc b/src/envoy/mixer/utils.cc new file mode 100644 index 00000000000..67bd933dd1b --- /dev/null +++ b/src/envoy/mixer/utils.cc @@ -0,0 +1,49 @@ +/* + * 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/mixer/utils.h" +#include "src/envoy/mixer/string_map.pb.h" + +namespace Http { +namespace Utils { + +const LowerCaseString kHeaderNameIstioAttributes("x-istio-attributes"); + +StringMap ExtractStringMap(const Json::Object& json, const std::string& name) { + StringMap map; + if (json.hasObject(name)) { + auto json_obj = json.getObject(name); + auto raw_obj = json_obj.get(); + json_obj->iterate( + [&map, raw_obj](const std::string& key, const Json::Object&) -> bool { + map[key] = raw_obj->getString(key); + return true; + }); + } + return map; +} + +std::string SerializeStringMap(const StringMap& string_map) { + ::istio::proxy::mixer::StringMap pb; + auto map_pb = pb.mutable_map(); + for (const auto& it : string_map) { + (*map_pb)[it.first] = it.second; + } + std::string str; + pb.SerializeToString(&str); + return str; +} + +} // namespace Utils +} // namespace Http diff --git a/src/envoy/mixer/utils.h b/src/envoy/mixer/utils.h new file mode 100644 index 00000000000..92b420110a3 --- /dev/null +++ b/src/envoy/mixer/utils.h @@ -0,0 +1,39 @@ +/* Copyright 2016 Google Inc. 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 "precompiled/precompiled.h" + +#include "common/http/headers.h" +#include "envoy/json/json_object.h" + +namespace Http { +namespace Utils { + +// The internal header to pass istio attributes. +extern const LowerCaseString kHeaderNameIstioAttributes; + +// The string map. +typedef std::map StringMap; + +// Extracts name/value attributes from a json object. +StringMap ExtractStringMap(const Json::Object& json, const std::string& name); + +// Serialize a string map to string. +std::string SerializeStringMap(const StringMap& map); + +} // namespace Utils +} // namespace Http From 622dd75c4dd90c64fa8111f14dfe7f880ddeda70 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Tue, 21 Feb 2017 19:50:27 -0800 Subject: [PATCH 2/4] Fix format --- src/envoy/mixer/http_control.cc | 3 +-- src/envoy/mixer/string_map.proto | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/envoy/mixer/http_control.cc b/src/envoy/mixer/http_control.cc index 96ce2c0f878..bab1cdb05a9 100644 --- a/src/envoy/mixer/http_control.cc +++ b/src/envoy/mixer/http_control.cc @@ -148,8 +148,7 @@ HttpControl::HttpControl(const std::string& mixer_server, mixer_client_ = ::istio::mixer_client::CreateMixerClient(options); } -void HttpControl::FillCheckAttributes(HeaderMap& header_map, - Attributes* attr) { +void HttpControl::FillCheckAttributes(HeaderMap& header_map, Attributes* attr) { // Extract attributes from x-istio-attributes header const HeaderEntry* entry = header_map.get(Utils::kHeaderNameIstioAttributes); if (entry) { diff --git a/src/envoy/mixer/string_map.proto b/src/envoy/mixer/string_map.proto index b8d5b991e15..ea345280e2f 100644 --- a/src/envoy/mixer/string_map.proto +++ b/src/envoy/mixer/string_map.proto @@ -19,4 +19,4 @@ package istio.proxy.mixer; // A map of string to string. message StringMap { map map = 1; -} \ No newline at end of file +} From 800c08864f04379b5888bc61d8f15248624faf13 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Tue, 21 Feb 2017 19:55:39 -0800 Subject: [PATCH 3/4] rename variable serialized_attributes_ --- src/envoy/mixer/send_attribute_filter.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/envoy/mixer/send_attribute_filter.cc b/src/envoy/mixer/send_attribute_filter.cc index 896f0a22268..73c6935debf 100644 --- a/src/envoy/mixer/send_attribute_filter.cc +++ b/src/envoy/mixer/send_attribute_filter.cc @@ -36,7 +36,7 @@ const std::string kJsonNameAttributes("attributes"); class Config : public Logger::Loggable { private: Upstream::ClusterManager& cm_; - std::string serialized_attributes_; + std::string attributes_; public: Config(const Json::Object& config, Server::Instance& server) @@ -45,14 +45,12 @@ class Config : public Logger::Loggable { Utils::ExtractStringMap(config, kJsonNameAttributes); if (!attributes.empty()) { std::string serialized_str = Utils::SerializeStringMap(attributes); - serialized_attributes_ = + attributes_ = Base64::encode(serialized_str.c_str(), serialized_str.size()); } } - const std::string& serialized_attributes() const { - return serialized_attributes_; - } + const std::string& attributes() const { return attributes_; } }; typedef std::shared_ptr ConfigPtr; @@ -66,9 +64,9 @@ class Instance : public Http::StreamDecoderFilter { FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) override { - if (!config_->serialized_attributes().empty()) { + if (!config_->attributes().empty()) { headers.addStatic(Utils::kHeaderNameIstioAttributes, - config_->serialized_attributes()); + config_->attributes()); } return FilterHeadersStatus::Continue; } From 38cdfeee84dde1ef159d9a8231e0b226baba38d1 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Tue, 21 Feb 2017 23:13:57 -0800 Subject: [PATCH 4/4] Address the comments. --- src/envoy/mixer/BUILD | 2 +- src/envoy/mixer/README.md | 12 +++--- src/envoy/mixer/envoy.conf.template | 2 +- ..._filter.cc => forward_attribute_filter.cc} | 38 +++++++++---------- src/envoy/mixer/http_control.cc | 15 +++++--- src/envoy/mixer/http_control.h | 2 +- src/envoy/mixer/http_filter.cc | 2 +- src/envoy/mixer/string_map.proto | 5 ++- src/envoy/mixer/utils.cc | 11 +++--- src/envoy/mixer/utils.h | 4 +- 10 files changed, 48 insertions(+), 45 deletions(-) rename src/envoy/mixer/{send_attribute_filter.cc => forward_attribute_filter.cc} (72%) diff --git a/src/envoy/mixer/BUILD b/src/envoy/mixer/BUILD index 7a64ad7bc36..d04b5105029 100644 --- a/src/envoy/mixer/BUILD +++ b/src/envoy/mixer/BUILD @@ -30,10 +30,10 @@ cc_proto_library( cc_library( name = "filter_lib", srcs = [ + "forward_attribute_filter.cc", "http_control.cc", "http_control.h", "http_filter.cc", - "send_attribute_filter.cc", "utils.cc", "utils.h", ], diff --git a/src/envoy/mixer/README.md b/src/envoy/mixer/README.md index 1d5a4c6b67c..d7d39f30e03 100644 --- a/src/envoy/mixer/README.md +++ b/src/envoy/mixer/README.md @@ -53,7 +53,7 @@ This Proxy will use Envoy and talk to Mixer server. This module has two HTTP filters: 1. mixer filter: intercept all HTTP requests, call the mixer. -2. send_attribute filter: Send some attributes to next hop istio/proxy with mixer filter. +2. forward_attribute filter: Forward attributes to the upstream istio/proxy. ### *mixer* filter: @@ -74,16 +74,16 @@ This filter will intercept all HTTP requests and call Mixer. Here is its config: Notes: * mixer_server is required -* attributes: these attributes will be send to mixer +* attributes: these attributes will be send to the mixer -### *send_attribute* HTTP filter: +### *forward_attribute* HTTP filter: -This filer will send attributes to the next hop istio/proxy with mixer_filter. +This filer will forward attributes to the upstream istio/proxy. ``` "filters": [ "type": "decoder", - "name": "send_attribute", + "name": "forward_attribute", "config": { "attributes": { "attribute_name1": "attribute_value1", @@ -93,7 +93,7 @@ This filer will send attributes to the next hop istio/proxy with mixer_filter. ``` Notes: -* attributes: these attributes will be send to the next hop istio/proxy with mixer filter. +* attributes: these attributes will be forwarded to the upstream istio/proxy. diff --git a/src/envoy/mixer/envoy.conf.template b/src/envoy/mixer/envoy.conf.template index b375fe2d53b..c5377632388 100644 --- a/src/envoy/mixer/envoy.conf.template +++ b/src/envoy/mixer/envoy.conf.template @@ -85,7 +85,7 @@ "filters": [ { "type": "decoder", - "name": "send_attribute", + "name": "forward_attribute", "config": { "attributes": { "source.uid": "POD11", diff --git a/src/envoy/mixer/send_attribute_filter.cc b/src/envoy/mixer/forward_attribute_filter.cc similarity index 72% rename from src/envoy/mixer/send_attribute_filter.cc rename to src/envoy/mixer/forward_attribute_filter.cc index 73c6935debf..08d58916f89 100644 --- a/src/envoy/mixer/send_attribute_filter.cc +++ b/src/envoy/mixer/forward_attribute_filter.cc @@ -1,4 +1,4 @@ -/* Copyright 2016 Google Inc. All Rights Reserved. +/* Copyright 2017 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. @@ -24,24 +24,22 @@ #include "src/envoy/mixer/utils.h" namespace Http { -namespace AddHeader { +namespace ForwardAttribute { namespace { -// The Json object name to specify attributes to pass to -// next hop istio proxy. +// The Json object name to specify attributes which will be forwarded +// to the upstream istio proxy. const std::string kJsonNameAttributes("attributes"); } // namespace class Config : public Logger::Loggable { private: - Upstream::ClusterManager& cm_; std::string attributes_; public: - Config(const Json::Object& config, Server::Instance& server) - : cm_(server.clusterManager()) { - const auto& attributes = + Config(const Json::Object& config) { + Utils::StringMap attributes = Utils::ExtractStringMap(config, kJsonNameAttributes); if (!attributes.empty()) { std::string serialized_str = Utils::SerializeStringMap(attributes); @@ -55,18 +53,17 @@ class Config : public Logger::Loggable { typedef std::shared_ptr ConfigPtr; -class Instance : public Http::StreamDecoderFilter { +class ForwardAttributeFilter : public Http::StreamDecoderFilter { private: ConfigPtr config_; public: - Instance(ConfigPtr config) : config_(config) {} + ForwardAttributeFilter(ConfigPtr config) : config_(config) {} FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) override { if (!config_->attributes().empty()) { - headers.addStatic(Utils::kHeaderNameIstioAttributes, - config_->attributes()); + headers.addStatic(Utils::kIstioAttributeHeader, config_->attributes()); } return FilterHeadersStatus::Continue; } @@ -84,33 +81,34 @@ class Instance : public Http::StreamDecoderFilter { StreamDecoderFilterCallbacks& callbacks) override {} }; -} // namespace AddHeader +} // namespace ForwardAttribute } // namespace Http namespace Server { namespace Configuration { -class AddHeaderConfig : public HttpFilterConfigFactory { +class ForwardAttributeConfig : public HttpFilterConfigFactory { public: HttpFilterFactoryCb tryCreateFilterFactory( HttpFilterType type, const std::string& name, const Json::Object& config, const std::string&, Server::Instance& server) override { - if (type != HttpFilterType::Decoder || name != "send_attribute") { + if (type != HttpFilterType::Decoder || name != "forward_attribute") { return nullptr; } - Http::AddHeader::ConfigPtr add_header_config( - new Http::AddHeader::Config(config, server)); + Http::ForwardAttribute::ConfigPtr add_header_config( + new Http::ForwardAttribute::Config(config)); return [add_header_config]( Http::FilterChainFactoryCallbacks& callbacks) -> void { - std::shared_ptr instance( - new Http::AddHeader::Instance(add_header_config)); + std::shared_ptr instance( + new Http::ForwardAttribute::ForwardAttributeFilter( + add_header_config)); callbacks.addStreamDecoderFilter(Http::StreamDecoderFilterPtr(instance)); }; } }; -static RegisterHttpFilterConfigFactory register_; +static RegisterHttpFilterConfigFactory register_; } // namespace Configuration } // namespace server diff --git a/src/envoy/mixer/http_control.cc b/src/envoy/mixer/http_control.cc index bab1cdb05a9..7e1f7deffcd 100644 --- a/src/envoy/mixer/http_control.cc +++ b/src/envoy/mixer/http_control.cc @@ -1,4 +1,5 @@ -/* +/* Copyright 2017 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 @@ -17,6 +18,7 @@ #include "common/common/base64.h" #include "common/common/utility.h" #include "common/http/utility.h" + #include "src/envoy/mixer/string_map.pb.h" #include "src/envoy/mixer/utils.h" @@ -81,7 +83,8 @@ std::string GetLastForwardedHost(const HeaderMap& header_map) { if (entry == nullptr) { return ""; } - auto xff_list = StringUtil::split(entry->value().c_str(), ','); + std::vector xff_list = + StringUtil::split(entry->value().c_str(), ','); if (xff_list.empty()) { return ""; } @@ -93,7 +96,7 @@ void FillRequestHeaderAttributes(const HeaderMap& header_map, // Pass in all headers header_map.iterate( [](const HeaderEntry& header, void* context) { - auto attr = static_cast(context); + Attributes* attr = static_cast(context); attr->attributes[kRequestHeaderPrefix + header.key().c_str()] = StringValue(header.value().c_str()); }, @@ -110,7 +113,7 @@ void FillResponseHeaderAttributes(const HeaderMap& header_map, Attributes* attr) { header_map.iterate( [](const HeaderEntry& header, void* context) { - auto attr = static_cast(context); + Attributes* attr = static_cast(context); attr->attributes[kResponseHeaderPrefix + header.key().c_str()] = StringValue(header.value().c_str()); }, @@ -150,7 +153,7 @@ HttpControl::HttpControl(const std::string& mixer_server, void HttpControl::FillCheckAttributes(HeaderMap& header_map, Attributes* attr) { // Extract attributes from x-istio-attributes header - const HeaderEntry* entry = header_map.get(Utils::kHeaderNameIstioAttributes); + const HeaderEntry* entry = header_map.get(Utils::kIstioAttributeHeader); if (entry) { ::istio::proxy::mixer::StringMap pb; std::string str(entry->value().c_str(), entry->value().size()); @@ -158,7 +161,7 @@ void HttpControl::FillCheckAttributes(HeaderMap& header_map, Attributes* attr) { for (const auto& it : pb.map()) { SetStringAttribute(it.first, it.second, attr); } - header_map.remove(Utils::kHeaderNameIstioAttributes); + header_map.remove(Utils::kIstioAttributeHeader); } FillRequestHeaderAttributes(header_map, attr); diff --git a/src/envoy/mixer/http_control.h b/src/envoy/mixer/http_control.h index 32db29a673b..c5938cf369d 100644 --- a/src/envoy/mixer/http_control.h +++ b/src/envoy/mixer/http_control.h @@ -1,4 +1,4 @@ -/* Copyright 2016 Google Inc. All Rights Reserved. +/* Copyright 2017 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. diff --git a/src/envoy/mixer/http_filter.cc b/src/envoy/mixer/http_filter.cc index 57554726674..a990b0fd7e3 100644 --- a/src/envoy/mixer/http_filter.cc +++ b/src/envoy/mixer/http_filter.cc @@ -1,4 +1,4 @@ -/* Copyright 2016 Google Inc. All Rights Reserved. +/* Copyright 2017 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. diff --git a/src/envoy/mixer/string_map.proto b/src/envoy/mixer/string_map.proto index ea345280e2f..bd9140c37d7 100644 --- a/src/envoy/mixer/string_map.proto +++ b/src/envoy/mixer/string_map.proto @@ -1,4 +1,4 @@ -// Copyright 2016 Google Inc. +// Copyright 2017 Istio Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,7 +16,8 @@ syntax = "proto3"; package istio.proxy.mixer; -// A map of string to string. +// A message with a map of string to string. It is used to serialize +// a string map. message StringMap { map map = 1; } diff --git a/src/envoy/mixer/utils.cc b/src/envoy/mixer/utils.cc index 67bd933dd1b..6dc3a78356d 100644 --- a/src/envoy/mixer/utils.cc +++ b/src/envoy/mixer/utils.cc @@ -1,4 +1,5 @@ -/* +/* Copyright 2017 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 @@ -18,13 +19,13 @@ namespace Http { namespace Utils { -const LowerCaseString kHeaderNameIstioAttributes("x-istio-attributes"); +const LowerCaseString kIstioAttributeHeader("x-istio-attributes"); StringMap ExtractStringMap(const Json::Object& json, const std::string& name) { StringMap map; if (json.hasObject(name)) { - auto json_obj = json.getObject(name); - auto raw_obj = json_obj.get(); + Json::ObjectPtr json_obj = json.getObject(name); + Json::Object* raw_obj = json_obj.get(); json_obj->iterate( [&map, raw_obj](const std::string& key, const Json::Object&) -> bool { map[key] = raw_obj->getString(key); @@ -36,7 +37,7 @@ StringMap ExtractStringMap(const Json::Object& json, const std::string& name) { std::string SerializeStringMap(const StringMap& string_map) { ::istio::proxy::mixer::StringMap pb; - auto map_pb = pb.mutable_map(); + ::google::protobuf::Map* map_pb = pb.mutable_map(); for (const auto& it : string_map) { (*map_pb)[it.first] = it.second; } diff --git a/src/envoy/mixer/utils.h b/src/envoy/mixer/utils.h index 92b420110a3..9273a9a2d8b 100644 --- a/src/envoy/mixer/utils.h +++ b/src/envoy/mixer/utils.h @@ -1,4 +1,4 @@ -/* Copyright 2016 Google Inc. All Rights Reserved. +/* Copyright 2017 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. @@ -24,7 +24,7 @@ namespace Http { namespace Utils { // The internal header to pass istio attributes. -extern const LowerCaseString kHeaderNameIstioAttributes; +extern const LowerCaseString kIstioAttributeHeader; // The string map. typedef std::map StringMap;