From 489c3b5b64c9b5714b02b6d5e950261bb6d64d1a Mon Sep 17 00:00:00 2001 From: "data-plane-api(Azure Pipelines)" Date: Mon, 8 Mar 2021 20:25:20 +0000 Subject: [PATCH] matching: introduce consistent hashing matcher (#14875) This introduces a new matcher that allows matching on an input value by computing a hash value and matching if the value % (configured value) is greater than a configured threshold. This is useful in being able to define match criteria that should match for a certain % of input values in a way that is consistent between independent Envoy instances (e.g. it does not rely on a random input). Risk Level: Low, new extension Testing: UTs Docs Changes: Inline proto docs Release Notes: n/a Platform Specific Features: n/a Fixes #14782 Signed-off-by: Snow Pettersen Mirrored from https://github.com/envoyproxy/envoy @ 7fe3d358f7e7e4d4c7282d50c498a7ab0e759a36 --- BUILD | 1 + envoy/config/common/matcher/v3/matcher.proto | 1 + .../common/matcher/v4alpha/matcher.proto | 1 + .../consistent_hashing/v3/BUILD | 9 +++++ .../v3/consistent_hashing.proto | 39 +++++++++++++++++++ versioning/BUILD | 1 + 6 files changed, 52 insertions(+) create mode 100644 envoy/extensions/matching/input_matchers/consistent_hashing/v3/BUILD create mode 100644 envoy/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto diff --git a/BUILD b/BUILD index 7819919e..e1ec17a8 100644 --- a/BUILD +++ b/BUILD @@ -243,6 +243,7 @@ proto_library( "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", + "//envoy/extensions/matching/input_matchers/consistent_hashing/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/request_id/uuid/v3:pkg", diff --git a/envoy/config/common/matcher/v3/matcher.proto b/envoy/config/common/matcher/v3/matcher.proto index 3128d28e..aa49132c 100644 --- a/envoy/config/common/matcher/v3/matcher.proto +++ b/envoy/config/common/matcher/v3/matcher.proto @@ -59,6 +59,7 @@ message Matcher { type.matcher.v3.StringMatcher value_match = 2; // Extension for custom matching logic. + // [#extension-category: envoy.matching.input_matchers] core.v3.TypedExtensionConfig custom_match = 3; } } diff --git a/envoy/config/common/matcher/v4alpha/matcher.proto b/envoy/config/common/matcher/v4alpha/matcher.proto index 7c846e1e..586a4a92 100644 --- a/envoy/config/common/matcher/v4alpha/matcher.proto +++ b/envoy/config/common/matcher/v4alpha/matcher.proto @@ -75,6 +75,7 @@ message Matcher { type.matcher.v4alpha.StringMatcher value_match = 2; // Extension for custom matching logic. + // [#extension-category: envoy.matching.input_matchers] core.v4alpha.TypedExtensionConfig custom_match = 3; } } diff --git a/envoy/extensions/matching/input_matchers/consistent_hashing/v3/BUILD b/envoy/extensions/matching/input_matchers/consistent_hashing/v3/BUILD new file mode 100644 index 00000000..ee92fb65 --- /dev/null +++ b/envoy/extensions/matching/input_matchers/consistent_hashing/v3/BUILD @@ -0,0 +1,9 @@ +# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. + +load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") + +licenses(["notice"]) # Apache 2 + +api_proto_package( + deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"], +) diff --git a/envoy/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto b/envoy/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto new file mode 100644 index 00000000..acf4377f --- /dev/null +++ b/envoy/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto @@ -0,0 +1,39 @@ +syntax = "proto3"; + +package envoy.extensions.matching.input_matchers.consistent_hashing.v3; + +import "udpa/annotations/migrate.proto"; +import "udpa/annotations/status.proto"; +import "udpa/annotations/versioning.proto"; +import "validate/validate.proto"; + +option java_package = "io.envoyproxy.envoy.extensions.matching.input_matchers.consistent_hashing.v3"; +option java_outer_classname = "ConsistentHashingProto"; +option java_multiple_files = true; +option (udpa.annotations.file_status).package_version_status = ACTIVE; + +// [#protodoc-title: Consistent Hashing Matcher] +// [#extension: envoy.matching.input_matchers.consistent_hashing] + +// The consistent hashing matchers computes a consistent hash from the input and matches if the resulting hash +// is within the configured threshold. +// More specifically, this matcher evaluates to true if hash(input, seed) % modulo >= threshold. +// Note that the consistency of the match result relies on the internal hash function (xxhash) remaining +// unchanged. While this is unlikely to happen intentionally, this could cause inconsistent match results +// between deployments. +message ConsistentHashing { + // The threshold the resulting hash must be over in order for this matcher to evaluate to true. + // This value must be below the configured modulo value. + // Setting this to 0 is equivalent to this matcher always matching. + uint32 threshold = 1; + + // The value to use for the modulus in the calculation. This effectively bounds the hash output, + // specifying the range of possible values. + // This value must be above the configured threshold. + uint32 modulo = 2 [(validate.rules).uint32 = {gt: 0}]; + + // Optional seed passed through the hash function. This allows using additional information when computing + // the hash value: by changing the seed value, a different partition of matching and non-matching inputs will + // be created that remains consistent for that seed value. + uint64 seed = 3; +} diff --git a/versioning/BUILD b/versioning/BUILD index 642a034e..7043b99a 100644 --- a/versioning/BUILD +++ b/versioning/BUILD @@ -126,6 +126,7 @@ proto_library( "//envoy/extensions/internal_redirect/allow_listed_routes/v3:pkg", "//envoy/extensions/internal_redirect/previous_routes/v3:pkg", "//envoy/extensions/internal_redirect/safe_cross_scheme/v3:pkg", + "//envoy/extensions/matching/input_matchers/consistent_hashing/v3:pkg", "//envoy/extensions/network/socket_interface/v3:pkg", "//envoy/extensions/rate_limit_descriptors/expr/v3:pkg", "//envoy/extensions/request_id/uuid/v3:pkg",