diff --git a/include/istio/control/http/report_data.h b/include/istio/control/http/report_data.h index 8cf7326fe0f..f0eb939ef6d 100644 --- a/include/istio/control/http/report_data.h +++ b/include/istio/control/http/report_data.h @@ -49,6 +49,9 @@ class ReportData { // Get destination ip/port. virtual bool GetDestinationIpPort(std::string *ip, int *port) const = 0; + // Indicates whether the upstream connection is secure. + virtual bool IsUpstreamSecure() const = 0; + // Get Rbac attributes. struct RbacReportInfo { std::string permissive_resp_code; diff --git a/include/istio/control/tcp/report_data.h b/include/istio/control/tcp/report_data.h index 91a6b7241c0..99fd42412c5 100644 --- a/include/istio/control/tcp/report_data.h +++ b/include/istio/control/tcp/report_data.h @@ -45,6 +45,9 @@ class ReportData { // Get upstream host UID. This value overrides the value in the report bag. virtual bool GetDestinationUID(std::string *uid) const = 0; + // Indicates whether the upstream connection is secure. + virtual bool IsUpstreamSecure() const = 0; + // ConnectionEvent is used to indicates the tcp connection event in Report // call. enum ConnectionEvent { diff --git a/include/istio/utils/attribute_names.h b/include/istio/utils/attribute_names.h index 5c6f4b249c9..2e99064f367 100644 --- a/include/istio/utils/attribute_names.h +++ b/include/istio/utils/attribute_names.h @@ -78,6 +78,7 @@ struct AttributeName { static const char kConnectionDuration[]; static const char kConnectionMtls[]; static const char kConnectionRequestedServerName[]; + static const char kConnectionUpstreamSecure[]; static const char kConnectionId[]; // Record TCP connection status: open, continue, close static const char kConnectionEvent[]; diff --git a/src/envoy/http/mixer/report_data.h b/src/envoy/http/mixer/report_data.h index 33f4c6b0ed2..fc9407939ea 100644 --- a/src/envoy/http/mixer/report_data.h +++ b/src/envoy/http/mixer/report_data.h @@ -115,6 +115,16 @@ class ReportData : public ::istio::control::http::ReportData, return false; } + bool IsUpstreamSecure() const override { + if (info_.upstreamHost()) { + return info_.upstreamHost() + ->cluster() + .transportSocketFactory() + .implementsSecureTransport(); + } + return false; + } + bool GetGrpcStatus(GrpcStatus *status) const override { // Check trailer first. // If not response body, grpc-status is in response headers. diff --git a/src/envoy/tcp/mixer/filter.cc b/src/envoy/tcp/mixer/filter.cc index 822d130fb9f..2270ca385a7 100644 --- a/src/envoy/tcp/mixer/filter.cc +++ b/src/envoy/tcp/mixer/filter.cc @@ -219,6 +219,16 @@ bool Filter::GetDestinationUID(std::string *uid) const { return false; } +bool Filter::IsUpstreamSecure() const { + if (filter_callbacks_->upstreamHost()) { + return filter_callbacks_->upstreamHost() + ->cluster() + .transportSocketFactory() + .implementsSecureTransport(); + } + return false; +} + const ::google::protobuf::Map &Filter::GetDynamicFilterState() const { return cached_filter_metadata_; diff --git a/src/envoy/tcp/mixer/filter.h b/src/envoy/tcp/mixer/filter.h index cf59f1cdb88..939ef188a68 100644 --- a/src/envoy/tcp/mixer/filter.h +++ b/src/envoy/tcp/mixer/filter.h @@ -60,6 +60,7 @@ class Filter : public Network::Filter, // ReportData virtual functions. bool GetDestinationIpPort(std::string *str_ip, int *port) const override; bool GetDestinationUID(std::string *uid) const override; + bool IsUpstreamSecure() const override; const ::google::protobuf::Map &GetDynamicFilterState() const override; void GetReportInfo( diff --git a/src/envoy/utils/utils.h b/src/envoy/utils/utils.h index 3fa4aac5b21..3e2288fc523 100644 --- a/src/envoy/utils/utils.h +++ b/src/envoy/utils/utils.h @@ -20,6 +20,7 @@ #include "envoy/http/header_map.h" #include "envoy/network/connection.h" +#include "envoy/upstream/upstream.h" #include "google/protobuf/util/json_util.h" #include "include/istio/mixerclient/check_response.h" diff --git a/src/istio/control/http/attributes_builder.cc b/src/istio/control/http/attributes_builder.cc index 32ffa5c8423..2cf03563bea 100644 --- a/src/istio/control/http/attributes_builder.cc +++ b/src/istio/control/http/attributes_builder.cc @@ -222,6 +222,10 @@ void AttributesBuilder::ExtractReportAttributes( builder.AddString(utils::AttributeName::kDestinationUID, uid); } + if (report_data->IsUpstreamSecure()) { + builder.AddBool(utils::AttributeName::kConnectionUpstreamSecure, true); + } + std::map headers = report_data->GetResponseHeaders(); builder.AddStringMap(utils::AttributeName::kResponseHeaders, headers); diff --git a/src/istio/control/http/attributes_builder_test.cc b/src/istio/control/http/attributes_builder_test.cc index 09c84bc1567..eac8649847f 100644 --- a/src/istio/control/http/attributes_builder_test.cc +++ b/src/istio/control/http/attributes_builder_test.cc @@ -758,6 +758,7 @@ TEST(AttributesBuilderTest, TestReportAttributes) { *uid = "pod1.ns2"; return true; })); + EXPECT_CALL(mock_data, IsUpstreamSecure()).WillOnce(testing::Return(true)); EXPECT_CALL(mock_data, GetResponseHeaders()) .WillOnce(Invoke([]() -> std::map { std::map map; @@ -803,6 +804,9 @@ TEST(AttributesBuilderTest, TestReportAttributes) { (*expected_attributes .mutable_attributes())[utils::AttributeName::kDestinationUID] .set_string_value("pod1.ns2"); + (*expected_attributes + .mutable_attributes())[utils::AttributeName::kConnectionUpstreamSecure] + .set_bool_value(true); (*expected_attributes .mutable_attributes())[utils::AttributeName::kResponseGrpcStatus] .set_string_value("grpc-status"); @@ -838,6 +842,7 @@ TEST(AttributesBuilderTest, TestReportAttributesWithDestIP) { return true; })); EXPECT_CALL(mock_data, GetDestinationUID(_)).WillOnce(testing::Return(false)); + EXPECT_CALL(mock_data, IsUpstreamSecure()).WillOnce(testing::Return(false)); EXPECT_CALL(mock_data, GetResponseHeaders()) .WillOnce(Invoke([]() -> std::map { std::map map; diff --git a/src/istio/control/http/mock_report_data.h b/src/istio/control/http/mock_report_data.h index 64c0402ef9b..80bd9f4c449 100644 --- a/src/istio/control/http/mock_report_data.h +++ b/src/istio/control/http/mock_report_data.h @@ -30,6 +30,7 @@ class MockReportData : public ReportData { MOCK_CONST_METHOD1(GetReportInfo, void(ReportInfo *info)); MOCK_CONST_METHOD2(GetDestinationIpPort, bool(std::string *ip, int *port)); MOCK_CONST_METHOD1(GetDestinationUID, bool(std::string *ip)); + MOCK_CONST_METHOD0(IsUpstreamSecure, bool()); MOCK_CONST_METHOD1(GetGrpcStatus, bool(GrpcStatus *status)); MOCK_CONST_METHOD1(GetRbacReportInfo, bool(RbacReportInfo *info)); MOCK_CONST_METHOD0( diff --git a/src/istio/control/tcp/attributes_builder.cc b/src/istio/control/tcp/attributes_builder.cc index 782d0bdf6d1..d2d459384dd 100644 --- a/src/istio/control/tcp/attributes_builder.cc +++ b/src/istio/control/tcp/attributes_builder.cc @@ -133,6 +133,10 @@ void AttributesBuilder::ExtractReportAttributes( builder.AddString(utils::AttributeName::kDestinationUID, uid); } + if (report_data->IsUpstreamSecure()) { + builder.AddBool(utils::AttributeName::kConnectionUpstreamSecure, true); + } + builder.FlattenMapOfStringToStruct(report_data->GetDynamicFilterState()); builder.AddTimestamp(utils::AttributeName::kContextTime, diff --git a/src/istio/control/tcp/attributes_builder_test.cc b/src/istio/control/tcp/attributes_builder_test.cc index 5c9c4ab9119..afe35839a0b 100644 --- a/src/istio/control/tcp/attributes_builder_test.cc +++ b/src/istio/control/tcp/attributes_builder_test.cc @@ -138,6 +138,12 @@ attributes { int64_value: 0 } } +attributes { + key: "connection.upstream_secure" + value { + bool_value: true + } +} attributes { key: "context.time" value { @@ -256,6 +262,12 @@ attributes { string_value: "pod1.ns2" } } +attributes { + key: "connection.upstream_secure" + value { + bool_value: true + } +} attributes { key: "foo.bar.com" value { @@ -317,6 +329,12 @@ attributes { bytes_value: "1.2.3.4" } } +attributes { + key: "connection.upstream_secure" + value { + bool_value: true + } +} attributes { key: "destination.port" value { @@ -402,6 +420,12 @@ attributes { string_value: "pod1.ns2" } } +attributes { + key: "connection.upstream_secure" + value { + bool_value: true + } +} attributes { key: "foo.bar.com" value { @@ -501,6 +525,8 @@ TEST(AttributesBuilderTest, TestReportAttributes) { *uid = "pod1.ns2"; return true; })); + EXPECT_CALL(mock_data, IsUpstreamSecure()) + .WillRepeatedly(testing::Return(true)); EXPECT_CALL(mock_data, GetDynamicFilterState()) .Times(4) .WillRepeatedly(ReturnRef(filter_metadata)); diff --git a/src/istio/control/tcp/mock_report_data.h b/src/istio/control/tcp/mock_report_data.h index 85c749ff360..d3bf9ed655a 100644 --- a/src/istio/control/tcp/mock_report_data.h +++ b/src/istio/control/tcp/mock_report_data.h @@ -28,6 +28,7 @@ class MockReportData : public ReportData { public: MOCK_CONST_METHOD2(GetDestinationIpPort, bool(std::string *ip, int *port)); MOCK_CONST_METHOD1(GetDestinationUID, bool(std::string *)); + MOCK_CONST_METHOD0(IsUpstreamSecure, bool()); MOCK_CONST_METHOD0( GetDynamicFilterState, const ::google::protobuf::Map diff --git a/src/istio/utils/attribute_names.cc b/src/istio/utils/attribute_names.cc index 31c3fc9c542..2043dfaa2d0 100644 --- a/src/istio/utils/attribute_names.cc +++ b/src/istio/utils/attribute_names.cc @@ -75,6 +75,8 @@ const char AttributeName::kConnectionDuration[] = "connection.duration"; const char AttributeName::kConnectionMtls[] = "connection.mtls"; const char AttributeName::kConnectionRequestedServerName[] = "connection.requested_server_name"; +const char AttributeName::kConnectionUpstreamSecure[] = + "connection.upstream_secure"; // Downstream TCP connection id. const char AttributeName::kConnectionId[] = "connection.id";