Skip to content

Commit

Permalink
wasm: use filter state instead of metadata (envoyproxy#2421)
Browse files Browse the repository at this point in the history
* fixing the plugins

Signed-off-by: Kuat Yessenov <[email protected]>

* ammend

Signed-off-by: Kuat Yessenov <[email protected]>

* update to use filter state

Signed-off-by: Kuat Yessenov <[email protected]>

* fixes

Signed-off-by: Kuat Yessenov <[email protected]>

* update to use simpler API

Signed-off-by: Kuat Yessenov <[email protected]>

* updates

Signed-off-by: Kuat Yessenov <[email protected]>

* forgot to initialize ints

Signed-off-by: Kuat Yessenov <[email protected]>

* second attempt

Signed-off-by: Kuat Yessenov <[email protected]>

* simplify

Signed-off-by: Kuat Yessenov <[email protected]>

* pull latest

Signed-off-by: Kuat Yessenov <[email protected]>

* fix bug

Signed-off-by: Kuat Yessenov <[email protected]>

* update formatting

Signed-off-by: Kuat Yessenov <[email protected]>

* merge fix

Signed-off-by: Kuat Yessenov <[email protected]>

* build fix

Signed-off-by: Kuat Yessenov <[email protected]>

* copy traffic direction

Signed-off-by: Kuat Yessenov <[email protected]>

* update envoy SHA

Signed-off-by: Kuat Yessenov <[email protected]>
  • Loading branch information
kyessenov authored and istio-testing committed Sep 25, 2019
1 parent 35f3727 commit e383776
Show file tree
Hide file tree
Showing 29 changed files with 164 additions and 422 deletions.
2 changes: 1 addition & 1 deletion .bazelversion
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.28.1
0.29.1
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:

macos:
macos:
xcode: "10.2.1"
xcode: "11.0.0"
environment:
- BAZEL_STARTUP_ARGS: "--output_base /Users/distiller/.cache/bazel"
- BAZEL_BUILD_ARGS: "--local_ram_resources=12288 --local_cpu_resources=8 --verbose_failures --test_env=ENVOY_IP_TEST_VERSIONS=v4only --test_output=all"
Expand Down
8 changes: 4 additions & 4 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ bind(
)

# Determine SHA256 `wget https://github.com/envoyproxy/envoy-wasm/archive/$COMMIT.tar.gz && sha256sum $COMMIT.tar.gz`
# envoy-wasm commit date: 08/26/2019
# bazel version: 0.28.1
ENVOY_SHA = "ef4da0bda2bee932c575c0c98508c473dd6085c5"
# envoy-wasm commit date: 09/24/2019
# bazel version: 0.29.1
ENVOY_SHA = "0196617a1b28d6efb95df005d548a59e54e3b5cd"

ENVOY_SHA256 = "cc23dc677124ccae56b722b8cc60144003f175db88d080aa926f986a3442ad6e"
ENVOY_SHA256 = "c5c8a7816f38dc23afa7aad4f2ccd3650e36e4357956fb57f2838135aa069191"

LOCAL_ENVOY_PROJECT = "/PATH/TO/ENVOY"

Expand Down
36 changes: 16 additions & 20 deletions extensions/common/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,9 @@ using Envoy::Extensions::Common::Wasm::StreamType;
using Envoy::Extensions::Common::Wasm::WasmResult;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getCurrentTimeNanoseconds;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getHeaderMapValue;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getMetadataStruct;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getRequestDestinationPort;
using Envoy::Extensions::Common::Wasm::Null::Plugin::
getRequestPeerCertificatePresented;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getRequestTlsVersion;
using Envoy::Extensions::Common::Wasm::Null::Plugin::
getResponsePeerCertificatePresented;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getResponseResponseCode;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getResponseTlsVersion;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getStringValue;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getStructValue;
using Envoy::Extensions::Common::Wasm::Null::Plugin::getValue;

#endif // NULL_PLUGIN

Expand Down Expand Up @@ -69,8 +63,7 @@ google::protobuf::util::Status extractNodeMetadata(
google::protobuf::util::Status extractLocalNodeMetadata(
wasm::common::NodeInfo *node_info) {
google::protobuf::Struct node;
if (getMetadataStruct(MetadataType::Node, "metadata", &node) !=
WasmResult::Ok) {
if (!getStructValue({"node", "metadata"}, &node)) {
return google::protobuf::util::Status(
google::protobuf::util::error::Code::NOT_FOUND, "metadata not found");
}
Expand All @@ -82,7 +75,10 @@ void populateHTTPRequestInfo(bool outbound, RequestInfo *request_info) {
request_info->end_timestamp = getCurrentTimeNanoseconds();

// Fill in request info.
getResponseResponseCode(&request_info->response_code);
int64_t response_code = 0;
if (getValue({"response", "code"}, &response_code)) {
request_info->response_code = response_code;
}

if (kGrpcContentTypes.count(getHeaderMapValue(HeaderMapType::RequestHeaders,
kContentTypeHeaderKey)
Expand All @@ -100,20 +96,20 @@ void populateHTTPRequestInfo(bool outbound, RequestInfo *request_info) {
request_info->request_operation =
getHeaderMapValue(HeaderMapType::RequestHeaders, kMethodHeaderKey)
->toString();
getRequestDestinationPort(&request_info->destination_port);

int64_t destination_port = 0;
std::string tls_version;
bool cert_presented;

if (outbound) {
getResponsePeerCertificatePresented(&cert_presented);
getResponseTlsVersion(&tls_version);
getValue({"upstream", "port"}, &destination_port);
getValue({"upstream", "mtls"}, &request_info->mTLS);
getStringValue({"upstream", "tls_version"}, &tls_version);
} else {
getRequestPeerCertificatePresented(&cert_presented);
getRequestTlsVersion(&tls_version);
getValue({"destination", "port"}, &destination_port);
getValue({"connection", "mtls"}, &request_info->mTLS);
getStringValue({"connection", "tls_version"}, &tls_version);
}

request_info->mTLS = !tls_version.empty() && cert_presented;
request_info->destination_port = destination_port;
}

} // namespace Common
Expand Down
7 changes: 7 additions & 0 deletions extensions/common/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ struct RequestContext {
const Common::RequestInfo& request;
};

// TrafficDirection is a mirror of envoy xDS traffic direction.
enum class TrafficDirection : int64_t {
Unspecified = 0,
Inbound = 1,
Outbound = 2,
};

// Extracts NodeInfo from proxy node metadata passed in as a protobuf struct.
// It converts the metadata struct to a JSON struct and parse NodeInfo proto
// from that JSON struct.
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
*/

#include "common/common/base64.h"
#include "src/envoy/http/metadata_exchange/plugin.h"
#include "extensions/metadata_exchange/plugin.h"

namespace Envoy {
namespace Extensions {
Expand All @@ -28,7 +28,7 @@ ::Envoy::Extensions::Common::Wasm::Null::NullPluginRootRegistry*
// Registration glue

class MetadataExchangeFactory
: public ::Envoy::Extensions::Common::Wasm::Null::NullPluginFactory {
: public ::Envoy::Extensions::Common::Wasm::Null::NullVmPluginFactory {
public:
const std::string name() const override {
return "envoy.wasm.metadata_exchange";
Expand All @@ -43,7 +43,7 @@ class MetadataExchangeFactory

static Registry::RegisterFactory<
MetadataExchangeFactory,
::Envoy::Extensions::Common::Wasm::Null::NullPluginFactory>
::Envoy::Extensions::Common::Wasm::Null::NullVmPluginFactory>
register_;

} // namespace MetadataExchange
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

#else
#include "common/common/base64.h"
#include "src/envoy/http/metadata_exchange/plugin.h"
#include "extensions/metadata_exchange/plugin.h"

namespace Envoy {
namespace Extensions {
Expand All @@ -42,7 +42,7 @@ NULL_PLUGIN_ROOT_REGISTRY;

namespace {

bool serializeToStringDeterministic(const google::protobuf::Struct& metadata,
bool serializeToStringDeterministic(const google::protobuf::Value& metadata,
std::string* metadata_bytes) {
google::protobuf::io::StringOutputStream md(metadata_bytes);
google::protobuf::io::CodedOutputStream mcs(&md);
Expand All @@ -61,32 +61,37 @@ static RegisterContextFactory register_MetadataExchange(
CONTEXT_FACTORY(PluginContext), ROOT_FACTORY(PluginRootContext));

void PluginRootContext::updateMetadataValue() {
google::protobuf::Value keys_value;
if (getMetadataValue(MetadataType::Node, NodeMetadataExchangeKeys,
&keys_value) != WasmResult::Ok) {
logDebug(
absl::StrCat("cannot get metadata key: ", NodeMetadataExchangeKeys));
google::protobuf::Struct node_metadata;
if (!getStructValue({"node", "metadata"}, &node_metadata)) {
logWarn("cannot get node metadata");
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(absl::StrCat("metadata key is not a string: ",
NodeMetadataExchangeKeys));
logWarn("metadata exchange key is not a string");
return;
}

google::protobuf::Struct metadata;
google::protobuf::Value metadata;

// select keys from the metadata using the keys
const std::set<absl::string_view> keys =
const std::set<std::string> keys =
absl::StrSplit(keys_value.string_value(), ',', absl::SkipWhitespace());
for (auto key : keys) {
google::protobuf::Value value;
if (getMetadataValue(MetadataType::Node, key, &value) == WasmResult::Ok) {
(*metadata.mutable_fields())[std::string(key)] = value;
} else {
logDebug(absl::StrCat("cannot get metadata key: ", key));
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
Expand All @@ -96,28 +101,14 @@ void PluginRootContext::updateMetadataValue() {
Base64::encode(metadata_bytes.data(), metadata_bytes.size());
}

void PluginRootContext::onConfigure(
std::unique_ptr<WasmData> ABSL_ATTRIBUTE_UNUSED configuration) {
bool PluginRootContext::onConfigure(std::unique_ptr<WasmData>) {
updateMetadataValue();

// TODO: this is really expensive since it fetches the entire metadata from
// before magic "." to get the whole node.
google::protobuf::Struct node;
if (getMetadataStruct(MetadataType::Node, WholeNodeKey, &node) ==
WasmResult::Ok) {
for (const auto& f : node.fields()) {
if (f.first == NodeIdKey &&
f.second.kind_case() == google::protobuf::Value::kStringValue) {
node_id_ = f.second.string_value();
break;
}
}
} else {
logDebug(absl::StrCat("cannot get metadata key: ", WholeNodeKey));
if (!getStringValue({"node", "id"}, &node_id_)) {
logDebug("cannot get node ID");
}

logDebug(
absl::StrCat("metadata_value_ id:", id(), " value:", metadata_value_));
logDebug(absl::StrCat("metadata_value_ id:", id(), " value:", metadata_value_,
" node:", node_id_));
return true;
}

FilterHeadersStatus PluginContext::onRequestHeaders() {
Expand All @@ -128,16 +119,15 @@ FilterHeadersStatus PluginContext::onRequestHeaders() {
removeRequestHeader(ExchangeMetadataHeader);
auto downstream_metadata_bytes =
Base64::decodeWithoutPadding(downstream_metadata_value->view());
setMetadataStruct(MetadataType::Request, DownstreamMetadataKey,
downstream_metadata_bytes);
setFilterState(DownstreamMetadataKey, downstream_metadata_bytes);
}

auto downstream_metadata_id = getRequestHeader(ExchangeMetadataHeaderId);
if (downstream_metadata_id != nullptr &&
!downstream_metadata_id->view().empty()) {
removeRequestHeader(ExchangeMetadataHeaderId);
setMetadataStringValue(MetadataType::Request, DownstreamMetadataIdKey,
downstream_metadata_id->view());
setFilterStateStringValue(DownstreamMetadataIdKey,
downstream_metadata_id->view());
}

auto metadata = metadataValue();
Expand All @@ -162,16 +152,15 @@ FilterHeadersStatus PluginContext::onResponseHeaders() {
removeResponseHeader(ExchangeMetadataHeader);
auto upstream_metadata_bytes =
Base64::decodeWithoutPadding(upstream_metadata_value->view());
setMetadataStruct(MetadataType::Request, UpstreamMetadataKey,
upstream_metadata_bytes);
setFilterState(UpstreamMetadataKey, upstream_metadata_bytes);
}

auto upstream_metadata_id = getResponseHeader(ExchangeMetadataHeaderId);
if (upstream_metadata_id != nullptr &&
!upstream_metadata_id->view().empty()) {
removeRequestHeader(ExchangeMetadataHeaderId);
setMetadataStringValue(MetadataType::Request, UpstreamMetadataIdKey,
upstream_metadata_id->view());
setFilterStateStringValue(UpstreamMetadataIdKey,
upstream_metadata_id->view());
}

auto metadata = metadataValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ namespace Plugin {
using namespace Envoy::Extensions::Common::Wasm::Null::Plugin;

// TODO(jplevyak): move these into the base envoy repo
using MetadataType = Envoy::Extensions::Common::Wasm::MetadataType;
using WasmResult = Envoy::Extensions::Common::Wasm::WasmResult;
using NullPluginRootRegistry =
::Envoy::Extensions::Common::Wasm::Null::NullPluginRootRegistry;
Expand All @@ -47,10 +46,6 @@ using NullPluginRootRegistry =
constexpr StringView ExchangeMetadataHeader = "x-envoy-peer-metadata";
constexpr StringView ExchangeMetadataHeaderId = "x-envoy-peer-metadata-id";

constexpr StringView NodeMetadataExchangeKeys = "EXCHANGE_KEYS";
constexpr StringView NodeIdKey = "id";
constexpr StringView WholeNodeKey = ".";

// DownstreamMetadataKey is the key in the request metadata for downstream peer
// metadata
constexpr StringView DownstreamMetadataKey =
Expand All @@ -74,7 +69,7 @@ class PluginRootContext : public RootContext {
: RootContext(id, root_id) {}
~PluginRootContext() = default;

void onConfigure(std::unique_ptr<WasmData>) override;
bool onConfigure(std::unique_ptr<WasmData>) override;
void onStart(std::unique_ptr<WasmData>) override{};
void onTick() override{};

Expand Down Expand Up @@ -104,13 +99,6 @@ class PluginContext : public Context {
inline StringView nodeId() { return rootContext()->nodeId(); }
};

// TODO(mjog) move this to proxy_wasm_impl.h
inline void setMetadataStruct(MetadataType type, StringView key,
StringView value) {
proxy_setMetadataStruct(type, key.data(), key.size(), value.data(),
value.size());
}

#ifdef NULL_PLUGIN
} // namespace Plugin
} // namespace MetadataExchange
Expand Down
Loading

0 comments on commit e383776

Please sign in to comment.