diff --git a/source/common/common/matchers.cc b/source/common/common/matchers.cc index 1026016fdd51..ac623b85ad8d 100644 --- a/source/common/common/matchers.cc +++ b/source/common/common/matchers.cc @@ -31,6 +31,8 @@ ValueMatcherConstSharedPtr ValueMatcher::create(const envoy::type::matcher::v3:: return std::make_shared(v.present_match()); case envoy::type::matcher::v3::ValueMatcher::MatchPatternCase::kListMatch: return std::make_shared(v.list_match()); + case envoy::type::matcher::v3::ValueMatcher::MatchPatternCase::kOrMatch: + return std::make_shared(v.or_match()); case envoy::type::matcher::v3::ValueMatcher::MatchPatternCase::MATCH_PATTERN_NOT_SET: break; // Fall through to PANIC. } @@ -88,6 +90,22 @@ bool ListMatcher::match(const ProtobufWkt::Value& value) const { return false; } +OrMatcher::OrMatcher(const envoy::type::matcher::v3::OrMatcher& matcher) { + or_matchers_.reserve(matcher.value_matchers().size()); + for (const auto& or_matcher : matcher.value_matchers()) { + or_matchers_.push_back(ValueMatcher::create(or_matcher)); + } +} + +bool OrMatcher::match(const ProtobufWkt::Value& value) const { + for (const auto& or_matcher : or_matchers_) { + if (or_matcher->match(value)) { + return true; + } + } + return false; +} + MetadataMatcher::MetadataMatcher(const envoy::type::matcher::v3::MetadataMatcher& matcher) : matcher_(matcher) { for (const auto& seg : matcher.path()) { diff --git a/source/common/common/matchers.h b/source/common/common/matchers.h index 5bdd03bb84a1..e96f3689322f 100644 --- a/source/common/common/matchers.h +++ b/source/common/common/matchers.h @@ -172,6 +172,16 @@ class ListMatcher : public ValueMatcher { ValueMatcherConstSharedPtr oneof_value_matcher_; }; +class OrMatcher : public ValueMatcher { +public: + OrMatcher(const envoy::type::matcher::v3::OrMatcher& matcher); + + bool match(const ProtobufWkt::Value& value) const override; + +private: + std::vector or_matchers_; +}; + class MetadataMatcher { public: MetadataMatcher(const envoy::type::matcher::v3::MetadataMatcher& matcher); diff --git a/test/common/common/matchers_test.cc b/test/common/common/matchers_test.cc index a07b7a00df35..68da1f973a22 100644 --- a/test/common/common/matchers_test.cc +++ b/test/common/common/matchers_test.cc @@ -184,6 +184,29 @@ TEST(MetadataTest, MatchPresentValue) { EXPECT_FALSE(Envoy::Matchers::MetadataMatcher(matcher).match(metadata)); } +TEST(MetadataTest, MatchStringOrBoolValue) { + envoy::config::core::v3::Metadata metadata; + Envoy::Config::Metadata::mutableMetadataValue(metadata, "envoy.filter.a", "label") + .set_string_value("test"); + Envoy::Config::Metadata::mutableMetadataValue(metadata, "envoy.filter.b", "label") + .set_bool_value(true); + Envoy::Config::Metadata::mutableMetadataValue(metadata, "envoy.filter.c", "label") + .set_bool_value(false); + + envoy::type::matcher::v3::MetadataMatcher matcher; + matcher.add_path()->set_key("label"); + + auto* or_match = matcher.mutable_value()->mutable_or_match(); + or_match->add_value_matchers()->mutable_string_match()->set_exact("test"); + or_match->add_value_matchers()->set_bool_match(true); + matcher.set_filter("envoy.filter.a"); + EXPECT_TRUE(Envoy::Matchers::MetadataMatcher(matcher).match(metadata)); + matcher.set_filter("envoy.filter.b"); + EXPECT_TRUE(Envoy::Matchers::MetadataMatcher(matcher).match(metadata)); + matcher.set_filter("envoy.filter.c"); + EXPECT_FALSE(Envoy::Matchers::MetadataMatcher(matcher).match(metadata)); +} + // Helper function to retrieve the reference of an entry in a ListMatcher from a MetadataMatcher. envoy::type::matcher::v3::ValueMatcher* listMatchEntry(envoy::type::matcher::v3::MetadataMatcher* matcher) {