Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bind(
)

# When updating envoy sha manually please update the sha in istio.deps file also
ENVOY_SHA = "c41fa7118e69a0872074d7a685a62331c5d5c17e"
ENVOY_SHA = "74de08a0d4d31bd466639d25d681df5d290bb770"

http_archive(
name = "envoy",
Expand Down
17 changes: 12 additions & 5 deletions include/istio/control/http/report_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <chrono>
#include <map>

#include "google/protobuf/struct.pb.h"

namespace istio {
namespace control {
namespace http {
Expand All @@ -42,27 +44,32 @@ class ReportData {
int response_code;
std::string response_flags;
};
virtual void GetReportInfo(ReportInfo* info) const = 0;
virtual void GetReportInfo(ReportInfo *info) const = 0;

// Get destination ip/port.
virtual bool GetDestinationIpPort(std::string* ip, int* port) const = 0;
virtual bool GetDestinationIpPort(std::string *ip, int *port) const = 0;

// Get Rbac attributes.
struct RbacReportInfo {
std::string permissive_resp_code;
std::string permissive_policy_id;
};
virtual bool GetRbacReportInfo(RbacReportInfo* report_info) const = 0;
virtual bool GetRbacReportInfo(RbacReportInfo *report_info) const = 0;

// Get upstream host UID. This value overrides the value in the report bag.
virtual bool GetDestinationUID(std::string* uid) const = 0;
virtual bool GetDestinationUID(std::string *uid) const = 0;

// gRPC status info
struct GrpcStatus {
std::string status;
std::string message;
};
virtual bool GetGrpcStatus(GrpcStatus* status) const = 0;
virtual bool GetGrpcStatus(GrpcStatus *status) const = 0;

// Get dynamic metadata generated by Envoy filters.
// Useful for logging info generated by custom codecs.
virtual const ::google::protobuf::Map<std::string, ::google::protobuf::Struct>
&GetDynamicFilterState() const = 0;
};

} // namespace http
Expand Down
14 changes: 11 additions & 3 deletions include/istio/control/tcp/report_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#include <chrono>
#include <string>

#include "google/protobuf/struct.pb.h"

namespace istio {
namespace control {
namespace tcp {
Expand All @@ -30,18 +32,18 @@ class ReportData {
virtual ~ReportData() {}

// Get upstream tcp connection IP and port. IP is returned in format of bytes.
virtual bool GetDestinationIpPort(std::string* ip, int* port) const = 0;
virtual bool GetDestinationIpPort(std::string *ip, int *port) const = 0;

// Get additional report data.
struct ReportInfo {
uint64_t send_bytes;
uint64_t received_bytes;
std::chrono::nanoseconds duration;
};
virtual void GetReportInfo(ReportInfo* info) const = 0;
virtual void GetReportInfo(ReportInfo *info) const = 0;

// Get upstream host UID. This value overrides the value in the report bag.
virtual bool GetDestinationUID(std::string* uid) const = 0;
virtual bool GetDestinationUID(std::string *uid) const = 0;

// ConnectionEvent is used to indicates the tcp connection event in Report
// call.
Expand All @@ -50,6 +52,12 @@ class ReportData {
CLOSE,
CONTINUE,
};

// Get dynamic metadata generated by Envoy filters.
// Useful for logging info generated by custom codecs.
virtual const ::google::protobuf::Map<::std::string,
::google::protobuf::Struct>
&GetDynamicFilterState() const = 0;
};

} // namespace tcp
Expand Down
60 changes: 41 additions & 19 deletions include/istio/utils/attributes_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,32 @@ namespace utils {
// .Add("key2", value2);
class AttributesBuilder {
public:
AttributesBuilder(::istio::mixer::v1::Attributes* attributes)
AttributesBuilder(::istio::mixer::v1::Attributes *attributes)
: attributes_(attributes) {}

void AddString(const std::string& key, const std::string& str) {
void AddString(const std::string &key, const std::string &str) {
(*attributes_->mutable_attributes())[key].set_string_value(str);
}

void AddBytes(const std::string& key, const std::string& bytes) {
void AddBytes(const std::string &key, const std::string &bytes) {
(*attributes_->mutable_attributes())[key].set_bytes_value(bytes);
}

void AddInt64(const std::string& key, int64_t value) {
void AddInt64(const std::string &key, int64_t value) {
(*attributes_->mutable_attributes())[key].set_int64_value(value);
}

void AddDouble(const std::string& key, double value) {
void AddDouble(const std::string &key, double value) {
(*attributes_->mutable_attributes())[key].set_double_value(value);
}

void AddBool(const std::string& key, bool value) {
void AddBool(const std::string &key, bool value) {
(*attributes_->mutable_attributes())[key].set_bool_value(value);
}

void AddTimestamp(
const std::string& key,
const std::chrono::time_point<std::chrono::system_clock>& value) {
const std::string &key,
const std::chrono::time_point<std::chrono::system_clock> &value) {
auto time_stamp =
(*attributes_->mutable_attributes())[key].mutable_timestamp_value();
long long nanos = std::chrono::duration_cast<std::chrono::nanoseconds>(
Expand All @@ -67,38 +67,38 @@ class AttributesBuilder {
time_stamp->set_nanos(nanos % 1000000000);
}

void AddDuration(const std::string& key,
const std::chrono::nanoseconds& value) {
void AddDuration(const std::string &key,
const std::chrono::nanoseconds &value) {
auto duration =
(*attributes_->mutable_attributes())[key].mutable_duration_value();
duration->set_seconds(value.count() / 1000000000);
duration->set_nanos(value.count() % 1000000000);
}

void AddStringMap(const std::string& key,
const std::map<std::string, std::string>& string_map) {
void AddStringMap(const std::string &key,
const std::map<std::string, std::string> &string_map) {
if (string_map.size() == 0) {
return;
}
auto entries = (*attributes_->mutable_attributes())[key]
.mutable_string_map_value()
->mutable_entries();
entries->clear();
for (const auto& map_it : string_map) {
for (const auto &map_it : string_map) {
(*entries)[map_it.first] = map_it.second;
}
}

void AddProtoStructStringMap(const std::string& key,
const google::protobuf::Struct& struct_map) {
void AddProtoStructStringMap(const std::string &key,
const google::protobuf::Struct &struct_map) {
if (struct_map.fields().empty()) {
return;
}
auto entries = (*attributes_->mutable_attributes())[key]
.mutable_string_map_value()
->mutable_entries();
entries->clear();
for (const auto& field : struct_map.fields()) {
for (const auto &field : struct_map.fields()) {
// Ignore all fields that are not string or string list.
switch (field.second.kind_case()) {
case google::protobuf::Value::kStringValue:
Expand All @@ -122,15 +122,37 @@ class AttributesBuilder {
break;
}
}

if (entries->empty()) {
attributes_->mutable_attributes()->erase(key);
}
}

// Serializes all the keys in a map<string, struct> and builds attributes.
// for example, foo.bar.com: struct {str:abc, list:[c,d,e]} will be emitted as
// foo.bar.com: string_map[str:abc, list: c,d,e]
// Only extracts strings and lists.
// TODO: add the ability to pack bools and nums as strings and recurse down
// the struct.
void FlattenMapOfStringToStruct(
const ::google::protobuf::Map<::std::string, ::google::protobuf::Struct>
&filter_state) {
if (filter_state.empty()) {
return;
}

for (const auto &filter : filter_state) {
AddProtoStructStringMap(filter.first, filter.second);
}
}

bool HasAttribute(const std::string& key) const {
const auto& attrs_map = attributes_->attributes();
bool HasAttribute(const std::string &key) const {
const auto &attrs_map = attributes_->attributes();
return attrs_map.find(key) != attrs_map.end();
}

private:
::istio::mixer::v1::Attributes* attributes_;
::istio::mixer::v1::Attributes *attributes_;
};

} // namespace utils
Expand Down
2 changes: 1 addition & 1 deletion istio.deps
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
"name": "ENVOY_SHA",
"repoName": "envoyproxy/envoy",
"file": "WORKSPACE",
"lastStableSHA": "c41fa7118e69a0872074d7a685a62331c5d5c17e"
"lastStableSHA": "74de08a0d4d31bd466639d25d681df5d290bb770"
}
]
7 changes: 7 additions & 0 deletions src/envoy/http/mixer/report_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "envoy/http/header_map.h"
#include "envoy/stream_info/stream_info.h"
#include "extensions/filters/http/well_known_names.h"
#include "google/protobuf/struct.pb.h"
#include "include/istio/control/http/controller.h"
#include "src/envoy/utils/utils.h"

Expand Down Expand Up @@ -156,6 +157,12 @@ class ReportData : public ::istio::control::http::ReportData,
return !report_info->permissive_resp_code.empty() ||
!report_info->permissive_policy_id.empty();
}

// Get attributes generated by http filters
const ::google::protobuf::Map<std::string, ::google::protobuf::Struct>
&GetDynamicFilterState() const override {
return info_.dynamicMetadata().filter_metadata();
}
};

} // namespace Mixer
Expand Down
31 changes: 19 additions & 12 deletions src/envoy/tcp/mixer/filter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace Envoy {
namespace Tcp {
namespace Mixer {

Filter::Filter(Control& control) : control_(control) {
Filter::Filter(Control &control) : control_(control) {
ENVOY_LOG(debug, "Called tcp filter: {}", __func__);
}

Expand All @@ -34,7 +34,7 @@ Filter::~Filter() {
}

void Filter::initializeReadFilterCallbacks(
Network::ReadFilterCallbacks& callbacks) {
Network::ReadFilterCallbacks &callbacks) {
ENVOY_LOG(debug, "Called tcp filter: {}", __func__);
filter_callbacks_ = &callbacks;
filter_callbacks_->connection().addConnectionCallbacks(*this);
Expand All @@ -60,14 +60,14 @@ void Filter::callCheck() {
state_ = State::Calling;
filter_callbacks_->connection().readDisable(true);
calling_check_ = true;
cancel_check_ = handler_->Check(this, [this](const CheckResponseInfo& info) {
cancel_check_ = handler_->Check(this, [this](const CheckResponseInfo &info) {
completeCheck(info.response_status);
});
calling_check_ = false;
}

// Network::ReadFilter
Network::FilterStatus Filter::onData(Buffer::Instance& data, bool) {
Network::FilterStatus Filter::onData(Buffer::Instance &data, bool) {
if (state_ == State::NotStarted) {
// By waiting to invoke the callCheck() at onData(), the call to Mixer
// will have sufficient SSL information to fill the check Request.
Expand All @@ -83,7 +83,7 @@ Network::FilterStatus Filter::onData(Buffer::Instance& data, bool) {
}

// Network::WriteFilter
Network::FilterStatus Filter::onWrite(Buffer::Instance& data, bool) {
Network::FilterStatus Filter::onWrite(Buffer::Instance &data, bool) {
ENVOY_CONN_LOG(debug, "Called tcp filter onWrite bytes: {}",
filter_callbacks_->connection(), data.length());
send_bytes_ += data.length();
Expand All @@ -101,7 +101,7 @@ Network::FilterStatus Filter::onNewConnection() {
return Network::FilterStatus::Continue;
}

void Filter::completeCheck(const Status& status) {
void Filter::completeCheck(const Status &status) {
ENVOY_LOG(debug, "Called tcp filter completeCheck: {}", status.ToString());
cancel_check_ = nullptr;
if (state_ == State::Closed) {
Expand Down Expand Up @@ -146,39 +146,46 @@ void Filter::onEvent(Network::ConnectionEvent event) {
}
}

bool Filter::GetSourceIpPort(std::string* str_ip, int* port) const {
bool Filter::GetSourceIpPort(std::string *str_ip, int *port) const {
return Utils::GetIpPort(filter_callbacks_->connection().remoteAddress()->ip(),
str_ip, port);
}
bool Filter::GetPrincipal(bool peer, std::string* user) const {
bool Filter::GetPrincipal(bool peer, std::string *user) const {
return Utils::GetPrincipal(&filter_callbacks_->connection(), peer, user);
}

bool Filter::IsMutualTLS() const {
return Utils::IsMutualTLS(&filter_callbacks_->connection());
}

bool Filter::GetRequestedServerName(std::string* name) const {
bool Filter::GetRequestedServerName(std::string *name) const {
return Utils::GetRequestedServerName(&filter_callbacks_->connection(), name);
}

bool Filter::GetDestinationIpPort(std::string* str_ip, int* port) const {
bool Filter::GetDestinationIpPort(std::string *str_ip, int *port) const {
if (filter_callbacks_->upstreamHost() &&
filter_callbacks_->upstreamHost()->address()) {
return Utils::GetIpPort(filter_callbacks_->upstreamHost()->address()->ip(),
str_ip, port);
}
return false;
}
bool Filter::GetDestinationUID(std::string* uid) const {
bool Filter::GetDestinationUID(std::string *uid) const {
if (filter_callbacks_->upstreamHost()) {
return Utils::GetDestinationUID(
*filter_callbacks_->upstreamHost()->metadata(), uid);
}
return false;
}
const ::google::protobuf::Map<std::string, ::google::protobuf::Struct>
&Filter::GetDynamicFilterState() const {
return filter_callbacks_->connection()
.streamInfo()
.dynamicMetadata()
.filter_metadata();
}
void Filter::GetReportInfo(
::istio::control::tcp::ReportData::ReportInfo* data) const {
::istio::control::tcp::ReportData::ReportInfo *data) const {
data->received_bytes = received_bytes_;
data->send_bytes = send_bytes_;
data->duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
Expand Down
Loading