matcher: add PathMatcher and use in routing, jwt and rbac (#10010)

Description: Add a new PathMatcher that strips the query and/or fragment string from the ":path" header before matching, use it in route, JWT and RBAC.
Risk Level: Low
Testing: Added unit tests and integration tests
Docs Changes: Updated types.rst for PathMatcher
Release Notes: Updated version_history.rst for RBAC API change

Signed-off-by: Yangmin Zhu <ymzhu@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ 7ea52d5e2b0bccbd3263a805e38778fa132b715d
master-ci-test
data-plane-api(CircleCI) 5 years ago
parent 2388a2e047
commit c78b01efa3
  1. 18
      envoy/config/rbac/v2/rbac.proto
  2. 18
      envoy/config/rbac/v3/rbac.proto
  3. 25
      envoy/type/matcher/path.proto
  4. 29
      envoy/type/matcher/v3/path.proto

@ -5,6 +5,7 @@ package envoy.config.rbac.v2;
import "envoy/api/v2/core/address.proto";
import "envoy/api/v2/route/route_components.proto";
import "envoy/type/matcher/metadata.proto";
import "envoy/type/matcher/path.proto";
import "envoy/type/matcher/string.proto";
import "google/api/expr/v1alpha1/syntax.proto";
@ -48,7 +49,8 @@ option java_multiple_files = true;
// - and_rules:
// rules:
// - header: { name: ":method", exact_match: "GET" }
// - header: { name: ":path", regex_match: "/products(/.*)?" }
// - url_path:
// path: { prefix: "/products" }
// - or_rules:
// rules:
// - destination_port: 80
@ -99,7 +101,7 @@ message Policy {
}
// Permission defines an action (or actions) that a principal can take.
// [#next-free-field: 10]
// [#next-free-field: 11]
message Permission {
// Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context,
// each are applied with the associated behavior.
@ -121,8 +123,13 @@ message Permission {
// A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only
// available for HTTP request.
// Note: the pseudo-header :path includes the query and fragment string. Use the `url_path`
// field if you want to match the URL path without the query and fragment string.
api.v2.route.HeaderMatcher header = 4;
// A URL path on the incoming HTTP request. Only available for HTTP.
type.matcher.PathMatcher url_path = 10;
// A CIDR block that describes the destination IP.
api.v2.core.CidrRange destination_ip = 5;
@ -161,7 +168,7 @@ message Permission {
}
// Principal defines an identity or a group of identities for a downstream subject.
// [#next-free-field: 9]
// [#next-free-field: 10]
message Principal {
// Used in the `and_ids` and `or_ids` fields in the `identifier` oneof. Depending on the context,
// each are applied with the associated behavior.
@ -199,8 +206,13 @@ message Principal {
// A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only
// available for HTTP request.
// Note: the pseudo-header :path includes the query and fragment string. Use the `url_path`
// field if you want to match the URL path without the query and fragment string.
api.v2.route.HeaderMatcher header = 6;
// A URL path on the incoming HTTP request. Only available for HTTP.
type.matcher.PathMatcher url_path = 9;
// Metadata that describes additional information about the principal.
type.matcher.MetadataMatcher metadata = 7;

@ -5,6 +5,7 @@ package envoy.config.rbac.v3;
import "envoy/config/core/v3/address.proto";
import "envoy/config/route/v3/route_components.proto";
import "envoy/type/matcher/v3/metadata.proto";
import "envoy/type/matcher/v3/path.proto";
import "envoy/type/matcher/v3/string.proto";
import "google/api/expr/v1alpha1/syntax.proto";
@ -50,7 +51,8 @@ option java_multiple_files = true;
// - and_rules:
// rules:
// - header: { name: ":method", exact_match: "GET" }
// - header: { name: ":path", regex_match: "/products(/.*)?" }
// - url_path:
// path: { prefix: "/products" }
// - or_rules:
// rules:
// - destination_port: 80
@ -105,7 +107,7 @@ message Policy {
}
// Permission defines an action (or actions) that a principal can take.
// [#next-free-field: 10]
// [#next-free-field: 11]
message Permission {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission";
@ -132,8 +134,13 @@ message Permission {
// A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only
// available for HTTP request.
// Note: the pseudo-header :path includes the query and fragment string. Use the `url_path`
// field if you want to match the URL path without the query and fragment string.
route.v3.HeaderMatcher header = 4;
// A URL path on the incoming HTTP request. Only available for HTTP.
type.matcher.v3.PathMatcher url_path = 10;
// A CIDR block that describes the destination IP.
core.v3.CidrRange destination_ip = 5;
@ -172,7 +179,7 @@ message Permission {
}
// Principal defines an identity or a group of identities for a downstream subject.
// [#next-free-field: 9]
// [#next-free-field: 10]
message Principal {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal";
@ -218,8 +225,13 @@ message Principal {
// A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only
// available for HTTP request.
// Note: the pseudo-header :path includes the query and fragment string. Use the `url_path`
// field if you want to match the URL path without the query and fragment string.
route.v3.HeaderMatcher header = 6;
// A URL path on the incoming HTTP request. Only available for HTTP.
type.matcher.v3.PathMatcher url_path = 9;
// Metadata that describes additional information about the principal.
type.matcher.v3.MetadataMatcher metadata = 7;

@ -0,0 +1,25 @@
syntax = "proto3";
package envoy.type.matcher;
import "envoy/type/matcher/string.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.type.matcher";
option java_outer_classname = "PathProto";
option java_multiple_files = true;
// [#protodoc-title: Path matcher]
// Specifies the way to match a path on HTTP request.
message PathMatcher {
oneof rule {
option (validate.required) = true;
// The `path` must match the URL path portion of the :path header. The query and fragment
// string (if present) are removed in the URL path portion.
// For example, the path */data* will match the *:path* header */data#fragment?param=value*.
StringMatcher path = 1 [(validate.rules).message = {required: true}];
}
}

@ -0,0 +1,29 @@
syntax = "proto3";
package envoy.type.matcher.v3;
import "envoy/type/matcher/v3/string.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.type.matcher.v3";
option java_outer_classname = "PathProto";
option java_multiple_files = true;
// [#protodoc-title: Path matcher]
// Specifies the way to match a path on HTTP request.
message PathMatcher {
option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.PathMatcher";
oneof rule {
option (validate.required) = true;
// The `path` must match the URL path portion of the :path header. The query and fragment
// string (if present) are removed in the URL path portion.
// For example, the path */data* will match the *:path* header */data#fragment?param=value*.
StringMatcher path = 1 [(validate.rules).message = {required: true}];
}
}
Loading…
Cancel
Save