/proc/self/cwd/source/extensions/filters/network/ext_authz/ext_authz.h
Line | Count | Source (jump to first uncovered line) |
1 | | #pragma once |
2 | | |
3 | | #include <cstdint> |
4 | | #include <memory> |
5 | | #include <string> |
6 | | #include <vector> |
7 | | |
8 | | #include "envoy/extensions/filters/network/ext_authz/v3/ext_authz.pb.h" |
9 | | #include "envoy/network/connection.h" |
10 | | #include "envoy/network/filter.h" |
11 | | #include "envoy/runtime/runtime.h" |
12 | | #include "envoy/service/auth/v3/external_auth.pb.h" |
13 | | #include "envoy/stats/scope.h" |
14 | | #include "envoy/stats/stats_macros.h" |
15 | | #include "envoy/upstream/cluster_manager.h" |
16 | | |
17 | | #include "source/common/common/matchers.h" |
18 | | #include "source/extensions/filters/common/ext_authz/ext_authz.h" |
19 | | #include "source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h" |
20 | | |
21 | | namespace Envoy { |
22 | | namespace Extensions { |
23 | | namespace NetworkFilters { |
24 | | namespace ExtAuthz { |
25 | | |
26 | | /** |
27 | | * All tcp external authorization stats. @see stats_macros.h |
28 | | */ |
29 | | #define ALL_TCP_EXT_AUTHZ_STATS(COUNTER, GAUGE) \ |
30 | 9 | COUNTER(cx_closed) \ |
31 | 9 | COUNTER(denied) \ |
32 | 9 | COUNTER(error) \ |
33 | 9 | COUNTER(failure_mode_allowed) \ |
34 | 9 | COUNTER(ok) \ |
35 | 9 | COUNTER(total) \ |
36 | 9 | COUNTER(disabled) \ |
37 | 9 | GAUGE(active, Accumulate) |
38 | | |
39 | | /** |
40 | | * Struct definition for all external authorization stats. @see stats_macros.h |
41 | | */ |
42 | | struct InstanceStats { |
43 | | ALL_TCP_EXT_AUTHZ_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT) |
44 | | }; |
45 | | |
46 | | /** |
47 | | * Global configuration for ExtAuthz filter. |
48 | | */ |
49 | | class Config { |
50 | | using LabelsMap = Protobuf::Map<std::string, std::string>; |
51 | | |
52 | | public: |
53 | | Config(const envoy::extensions::filters::network::ext_authz::v3::ExtAuthz& config, |
54 | | Stats::Scope& scope, envoy::config::bootstrap::v3::Bootstrap& bootstrap) |
55 | | : stats_(generateStats(config.stat_prefix(), scope)), |
56 | | failure_mode_allow_(config.failure_mode_allow()), |
57 | | include_peer_certificate_(config.include_peer_certificate()), |
58 | | filter_enabled_metadata_( |
59 | | config.has_filter_enabled_metadata() |
60 | | ? absl::optional<Matchers::MetadataMatcher>(config.filter_enabled_metadata()) |
61 | 9 | : absl::nullopt) { |
62 | 9 | auto labels_key_it = |
63 | 9 | bootstrap.node().metadata().fields().find(config.bootstrap_metadata_labels_key()); |
64 | 9 | if (labels_key_it != bootstrap.node().metadata().fields().end()) { |
65 | 0 | for (const auto& labels_it : labels_key_it->second.struct_value().fields()) { |
66 | 0 | destination_labels_[labels_it.first] = labels_it.second.string_value(); |
67 | 0 | } |
68 | 0 | } |
69 | 9 | } |
70 | | |
71 | 72 | const InstanceStats& stats() { return stats_; } |
72 | 0 | bool failureModeAllow() const { return failure_mode_allow_; } |
73 | 0 | void setFailModeAllow(bool value) { failure_mode_allow_ = value; } |
74 | 3 | bool includePeerCertificate() const { return include_peer_certificate_; } |
75 | 3 | const LabelsMap& destinationLabels() const { return destination_labels_; } |
76 | 243 | bool filterEnabledMetadata(const envoy::config::core::v3::Metadata& metadata) const { |
77 | 243 | return filter_enabled_metadata_.has_value() ? filter_enabled_metadata_->match(metadata) : true; |
78 | 243 | } |
79 | | |
80 | | private: |
81 | | static InstanceStats generateStats(const std::string& name, Stats::Scope& scope); |
82 | | const InstanceStats stats_; |
83 | | bool failure_mode_allow_; |
84 | | LabelsMap destination_labels_; |
85 | | const bool include_peer_certificate_; |
86 | | const absl::optional<Matchers::MetadataMatcher> filter_enabled_metadata_; |
87 | | }; |
88 | | |
89 | | using ConfigSharedPtr = std::shared_ptr<Config>; |
90 | | |
91 | | /** |
92 | | * ExtAuthz filter instance. This filter will call the Authorization service with the given |
93 | | * configuration parameters. If the authorization service returns an error or a deny the |
94 | | * connection will be closed without any further filters being called. Otherwise all buffered |
95 | | * data will be released to further filters. |
96 | | */ |
97 | | class Filter : public Network::ReadFilter, |
98 | | public Network::ConnectionCallbacks, |
99 | | public Filters::Common::ExtAuthz::RequestCallbacks { |
100 | | using LabelsMap = std::map<std::string, std::string>; |
101 | | |
102 | | public: |
103 | | Filter(ConfigSharedPtr config, Filters::Common::ExtAuthz::ClientPtr&& client) |
104 | 6 | : config_(config), client_(std::move(client)) {} |
105 | 6 | ~Filter() override = default; |
106 | | |
107 | | // Network::ReadFilter |
108 | | Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override; |
109 | | Network::FilterStatus onNewConnection() override; |
110 | 6 | void initializeReadFilterCallbacks(Network::ReadFilterCallbacks& callbacks) override { |
111 | 6 | filter_callbacks_ = &callbacks; |
112 | 6 | filter_callbacks_->connection().addConnectionCallbacks(*this); |
113 | 6 | } |
114 | | |
115 | | // Network::ConnectionCallbacks |
116 | | void onEvent(Network::ConnectionEvent event) override; |
117 | 0 | void onAboveWriteBufferHighWatermark() override {} |
118 | 0 | void onBelowWriteBufferLowWatermark() override {} |
119 | | |
120 | | // ExtAuthz::RequestCallbacks |
121 | | void onComplete(Filters::Common::ExtAuthz::ResponsePtr&&) override; |
122 | | |
123 | | private: |
124 | | // State of this filter's communication with the external authorization service. |
125 | | // The filter has either not started calling the external service, in the middle of calling |
126 | | // it or has completed. |
127 | | enum class Status { NotStarted, Calling, Complete }; |
128 | | // FilterReturn is used to capture what the return code should be to the filter chain. |
129 | | // if this filter is either in the middle of calling the external service or the result is denied |
130 | | // then the filter chain should stop. Otherwise the filter chain can continue to the next filter. |
131 | | enum class FilterReturn { Stop, Continue }; |
132 | | void callCheck(); |
133 | | |
134 | 243 | bool filterEnabled(const envoy::config::core::v3::Metadata& metadata) { |
135 | 243 | return config_->filterEnabledMetadata(metadata); |
136 | 243 | } |
137 | | absl::optional<MonotonicTime> start_time_; |
138 | | |
139 | | ConfigSharedPtr config_; |
140 | | Filters::Common::ExtAuthz::ClientPtr client_; |
141 | | Network::ReadFilterCallbacks* filter_callbacks_{}; |
142 | | Status status_{Status::NotStarted}; |
143 | | FilterReturn filter_return_{FilterReturn::Stop}; |
144 | | // Used to identify if the callback to onComplete() is synchronous (on the stack) or asynchronous. |
145 | | bool calling_check_{}; |
146 | | envoy::service::auth::v3::CheckRequest check_request_{}; |
147 | | }; |
148 | | } // namespace ExtAuthz |
149 | | } // namespace NetworkFilters |
150 | | } // namespace Extensions |
151 | | } // namespace Envoy |