-
Notifications
You must be signed in to change notification settings - Fork 5.5k
filter: add conditions to access control filter #7716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 16 commits
3d4f7aa
beb197c
e914f46
ec74571
97efd6d
f3668b2
dca0933
8e80999
970b361
ebf4c4a
d1fd462
1235c7d
41220da
982e3fd
c31b4a7
e309dd8
6cdbe8e
f934dda
bf99900
6861b98
b27790a
9393ca9
5d44fea
784a970
c081695
9f812b5
184fe6b
811fba6
64c9201
684d473
08fe702
580a79f
8f72a50
a2a9a7f
f86eadf
b9c755c
532ed67
c1f1890
aed67b6
76b6788
a0daefa
753b352
8df3414
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,10 +24,10 @@ REPOSITORY_LOCATIONS = dict( | |
| urls = ["https://commondatastorage.googleapis.com/chromium-boringssl-docs/fips/boringssl-66005f41fbc3529ffe8d007708756720529da20d.tar.xz"], | ||
| ), | ||
| com_google_absl = dict( | ||
| sha256 = "7ddf863ddced6fa5bf7304103f9c7aa619c20a2fcf84475512c8d3834b9d14fa", | ||
| strip_prefix = "abseil-cpp-61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529", | ||
| # 2019-06-05 | ||
| urls = ["https://github.com/abseil/abseil-cpp/archive/61c9bf3e3e1c28a4aa6d7f1be4b37fd473bb5529.tar.gz"], | ||
| sha256 = "05a97ad5bb123ee3f6d65c7b06f6d7de5ce62e4fb971cbe4b5e391dd69704bb7", | ||
| strip_prefix = "abseil-cpp-ad1485c8986246b2ae9105e512738d0e97aec887", | ||
| # 2019-07-24 | ||
| urls = ["https://github.com/abseil/abseil-cpp/archive/ad1485c8986246b2ae9105e512738d0e97aec887.tar.gz"], | ||
| ), | ||
| com_github_apache_thrift = dict( | ||
| sha256 = "7d59ac4fdcb2c58037ebd4a9da5f9a49e3e034bf75b3f26d9fe48ba3d8806e6b", | ||
|
|
@@ -247,4 +247,14 @@ REPOSITORY_LOCATIONS = dict( | |
| sha256 = "fcdebf54c89d839ffa7eefae166c8e4b551c765559db13ff15bff98047f344fb", | ||
| urls = ["https://storage.googleapis.com/quiche-envoy-integration/2a930469533c3b541443488a629fe25cd8ff53d0.tar.gz"], | ||
| ), | ||
| com_google_cel_cpp = dict( | ||
| sha256 = "a0e6a6ccf25c1e57ba3c7a997edd9279f8e0b0112e0a3ac705a5568fa32792fc", | ||
| strip_prefix = "cel-cpp-d56f26adb53d0f41508a909d15e74d9ffb0e8a6c", | ||
| urls = ["https://github.com/google/cel-cpp/archive/d56f26adb53d0f41508a909d15e74d9ffb0e8a6c.tar.gz"], | ||
| ), | ||
| com_google_re2 = dict( | ||
|
kyessenov marked this conversation as resolved.
Outdated
|
||
| sha256 = "f31db9cd224d018a7e4fe88ef84aaa874b0b3ed91d4d98ee5a1531101d3fdc64", | ||
| strip_prefix = "re2-87e2ad45e7b18738e1551474f7ee5886ff572059", | ||
| urls = ["https://github.com/google/re2/archive/87e2ad45e7b18738e1551474f7ee5886ff572059.tar.gz"], | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kyessenov qq: does cel-cpp rely on specific commit of re2? Asking because it might conflict with #7878, or latest release (2019-08-01) is fine? cc @mattklein123
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There should be no difference between which version is used. I think I chose the latest version which I started this PR.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK that's fine.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was going to ask the same question. I'll switch this back a release version of re2 on a subsequent dependency PR.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will just fix this when I merge master.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Happy to help if necessary. Google3 doesn't really have versions for its repositories, and the upstream cel-cpp is continuously tested against head. |
||
| ), | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| licenses(["notice"]) # Apache 2 | ||
|
|
||
| load( | ||
| "//bazel:envoy_build_system.bzl", | ||
| "envoy_cc_library", | ||
| "envoy_package", | ||
| ) | ||
|
|
||
| envoy_package() | ||
|
|
||
| envoy_cc_library( | ||
| name = "evaluator_lib", | ||
| srcs = ["evaluator.cc"], | ||
| hdrs = ["evaluator.h"], | ||
| deps = [ | ||
| ":context_lib", | ||
| "//source/common/http:utility_lib", | ||
| "//source/common/protobuf", | ||
| "@com_google_cel_cpp//eval/public:builtin_func_registrar", | ||
| "@com_google_cel_cpp//eval/public:cel_expr_builder_factory", | ||
| "@com_google_cel_cpp//eval/public:cel_expression", | ||
| "@com_google_cel_cpp//eval/public:cel_value", | ||
| ], | ||
| ) | ||
|
|
||
| envoy_cc_library( | ||
| name = "context_lib", | ||
| srcs = ["context.cc"], | ||
| hdrs = ["context.h"], | ||
| deps = [ | ||
| "//source/common/http:utility_lib", | ||
| "@com_google_cel_cpp//eval/public:cel_value", | ||
| ], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| #include "extensions/filters/common/expr/context.h" | ||
|
|
||
| #include "absl/strings/numbers.h" | ||
| #include "absl/time/time.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Extensions { | ||
| namespace Filters { | ||
| namespace Common { | ||
| namespace Expr { | ||
|
|
||
| namespace { | ||
|
|
||
| absl::optional<CelValue> convertHeaderEntry(const Http::HeaderEntry* header) { | ||
| if (header == nullptr) { | ||
| return {}; | ||
| } | ||
| return CelValue::CreateString(header->value().getStringView()); | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| absl::optional<CelValue> HeadersWrapper::operator[](CelValue key) const { | ||
| if (!key.IsString()) { | ||
| return {}; | ||
| } | ||
| auto out = headers_.get(Http::LowerCaseString(std::string(key.StringOrDie().value()))); | ||
| return convertHeaderEntry(out); | ||
| } | ||
|
|
||
| absl::optional<CelValue> RequestWrapper::operator[](CelValue key) const { | ||
| if (!key.IsString()) { | ||
| return {}; | ||
| } | ||
| auto value = key.StringOrDie().value(); | ||
| if (value == Path) { | ||
| return convertHeaderEntry(wrapper_.headers_.Path()); | ||
| } else if (value == Host) { | ||
| return convertHeaderEntry(wrapper_.headers_.Host()); | ||
| } else if (value == Scheme) { | ||
| return convertHeaderEntry(wrapper_.headers_.Scheme()); | ||
| } else if (value == Method) { | ||
| return convertHeaderEntry(wrapper_.headers_.Method()); | ||
| } else if (value == Referer) { | ||
| return convertHeaderEntry(wrapper_.headers_.Referer()); | ||
| } else if (value == Headers) { | ||
| return CelValue::CreateMap(&wrapper_); | ||
| } else if (value == Time) { | ||
| return CelValue::CreateTimestamp(absl::FromChrono(info_.startTime())); | ||
| } else if (value == ID) { | ||
| return convertHeaderEntry(wrapper_.headers_.RequestId()); | ||
| } else if (value == UserAgent) { | ||
| return convertHeaderEntry(wrapper_.headers_.UserAgent()); | ||
| } else if (value == Size) { | ||
|
kyessenov marked this conversation as resolved.
|
||
| // it is important to make a choice whether to rely on content-length vs stream info | ||
| // (which is not available at the time of the request headers) | ||
| auto length_header = wrapper_.headers_.ContentLength(); | ||
| if (length_header != nullptr) { | ||
| int64_t length; | ||
| if (absl::SimpleAtoi(length_header->value().getStringView(), &length)) { | ||
| return CelValue::CreateInt64(length); | ||
| } | ||
| } | ||
| } else if (value == TotalSize) { | ||
| return CelValue::CreateInt64(info_.bytesReceived() + wrapper_.headers_.byteSize()); | ||
| } else if (value == Duration) { | ||
| auto duration = info_.requestComplete(); | ||
| if (duration.has_value()) { | ||
| return CelValue::CreateDuration(absl::FromChrono(duration.value())); | ||
| } | ||
| } | ||
| return {}; | ||
| } | ||
|
|
||
| absl::optional<CelValue> ResponseWrapper::operator[](CelValue key) const { | ||
| if (!key.IsString()) { | ||
| return {}; | ||
| } | ||
| auto value = key.StringOrDie().value(); | ||
| if (value == Code) { | ||
| auto code = info_.responseCode(); | ||
| if (code.has_value()) { | ||
| return CelValue::CreateInt64(code.value()); | ||
| } | ||
| } else if (value == Size) { | ||
| return CelValue::CreateInt64(info_.bytesSent()); | ||
| } | ||
| return {}; | ||
| } | ||
|
|
||
| absl::optional<CelValue> ConnectionWrapper::operator[](CelValue key) const { | ||
| if (!key.IsString()) { | ||
| return {}; | ||
| } | ||
| auto value = key.StringOrDie().value(); | ||
| if (value == LocalAddress) { | ||
| return CelValue::CreateString(info_.downstreamLocalAddress()->asStringView()); | ||
| } else if (value == LocalPort) { | ||
| if (info_.downstreamLocalAddress()->ip() != nullptr) { | ||
| return CelValue::CreateInt64(info_.downstreamLocalAddress()->ip()->port()); | ||
| } | ||
| } else if (value == RemoteAddress) { | ||
| return CelValue::CreateString(info_.downstreamRemoteAddress()->asStringView()); | ||
| } else if (value == RemotePort) { | ||
| if (info_.downstreamRemoteAddress()->ip() != nullptr) { | ||
| return CelValue::CreateInt64(info_.downstreamRemoteAddress()->ip()->port()); | ||
| } | ||
| } else if (value == UpstreamAddress) { | ||
| auto upstream_host = info_.upstreamHost(); | ||
| if (upstream_host != nullptr && upstream_host->address() != nullptr) { | ||
| return CelValue::CreateString(upstream_host->address()->asStringView()); | ||
| } | ||
| } else if (value == UpstreamPort) { | ||
| auto upstream_host = info_.upstreamHost(); | ||
| if (upstream_host != nullptr && upstream_host->address() != nullptr && | ||
| upstream_host->address()->ip() != nullptr) { | ||
| return CelValue::CreateInt64(upstream_host->address()->ip()->port()); | ||
| } | ||
| } | ||
|
|
||
| auto downstream_ssl = info_.downstreamSslConnection(); | ||
| if (downstream_ssl != nullptr) { | ||
| if (value == MTLS) { | ||
| return CelValue::CreateBool(downstream_ssl->peerCertificatePresented()); | ||
| } | ||
| } | ||
|
|
||
| return {}; | ||
| } | ||
|
|
||
| } // namespace Expr | ||
| } // namespace Common | ||
| } // namespace Filters | ||
| } // namespace Extensions | ||
| } // namespace Envoy | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| #pragma once | ||
|
|
||
| #include "envoy/stream_info/stream_info.h" | ||
|
|
||
| #include "common/http/headers.h" | ||
|
|
||
| #include "eval/public/cel_value.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Extensions { | ||
| namespace Filters { | ||
| namespace Common { | ||
| namespace Expr { | ||
|
|
||
| using CelValue = google::api::expr::runtime::CelValue; | ||
|
|
||
| // Symbols for traversing the request properties | ||
| constexpr absl::string_view Request = "request"; | ||
| constexpr absl::string_view Path = "path"; | ||
| constexpr absl::string_view Host = "host"; | ||
| constexpr absl::string_view Scheme = "scheme"; | ||
| constexpr absl::string_view Method = "method"; | ||
| constexpr absl::string_view Referer = "referer"; | ||
| constexpr absl::string_view Headers = "headers"; | ||
| constexpr absl::string_view Time = "time"; | ||
| constexpr absl::string_view ID = "id"; | ||
| constexpr absl::string_view UserAgent = "useragent"; | ||
|
kyessenov marked this conversation as resolved.
|
||
| constexpr absl::string_view Size = "size"; | ||
| constexpr absl::string_view TotalSize = "total_size"; | ||
| constexpr absl::string_view Duration = "duration"; | ||
|
|
||
| // Symbols for traversing the response properties | ||
| constexpr absl::string_view Response = "response"; | ||
| constexpr absl::string_view Code = "code"; | ||
|
|
||
| // Per-request or per-connection metadata | ||
| constexpr absl::string_view Metadata = "metadata"; | ||
|
|
||
| // Connection properties | ||
| constexpr absl::string_view Connection = "connection"; | ||
| constexpr absl::string_view LocalAddress = "local_address"; | ||
| constexpr absl::string_view LocalPort = "local_port"; | ||
| constexpr absl::string_view RemoteAddress = "remote_address"; | ||
| constexpr absl::string_view RemotePort = "remote_port"; | ||
| constexpr absl::string_view UpstreamAddress = "upstream_address"; | ||
| constexpr absl::string_view UpstreamPort = "upstream_port"; | ||
| constexpr absl::string_view MTLS = "mtls"; | ||
|
|
||
|
kyessenov marked this conversation as resolved.
|
||
| class RequestWrapper; | ||
|
|
||
| class HeadersWrapper : public google::api::expr::runtime::CelMap { | ||
|
kyessenov marked this conversation as resolved.
|
||
| public: | ||
| HeadersWrapper(const Http::HeaderMap& headers) : headers_(headers) {} | ||
| absl::optional<CelValue> operator[](CelValue key) const override; | ||
| int size() const override { return headers_.size(); } | ||
| bool empty() const override { return headers_.empty(); } | ||
| const google::api::expr::runtime::CelList* ListKeys() const override { return nullptr; } | ||
|
|
||
| private: | ||
| friend class RequestWrapper; | ||
| const Http::HeaderMap& headers_; | ||
| }; | ||
|
|
||
| class BaseWrapper : public google::api::expr::runtime::CelMap { | ||
| public: | ||
| int size() const override { return 0; } | ||
| bool empty() const override { return false; } | ||
|
kyessenov marked this conversation as resolved.
|
||
| const google::api::expr::runtime::CelList* ListKeys() const override { return nullptr; } | ||
| }; | ||
|
|
||
| class RequestWrapper : public BaseWrapper { | ||
|
kyessenov marked this conversation as resolved.
|
||
| public: | ||
| RequestWrapper(const Http::HeaderMap& headers, const StreamInfo::StreamInfo& info) | ||
| : wrapper_(headers), info_(info) {} | ||
| absl::optional<CelValue> operator[](CelValue key) const override; | ||
|
|
||
| private: | ||
| const HeadersWrapper wrapper_; | ||
| const StreamInfo::StreamInfo& info_; | ||
| }; | ||
|
|
||
| class ResponseWrapper : public BaseWrapper { | ||
| public: | ||
| ResponseWrapper(const StreamInfo::StreamInfo& info) : info_(info) {} | ||
| absl::optional<CelValue> operator[](CelValue key) const override; | ||
|
|
||
| private: | ||
| const StreamInfo::StreamInfo& info_; | ||
| }; | ||
|
|
||
| class ConnectionWrapper : public BaseWrapper { | ||
| public: | ||
| ConnectionWrapper(const StreamInfo::StreamInfo& info) : info_(info) {} | ||
| absl::optional<CelValue> operator[](CelValue key) const override; | ||
|
|
||
| private: | ||
| const StreamInfo::StreamInfo& info_; | ||
| }; | ||
|
|
||
| } // namespace Expr | ||
| } // namespace Common | ||
| } // namespace Filters | ||
| } // namespace Extensions | ||
| } // namespace Envoy | ||
Uh oh!
There was an error while loading. Please reload this page.