diff --git a/include/istio/control/http/report_data.h b/include/istio/control/http/report_data.h index 23ad4b27777..11b1e7e9f59 100644 --- a/include/istio/control/http/report_data.h +++ b/include/istio/control/http/report_data.h @@ -47,6 +47,13 @@ class ReportData { // Get destination ip/port. 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; + // Get upstream host UID. This value overrides the value in the report bag. virtual bool GetDestinationUID(std::string* uid) const = 0; diff --git a/include/istio/utils/attribute_names.h b/include/istio/utils/attribute_names.h index 3f47247131f..90bafc9f8d3 100644 --- a/include/istio/utils/attribute_names.h +++ b/include/istio/utils/attribute_names.h @@ -95,6 +95,9 @@ struct AttributeName { static const char kResponseGrpcStatus[]; static const char kResponseGrpcMessage[]; + + static const char kRbacPermissiveResponseCode[]; + static const char kRbacPermissivePolicyId[]; }; } // namespace utils diff --git a/src/envoy/http/mixer/report_data.h b/src/envoy/http/mixer/report_data.h index cb27f67cc38..02013e1f9cb 100644 --- a/src/envoy/http/mixer/report_data.h +++ b/src/envoy/http/mixer/report_data.h @@ -18,6 +18,7 @@ #include "common/request_info/utility.h" #include "envoy/http/header_map.h" #include "envoy/request_info/request_info.h" +#include "extensions/filters/http/well_known_names.h" #include "include/istio/control/http/controller.h" #include "src/envoy/utils/utils.h" @@ -25,6 +26,9 @@ namespace Envoy { namespace Http { namespace Mixer { namespace { +const std::string kRbacPermissivePolicyIDField = "shadow_effective_policyID"; +const std::string kRbacPermissiveRespCodeField = "shadow_response_code"; + // Set of headers excluded from response.headers attribute. const std::set ResponseHeaderExclusives = {}; @@ -114,6 +118,32 @@ class ReportData : public ::istio::control::http::ReportData { return ExtractGrpcStatus(trailers_, status) || ExtractGrpcStatus(headers_, status); } + + // Get Rbac related attributes. + bool GetRbacReportInfo(RbacReportInfo *report_info) const override { + const auto filter_meta = info_.dynamicMetadata().filter_metadata(); + const auto filter_it = + filter_meta.find(Extensions::HttpFilters::HttpFilterNames::get().Rbac); + if (filter_it == filter_meta.end()) { + return false; + } + + const auto &data_struct = filter_it->second; + const auto resp_code_it = + data_struct.fields().find(kRbacPermissiveRespCodeField); + if (resp_code_it != data_struct.fields().end()) { + report_info->permissive_resp_code = resp_code_it->second.string_value(); + } + + const auto policy_id_it = + data_struct.fields().find(kRbacPermissivePolicyIDField); + if (policy_id_it != data_struct.fields().end()) { + report_info->permissive_policy_id = policy_id_it->second.string_value(); + } + + return !report_info->permissive_resp_code.empty() || + !report_info->permissive_policy_id.empty(); + } }; } // namespace Mixer diff --git a/src/istio/control/http/attributes_builder.cc b/src/istio/control/http/attributes_builder.cc index 2650c196836..f314545fd66 100644 --- a/src/istio/control/http/attributes_builder.cc +++ b/src/istio/control/http/attributes_builder.cc @@ -229,6 +229,18 @@ void AttributesBuilder::ExtractReportAttributes(ReportData *report_data) { builder.AddString(utils::AttributeName::kContextProxyErrorCode, info.response_flags); + + ReportData::RbacReportInfo rbac_info; + if (report_data->GetRbacReportInfo(&rbac_info)) { + if (!rbac_info.permissive_resp_code.empty()) { + builder.AddString(utils::AttributeName::kRbacPermissiveResponseCode, + rbac_info.permissive_resp_code); + } + if (!rbac_info.permissive_policy_id.empty()) { + builder.AddString(utils::AttributeName::kRbacPermissivePolicyId, + rbac_info.permissive_policy_id); + } + } } } // namespace http diff --git a/src/istio/control/http/attributes_builder_test.cc b/src/istio/control/http/attributes_builder_test.cc index 7a0f7c31c12..dda7defd60e 100644 --- a/src/istio/control/http/attributes_builder_test.cc +++ b/src/istio/control/http/attributes_builder_test.cc @@ -342,6 +342,18 @@ attributes { string_value: "NR" } } +attributes { + key: "rbac.permissive.response_code" + value { + string_value: "403" + } +} +attributes { + key: "rbac.permissive.effective_policy_id" + value { + string_value: "policy-foo" + } +} )"; void ClearContextTime(const std::string &name, RequestContext *request) { @@ -561,6 +573,12 @@ TEST(AttributesBuilderTest, TestReportAttributes) { status->message = "grpc-message"; return true; })); + EXPECT_CALL(mock_data, GetRbacReportInfo(_)) + .WillOnce(Invoke([](ReportData::RbacReportInfo *report_info) -> bool { + report_info->permissive_resp_code = "403"; + report_info->permissive_policy_id = "policy-foo"; + return true; + })); RequestContext request; AttributesBuilder builder(&request); @@ -610,6 +628,12 @@ TEST(AttributesBuilderTest, TestReportAttributesWithDestIP) { info->response_flags = "NR"; })); EXPECT_CALL(mock_data, GetGrpcStatus(_)).WillOnce(testing::Return(false)); + EXPECT_CALL(mock_data, GetRbacReportInfo(_)) + .WillOnce(Invoke([](ReportData::RbacReportInfo *report_info) -> bool { + report_info->permissive_resp_code = "403"; + report_info->permissive_policy_id = "policy-foo"; + return true; + })); RequestContext request; SetDestinationIp(&request, "1.2.3.4"); diff --git a/src/istio/control/http/mock_report_data.h b/src/istio/control/http/mock_report_data.h index 26ca3830133..423a1b6ef4f 100644 --- a/src/istio/control/http/mock_report_data.h +++ b/src/istio/control/http/mock_report_data.h @@ -31,6 +31,7 @@ class MockReportData : public ReportData { MOCK_CONST_METHOD2(GetDestinationIpPort, bool(std::string* ip, int* port)); MOCK_CONST_METHOD1(GetDestinationUID, bool(std::string* ip)); MOCK_CONST_METHOD1(GetGrpcStatus, bool(GrpcStatus* status)); + MOCK_CONST_METHOD1(GetRbacReportInfo, bool(RbacReportInfo* info)); }; } // namespace http diff --git a/src/istio/utils/attribute_names.cc b/src/istio/utils/attribute_names.cc index 9b6981b6619..3a9677fd147 100644 --- a/src/istio/utils/attribute_names.cc +++ b/src/istio/utils/attribute_names.cc @@ -91,5 +91,11 @@ const char AttributeName::kRequestAuthRawClaims[] = "request.auth.raw_claims"; const char AttributeName::kResponseGrpcStatus[] = "response.grpc_status"; const char AttributeName::kResponseGrpcMessage[] = "response.grpc_message"; +// Rbac attributes +const char AttributeName::kRbacPermissiveResponseCode[] = + "rbac.permissive.response_code"; +const char AttributeName::kRbacPermissivePolicyId[] = + "rbac.permissive.effective_policy_id"; + } // namespace utils } // namespace istio